From 3999ff518d08778d25cb0d00329943ee5c2ef222 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 18 Jul 2020 21:13:09 +0200 Subject: Draw tooltips below the mouse cursor instead of below parent widget. --- src/ui/ui.cc | 20 ++++++++++++----- src/ui/widget.h | 69 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 7fb25dd..c1558b1 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -283,12 +283,19 @@ 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()) + if (ui_mouse_focus && ui_mouse_focus->tooltip() && ui_mouse_focus->tooltip()->text().size() && 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()) { + // move the tooltip below the mouse cursor + math::Vector2f p( + ui_mouse_focus->tooltip()->parent() ? + ui_mouse_focus->tooltip()->parent()->to_local_coords(mouse_cursor) : + mouse_cursor); + + ui_mouse_focus->tooltip()->set_location(p.x() - ui_mouse_focus->tooltip()->width() * 0.5f, p.y() + pointer_size * 0.5f); ui_mouse_focus->tooltip()->show(); } } @@ -299,12 +306,13 @@ void UI::frame() // draw the widget stack event_draw(); - // draw tooltip - Tooltip::event_draw_global(); - - // draw the mouse pointer - if (visible()) + if (visible()) { + // draw tooltip + Tooltip::event_draw_global(); + + // draw the mouse pointer draw_pointer(); + } } /* -- global event handlers ---------------------------------------- */ diff --git a/src/ui/widget.h b/src/ui/widget.h index c3d952c..9c7871f 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -316,41 +316,14 @@ public: inline void emit(const Event event, void *data=0) { event_emit(this, event, data); } - -protected: - - /// find the widget that has input focus - virtual Widget *find_input_focus(); - - /** - * @brief find the widget in a given location - * Searches the widget's children tree for the leaf widget visible in a given location. - * If no child contains the location, the widget itself is tested. Returns a nullptr ig - * the location is not within the widget's boundries. - * @param location search position, relative to this widget's location - **/ - Widget *find_widget_in_location(const math::Vector2f &location); - /// find a visible widget - Widget *find_visible_child(const Widget *widget); - - /// list widget content - size_t list(const size_t indent, const bool visible_only = false) const; - - /// print widget description - virtual void print(const size_t indent) const; - - /// true of this sibling has local focus - inline bool focus() const { - return widget_focus; - } - + /* -- coordinate mapping ----------------------------------- */ /// map local widget location to global location - inline math::Vector2f global_location() { + inline const math::Vector2f global_location() const { math::Vector2f v(widget_location); - Widget *parent = widget_parent; + const Widget *parent = widget_parent; while (parent) { v += parent->location(); parent = parent->parent(); @@ -359,9 +332,9 @@ protected: } /// map local coordinates to global coordinates - inline math::Vector2f to_global_coords(const math::Vector2f &local) { + inline const math::Vector2f to_global_coords(const math::Vector2f &local) const { math::Vector2f v(local); - Widget *parent = widget_parent; + const Widget *parent = widget_parent; do { v += parent->location(); parent = parent->parent(); @@ -370,9 +343,9 @@ protected: } /// map global coordinates to local coordinates - inline math::Vector2f to_local_coords(const math::Vector2f &global) { + inline const math::Vector2f to_local_coords(const math::Vector2f &global) const { math::Vector2f v(global); - Widget *parent = this; + const Widget *parent = this; while (parent) { v -= parent->location(); parent = parent->parent(); @@ -380,6 +353,34 @@ protected: return v; } +protected: + + /// find the widget that has input focus + virtual Widget *find_input_focus(); + + /** + * @brief find the widget in a given location + * Searches the widget's children tree for the leaf widget visible in a given location. + * If no child contains the location, the widget itself is tested. Returns a nullptr ig + * the location is not within the widget's boundries. + * @param location search position, relative to this widget's location + **/ + Widget *find_widget_in_location(const math::Vector2f &location); + + /// find a visible widget + Widget *find_visible_child(const Widget *widget); + + /// list widget content + size_t list(const size_t indent, const bool visible_only = false) const; + + /// print widget description + virtual void print(const size_t indent) const; + + /// true of this sibling has local focus + inline bool focus() const { + return widget_focus; + } + /* -- event handlers --------------------------------------- */ /// called when the mouse receives mouse movement -- cgit v1.2.3