/* 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::Widget(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_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_tradewindow); menu_slider->set_background(false); menu_slider->set_border(true); menu_msgtext = new ui::Label(menu_tradewindow); 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(); 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(false); menu_inventorytext->set_border(false); 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(false); menu_tradertext->set_border(false); menu_tradertext->set_font(ui::root()->font_small()); menu_closebutton = new ui::Button(menu_tradewindow, "Return", "view hide"); 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_namelabel->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(); menu_namelabel->set_text("Trade"); menu_tradertext->clear(); menu_msgtext->clear(); menu_msgtext->hide(); menu_slider->hide(); menu_buybutton->set_command(""); menu_buybutton->hide(); // FIXME enable/disable button 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) { // item in ship inventory selected (SELL) menu_buybutton->set_text("Sell"); menu_traderlistview->deselect(); const core::Item *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->info()->type()->label() << " " << item->info()->label() << " " << amount; menu_buybutton->set_command(commandstr.str()); menu_buybutton->enable(); menu_buybutton->show(); } if (amount < 1) { menu_msgtext->set_text("^1Can not sell here"); menu_msgtext->show(); } std::ostringstream str; 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(); } std::ostringstream labelstr; labelstr << "Sell " << item->info()->name(); if (amount) labelstr << " (" << amount << ")"; menu_namelabel->set_text(labelstr.str()); } else if (item->parent() == menu_traderlistview) { // item in trader inventory selected (BUY) menu_buybutton->set_text("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->info()->type()->label() << " " << item->info()->label() << " " << amount; menu_buybutton->set_command(commandstr.str()); menu_buybutton->enable(); menu_buybutton->show(); } if (amount < 1) { if (item->item()->amount() == 0 ) { menu_msgtext->set_text("^1Not 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 << "Price: " << std::setw(12) << (amount > 0 ? amount : 1) * item->item()->price() << '\n' << "Volume: " << std::setw(12) << (float) (amount > 0 ? amount : 1) * item->info()->volume(); menu_tradertext->set_text(str.str()); } std::ostringstream labelstr; labelstr << "Buy " << item->info()->name(); if (amount > 0) labelstr << " (" << amount << ")"; menu_namelabel->set_text(labelstr.str()); } 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 inventory listview menu_inventorylistview->set_size(ui::UI::elementsize.width(), menu_tradewindow->height() - smallmargin * 2.0f - fontmargin * 6.0f); menu_inventorylistview->set_location(fontmargin, fontmargin * 3.0f); menu_inventorytext->set_size(menu_inventorylistview->width(), fontmargin * 2.0f); menu_inventorytext->set_location(menu_inventorylistview->left(), menu_inventorylistview->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 slider menu_slider->set_size(menu_modelview->width(), fontmargin); menu_slider->set_location(menu_modelview->left(), menu_modelview->bottom() - menu_slider->height()); // warning text menu_msgtext->set_size(menu_slider->size()); menu_msgtext->set_location(menu_slider->location()); // resize scrollpane menu_scrollpane->set_size(menu_tradewindow->width() - 2.0f * ui::UI::elementsize.width() - fontmargin * 4.0f, menu_inventorylistview->height() + 2.0f * fontmargin - ui::UI::elementsize.width()); menu_scrollpane->set_location(fontmargin * 2.0f + ui::UI::elementsize.width(), fontmargin * 4.0f + ui::UI::elementsize.width()); // resize trader listview menu_traderlistview->set_size(ui::UI::elementsize.width(), menu_tradewindow->height() - smallmargin * 2.0f - fontmargin * 6.0f); menu_traderlistview->set_location(menu_tradewindow->width() - menu_traderlistview->width() - fontmargin, fontmargin * 3.0f); menu_tradertext->set_size(menu_traderlistview->width(), fontmargin * 2.0f); menu_tradertext->set_location(menu_traderlistview->left(), menu_traderlistview->bottom() + fontmargin); // resize buttons menu_buybutton->set_size(ui::UI::elementsize); menu_buybutton->set_location(menu_tradewindow->width() * 0.5f - ui::UI::elementsize.width() - smallmargin * 2.0f, menu_tradewindow->height() - smallmargin * 1.5f); menu_closebutton->set_size(ui::UI::elementsize); menu_closebutton->set_location(menu_tradewindow->width() * 0.5f + smallmargin * 2.0f, menu_tradewindow->height() - smallmargin * 1.5f); } 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; } return ui::Widget::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 << "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()); Widget::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 Widget::on_keypress(key, modifier); } } // namespace client