/* client/trademenu.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include "core/application.h" #include "core/info.h" #include "core/inventory.h" #include "ui/button.h" #include "ui/paint.h" #include "ui/ui.h" #include "ui/listitem.h" #include "client/trademenu.h" namespace client { TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent) { set_border(false); set_background(false); if (label) set_label(label); else set_label("trademenu"); menu_tradewindow = new ui::Window(this); menu_tradewindow->set_label("tradewindow"); menu_tradewindow->set_border(true); menu_tradewindow->set_background(true); menu_modelview = new ui::ModelView(menu_tradewindow); menu_modelview->set_label("modelview"); menu_modelview->set_background(false); menu_modelview->set_border(false); menu_slider = new ui::Slider(menu_modelview); //menu_slider->set_background(false); //menu_slider->set_border(true); menu_modellabel = new ui::Label(menu_modelview); menu_modellabel->set_background(false); menu_modellabel->set_border(false); menu_modellabel->set_alignment(ui::AlignCenter); menu_msgtext = new ui::Label(menu_modelview); menu_msgtext->set_label("label"); menu_msgtext->set_background(false); menu_msgtext->set_border(false); menu_msgtext->set_alignment(ui::AlignCenter); menu_namelabel = new ui::Label(menu_tradewindow); 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->show(); // close button menu_closebutton = new ui::IconButton(menu_namelabel, "bitmaps/icons/window_close"); menu_inventorylistview = new InventoryListView(menu_tradewindow); menu_inventorylistview->set_label("inventorylistview"); //menu_inventorylistview->set_background(false); //menu_inventorylistview->set_border(true); menu_inventorytext = new ui::PlainText(menu_tradewindow); menu_inventorytext->set_label("inventorytext"); menu_inventorytext->set_background(true); menu_inventorytext->set_border(true); menu_inventorytext->set_font(ui::root()->font_small()); menu_scrollpane = new ui::ScrollPane(menu_tradewindow, menu_infotext); menu_scrollpane->set_background(false); menu_scrollpane->set_border(false); menu_scrollpane->set_alignment(ui::AlignTop); menu_traderlistview = new InventoryListView(menu_tradewindow); menu_traderlistview->set_label("traderlistview"); //menu_traderlistview->set_background(false); //menu_traderlistview->set_border(true); menu_traderlistview->set_showempty(true); menu_tradertext = new ui::PlainText(menu_tradewindow); menu_tradertext->set_label("tradertext"); menu_tradertext->set_background(true); menu_tradertext->set_border(true); menu_tradertext->set_font(ui::root()->font_small()); menu_buybutton = new ui::Button(menu_tradewindow, "Buy"); menu_listitem = 0; set_itemtype(0); set_item(0); hide(); } TradeMenu::~TradeMenu() { } void TradeMenu::set_itemtype(core::InfoType *item_type) { // reset menu_modellabel->set_text(0); menu_itemtype = item_type; core::Inventory *inventory_player = 0; core::Inventory *inventory_view = 0; if (core::localcontrol()) inventory_player = core::game()->request_inventory(core::localcontrol()); if(core::localplayer()->view()) inventory_view = core::game()->request_inventory(core::localplayer()->view()); menu_inventorylistview->set_inventory(inventory_player, item_type); menu_traderlistview->set_inventory(inventory_view, item_type); //set_item(0); } void TradeMenu::set_item(ui::ListItem *item) { menu_infotext.clear(); std::string title; if (core::localplayer()->view()) { title.assign(core::localplayer()->view()->name()); title += ' '; } title.append ("TRADER"); aux::to_uppercase(title); menu_namelabel->set_text(title); menu_tradertext->set_text("TRADER"); menu_msgtext->clear(); menu_msgtext->hide(); menu_slider->hide(); menu_buybutton->set_command(""); menu_buybutton->disable(); if (item != menu_listitem) { menu_slider->set_range(0, 2); menu_slider->set_value(1); menu_listitem = item; } if (!item || !item->info()) { menu_traderlistview->deselect(); menu_inventorylistview->deselect(); menu_scrollpane->hide(); menu_modelview->hide(); menu_slider->set_range(0, 2); menu_slider->set_value(1); return; } long amount = 0; for (core::Info::Text::const_iterator it = item->info()->text().begin(); it != item->info()->text().end(); it++) { menu_infotext.push_back((*it)); } menu_scrollpane->show(); menu_modelview->set_modelname(item->info()->modelname()); menu_modelview->show(); if (item->parent() == menu_inventorylistview) { menu_buybutton->set_text("Sell"); // item in ship inventory selected (SELL) menu_traderlistview->deselect(); const core::Item *trader_item = 0; if (item->item()->unrestricted()) { trader_item = item->item(); } else { trader_item = (menu_traderlistview->inventory() ? menu_traderlistview->inventory()->find(item->info()) : 0); } if (trader_item) { const long max_amount = item->item()->amount(); if (max_amount > 0) { menu_slider->set_range(1, max_amount); menu_slider->show(); amount = (long) menu_slider->value(); std::ostringstream commandstr; commandstr << "remote sell " << item->item()->id() << " " << amount; menu_buybutton->set_command(commandstr.str()); menu_buybutton->enable(); } if (amount < 1) { menu_msgtext->set_text("^1Can not sell here"); menu_msgtext->show(); } std::ostringstream str; str << "TRADER" << '\n' << '\n'; str << "Price: " << std::setw(12) << (amount > 0 ? amount : 1) * trader_item->price() << '\n' << "Volume: " << std::setw(12) << (float)(amount > 0 ? amount : 1) * trader_item->info()->volume(); menu_tradertext->set_text(str.str()); } else { menu_msgtext->set_text("^1Can not sell here"); menu_msgtext->show(); } menu_modellabel->set_text(item->info()->name()); } else if (item->parent() == menu_traderlistview) { menu_buybutton->set_text("Buy"); // item in trader inventory selected (BUY) menu_inventorylistview->deselect(); if (menu_inventorylistview->inventory()) { const long item_unit_price = item->item()->price(); const float item_unit_volume = item->info()->volume(); long max_amount = core::localcontrol()->inventory()->max_amount(core::localplayer()->credits(), item_unit_price, item_unit_volume); if (item->item()->amount() >= 0) { max_amount = math::min(max_amount, item->item()->amount()); } if (max_amount > 0) { menu_slider->set_range(1, max_amount); menu_slider->show(); amount = (long) menu_slider->value(); std::ostringstream commandstr; commandstr << "remote buy " << item->item()->id() << " " << amount; menu_buybutton->set_command(commandstr.str()); menu_buybutton->enable(); } if (amount < 1) { if (item->item()->amount() == 0 ) { menu_msgtext->set_text("^1None available"); } else if (item_unit_price > core::localplayer()->credits()) { menu_msgtext->set_text("^1Not enough credits"); } else if (item_unit_volume > menu_inventorylistview->inventory()->capacity_available()) { menu_msgtext->set_text("^1Not enough cargo space"); } else { menu_msgtext->set_text("^1Can not buy here"); } menu_msgtext->show(); } std::ostringstream str; str << "TRADER" << '\n' << '\n'; str << "Price: " << std::setw(12) << (amount > 0 ? (float) amount : 1.0f) * item->item()->price() << '\n' << "Volume: " << std::setw(12) << (amount > 0 ? (float) amount : 1.0f) * item->info()->volume() << '\n'; menu_tradertext->set_text(str.str()); } menu_modellabel->set_text(item->info()->name()); } else { menu_traderlistview->deselect(); menu_inventorylistview->deselect(); } } void TradeMenu::resize() { const float smallmargin = ui::UI::elementsize.height(); const float fontmargin = ui::root()->font_large()->height(); // this menu takes the entire screen set_size(parent()->size()); // resize the subwindow menu_tradewindow->set_size(width() - smallmargin * 2.0f, height()- smallmargin * 4.0f); menu_tradewindow->set_location(smallmargin, smallmargin * 2.0f); // resize label menu_namelabel->set_size(menu_tradewindow->width() - fontmargin * 2.0f, menu_namelabel->font()->height()); menu_namelabel->set_location(fontmargin, fontmargin); // resize close button menu_closebutton->set_size(menu_namelabel->font()->height(), menu_namelabel->font()->height()); menu_closebutton->set_location(menu_namelabel->width() - menu_closebutton->width(), 0); // resize player inventory text menu_inventorytext->set_size( ui::UI::elementsize.width(), fontmargin * 3.0f ); menu_inventorytext->set_location(fontmargin, menu_namelabel->bottom() + fontmargin); // resize player inventory listview menu_inventorylistview->set_size( ui::UI::elementsize.width(), menu_tradewindow->height() - menu_inventorytext->bottom() - 2.0f * fontmargin ); menu_inventorylistview->set_location( fontmargin, menu_inventorytext->bottom() + fontmargin ); // resize modelview menu_modelview->set_size(menu_tradewindow->width() - 2.0f * ui::UI::elementsize.width() - fontmargin * 4.0f, ui::UI::elementsize.width()); menu_modelview->set_location(fontmargin * 2.0f + ui::UI::elementsize.width(), fontmargin * 3.0f); // resize modelview title label menu_modellabel->set_location(0, 0); menu_modellabel->set_size(menu_modelview->width(), menu_modellabel->font()->height()); // resize slider menu_slider->set_size(menu_modelview->width(), menu_slider->font()->height()); menu_slider->set_location(0, menu_modelview->height() - menu_slider->height()); // warning text menu_msgtext->set_size(menu_slider->size()); menu_msgtext->set_location(menu_slider->location()); // resize trader inventory text menu_tradertext->set_size( ui::UI::elementsize.width(), fontmargin * 3.0f ); menu_tradertext->set_location( menu_tradewindow->width() - ui::UI::elementsize.width() - fontmargin, menu_namelabel->bottom() + fontmargin ); // resize trader inventory listview menu_traderlistview->set_size( ui::UI::elementsize.width(), menu_tradewindow->height() - menu_tradertext->bottom() - 2.0f * fontmargin ); menu_traderlistview->set_location( menu_tradewindow->width() - ui::UI::elementsize.width() - fontmargin, menu_tradertext->bottom() + fontmargin ); // resize buttons menu_buybutton->set_size(ui::UI::elementsize); menu_buybutton->set_location( menu_modelview->left() + (menu_modelview->width() - menu_buybutton->width()) * 0.5f, menu_modelview->bottom() + fontmargin ); // resize infotext scrollpane menu_scrollpane->set_size( menu_tradewindow->width() - 2.0f * ui::UI::elementsize.width() - fontmargin * 4.0f, menu_tradewindow->height() - menu_buybutton->bottom() - fontmargin * 2.0f ); menu_scrollpane->set_location( fontmargin * 2.0f + ui::UI::elementsize.width(), menu_buybutton->bottom() + fontmargin ); } bool TradeMenu::on_emit(Widget *sender, const Event event, void *data) { if (event == ui::Widget::EventSliderChanged) { // slider value changed if (menu_traderlistview->selected()) { set_item(menu_traderlistview->selected()); } else { set_item(menu_inventorylistview->selected()); } return true; } else if (event == ui::Widget::EventListViewChanged) { // listview changed if (sender == menu_traderlistview) { set_item(menu_traderlistview->selected()); } else if (sender == menu_inventorylistview) { set_item(menu_inventorylistview->selected()); } return true; } else if (event == ui::Widget::EventButtonClicked) { if (sender == menu_closebutton) { hide(); } return true; } return ui::Window::on_emit(sender, event, data); } void TradeMenu::draw() { // sanity check if ((menu_inventorylistview->inventory() != (core::localcontrol() ? core::localcontrol()->inventory() : 0 )) || (menu_traderlistview->inventory() != (core::localplayer()->view() ? core::localplayer()->view()->inventory() : 0 ))) { set_itemtype(menu_itemtype); } std::stringstream creditstr; creditstr << core::localplayer()->credits(); std::stringstream str; str << "INVENTORY" << '\n' << '\n'; str << "Credits: " << aux::pad_left(creditstr.str(),12); 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(); } bool TradeMenu::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