/* 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"); } // container window menu_tradewindow = new ui::Window(this); menu_tradewindow->set_label("tradewindow"); menu_tradewindow->set_border(true); menu_tradewindow->set_background(true); // ---- center pane pane menu_pane_center = new ui::Widget(menu_tradewindow); menu_pane_center->set_background(true); menu_pane_center->set_border(true); // modelview, add it first so it gets rendered before anything else menu_modelview = new ui::ModelView(menu_pane_center); menu_modelview->set_label("modelview"); menu_modelview->set_background(false); menu_modelview->set_border(false); menu_modellabel = new ui::Label(menu_pane_center); menu_modellabel->set_background(false); menu_modellabel->set_border(false); menu_modellabel->set_alignment(ui::AlignCenter); menu_msgtext = new ui::Label(menu_pane_center); menu_msgtext->set_label("label"); menu_msgtext->set_background(false); menu_msgtext->set_border(false); menu_msgtext->set_alignment(ui::AlignCenter); menu_slider = new ui::Slider(menu_pane_center); menu_slider->set_background(false); menu_slider->set_border(true); menu_buybutton = new ui::Button(menu_pane_center, "Buy"); menu_scrollpane = new ui::ScrollPane(menu_pane_center, menu_infotext); menu_scrollpane->set_background(false); menu_scrollpane->set_border(false); menu_scrollpane->set_alignment(ui::AlignTop); // window title lable menu_titlelabel = new ui::Label(menu_tradewindow); menu_titlelabel->set_label("label"); menu_titlelabel->set_background(false); menu_titlelabel->set_border(false); menu_titlelabel->set_font(ui::root()->font_large()); menu_titlelabel->set_alignment(ui::AlignCenter); menu_titlelabel->show(); // close button menu_closebutton = new ui::IconButton(menu_titlelabel, "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::Label(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_inventorytext->set_alignment(ui::AlignLeft | 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::Label(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_inventorytext->set_alignment(ui::AlignLeft | ui::AlignTop); 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_titlelabel->set_text(title); menu_tradertext->set_text(aux::pad_left("TRADER", 19)); menu_modellabel->clear(); 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_modelview->hide(); menu_buybutton->hide(); menu_slider->set_range(0, 2); menu_slider->set_value(1); if (core::localplayer()->view() && core::localplayer()->view()->info()) { for (core::Info::Text::const_iterator it = core::localplayer()->view()->info()->text().begin(); it != core::localplayer()->view()->info()->text().end(); it++) { menu_infotext.push_back((*it)); } menu_scrollpane->show(); menu_msgtext->set_text(core::localplayer()->view()->info()->name()); menu_msgtext->show(); } else { menu_scrollpane->hide(); } return; } else { menu_buybutton->show(); } 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 << aux::pad_left("TRADER", 19) << '\n' << '\n'; str << "Price: " << std::setw(11) << (amount > 0 ? amount : 1) * trader_item->price() << '\n'; str << "Volume: " << std::setw(11) << (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 << aux::pad_left("TRADER", 19) << '\n' << '\n'; str << "Price: " << std::setw(11) << (amount > 0 ? (float) amount : 1.0f) * item->item()->price() << '\n'; str << "Volume: " << std::setw(11) << (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 padding = ui::root()->font_large()->height(); // this menu takes the entire screen set_size(parent()->size()); // resize the container window menu_tradewindow->set_size(width() - smallmargin * 2.0f, height()- smallmargin * 4.0f); menu_tradewindow->set_location(smallmargin, smallmargin * 2.0f); // ---- window title // resize label menu_titlelabel->set_size(menu_tradewindow->width() - padding * 2.0f, menu_titlelabel->font()->height()); menu_titlelabel->set_location(padding, padding); // resize close button menu_closebutton->set_size(menu_titlelabel->font()->height(), menu_titlelabel->font()->height()); menu_closebutton->set_location(menu_titlelabel->width() - menu_closebutton->width(), 0.0f); // ---- left // resize player inventory text menu_inventorytext->set_size(ui::UI::elementsize.width(), menu_inventorytext->font()->height() * 5.0f); menu_inventorytext->set_location(padding, menu_titlelabel->bottom() + padding); // resize player inventory listview menu_inventorylistview->set_size(ui::UI::elementsize.width(), menu_tradewindow->height() - menu_inventorytext->bottom() - 2.0f * padding); menu_inventorylistview->set_location(padding, menu_inventorytext->bottom() + padding); // ---- right // resize trader inventory text menu_tradertext->set_size(ui::UI::elementsize.width(), menu_inventorytext->font()->height() * 5.0f); menu_tradertext->set_location(menu_tradewindow->width() - ui::UI::elementsize.width() - padding, menu_titlelabel->bottom() + padding); // resize trader inventory listview menu_traderlistview->set_size(ui::UI::elementsize.width(), menu_tradewindow->height() - menu_tradertext->bottom() - 2.0f * padding); menu_traderlistview->set_location(menu_tradewindow->width() - ui::UI::elementsize.width() - padding, menu_tradertext->bottom() + padding); // ---- center pane menu_pane_center->set_size(menu_tradertext->left() - menu_inventorytext->right() - 2.0f * padding, menu_tradewindow->height() - menu_titlelabel->bottom() - 2.0f * padding); menu_pane_center->set_location(menu_inventorytext->right() + padding, menu_titlelabel->bottom() + padding); { const ui::Widget *pane = menu_pane_center; const float margin_horizontal = pane->font()->width(); const float margin_vertical = pane->font()->height() * 0.5f; // resize modelview title label menu_modellabel->set_size(pane->width() - 2.0f * margin_horizontal, menu_modellabel->font()->height()); menu_modellabel->set_location(margin_horizontal, margin_vertical); // resize modelview menu_modelview->set_size(pane->width() - 2.0f * margin_horizontal, ui::UI::elementsize.width()); menu_modelview->set_location(margin_horizontal, menu_modellabel->bottom() + margin_vertical); // warning text menu_msgtext->set_size(pane->width() - 2.0f * margin_horizontal, menu_msgtext->font()->height()); menu_msgtext->set_location(margin_horizontal, menu_modelview->bottom() + margin_vertical); // resize slider menu_slider->set_size( math::min(pane->width() - padding * 2.0f - margin_horizontal * 2.0f, ui::UI::elementsize.width() * 2.5f), menu_slider->font()->height() ); menu_slider->set_location((pane->width() - menu_slider->width()) * 0.5f, menu_msgtext->top()); // resize button menu_buybutton->set_size(ui::UI::elementsize); menu_buybutton->set_location((pane->width() - menu_buybutton->width()) * 0.5f, menu_msgtext->bottom() + padding); // resize infotext scrollpane menu_scrollpane->set_size(pane->width() - 2.0f * margin_horizontal, pane->height() - menu_buybutton->bottom() - margin_vertical - padding); menu_scrollpane->set_location(margin_horizontal, menu_buybutton->bottom() + padding); } } 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(), 10); 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