Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-09-20 16:30:45 +0000
committerStijn Buys <ingar@osirion.org>2010-09-20 16:30:45 +0000
commite40f70a3af1142e6c0c89c6ea2ee47b996495661 (patch)
treeba70a909b5066ad0e07e2f4eb8bc98684e4598e6
parente8f7c4a06fce9e41fb23ffc42a566501a78210cb (diff)
corrected trading inconsistencies, improved trade window, initial slider widget
-rw-r--r--src/client/inventorylistview.cc2
-rw-r--r--src/client/trademenu.cc206
-rw-r--r--src/client/trademenu.h10
-rw-r--r--src/core/inventory.cc9
-rw-r--r--src/core/inventory.h10
-rw-r--r--src/game/base/cargo.cc10
-rw-r--r--src/math/functions.cc20
-rw-r--r--src/math/functions.h60
-rw-r--r--src/ui/Makefile.am4
-rw-r--r--src/ui/listitem.h2
-rw-r--r--src/ui/listview.cc3
-rw-r--r--src/ui/slider.cc111
-rw-r--r--src/ui/slider.h101
-rw-r--r--src/ui/widget.cc28
-rw-r--r--src/ui/widget.h32
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;