Factor out 'persistent' tooltip code from the panner
authorCarl Hetherington <carl@carlh.net>
Mon, 11 Jun 2012 21:21:10 +0000 (21:21 +0000)
committerCarl Hetherington <carl@carlh.net>
Mon, 11 Jun 2012 21:21:10 +0000 (21:21 +0000)
interface and use it for processor box sliders (#4461).

git-svn-id: svn://localhost/ardour2/branches/3.0@12661 d708f5d6-7413-0410-9779-e7cbd77b26cf

13 files changed:
gtk2_ardour/mono_panner.cc
gtk2_ardour/mono_panner.h
gtk2_ardour/panner_interface.cc
gtk2_ardour/panner_interface.h
gtk2_ardour/processor_box.cc
gtk2_ardour/processor_box.h
gtk2_ardour/stereo_panner.cc
gtk2_ardour/stereo_panner.h
libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h [new file with mode: 0644]
libs/gtkmm2ext/gtkmm2ext/utils.h
libs/gtkmm2ext/persistent_tooltip.cc [new file with mode: 0644]
libs/gtkmm2ext/utils.cc
libs/gtkmm2ext/wscript

index 8b28d7f1a45fe24c9d46577f7482d62581d36c6d..7dd16d4853db726c4c325471fc874275c75b126c 100644 (file)
@@ -31,6 +31,7 @@
 #include "gtkmm2ext/gtk_ui.h"
 #include "gtkmm2ext/keyboard.h"
 #include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/persistent_tooltip.h"
 
 #include "ardour/pannable.h"
 #include "ardour/panner.h"
@@ -64,6 +65,7 @@ MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::Panner> panner)
         , accumulated_delta (0)
         , detented (false)
         , position_binder (position_control)
+       , _dragging (false)
 {
         if (!have_colors) {
                 set_colors ();
@@ -73,6 +75,8 @@ MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::Panner> panner)
         position_control->Changed.connect (connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context());
 
        ColorsChanged.connect (sigc::mem_fun (*this, &MonoPanner::color_handler));
+
+       set_tooltip ();
 }
 
 MonoPanner::~MonoPanner ()
@@ -81,12 +85,8 @@ MonoPanner::~MonoPanner ()
 }
 
 void
-MonoPanner::set_drag_data ()
+MonoPanner::set_tooltip ()
 {
-        if (!_drag_data_label) {
-                return;
-        }
-
         double pos = position_control->get_value(); // 0..1
 
         /* We show the position of the center of the image relative to the left & right.
@@ -101,7 +101,7 @@ MonoPanner::set_drag_data ()
         snprintf (buf, sizeof (buf), "L:%3d R:%3d",
                   (int) rint (100.0 * (1.0 - pos)),
                   (int) rint (100.0 * pos));
-        _drag_data_label->set_markup (buf);
+        _tooltip.set_tip (buf);
 }
 
 bool
@@ -255,6 +255,7 @@ MonoPanner::on_button_press_event (GdkEventButton* ev)
         last_drag_x = ev->x;
 
         _dragging = false;
+       _tooltip.target_stop_drag ();
         accumulated_delta = 0;
         detented = false;
 
@@ -290,6 +291,7 @@ MonoPanner::on_button_press_event (GdkEventButton* ev)
                 }
 
                 _dragging = false;
+               _tooltip.target_stop_drag ();
 
         } else if (ev->type == GDK_BUTTON_PRESS) {
 
@@ -299,8 +301,8 @@ MonoPanner::on_button_press_event (GdkEventButton* ev)
                 }
 
                 _dragging = true;
+               _tooltip.target_start_drag ();
                 StartGesture ();
-               show_drag_data_window ();
         }
 
         return true;
@@ -318,11 +320,10 @@ MonoPanner::on_button_release_event (GdkEventButton* ev)
         }
 
         _dragging = false;
+       _tooltip.target_stop_drag ();
         accumulated_delta = 0;
         detented = false;
 
-       hide_drag_data_window ();
-
         if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
                _panner->reset ();
         } else {
index 3b7a37c993d9fb6d2af33749c3455fc3c520f3a5..1c387ad32cab50ed7c364e49fc672eab998a7042 100644 (file)
@@ -63,7 +63,7 @@ class MonoPanner : public PannerInterface
 
         BindingProxy position_binder;
 
-        void set_drag_data ();
+        void set_tooltip ();
 
         struct ColorScheme {
             uint32_t outline;
@@ -74,6 +74,8 @@ class MonoPanner : public PannerInterface
             uint32_t pos_fill;
         };
 
+       bool _dragging;
+
         static ColorScheme colors;
         static void set_colors ();
         static bool have_colors;
index 09155c6b793ca01e9423888503fa3000c735e57f..09cf29dfd62757718e1c54cb3dbc580ed0008a08 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <gtkmm.h>
 #include "gtkmm2ext/keyboard.h"
+#include "gtkmm2ext/persistent_tooltip.h"
 #include "panner_interface.h"
 #include "panner_editor.h"
 #include "global_signals.h"
@@ -32,9 +33,7 @@ using namespace Gtkmm2ext;
 
 PannerInterface::PannerInterface (boost::shared_ptr<Panner> p)
        : _panner (p)
-       , _drag_data_window (0)
-       , _drag_data_label (0)
-        , _dragging (false)
+       , _tooltip (this)
        , _editor (0)
 {
         set_flags (Gtk::CAN_FOCUS);
@@ -49,66 +48,14 @@ PannerInterface::PannerInterface (boost::shared_ptr<Panner> p)
 
 PannerInterface::~PannerInterface ()
 {
-       delete _drag_data_window;
        delete _editor;
 }
 
-void
-PannerInterface::show_drag_data_window ()
-{
-        if (!_drag_data_window) {
-               _drag_data_window = new Window (WINDOW_POPUP);
-               _drag_data_window->set_name (X_("ContrastingPopup"));
-               _drag_data_window->set_position (WIN_POS_MOUSE);
-               _drag_data_window->set_decorated (false);
-               
-               _drag_data_label = manage (new Label);
-               _drag_data_label->set_use_markup (true);
-               
-               _drag_data_window->set_border_width (6);
-               _drag_data_window->add (*_drag_data_label);
-               _drag_data_label->show ();
-               
-               Window* toplevel = dynamic_cast<Window*> (get_toplevel());
-               if (toplevel) {
-                       _drag_data_window->set_transient_for (*toplevel);
-               }
-       }
-
-       set_drag_data ();
-       
-        if (!_drag_data_window->is_visible ()) {
-                /* move the window a little away from the mouse */
-                int rx, ry;
-                get_window()->get_origin (rx, ry);
-                _drag_data_window->move (rx, ry + get_height());
-                _drag_data_window->present ();
-        }
-}
-
-void
-PannerInterface::hide_drag_data_window ()
-{
-        if (_drag_data_window) {
-                _drag_data_window->hide ();
-        }
-}
-
 bool
 PannerInterface::on_enter_notify_event (GdkEventCrossing *)
 {
        grab_focus ();
        Keyboard::magic_widget_grab_focus ();
-
-       _drag_data_timeout = Glib::signal_timeout().connect (sigc::mem_fun (*this, &PannerInterface::drag_data_timeout), 500);
-       
-       return false;
-}
-
-bool
-PannerInterface::drag_data_timeout ()
-{
-       show_drag_data_window ();
        return false;
 }
 
@@ -116,12 +63,6 @@ bool
 PannerInterface::on_leave_notify_event (GdkEventCrossing *)
 {
        Keyboard::magic_widget_drop_focus ();
-
-       _drag_data_timeout.disconnect ();
-       if (!_dragging) {
-               hide_drag_data_window ();
-       }
-       
        return false;
 }
 
@@ -134,7 +75,7 @@ PannerInterface::on_key_release_event (GdkEventKey*)
 void
 PannerInterface::value_change ()
 {
-       set_drag_data ();
+       set_tooltip ();
        queue_draw ();
 }
 
@@ -167,3 +108,28 @@ PannerInterface::edit ()
        _editor = editor ();
        _editor->show ();
 }
+
+PannerPersistentTooltip::PannerPersistentTooltip (Gtk::Widget* w)
+       : PersistentTooltip (w)
+       , _dragging (false)
+{
+
+}
+
+void
+PannerPersistentTooltip::target_start_drag ()
+{
+       _dragging = true;
+}
+
+void
+PannerPersistentTooltip::target_stop_drag ()
+{
+       _dragging = false;
+}
+
+bool
+PannerPersistentTooltip::dragging () const
+{
+       return _dragging;
+}
index 8dd19d1a143bd91adb20702efd0402906cd0e95f..02f4e210bde88714ad775b1a284b2c16cf913365 100644 (file)
@@ -23,6 +23,7 @@
 #include <boost/shared_ptr.hpp>
 #include <gtkmm/drawingarea.h>
 #include <gtkmm/label.h>
+#include "gtkmm2ext/persistent_tooltip.h"
 #include "pbd/destructible.h"
 
 namespace ARDOUR {
@@ -31,6 +32,21 @@ namespace ARDOUR {
 
 class PannerEditor;
 
+class PannerPersistentTooltip : public Gtkmm2ext::PersistentTooltip
+{
+public:
+       PannerPersistentTooltip (Gtk::Widget* w);
+
+       void target_start_drag ();
+       void target_stop_drag ();
+
+       bool dragging () const;
+
+private:
+       bool _dragging;
+};
+       
+
 /** Parent class for some panner UI classes that contains some common code */
 class PannerInterface : public Gtk::DrawingArea, public PBD::Destructible
 {
@@ -45,10 +61,8 @@ public:
        void edit ();
 
 protected:
-       virtual void set_drag_data () = 0;
+       virtual void set_tooltip () = 0;
 
-       void show_drag_data_window ();
-       void hide_drag_data_window ();
        void value_change ();
        
         bool on_enter_notify_event (GdkEventCrossing *);
@@ -58,14 +72,9 @@ protected:
        bool on_button_release_event (GdkEventButton*);
 
        boost::shared_ptr<ARDOUR::Panner> _panner;
-        Gtk::Window* _drag_data_window;
-        Gtk::Label*  _drag_data_label;
-        bool _dragging;
+       PannerPersistentTooltip _tooltip;
 
 private:
-       bool drag_data_timeout ();
-       sigc::connection _drag_data_timeout;
-
        virtual PannerEditor* editor () = 0;
        PannerEditor* _editor;
 };
index 525aca33e9bc1af412751e019fd78341b8edbb66..ac35204fb7c0643e882c8891c8b22ac0ebc07212 100644 (file)
@@ -411,6 +411,7 @@ ProcessorEntry::Control::Control (Glib::RefPtr<Gdk::Pixbuf> s, Glib::RefPtr<Gdk:
        : _control (c)
        , _adjustment (gain_to_slider_position_with_max (1.0, Config->get_max_gain()), 0, 1, 0.01, 0.1)
        , _slider (s, sd, &_adjustment, 0, false)
+       , _slider_persistant_tooltip (&_slider)
        , _button (ArdourButton::Element (ArdourButton::Text | ArdourButton::Indicator))
        , _ignore_ui_adjustment (false)
        , _visible (false)
@@ -454,6 +455,9 @@ ProcessorEntry::Control::Control (Glib::RefPtr<Gdk::Pixbuf> s, Glib::RefPtr<Gdk:
        
        control_changed ();
        set_tooltip ();
+
+       /* We're providing our own PersistentTooltip */
+       set_no_tooltip_whatsoever (_slider);
 }
 
 void
@@ -470,11 +474,13 @@ ProcessorEntry::Control::set_tooltip ()
        if (c->toggled ()) {
                s << (c->get_value() > 0.5 ? _("on") : _("off"));
        } else {
-               s << c->internal_to_interface (c->get_value ());
+               s << setprecision(2) << fixed;
+               s << c->internal_to_user (c->get_value ());
        }
        
        ARDOUR_UI::instance()->set_tip (_label, s.str ());
-       ARDOUR_UI::instance()->set_tip (_slider, s.str ());
+       _slider_persistant_tooltip.set_tip (s.str ());
+//     ARDOUR_UI::instance()->set_tip (_slider, " ");
        ARDOUR_UI::instance()->set_tip (_button, s.str ());
 }
 
@@ -498,6 +504,7 @@ ProcessorEntry::Control::slider_adjusted ()
        }
 
        c->set_value (c->interface_to_internal (_adjustment.get_value ()));
+       set_tooltip ();
 }
 
 void
@@ -537,8 +544,6 @@ ProcessorEntry::Control::control_changed ()
                s.precision (1);
                s.setf (ios::fixed, ios::floatfield);
                s << c->internal_to_user (c->get_value ());
-               
-               _slider.set_tooltip_text (s.str ());
        }
        
        _ignore_ui_adjustment = false;
index 67a9e315d505bf8cdee73321a2cec47b7c590fb7..d300f70d5adbd70f90eb63a2482bd7b214608882 100644 (file)
@@ -34,6 +34,7 @@
 #include "gtkmm2ext/click_box.h"
 #include "gtkmm2ext/dndvbox.h"
 #include "gtkmm2ext/pixfader.h"
+#include "gtkmm2ext/persistent_tooltip.h"
 
 #include "pbd/stateful.h"
 #include "pbd/signals.h"
@@ -189,6 +190,7 @@ private:
                Gtk::Adjustment _adjustment;
                Gtkmm2ext::HSliderController _slider;
                Gtk::Label _label;
+               Gtkmm2ext::PersistentTooltip _slider_persistant_tooltip;
                /* things for a button */
                ArdourButton _button;
                bool _ignore_ui_adjustment;
index 5ee75ecc195ca2ca2e79917bd60610e971f33df4..ebb55e7c867d0515108be46ba4b56f9d164b4d25 100644 (file)
@@ -30,6 +30,7 @@
 #include "gtkmm2ext/gtk_ui.h"
 #include "gtkmm2ext/keyboard.h"
 #include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/persistent_tooltip.h"
 
 #include "ardour/pannable.h"
 #include "ardour/panner.h"
@@ -70,6 +71,7 @@ StereoPanner::StereoPanner (boost::shared_ptr<Panner> panner)
        , detented (false)
        , position_binder (position_control)
        , width_binder (width_control)
+       , _dragging (false)
 {
        if (!have_colors) {
                set_colors ();
@@ -80,6 +82,8 @@ StereoPanner::StereoPanner (boost::shared_ptr<Panner> panner)
        width_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
 
        ColorsChanged.connect (sigc::mem_fun (*this, &StereoPanner::color_handler));
+
+       set_tooltip ();
 }
 
 StereoPanner::~StereoPanner ()
@@ -88,12 +92,8 @@ StereoPanner::~StereoPanner ()
 }
 
 void
-StereoPanner::set_drag_data ()
+StereoPanner::set_tooltip ()
 {
-       if (!_drag_data_label) {
-               return;
-       }
-
        double pos = position_control->get_value(); // 0..1
 
        /* We show the position of the center of the image relative to the left & right.
@@ -108,7 +108,7 @@ StereoPanner::set_drag_data ()
        snprintf (buf, sizeof (buf), "L:%3d R:%3d Width:%d%%", (int) rint (100.0 * (1.0 - pos)),
                  (int) rint (100.0 * pos),
                  (int) floor (100.0 * width_control->get_value()));
-       _drag_data_label->set_markup (buf);
+       _tooltip.set_tip (buf);
 }
 
 bool
@@ -360,8 +360,6 @@ StereoPanner::on_button_press_event (GdkEventButton* ev)
                        return true;
                }
 
-               show_drag_data_window ();
-
                if (ev->y < 20) {
                        /* top section of widget is for position drags */
                        dragging_position = true;
@@ -395,6 +393,7 @@ StereoPanner::on_button_press_event (GdkEventButton* ev)
                }
 
                _dragging = true;
+               _tooltip.target_start_drag ();
        }
 
        return true;
@@ -414,14 +413,13 @@ StereoPanner::on_button_release_event (GdkEventButton* ev)
        bool const dp = dragging_position;
 
        _dragging = false;
+       _tooltip.target_stop_drag ();
        dragging_position = false;
        dragging_left = false;
        dragging_right = false;
        accumulated_delta = 0;
        detented = false;
 
-       hide_drag_data_window ();
-
        if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
                _panner->reset ();
        } else {
index 19fa0c056ec892fc20504c6ab66d3324ddb92c4b..8b62b7d82a412bb41971914215817e52ecdb331b 100644 (file)
@@ -72,7 +72,7 @@ class StereoPanner : public PannerInterface
         BindingProxy position_binder;
         BindingProxy width_binder;
 
-        void set_drag_data ();
+        void set_tooltip ();
 
         struct ColorScheme {
             uint32_t outline;
@@ -88,6 +88,8 @@ class StereoPanner : public PannerInterface
                 Inverted
         };
 
+       bool _dragging;
+
         static ColorScheme colors[3];
         static void set_colors ();
         static bool have_colors;
diff --git a/libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h b/libs/gtkmm2ext/gtkmm2ext/persistent_tooltip.h
new file mode 100644 (file)
index 0000000..edd1e19
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+    Copyright (C) 2012 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef gtkmm2ext_persistent_tooltip_h
+#define gtkmm2ext_persistent_tooltip_h
+
+#include <sigc++/trackable.h>
+
+namespace Gtkmm2ext {
+
+/** A class which offers a tooltip-like window which can be made to
+ *  stay open during a drag.
+ */
+class PersistentTooltip : public sigc::trackable
+{
+public:
+       PersistentTooltip (Gtk::Widget *);
+       virtual ~PersistentTooltip ();
+       
+       void set_tip (std::string);
+
+       virtual bool dragging () const;
+
+private:
+       bool timeout ();
+       void show ();
+       void hide ();
+       bool enter (GdkEventCrossing *);
+       bool leave (GdkEventCrossing *);
+       bool press (GdkEventButton *);
+       bool release (GdkEventButton *);
+
+       /** The widget that we are providing a tooltip for */
+       Gtk::Widget* _target;
+       /** Our window */
+       Gtk::Window* _window;
+       /** Our label */
+       Gtk::Label* _label;
+       /** true if we are `dragging', in the sense that button 1
+           is being held over _target.
+       */
+       bool _maybe_dragging;
+       /** Connection to a timeout used to open the tooltip */
+       sigc::connection _timeout;
+       /** The tip text */
+       std::string _tip;
+};
+
+}
+
+#endif
index b7e27ea351c4d901bdbf52a9f8e9a005df3f4606..c4c9a4125cfcba877459edb22de7a12e418b4013 100644 (file)
@@ -108,6 +108,8 @@ namespace Gtkmm2ext {
        void rounded_bottom_half_rectangle (cairo_t*, double x, double y, double w, double h, double r=10);
 
        Gtk::Label* left_aligned_label (std::string const &);
+
+       void set_no_tooltip_whatsoever (Gtk::Widget &);
 };
 
 #endif /*  __gtkmm2ext_utils_h__ */
diff --git a/libs/gtkmm2ext/persistent_tooltip.cc b/libs/gtkmm2ext/persistent_tooltip.cc
new file mode 100644 (file)
index 0000000..d50bbe7
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+    Copyright (C) 2012 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <gtkmm/window.h>
+#include <gtkmm/label.h>
+#include "gtkmm2ext/persistent_tooltip.h"
+
+#include "i18n.h"
+
+using namespace std;
+using namespace Gtk;
+using namespace Gtkmm2ext;
+
+/** @param target The widget to provide the tooltip for */
+PersistentTooltip::PersistentTooltip (Gtk::Widget* target)
+       : _target (target)
+       , _window (0)
+       , _label (0)
+       , _maybe_dragging (false)
+{
+       target->signal_enter_notify_event().connect (sigc::mem_fun (*this, &PersistentTooltip::enter), false);
+       target->signal_leave_notify_event().connect (sigc::mem_fun (*this, &PersistentTooltip::leave), false);
+       target->signal_button_press_event().connect (sigc::mem_fun (*this, &PersistentTooltip::press), false);
+       target->signal_button_release_event().connect (sigc::mem_fun (*this, &PersistentTooltip::release), false);
+}
+
+PersistentTooltip::~PersistentTooltip ()
+{
+       delete _window;
+}
+
+bool
+PersistentTooltip::enter (GdkEventCrossing *)
+{
+       _timeout = Glib::signal_timeout().connect (sigc::mem_fun (*this, &PersistentTooltip::timeout), 500);
+       return false;
+}
+
+bool
+PersistentTooltip::timeout ()
+{
+       show ();
+       return false;
+}
+
+bool
+PersistentTooltip::leave (GdkEventCrossing *)
+{
+       _timeout.disconnect ();
+       if (!dragging ()) {
+               hide ();
+       }
+
+       return false;
+}
+
+bool
+PersistentTooltip::press (GdkEventButton* ev)
+{
+       if (ev->type == GDK_BUTTON_PRESS && ev->button == 1) {
+               _maybe_dragging = true;
+       }
+
+       return false;
+}
+
+bool
+PersistentTooltip::release (GdkEventButton* ev)
+{
+       if (ev->type == GDK_BUTTON_RELEASE && ev->button == 1) {
+               _maybe_dragging = false;
+       }
+
+       return false;
+}
+
+bool
+PersistentTooltip::dragging () const
+{
+       return _maybe_dragging;
+}
+
+void
+PersistentTooltip::hide ()
+{
+       if (_window) {
+               _window->hide ();
+       }
+}
+
+void
+PersistentTooltip::show ()
+{
+       if (!_window) {
+               _window = new Window (WINDOW_POPUP);
+               _window->set_name (X_("ContrastingPopup"));
+               _window->set_position (WIN_POS_MOUSE);
+               _window->set_decorated (false);
+
+               _label = manage (new Label);
+               _label->set_use_markup (true);
+
+               _window->set_border_width (6);
+               _window->add (*_label);
+               _label->show ();
+
+               Gtk::Window* tlw = dynamic_cast<Gtk::Window*> (_target->get_toplevel ());
+               if (tlw) {
+                       _window->set_transient_for (*tlw);
+               }
+       }
+       
+       set_tip (_tip);
+
+        if (!_window->is_visible ()) {
+                /* move the window a little away from the mouse */
+                int rx, ry;
+                _target->get_window()->get_origin (rx, ry);
+                _window->move (rx, ry + _target->get_height());
+                _window->present ();
+        }
+}
+
+void
+PersistentTooltip::set_tip (string t)
+{
+       _tip = t;
+
+       if (_label) {
+               _label->set_markup (t);
+       }
+}
index 63d7655331f3ec1c9f55c3f662b40d7653a1f911..11c5b907225eaa18e93748a667b85dfe84f58002 100644 (file)
@@ -30,6 +30,7 @@
 #include <gtkmm/paned.h>
 #include <gtkmm/label.h>
 #include <gtkmm/comboboxtext.h>
+#include <gtkmm/tooltip.h>
 
 #include "i18n.h"
 
@@ -631,3 +632,21 @@ Gtkmm2ext::left_aligned_label (string const & t)
        l->set_alignment (0, 0.5);
        return l;
 }
+
+static bool
+make_null_tooltip (int, int, bool, const Glib::RefPtr<Gtk::Tooltip>& t)
+{
+       t->set_tip_area (Gdk::Rectangle (0, 0, 0, 0));
+       return true;
+}
+
+/** Hackily arrange for the provided widget to have no tooltip,
+ *  and also to stop any other widget from providing one while
+ * the mouse is over w.
+ */
+void
+Gtkmm2ext::set_no_tooltip_whatsoever (Gtk::Widget& w)
+{
+       w.property_has_tooltip() = true;
+       w.signal_query_tooltip().connect (sigc::ptr_fun (make_null_tooltip));
+}
index 1d386ce6ee051afa67e964ed1dbebac775e2c4a5..2f7d8b77b4e5dadf2754ec6c2135b55f53d5531e 100644 (file)
@@ -45,6 +45,7 @@ gtkmm2ext_sources = [
         'idle_adjustment.cc',
         'keyboard.cc',
         'motionfeedback.cc',
+        'persistent_tooltip.cc',
         'prolooks_helpers.c',
         'pixfader.cc',
         'pixscroller.cc',