From b19afea9427dde861c990236ab11e23edfeb267c Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 18 Jul 2020 14:49:13 +0200 Subject: Completed ui library tooltip implementation. --- src/ui/Makefile.am | 2 ++ src/ui/font.h | 6 +++++ src/ui/label.h | 1 - src/ui/toolbar.h | 2 +- src/ui/tooltip.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui/tooltip.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui/ui.cc | 32 +++++++++++++++++++++++++++ src/ui/ui.h | 3 +++ src/ui/widget.cc | 19 ++++++++-------- src/ui/widget.h | 15 ++++++++----- 10 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 src/ui/tooltip.cc create mode 100644 src/ui/tooltip.h diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 1485565..875ffcd 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -29,6 +29,7 @@ noinst_HEADERS = \ scrollpane.h \ slider.h \ toolbar.h \ + tooltip.h \ ui.h \ widget.h \ window.h @@ -53,6 +54,7 @@ libui_la_SOURCES = \ scrollpane.cc \ slider.cc \ toolbar.cc \ + tooltip.cc \ ui.cc \ widget.cc \ window.cc diff --git a/src/ui/font.h b/src/ui/font.h index b91120e..be08cfd 100644 --- a/src/ui/font.h +++ b/src/ui/font.h @@ -27,10 +27,16 @@ public: return font_size; } + /** + * @brief width of a single character + * */ inline float width() const { return font_size.width(); } + /** + * @height width of a single character + * */ inline float height() const { return font_size.height(); } diff --git a/src/ui/label.h b/src/ui/label.h index f187520..a895691 100644 --- a/src/ui/label.h +++ b/src/ui/label.h @@ -12,7 +12,6 @@ namespace ui { - /** * @brief a widget displaying a single line of text */ diff --git a/src/ui/toolbar.h b/src/ui/toolbar.h index baff21b..ccb3d30 100644 --- a/src/ui/toolbar.h +++ b/src/ui/toolbar.h @@ -27,7 +27,7 @@ public: protected: /// re-arrange child widgets - void resize(); + virtual void resize(); }; } diff --git a/src/ui/tooltip.cc b/src/ui/tooltip.cc new file mode 100644 index 0000000..95f1ac8 --- /dev/null +++ b/src/ui/tooltip.cc @@ -0,0 +1,64 @@ +/* + ui/tooltip.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "ui/tooltip.h" +#include "ui/ui.h" + +#include + +namespace ui +{ + +Tooltip *Tooltip::tooltip_global = nullptr; + +Tooltip::Tooltip(Widget *parent) : Label(parent) +{ + set_label("tooltip"); + set_alignment(AlignCenter); + set_background(true); + set_visible(false); +} + +Tooltip::~Tooltip() +{ +} + +void Tooltip::resize() +{ + set_size(font()->width() * text().size() + UI::padding, font()->height() + + UI::padding); + set_location((parent()->width() - width()) * 0.5f, parent()->height()); +} + +void Tooltip::draw() +{ + if (tooltip_global != this) { + hide(); + } else { + Label::draw(); + } +} + +void Tooltip::show() +{ + if ((tooltip_global != nullptr) && (tooltip_global != this)) { + tooltip_global->hide(); + } + tooltip_global = this; + event_resize(); + + Label::show(); +} + +void Tooltip::hide() +{ + if (tooltip_global == this) { + tooltip_global = nullptr; + } + Label::hide(); +} + + +} diff --git a/src/ui/tooltip.h b/src/ui/tooltip.h new file mode 100644 index 0000000..2345973 --- /dev/null +++ b/src/ui/tooltip.h @@ -0,0 +1,61 @@ +/* + ui/tooltip.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_TOOLTIP_H__ +#define __INCLUDED_UI_TOOLTIP_H__ + +#include "ui/label.h" + +namespace ui +{ + /** + * @brief a widget displaying a tooltip. + * This class makes sure only one Tooltip is globally visible. + */ +class Tooltip : public Label +{ + public: + Tooltip(Widget *parent); + ~Tooltip(); + + /** + * @brief resize the tooltip + */ + virtual void resize(); + + /** + * @brief show the tooltip + */ + virtual void show(); + + /** + * @brief hide the tooltip + */ + virtual void hide(); + + /** + * @brief the tooltip that is currently visible, nullptr if no tooltip is currently shown + * + **/ + static inline Tooltip *global() + { + return tooltip_global; + } + + protected: + /** + * @brief draw the tooltip + */ + virtual void draw(); + + private: + + static Tooltip *tooltip_global; +}; + +} + +#endif // __INCLUDED_UI_TOOLTIP_H__ diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 700099e..fc52bbf 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -11,6 +11,7 @@ #include "auxiliary/functions.h" #include "core/core.h" #include "core/application.h" +#include "core/cvar.h" #include "filesystem/filesystem.h" #include "render/gl.h" #include "sys/sys.h" @@ -34,6 +35,8 @@ float UI::margin = 16.0f; float UI::pointer_size = 48.0f; +core::Cvar *ui_tooltiptimeout = nullptr; + UI *global_ui = 0; UI *root() @@ -44,6 +47,9 @@ UI *root() void init() { con_print << "^BInitializing user interface..." << std::endl; + + ui_tooltiptimeout = core::Cvar::get("ui_tooltiptimeout", "250", core::Cvar::Archive); + ui_tooltiptimeout->set_info("[int] time in milliseconds before a tooltip is shown"); if (!global_ui) { global_ui = new UI(); @@ -94,6 +100,7 @@ UI::UI() : Window(0) mouse_pointer_bitmap.assign("pointer"); mouse_buttonleft_pressed = false; + ui_tooltip_timestamp = core::application()->timestamp(); } UI::~UI() @@ -275,6 +282,17 @@ void UI::frame() } ui_mouse_focus = f; + // show tooltip if the timeout has expired + if (ui_mouse_focus && ui_mouse_focus->tooltip() && ui_mouse_focus->tooltip()->hidden()) + { + assert(ui_tooltiptimeout != nullptr); + unsigned long timeout = (unsigned long) ui_tooltiptimeout->value(); + + if (ui_tooltip_timestamp + timeout < core::application()->timestamp()) { + ui_mouse_focus->tooltip()->show(); + } + } + // reset mouse pointer ui::root()->set_pointer("pointer"); @@ -293,6 +311,13 @@ void UI::frame() */ void UI::input_mouse(const float x, const float y) { + // hide tooltip if the mouse has been moved + if (Tooltip::global() && Tooltip::global()->visible()) + { + Tooltip::global()->hide(); + } + ui_tooltip_timestamp = core::application()->timestamp(); + mouse_cursor.assign(x, y); } @@ -300,6 +325,13 @@ bool UI::input_mouse_button(const bool pressed, unsigned int button) { bool handled = false; + // hide tooltip if a mouse button has been clicked + if (Tooltip::global() && Tooltip::global()->visible()) + { + Tooltip::global()->hide(); + } + ui_tooltip_timestamp = core::application()->timestamp(); + if (button == SDL_BUTTON_LEFT) { mouse_buttonleft_pressed = pressed; diff --git a/src/ui/ui.h b/src/ui/ui.h index aaf4acc..c3b2f18 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -10,6 +10,7 @@ #include "ui/console.h" #include "ui/font.h" #include "ui/palette.h" +#include "ui/tooltip.h" #include "ui/widget.h" #include "ui/window.h" @@ -138,6 +139,8 @@ private: Palette::Color mouse_pointer_color; bool mouse_pointer_animated; bool mouse_buttonleft_pressed; + + unsigned long ui_tooltip_timestamp; }; /// initialize the user interface diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 8c40c04..73c454a 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -9,6 +9,7 @@ #include "ui/paint.h" #include "ui/ui.h" #include "ui/widget.h" +#include "ui/tooltip.h" #include @@ -22,8 +23,9 @@ Widget::Widget(Widget *parent) widget_border = true; widget_background = false; widget_enabled = true; - widget_palette = 0; - widget_font = 0; + widget_palette = nullptr; + widget_font = nullptr; + widget_tooltip = nullptr; widget_label.assign("widget"); if (!parent) { @@ -241,19 +243,18 @@ void Widget::set_label(const char *label) } -void Widget::set_tooltip(const std::string &tooltip) +void Widget::set_tooltip(const std::string &tooltip_text) { - widget_tooltip.assign(tooltip); + set_tooltip(tooltip_text.c_str()); } -void Widget::set_tooltip(const char *tooltip) +void Widget::set_tooltip(const char *tooltip_text) { - if (tooltip == nullptr) + if (widget_tooltip == nullptr) { - widget_tooltip.clear(); - } else { - widget_label.assign(tooltip); + widget_tooltip = new Tooltip(this); } + widget_tooltip->set_text(tooltip_text); } void Widget::set_palette(const Palette *palette) diff --git a/src/ui/widget.h b/src/ui/widget.h index 243fdda..e1f199d 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -23,6 +23,8 @@ namespace ui { +class Tooltip; + class Widget { @@ -131,7 +133,7 @@ public: } /// widget tooltip - inline const std::string &tooltip() const { + inline Tooltip *tooltip() { return widget_tooltip; } @@ -249,11 +251,11 @@ public: /// set the widget's label void set_label(const char *label = nullptr); - /// set the wdiget's widget_tooltip - void set_tooltip(const std::string &tooltip); + /// set the wdiget's tooltip text + void set_tooltip(const std::string &tooltip_text); - /// set the wdiget's widget_tooltip - void set_tooltip(const char *tooltip = nullptr); + /// set the wdiget's tooltip text + void set_tooltip(const char *tooltip_text = nullptr); /// enable or disable widget border void set_border(const bool border = true); @@ -446,13 +448,14 @@ private: math::Vector2f widget_location; math::Vector2f widget_size; std::string widget_label; - std::string widget_tooltip; Children widget_children; const Palette *widget_palette; const Font *widget_font; Widget *widget_parent; + + Tooltip *widget_tooltip; Children::iterator find_child(Widget *child); -- cgit v1.2.3