From 3999ff518d08778d25cb0d00329943ee5c2ef222 Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@telenet.be>
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(-)

(limited to 'src/ui')

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