/* client/inventory.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include "core/application.h" #include "client/inventory.h" #include "ui/label.h" #include "ui/listitem.h" #include "ui/paint.h" #include "ui/ui.h" #include namespace client { Inventory::Inventory(ui::Widget *parent) : ui::Window(parent) { menu_infotimestamp = 0; menu_inventorytimestamp = 0; menu_inforecord = 0; menu_amount = 0; menu_modelview = new ui::ModelView(this); menu_modelview->set_label("modelview"); menu_modelview->set_background(false); menu_modelview->set_border(false); menu_namelabel = new ui::Label(this); menu_namelabel->set_label("label"); menu_namelabel->set_background(false); menu_namelabel->set_border(false); menu_namelabel->set_font(ui::root()->font_large()); menu_namelabel->set_alignment(ui::AlignCenter); menu_namelabel->set_text("Inventory"); menu_listview = new ui::ListView(this); menu_listview->set_label("listview"); menu_listview->set_background(false); menu_listview->set_border(true); menu_inventorytext = new ui::PlainText(this); menu_inventorytext->set_label("inventorytext"); menu_inventorytext->set_background(false); menu_inventorytext->set_border(false); menu_inventorytext->set_font(ui::root()->font_small()); menu_scrollpane = new ui::ScrollPane(this, menu_infotext); menu_scrollpane->set_background(false); menu_scrollpane->set_border(false); menu_scrollpane->set_alignment(ui::AlignTop); menu_shipbutton = new ui::IconButton(this, "bitmaps/icons/button_ship"); hide(); } Inventory::~Inventory() { } void Inventory::toggle() { if (visible()) hide(); else show(); } void Inventory::update_inventory() { menu_listview->clear(); menu_inventorytimestamp = 0; menu_infotimestamp = 0; if (!core::localcontrol() || !core::localcontrol()->inventory()) { return; } const core::Item *selecteditem = (menu_listview->selected() ? menu_listview->selected()->item() : 0); for (core::Inventory::Items::const_iterator it = core::localcontrol()->inventory()->items().begin(); it != core::localcontrol()->inventory()->items().end(); it++) { core::Item *item = (*it); if (!item->info()) { continue; } // this makes sure inventory info gets requested from the server core::game()->request_info(item->info()->id()); if (item->info()->timestamp() > menu_infotimestamp) { menu_infotimestamp = item->info()->timestamp(); } if (item->amount() != 0) { ui::ListItem *listitem = 0; std::ostringstream str; str << item->info()->name().c_str(); if (item->amount() > 0) { str << " (" << item->amount() << ")"; } listitem = new ui::ListItem(menu_listview, str.str().c_str()); listitem->set_height(listitem->font()->height() * 2.0f); listitem->set_item(item); listitem->set_info(item->info()); std::string sortkey(item->info()->type()->label()); sortkey += '.'; sortkey += item->info()->label(); listitem->set_sortkey(sortkey); // preserve previous selection during update if (item == selecteditem) { menu_listview->select(listitem); } } } // request ship info if (core::localcontrol()->info()) { core::game()->request_info(core::localcontrol()->info()->id()); if (core::localcontrol()->info()->timestamp() > menu_infotimestamp) menu_infotimestamp = core::localcontrol()->info()->timestamp(); } menu_inventorytimestamp = core::localcontrol()->inventory()->timestamp(); if (menu_listview->selected()) { set_info(menu_listview->selected()->info(), menu_listview->selected()->item()->amount()); } else if (menu_inforecord != core::localcontrol()->info()) { set_info(0, 0); } menu_listview->sort(); menu_listview->event_resize(); } bool Inventory::verify() const { if (!core::localcontrol() || !core::localcontrol()->inventory()) { return true; } if (menu_inventorytimestamp != core::localcontrol()->inventory()->timestamp()) { return false; } for (core::Inventory::Items::const_iterator it = core::localcontrol()->inventory()->items().begin(); it != core::localcontrol()->inventory()->items().end(); it++) { core::Item *item = (*it); if (!item->info()) { continue; } if (item->info()->timestamp() > menu_infotimestamp) { return false; } } return true; } void Inventory::resize() { const float smallmargin = ui::UI::elementsize.height(); const float fontmargin = ui::root()->font_large()->height(); const float icon_size = 48.0f; // resize label menu_namelabel->set_size(width() - fontmargin * 2.0f, menu_namelabel->font()->height()); menu_namelabel->set_location(fontmargin, fontmargin); // resize inventory listview menu_listview->set_size(ui::UI::elementsize.width(), height() - smallmargin * 2.0f - fontmargin * 6.0f); menu_listview->set_location(fontmargin, fontmargin * 3.0f); menu_inventorytext->set_size(menu_listview->width(), fontmargin * 2.0f); menu_inventorytext->set_location(menu_listview->left(), menu_listview->bottom() + fontmargin); menu_shipbutton->set_size(icon_size, icon_size); menu_shipbutton->set_location(menu_inventorytext->left(), height() - icon_size - fontmargin); // resize modelview menu_modelview->set_size( width() - menu_listview->right() - fontmargin * 2.0f ,ui::UI::elementsize.width()); menu_modelview->set_location(menu_listview->right() + fontmargin, fontmargin * 3.0f); // resize infotext menu_scrollpane->set_size(menu_modelview->width(), height() - menu_modelview->bottom() - 2.0f * fontmargin); menu_scrollpane->set_location(menu_modelview->left(), menu_modelview->bottom() + fontmargin); } void Inventory::draw() { if (!verify()) { update_inventory(); } if (menu_inforecord && (menu_inforecord->timestamp() > menu_infotimestamp)) { set_info(menu_inforecord, menu_amount); } std::stringstream str; str << "Credits: " << std::setw(12) << core::localplayer()->credits(); if (core::localcontrol() && core::localcontrol()->inventory()) { core::Inventory *inventory = core::localcontrol()->inventory(); std::stringstream cargostr; cargostr << inventory->capacity_used() << " of " << inventory->capacity(); str << '\n' << "Cargo: " << aux::pad_left(cargostr.str(),12); } menu_inventorytext->set_text(str.str()); Window::draw(); } void Inventory::show() { menu_listview->deselect(); set_info(0, 0); Window::show(); } void Inventory::set_info(const core::Info *info, const int amount) { menu_inforecord = info; menu_infotext.clear(); menu_amount = amount; if (!info) { menu_modelview->set_modelname(0); menu_namelabel->set_text("Inventory"); } else { std::stringstream titlestr; titlestr << info->name(); if (amount > 0) { titlestr << " (" << amount << ")"; } menu_namelabel->set_text(titlestr.str().c_str()); core::game()->request_info(info->id()); menu_modelview->set_modelname(info->modelname()); for (core::Info::Text::const_iterator it = menu_inforecord->text().begin(); it != menu_inforecord->text().end(); it++) { menu_infotext.push_back((*it)); } if (info->timestamp() > menu_infotimestamp) { menu_infotimestamp = info->timestamp(); } } } bool Inventory::on_emit(Widget *sender, const Event event, void *data) { if (event == ui::Widget::EventButtonClicked) { if (sender == menu_shipbutton) { menu_listview->deselect(); set_info(core::localcontrol() ? core::localcontrol()->info() : 0, 0); } return true; } else if (event == ui::Widget::EventListViewChanged) { if (sender == menu_listview) { set_info(menu_listview->selected() ? menu_listview->selected()->info() : 0, menu_listview->selected()->item()->amount()); } return true; } return Window::on_emit(sender, event, data); } bool Inventory::on_keypress(const int key, const unsigned int modifier) { switch (key) { case SDLK_ESCAPE: this->hide(); return true; break; default: break; } return Window::on_keypress(key, modifier); } } // namespace client