Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ui/scrollbar.cc226
-rw-r--r--src/ui/scrollbar.h121
2 files changed, 347 insertions, 0 deletions
diff --git a/src/ui/scrollbar.cc b/src/ui/scrollbar.cc
new file mode 100644
index 0000000..9be1432
--- /dev/null
+++ b/src/ui/scrollbar.cc
@@ -0,0 +1,226 @@
+/*
+ ui/scrollbar.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/scrollbar.h"
+
+namespace ui {
+
+ScrollBar::ScrollBar(Widget *parent, const float minimum, const float maximum) : Widget(parent)
+{
+ set_label("scrollbar");
+ scrollbar_dragging = false;
+
+ scrollbar_minimum = minimum;
+ scrollbar_maximum = maximum;
+ scrollbar_value = scrollbar_minimum;
+
+ scrollbar_minbutton = new ui::Button(this, "o");
+ scrollbar_minbutton->set_border(false);
+
+ scrollbar_decbutton = new ui::Button(this, "-");
+ scrollbar_decbutton->set_border(false);
+
+ scrollbar_incbutton = new ui::Button(this, "+");
+ scrollbar_incbutton->set_border(false);
+
+ scrollbar_maxbutton = new ui::Button(this, "o");
+ scrollbar_maxbutton->set_border(false);
+
+ set_background(true);
+ set_border(true);
+
+ validate();
+}
+
+ScrollBar::~ScrollBar() {
+}
+
+void ScrollBar::set_value(const float value)
+{
+ scrollbar_value = value;
+ validate();
+}
+
+void ScrollBar::set_minimum(const float minimum)
+{
+ scrollbar_minimum = minimum;
+ validate();
+}
+
+void ScrollBar::set_maximum(const float maximum)
+{
+ scrollbar_maximum = maximum;
+ validate();
+}
+
+void ScrollBar::set_range(const float minimum, const float maximum)
+{
+ scrollbar_minimum = minimum;
+ scrollbar_maximum = maximum;
+ validate();
+}
+
+void ScrollBar::validate()
+{
+ if (scrollbar_minimum > scrollbar_maximum) {
+ math::swap(scrollbar_minimum, scrollbar_maximum);
+ }
+
+ math::clamp(scrollbar_value, scrollbar_minimum, scrollbar_maximum);
+}
+
+void ScrollBar::print(const size_t indent) const
+{
+ std::string marker("");
+ con_print << aux::pad_left(marker, indent*2) << label() << " \"" << minimum() << "-" << maximum() << "\"" << std::endl;
+}
+
+bool ScrollBar::on_emit(Widget *sender, const Event event, void *data)
+{
+ if (event == EventButtonClicked) {
+ if (sender == scrollbar_minbutton) {
+ scrollbar_value = scrollbar_minimum;
+ emit(EventScrollBarChanged, this);
+ return true;
+ } else if (sender == scrollbar_decbutton) {
+ if (scrollbar_value > scrollbar_minimum) {
+ scrollbar_value--;
+ emit(EventScrollBarChanged, this);
+ }
+ return true;
+ } else if (sender == scrollbar_incbutton) {
+ if (scrollbar_value < scrollbar_maximum) {
+ scrollbar_value++;
+ emit(EventScrollBarChanged, this);
+ }
+ return true;
+ } else if (sender == scrollbar_maxbutton) {
+ scrollbar_value = scrollbar_maximum;
+ emit(EventScrollBarChanged, this);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ScrollBar::on_keypress(const int key, const unsigned int modifier)
+{
+ switch (key) {
+
+ case 512 + SDL_BUTTON_WHEELDOWN:
+ if (scrollbar_value < scrollbar_maximum) {
+ scrollbar_value++;
+ emit(EventScrollBarChanged, this);
+ }
+ return true;
+ break;
+
+ case 512 + SDL_BUTTON_WHEELUP:
+ if (scrollbar_value > scrollbar_minimum) {
+ scrollbar_value--;
+ emit(EventScrollBarChanged, this);
+ }
+ return true;
+ break;
+
+ case 512 + SDL_BUTTON_LEFT:
+ if (scrollbar_maximum > scrollbar_minimum) {
+ // TODO position hit test
+ scrollbar_dragging = true;
+ }
+ return true;
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ScrollBar::on_keyrelease(const int key, const unsigned int modifier)
+{
+ if (key == 512 + SDL_BUTTON_LEFT) {
+ scrollbar_dragging = false;
+ return true;
+ }
+
+ return false;
+}
+
+void ScrollBar::on_mousemove(const math::Vector2f &cursor)
+{
+ if ((width() <= 0) || (height() <= 0)) {
+ return;
+ }
+
+ if (scrollbar_dragging && (scrollbar_maximum > scrollbar_minimum)) {
+ // total width of dragable area
+ if ((cursor.y() >= 2.0f * width()) && (cursor.y() <= height() - 2.0f * width())) {
+
+ const float h = (height() - 4.0f * width());
+ const float s = h / (scrollbar_maximum - scrollbar_minimum);
+ const float p = cursor.y() - 2.0f * width();
+ const float newvalue = scrollbar_minimum + round(p / s);
+ if (scrollbar_value != newvalue) {
+ scrollbar_value = newvalue;
+ emit(EventScrollBarChanged, this);
+ }
+ }
+ }
+
+}
+
+void ScrollBar::on_mouseover(const math::Vector2f &cursor)
+{
+ scrollbar_dragging = false;
+}
+
+void ScrollBar::show()
+{
+ Widget::show();
+ resize();
+}
+
+void ScrollBar::resize()
+{
+ // note: scrollbar expects height > width
+ scrollbar_minbutton->set_size(width(), width());
+ scrollbar_minbutton->set_location(0, 0);
+
+ scrollbar_decbutton->set_size(width(), width());
+ scrollbar_decbutton->set_location(0, scrollbar_minbutton->bottom());
+
+ scrollbar_maxbutton->set_size(width(), width());
+ scrollbar_maxbutton->set_location(0, height() - scrollbar_maxbutton->height());
+
+ scrollbar_incbutton->set_size(width(), width());
+ scrollbar_incbutton->set_location(0, scrollbar_maxbutton->top() - scrollbar_incbutton->height());
+}
+
+void ScrollBar::draw()
+{
+ if (scrollbar_maximum > scrollbar_minimum) {
+ const float range = (scrollbar_value - scrollbar_minimum) / (scrollbar_maximum - scrollbar_minimum);
+ const float y = (height() - 5.0f * width()) * range;
+ if (scrollbar_dragging) {
+ Paint::set_color(palette()->highlight());
+ } else {
+ Paint::set_color(palette()->foreground());
+ }
+ Paint::draw_rectangle(
+ math::Vector2f(global_location().x() + 1.0f,
+ global_location().y() + 2.0f * width() + y + 1.0f),
+ math::Vector2f(width() - 2, width() - 2)
+ );
+ }
+
+ Widget::draw();
+}
+
+} // namespace ui
diff --git a/src/ui/scrollbar.h b/src/ui/scrollbar.h
new file mode 100644
index 0000000..0689969
--- /dev/null
+++ b/src/ui/scrollbar.h
@@ -0,0 +1,121 @@
+/*
+ ui/scrollbar.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_SCROLLBAR_H__
+#define __INCLUDED_UI_SCROLLBAR_H__
+
+#include <string>
+#include "ui/button.h"
+#include "ui/widget.h"
+
+namespace ui
+{
+
+/**
+ * @brief a scrollbar widget
+ */
+class ScrollBar : public Widget
+{
+public:
+ ScrollBar(Widget *parent, const float minimum = 0.0f, const float maximum = 1.0f);
+
+ ~ScrollBar();
+
+ /**
+ * @brief the current slider value
+ */
+ inline const float value() const {
+ return scrollbar_value;
+ }
+
+ /**
+ * @brief the minimum value
+ */
+ inline const float minimum() const {
+ return scrollbar_minimum;
+ }
+
+ /**
+ * @brief the maximum value
+ */
+ inline const float maximum() const {
+ return scrollbar_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);
+
+ /// show the widget
+ virtual void show();
+
+protected:
+
+ /// resize event handler
+ virtual void resize();
+
+ /// draw event handler
+ virtual void draw();
+
+ /// emit event handler
+ virtual bool on_emit(Widget *sender, const Event event, void *data=0);
+
+ /// keypress event handler
+ virtual bool on_keypress(const int key, const unsigned int modifier);
+
+ /// keyrelease event handler
+ virtual bool on_keyrelease(const int key, const unsigned int modifier);
+
+ virtual void on_mouseover(const math::Vector2f &cursor);
+
+ /// mouse movement handler
+ virtual void on_mousemove(const math::Vector2f &cursor);
+
+private:
+ /// validate slider value
+ void validate();
+
+ float scrollbar_minimum;
+ float scrollbar_maximum;
+ float scrollbar_value;
+ bool scrollbar_dragging;
+
+ Button *scrollbar_minbutton;
+ Button *scrollbar_decbutton;
+ Button *scrollbar_incbutton;
+ Button *scrollbar_maxbutton;
+};
+
+}
+
+#endif // __INCLUDED_UI_SCROLLBAR_H__
+