summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-09-25 21:43:15 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-09-25 21:43:15 -0400
commitd0dafc171c75146e16081c263e92190570b88a0f (patch)
treeb5fa97e74687ed11b0bb05e6d5ce0d4082d31574 /libs
parent3ec0f367c10bcb4a6095e950bdc4575911231273 (diff)
basic design of Canvas item tooltip mechanism.
No window yet to actually display the tooltip.
Diffstat (limited to 'libs')
-rw-r--r--libs/canvas/canvas.cc81
-rw-r--r--libs/canvas/canvas/canvas.h17
-rw-r--r--libs/canvas/canvas/item.h7
-rw-r--r--libs/canvas/item.cc26
4 files changed, 129 insertions, 2 deletions
diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc
index b61afed751..c671ce253e 100644
--- a/libs/canvas/canvas.cc
+++ b/libs/canvas/canvas.cc
@@ -26,6 +26,7 @@
#include <cassert>
#include <gtkmm/adjustment.h>
#include <gtkmm/label.h>
+#include <gtkmm/window.h>
#include "pbd/compose.h"
#include "pbd/stacktrace.h"
@@ -345,6 +346,8 @@ GtkCanvas::GtkCanvas ()
, _new_current_item (0)
, _grabbed_item (0)
, _focused_item (0)
+ , current_tooltip_item (0)
+ , tooltip_window (0)
{
/* these are the events we want to know about */
add_events (Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK |
@@ -607,7 +610,9 @@ GtkCanvas::deliver_enter_leave (Duple const & point, int state)
_new_current_item->Event ((GdkEvent*)&enter_event);
}
+ start_tooltip_timeout (_new_current_item);
_current_item = _new_current_item;
+
}
@@ -689,6 +694,11 @@ GtkCanvas::item_going_away (Item* item, boost::optional<Rect> bounding_box)
_focused_item = 0;
}
+ if (current_tooltip_item) {
+ current_tooltip_item = 0;
+ stop_tooltip_timeout ();
+ }
+
ScrollGroup* sg = dynamic_cast<ScrollGroup*>(item);
if (sg) {
scrollers.remove (sg);
@@ -834,6 +844,8 @@ GtkCanvas::get_mouse_position (Duple& winpos) const
bool
GtkCanvas::on_motion_notify_event (GdkEventMotion* ev)
{
+ hide_tooltip ();
+
/* translate event coordinates from window to canvas */
GdkEvent copy = *((GdkEvent*)ev);
@@ -974,6 +986,75 @@ GtkCanvas::height() const
return get_allocation().get_height();
}
+void
+GtkCanvas::start_tooltip_timeout (Item* item)
+{
+ stop_tooltip_timeout ();
+
+ if (item) {
+ current_tooltip_item = item;
+
+ /* wait for the first idle that happens after this is
+ called. this means that we've stopped processing events, which
+ in turn implies that the user has stopped doing stuff for a
+ little while.
+ */
+
+ std::cerr << "wait for idle now that we're in " << item->name << std::endl;
+
+ Glib::signal_idle().connect (sigc::mem_fun (*this, &GtkCanvas::really_start_tooltip_timeout));
+ }
+}
+
+bool
+GtkCanvas::really_start_tooltip_timeout ()
+{
+ /* an idle has occured since we entered a tooltip-bearing widget. Now
+ * wait 1 second and if the timeout isn't cancelled, show the tooltip.
+ */
+
+ std::cerr << "gone idle\n";
+
+
+ if (current_tooltip_item) {
+ std::cerr << "have an item " << current_tooltip_item->name << " now wait 1second\n";
+ _current_timeout_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &GtkCanvas::show_tooltip), 1000);
+ }
+
+ return false; /* this is called from an idle callback, don't call it again */
+}
+
+void
+GtkCanvas::stop_tooltip_timeout ()
+{
+ if (current_tooltip_item) {
+ std::cerr << "Stop timeout for " << current_tooltip_item->name << "\n";
+ }
+ current_tooltip_item = 0;
+ _current_timeout_connection.disconnect ();
+}
+
+bool
+GtkCanvas::show_tooltip ()
+{
+ if (current_tooltip_item) {
+ std::cerr << "Would show a tooltip for " << current_tooltip_item->name << '\n';
+ } else {
+ std::cerr << "tooltip timeout expired, but no item\n";
+ }
+
+ /* called from a timeout handler, don't call it again */
+ return false;
+}
+
+void
+GtkCanvas::hide_tooltip ()
+{
+ if (tooltip_window) {
+ tooltip_window->hide ();
+ }
+}
+
/** Create a GtkCanvaSViewport.
* @param hadj Adjustment to use for horizontal scrolling.
* @param vadj Adjustment to use for vertica scrolling.
diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h
index c3ab322b67..a7da4517bb 100644
--- a/libs/canvas/canvas/canvas.h
+++ b/libs/canvas/canvas/canvas.h
@@ -140,13 +140,16 @@ public:
an enter event for it.
*/
virtual void re_enter () = 0;
-
+
+ virtual void start_tooltip_timeout (Item*) {}
+ virtual void stop_tooltip_timeout () {}
+
protected:
void queue_draw_item_area (Item *, Rect);
/** our root item */
Root _root;
-
+
virtual void pick_current_item (int state) = 0;
virtual void pick_current_item (Duple const &, int state) = 0;
@@ -176,6 +179,9 @@ public:
void re_enter ();
+ void start_tooltip_timeout (Item*);
+ void stop_tooltip_timeout ();
+
protected:
bool on_scroll_event (GdkEventScroll *);
bool on_expose_event (GdkEventExpose *);
@@ -205,6 +211,13 @@ private:
Item * _grabbed_item;
/** the item that currently has key focus or 0 */
Item * _focused_item;
+
+ sigc::connection _current_timeout_connection;
+ Item* current_tooltip_item;
+ Gtk::Window* tooltip_window;
+ bool show_tooltip ();
+ void hide_tooltip ();
+ bool really_start_tooltip_timeout ();
};
/** A GTK::Alignment with a GtkCanvas inside it plus some Gtk::Adjustments for
diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h
index 9b058ab83a..4492cb8651 100644
--- a/libs/canvas/canvas/item.h
+++ b/libs/canvas/canvas/item.h
@@ -228,6 +228,12 @@ public:
void grab_focus ();
#endif
+ const std::string& tooltip () const { return _tooltip; }
+ void set_tooltip (const std::string&);
+
+ void start_tooltip_timeout ();
+ void stop_tooltip_timeout ();
+
virtual void dump (std::ostream&) const;
std::string whatami() const;
@@ -288,6 +294,7 @@ protected:
private:
void init ();
+ std::string _tooltip;
bool _ignore_events;
Duple scroll_offset() const;
diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc
index 9be1f62d92..5aef4cc779 100644
--- a/libs/canvas/item.cc
+++ b/libs/canvas/item.cc
@@ -45,6 +45,8 @@ Item::Item (Canvas* canvas)
, _lut (0)
, _ignore_events (false)
{
+ _tooltip = "This is a tooltip";
+
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
}
@@ -59,6 +61,8 @@ Item::Item (Item* parent)
, _lut (0)
, _ignore_events (false)
{
+ _tooltip = "This is a tooltip";
+
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
if (parent) {
@@ -80,6 +84,8 @@ Item::Item (Item* parent, Duple const& p)
, _lut (0)
, _ignore_events (false)
{
+ _tooltip = "This is a tooltip";
+
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
if (parent) {
@@ -982,6 +988,26 @@ Item::add_items_at_point (Duple const point, vector<Item const *>& items) const
}
void
+Item::set_tooltip (const std::string& s)
+{
+ _tooltip = s;
+}
+
+void
+Item::start_tooltip_timeout ()
+{
+ if (!_tooltip.empty()) {
+ _canvas->start_tooltip_timeout (this);
+ }
+}
+
+void
+Item::stop_tooltip_timeout ()
+{
+ _canvas->stop_tooltip_timeout ();
+}
+
+void
Item::dump (ostream& o) const
{
boost::optional<ArdourCanvas::Rect> bb = bounding_box();