diff options
author | Stijn Buys <ingar@osirion.org> | 2010-09-20 16:30:45 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2010-09-20 16:30:45 +0000 |
commit | e40f70a3af1142e6c0c89c6ea2ee47b996495661 (patch) | |
tree | ba70a909b5066ad0e07e2f4eb8bc98684e4598e6 | |
parent | e8f7c4a06fce9e41fb23ffc42a566501a78210cb (diff) |
corrected trading inconsistencies, improved trade window, initial slider widget
-rw-r--r-- | src/client/inventorylistview.cc | 2 | ||||
-rw-r--r-- | src/client/trademenu.cc | 206 | ||||
-rw-r--r-- | src/client/trademenu.h | 10 | ||||
-rw-r--r-- | src/core/inventory.cc | 9 | ||||
-rw-r--r-- | src/core/inventory.h | 10 | ||||
-rw-r--r-- | src/game/base/cargo.cc | 10 | ||||
-rw-r--r-- | src/math/functions.cc | 20 | ||||
-rw-r--r-- | src/math/functions.h | 60 | ||||
-rw-r--r-- | src/ui/Makefile.am | 4 | ||||
-rw-r--r-- | src/ui/listitem.h | 2 | ||||
-rw-r--r-- | src/ui/listview.cc | 3 | ||||
-rw-r--r-- | src/ui/slider.cc | 111 | ||||
-rw-r--r-- | src/ui/slider.h | 101 | ||||
-rw-r--r-- | src/ui/widget.cc | 28 | ||||
-rw-r--r-- | src/ui/widget.h | 32 |
15 files changed, 486 insertions, 122 deletions
diff --git a/src/client/inventorylistview.cc b/src/client/inventorylistview.cc index 0126ff4..d87ed2b 100644 --- a/src/client/inventorylistview.cc +++ b/src/client/inventorylistview.cc @@ -60,6 +60,8 @@ void InventoryListView::set_inventory(core::Inventory *inventory, core::InfoType listview_timestamp = inventory->timestamp(); event_resize(); + + emit(EventListViewChanged); } void InventoryListView::draw() diff --git a/src/client/trademenu.cc b/src/client/trademenu.cc index 47655f6..0b8fb64 100644 --- a/src/client/trademenu.cc +++ b/src/client/trademenu.cc @@ -34,6 +34,10 @@ TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent 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_namelabel = new ui::Label(menu_tradewindow); menu_namelabel->set_label("label"); @@ -71,14 +75,10 @@ TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent menu_tradertext->set_font(ui::root()->font_small()); menu_closebutton = new ui::Button(menu_tradewindow, "Return", "view hide"); - - menu_buyallbutton = new ui::Button(menu_modelview, "<<"); - menu_buybutton = new ui::Button(menu_modelview, "<"); - menu_sellallbutton = new ui::Button(menu_modelview, ">>"); - menu_sellbutton = new ui::Button(menu_modelview, ">"); + menu_buybutton = new ui::Button(menu_tradewindow, "Buy"); + menu_listitem = 0; - std::string test("test"); set_itemtype(0); hide(); @@ -115,78 +115,130 @@ void TradeMenu::set_item(ui::ListItem *item) menu_infotext.clear(); menu_namelabel->set_text("Trade"); menu_tradertext->clear(); + menu_buybutton->hide(); + menu_slider->hide(); + 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 = 1; // reserved + long amount = 0; // reserved + + 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_traderlistview->deselect(); - // item in ship inventory selected (SELL) - menu_namelabel->set_text("Sell " + item->info()->name()); - menu_buyallbutton->hide(); - menu_buybutton->hide(); - - menu_sellallbutton->show(); - menu_sellallbutton->set_command("remote sell " + item->info()->type()->label() + " " + item->info()->label() + " -1"); - - menu_sellbutton->show(); - menu_sellbutton->set_command("remote sell " + item->info()->type()->label() + " " + item->info()->label() + " 1"); + // item in ship inventory selected (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 = 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->set_text("Sell"); + menu_buybutton->show(); + } + + if (amount < 1) { + menu_buybutton->set_command(""); + menu_buybutton->set_text("^1Can not sell"); + menu_buybutton->show(); + } + std::ostringstream str; - str << "Price: " << std::setw(8) << amount * trader_item->price() << '\n' << "Volume: " << std::setw(7) << std::setprecision(2) << amount * trader_item->info()->volume(); + str << "Price: " << std::setw(12) << (amount > 0 ? amount : 1) * trader_item->price() << '\n' + << "Volume: " << std::setw(12) << std::setprecision(2) << (float)(amount > 0 ? amount : 1) * trader_item->info()->volume(); menu_tradertext->set_text(str.str()); } else { - menu_tradertext->set_text("^1Can not sell here"); + menu_tradertext->set_text(" ^1Can not sell here"); } + + std::ostringstream labelstr; + labelstr << "Sell " << item->info()->name(); + if (amount) + labelstr << " (" << amount << ")"; + menu_namelabel->set_text(labelstr.str()); + } else if (item->parent() == menu_traderlistview) { - menu_inventorylistview->deselect(); - // item in trader inventory selected (BUY) - menu_namelabel->set_text("Buy " + item->info()->name()); - - menu_buyallbutton->show(); - menu_buyallbutton->set_command("remote buy " + item->info()->type()->label() + " " + item->info()->label() + " -1"); - menu_buybutton->show(); - menu_buybutton->set_command("remote buy " + item->info()->type()->label() + " " + item->info()->label() + " 1"); - - std::ostringstream str; - str << "Price: " << std::setw(8) << amount * item->item()->price() << '\n' << "Volume: " << std::setw(7) << std::setprecision(2) << amount * item->info()->volume(); - menu_tradertext->set_text(str.str()); - - menu_sellallbutton->hide(); - menu_sellbutton->hide(); + // item in trader inventory selected (BUY) - } else { - menu_traderlistview->deselect(); menu_inventorylistview->deselect(); - - menu_buyallbutton->hide(); - menu_buybutton->hide(); - - menu_sellallbutton->hide(); - menu_sellbutton->hide(); - } + + 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 = 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->set_text("Buy"); + menu_buybutton->show(); + } - if (item->info()) { - for (core::Info::Text::const_iterator it = item->info()->text().begin(); it != item->info()->text().end(); it++) { - menu_infotext.push_back((*it)); + if (amount < 1) { + menu_buybutton->set_command(""); + menu_buybutton->set_text("^1Can not buy"); + menu_buybutton->show(); + } + + std::ostringstream str; + str << "Price: " << std::setw(12) << (amount > 0 ? amount : 1) * item->item()->price() << '\n' + << "Volume: " << std::setw(12) << std::setprecision(2) << (float) (amount > 0 ? amount : 1) * item->info()->volume(); + + menu_tradertext->set_text(str.str()); } - menu_scrollpane->show(); - menu_modelview->set_modelname(item->info()->modelname()); - menu_modelview->show(); + 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(); } } @@ -210,26 +262,17 @@ void TradeMenu::resize() 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); + 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 buttons - menu_buyallbutton->set_size(fontmargin, fontmargin); - menu_buyallbutton->set_location(0, menu_modelview->height() - fontmargin); + // resize slider + menu_slider->set_size(menu_modelview->width(), fontmargin); + menu_slider->set_location(menu_modelview->left(), menu_modelview->bottom() - menu_slider->height()); - menu_buybutton->set_size(fontmargin, fontmargin); - menu_buybutton->set_location(2.0f * fontmargin, menu_modelview->height() - fontmargin); - - menu_sellallbutton->set_size(fontmargin, fontmargin); - menu_sellallbutton->set_location(menu_modelview->width() - fontmargin, menu_modelview->height() - fontmargin); - - menu_sellbutton->set_size(fontmargin, fontmargin); - menu_sellbutton->set_location(menu_modelview->width() - 3.0f * fontmargin, menu_modelview->height() - fontmargin); - // 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()); @@ -238,18 +281,34 @@ void TradeMenu::resize() 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); + menu_tradertext->set_size(menu_traderlistview->width(), fontmargin * 2.0f); menu_tradertext->set_location(menu_traderlistview->left(), menu_traderlistview->bottom() + fontmargin); - // resize close button + // 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(0.5f * (menu_tradewindow->width() - ui::UI::elementsize.width()), menu_tradewindow->height() - smallmargin * 1.5f ); + 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::EventListItemClicked) { - set_item(static_cast<ui::ListItem *>(sender)); + 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; } @@ -265,12 +324,15 @@ void TradeMenu::draw() } std::stringstream str; - str << "Credit: " << std::setw(8) << core::localplayer()->credits(); - + str << "Credits: " << std::setw(12) << core::localplayer()->credits(); + if (core::localcontrol() && core::localcontrol()->inventory()) { core::Inventory *inventory = core::localcontrol()->inventory(); - str << '\n'; - str << "Cargo: " << std::setprecision(2) << std::setw(6) << inventory->capacity_used() << " of " << inventory->capacity(); + + 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()); diff --git a/src/client/trademenu.h b/src/client/trademenu.h index 4682ce7..e835043 100644 --- a/src/client/trademenu.h +++ b/src/client/trademenu.h @@ -13,6 +13,7 @@ #include "ui/listitem.h" #include "ui/modelview.h" #include "ui/plaintext.h" +#include "ui/slider.h" #include "ui/scrollpane.h" #include "ui/widget.h" #include "client/inventorylistview.h" @@ -44,24 +45,23 @@ private: void set_item(ui::ListItem *item); ui::Window *menu_tradewindow; - ui::Button *menu_closebutton; ui::Label *menu_namelabel; ui::PlainText *menu_inventorytext; ui::PlainText *menu_tradertext; ui::ModelView *menu_modelview; ui::ScrollPane *menu_scrollpane; + ui::Slider *menu_slider; - ui::Button *menu_buyallbutton; + ui::Button *menu_closebutton; ui::Button *menu_buybutton; - ui::Button *menu_sellallbutton; - ui::Button *menu_sellbutton; - + InventoryListView *menu_inventorylistview; InventoryListView *menu_traderlistview; ui::Text menu_infotext; core::InfoType *menu_itemtype; + ui::ListItem *menu_listitem; }; } diff --git a/src/core/inventory.cc b/src/core/inventory.cc index 03cd21e..4b9a2e5 100644 --- a/src/core/inventory.cc +++ b/src/core/inventory.cc @@ -97,5 +97,14 @@ void Inventory::recalculate() } } +const long Inventory::max_amount(const long credits, const long price, const float volume) const +{ + if ((price * volume) == 0) { + return 0; + } + + return math::min((long)(capacity_available() / volume), credits / price); +} + } // namespace core diff --git a/src/core/inventory.h b/src/core/inventory.h index 805d943..7aaf299 100644 --- a/src/core/inventory.h +++ b/src/core/inventory.h @@ -66,13 +66,21 @@ public: } /** - * @brief return the availableinventory capacity, in cubic meters + * @brief return the available inventory capacity, in cubic meters */ inline const float capacity_available() const { return inventory_capacity - inventory_capacity_used; } /** + * @brief returns the number of units of an item that can be stored in this inventory + * @param credits number of player credits, limits the amount + * @param price price of a single unit + * @param volume volume of a single unit + */ + const long max_amount(const long credits, const long price, const float volume) const; + + /** * @brief search the inventory for a specific item type */ Item *find(const Info *info) const; diff --git a/src/game/base/cargo.cc b/src/game/base/cargo.cc index 382b03c..b54af55 100644 --- a/src/game/base/cargo.cc +++ b/src/game/base/cargo.cc @@ -257,11 +257,17 @@ void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int } // if amount is set to -1. the base has a limitless supply + if (seller_item->amount() == 0) { buyer->owner()->send("^WCargo not available!"); return; - } else if ((seller_item->amount() > 0) && (negotiated_amount > seller_item->amount())) { - negotiated_amount = seller_item->amount(); + + } else if (seller_item->amount() > 0) { + + if (negotiated_amount > seller_item->amount()) { + negotiated_amount = seller_item->amount(); + } + seller_item->dec_amount(negotiated_amount); seller->inventory()->set_dirty(); } diff --git a/src/math/functions.cc b/src/math/functions.cc index 7fb40be..7c95a79 100644 --- a/src/math/functions.cc +++ b/src/math/functions.cc @@ -12,26 +12,6 @@ namespace math const float DELTA = 10e-10; -float min(float a, float b) -{ - return (a < b ? a : b); -} - -float max(float a, float b) -{ - return (a > b ? a : b); -} - -int min(int a, int b) -{ - return (a < b ? a : b); -} - -int max(int a, int b) -{ - return (a > b ? a : b); -} - float randomf(const float max) { return ((float) rand() / (float) RAND_MAX) * max; diff --git a/src/math/functions.h b/src/math/functions.h index 5a53d44..8135392 100644 --- a/src/math/functions.h +++ b/src/math/functions.h @@ -15,17 +15,53 @@ namespace math { -/// return the smallest of two float values -float min(float a, float b); +/** + * @brief return the smallest of two floats + */ +inline const float min(const float a, const float b) +{ + return (a < b ? a : b); +} -/// return the smallest of two integers -int min(int a, int b); +/** + * @brief return the smallest of two integers + */ +inline const int min(const int a, const int b) +{ + return (a < b ? a : b); +} -/// return the largest of two float values -float max(float a, float b); +/** + * @brief return the smallest of two longs + */ +inline const long min(const long a, const long b) +{ + return (a < b ? a : b); +} -/// return the largest of two integers -int max(int a, int b); +/** + * @brief return the largest of two floats + */ +inline const float max(const float a, const float b) +{ + return (a > b ? a : b); +} + +/** + * @brief return the largest of two integers + */ +inline const int max(const int a, const int b) +{ + return (a > b ? a : b); +} + +/** + * @brief return the largest of two longs + */ +inline const long max(const long a, const long b) +{ + return (a > b ? a : b); +} /// returns a random float /** The value returned will be in the interval [0-max] @@ -63,6 +99,14 @@ inline float absf(const float f) return ( f < 0.0f ? -f : f ); } +/// swap two float values +inline void swap(float &x, float &y) +{ + float tmp = x; + x = y; + y = tmp; +} + } // namespace math #endif // __INCLUDED_MATH_FUNCTIONS_H__ diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index e62a5dd..a98e964 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -10,12 +10,12 @@ endif noinst_HEADERS = bitmap.h button.h console.h container.h definitions.h font.h \ iconbutton.h inputbox.h label.h listitem.h listview.h \ menu.h modelview.h paint.h palette.h plaintext.h scrollpane.h \ - toolbar.h ui.h widget.h window.h + slider.h toolbar.h ui.h widget.h window.h libui_la_SOURCES = bitmap.cc button.cc console.cc container.cc font.cc \ iconbutton.cc inputbox.cc label.cc listitem.cc listview.cc \ menu.cc modelview.cc paint.cc palette.cc plaintext.cc scrollpane.cc \ - toolbar.cc ui.cc widget.cc window.cc + slider.cc toolbar.cc ui.cc widget.cc window.cc libui_la_LDFLAGS = -avoid-version -no-undefined diff --git a/src/ui/listitem.h b/src/ui/listitem.h index 1d4cd33..6fad3e9 100644 --- a/src/ui/listitem.h +++ b/src/ui/listitem.h @@ -43,6 +43,8 @@ public: listitem_item = item; } + void select(); + protected: /// keypress event handler virtual bool on_keypress(const int key, const unsigned int modifier); diff --git a/src/ui/listview.cc b/src/ui/listview.cc index e503807..ced0dd6 100644 --- a/src/ui/listview.cc +++ b/src/ui/listview.cc @@ -90,7 +90,8 @@ bool ListView::on_emit(Widget *sender, const Event event, void *data) { if ((sender->parent() == this) && (event == Widget::EventListItemClicked)) { listview_selecteditem = static_cast<ListItem *>(sender); - return false; // return false because parent widgets might want to handle this event + emit(EventListViewChanged); + return true; } return ui::Widget::on_emit(sender, event, data); diff --git a/src/ui/slider.cc b/src/ui/slider.cc new file mode 100644 index 0000000..5de82b2 --- /dev/null +++ b/src/ui/slider.cc @@ -0,0 +1,111 @@ +/* + ui/slider.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "math/functions.h" +#include "ui/paint.h" +#include "ui/slider.h" + +namespace ui { + +Slider::Slider(Widget *parent, const float minimum, const float maximum) : Widget(parent) +{ + slider_minimum = minimum; + slider_maximum = maximum; + slider_value = slider_minimum; + + slider_minbutton = new ui::Button(this, "<"); + slider_minbutton->set_border(false); + + slider_maxbutton = new ui::Button(this, ">>"); + slider_maxbutton->set_border(false); + + validate(); +} + +Slider::~Slider() { +} + +void Slider::set_value(const float value) +{ + slider_value = value; + validate(); +} + +void Slider::set_minimum(const float minimum) +{ + slider_minimum = minimum; + validate(); +} + +void Slider::set_maximum(const float maximum) +{ + slider_maximum = maximum; + validate(); +} + +void Slider::set_range(const float minimum, const float maximum) +{ + slider_minimum = minimum; + slider_maximum = maximum; + validate(); +} + +void Slider::validate() +{ + if (slider_minimum > slider_maximum) { + math::swap(slider_minimum, slider_maximum); + } + + math::clamp(slider_value, slider_minimum, slider_maximum); +} + +void Slider::print(const size_t indent) const +{ + std::string marker(""); + con_print << aux::pad_left(marker, indent*2) << label() << " \"" << minimum() << "-" << maximum() << "\"" << std::endl; +} + +bool Slider::on_emit(Widget *sender, const Event event, void *data) +{ + if (event == EventButtonClicked) { + if (sender == slider_minbutton) { + slider_value = slider_minimum; + emit(EventSliderChanged, this); + return true; + } else if (sender == slider_maxbutton) { + slider_value = slider_maximum; + emit(EventSliderChanged, this); + return true; + } + } + + return false; +} + + +void Slider::resize() +{ + // note: slider expects width > height + slider_minbutton->set_size(height(), height()); + slider_minbutton->set_location(0, 0); + + slider_maxbutton->set_size(height(), height()); + slider_maxbutton->set_location(width() - slider_maxbutton->width(), 0); +} + +void Slider::draw() +{ + if (slider_maximum > slider_minimum) { + const float range = (slider_value - slider_minimum) / (slider_maximum - slider_minimum); + const float x = (width() - 3.0f * height()) * range; + Paint::set_color(palette()->foreground()); + Paint::draw_rectangle(math::Vector2f(global_location().x() + height() + x, global_location().y()), math::Vector2f(height(), height())); + } + + Widget::draw(); +} + +} // namespace ui diff --git a/src/ui/slider.h b/src/ui/slider.h new file mode 100644 index 0000000..8bcb427 --- /dev/null +++ b/src/ui/slider.h @@ -0,0 +1,101 @@ +/* + ui/slider.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_UI_SLIDER_H__ +#define __INCLUDED_UI_SLIDER_H__ + +#include <string> +#include "ui/button.h" +#include "ui/widget.h" + +namespace ui +{ + +/** + * @brief a slider widget + */ +class Slider : public Widget +{ +public: + Slider(Widget *parent, const float minimum = 0.0f, const float maximum = 1.0f); + ~Slider(); + + /** + * @brief the current slider value + */ + inline const float value() const { + return slider_value; + } + + /** + * @brief the minimum value + */ + inline const float minimum() const { + return slider_minimum; + } + + /** + * @brief the maximum value + */ + inline const float maximum() const { + return slider_maximum; + } + + /** + * @brief print widget description to console + */ + virtual void print(const size_t indent) const; + + /** + * @brief set the current slider value + * @see value + */ + void set_value(const float value); + + /** + * @brief set the minimum slider value + * @see minimum + */ + void set_minimum(const float minimum); + + /** + * @brief set the maximum slider value + * @see maximum + */ + void set_maximum(const float maximum); + + /** + * @brief set the minimum and maximum slider values + * @see minimum + * @see maximum + */ + void set_range(const float minimum, const float maximum); + +protected: + /// resize event handler + virtual void resize(); + + /// draw event handler + virtual void draw(); + + virtual bool on_emit(Widget *sender, const Event event, void *data=0); + +private: + /// validate slider value + void validate(); + + float slider_minimum; + float slider_maximum; + float slider_value; + + Button *slider_minbutton; + Button *slider_maxbutton; +}; + +} + +#endif // __INCLUDED_UI_SLIDER_H__ + diff --git a/src/ui/widget.cc b/src/ui/widget.cc index b3aa27c..2f35185 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -19,6 +19,7 @@ Widget::Widget(Widget *parent) widget_visible = true; widget_border = true; widget_background = false; + widget_enabled = true; widget_palette = 0; widget_font = 0; widget_label.assign("widget"); @@ -162,7 +163,7 @@ void Widget::hide() } -void Widget::set_visible(bool visible) +void Widget::set_visible(const bool visible) { if (visible) show(); @@ -170,24 +171,41 @@ void Widget::set_visible(bool visible) hide(); } -void Widget::set_border(bool border) +void Widget::enable() +{ + widget_enabled = true; +} + +void Widget::disable() +{ + widget_enabled = false; +} + +void Widget::set_enabled(const bool enabled) +{ + if (enabled) + enable(); + else + disable(); +} +void Widget::set_border(const bool border) { widget_border = border; } -void Widget::set_background(bool background) +void Widget::set_background(const bool background) { widget_background = background; } -void Widget::set_label(std::string const & label) +void Widget::set_label(const std::string & label) { widget_label.assign(label); aux::to_label(widget_label); } -void Widget::set_label(char const *label) +void Widget::set_label(const char *label) { if (label) { widget_label.assign(label); diff --git a/src/ui/widget.h b/src/ui/widget.h index 3ae75d2..8b61bc1 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -28,7 +28,7 @@ class Widget public: /// types of custom events a widget can emit - enum Event {EventNone = 0, EventButtonClicked, EventListItemClicked}; + enum Event {EventNone = 0, EventButtonClicked, EventListItemClicked, EventListViewChanged, EventSliderChanged}; /// create a new widget Widget(Widget *parent = 0); @@ -128,6 +128,16 @@ public: return !widget_visible; } + /// true if the widget is enabled + inline bool enabled() const { + return widget_enabled; + } + + /// true if the widget is disabled + inline bool disabled() const { + return !widget_enabled; + } + /// the palette used to draw this widget const Palette *palette() const; @@ -156,9 +166,18 @@ public: /// hide the widget virtual void hide(); - + /// set visibility - void set_visible(bool visible = true); + void set_visible(const bool visible = true); + + /// disable the widget + virtual void disable(); + + /// enable the widget + virtual void enable(); + + ///set enabled or disabled state + void set_enabled(const bool enabled = true); /// set input focus void set_focus(); @@ -194,16 +213,16 @@ public: void set_font(const Font *font); /// set the widgets label - void set_label(std::string const &label); + void set_label(const std::string &label); /// set the widgets label void set_label(const char *label); /// enable or disable widget border - void set_border(bool border = true); + void set_border(const bool border = true); /// enable or disable widget background - void set_background(bool background = true); + void set_background(const bool background = true); /* -- event distributors --------------------------------------- */ @@ -354,6 +373,7 @@ private: bool widget_background; bool widget_border; bool widget_focus; + bool widget_enabled; math::Vector2f widget_location; math::Vector2f widget_size; |