enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / gtkmm2ext / barcontroller.cc
index 734c4b77e283874204884d5b6f6fda2a35acd482..d213f22d2686d06468412034d16d4a7585b978ca 100644 (file)
     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.
-
-    $Id$
 */
 
 #include <string>
+#include <sstream>
 #include <climits>
 #include <cstdio>
 #include <cmath>
 #include <algorithm>
 
 #include <pbd/controllable.h>
+#include <pbd/locale_guard.h>
 
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/barcontroller.h>
+#include "gtkmm2ext/gtk_ui.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/keyboard.h"
+#include "gtkmm2ext/barcontroller.h"
+#include "gtkmm2ext/cairo_widget.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace Gtk;
 using namespace Gtkmm2ext;
 
 BarController::BarController (Gtk::Adjustment& adj,
-                             PBD::Controllable& mc,
-                             sigc::slot<void,char*,unsigned int> lc) 
-
-       : adjustment (adj),
-         binding_proxy (mc),
-         label_callback (lc),
-         spinner (adjustment)
-
-{                        
-       _style = LeftToRight;
-       grabbed = false;
-       switching = false;
-       switch_on_release = false;
-       with_text = true;
-       use_parent = false;
-
-       layout = darea.create_pango_layout("");
-
-       set_shadow_type (SHADOW_NONE);
-
-       initial_value = adjustment.get_value ();
-
-       adjustment.signal_value_changed().connect (mem_fun (*this, &Gtk::Widget::queue_draw));
-       adjustment.signal_changed().connect (mem_fun (*this, &Gtk::Widget::queue_draw));
+               boost::shared_ptr<PBD::Controllable> mc)
+       : _slider (&adj, mc, 60, 16)
+       , _switching (false)
+       , _switch_on_release (false)
+{
 
-       darea.add_events (Gdk::BUTTON_RELEASE_MASK|
-                         Gdk::BUTTON_PRESS_MASK|
-                         Gdk::POINTER_MOTION_MASK|
-                         Gdk::ENTER_NOTIFY_MASK|
-                         Gdk::LEAVE_NOTIFY_MASK|
-                         Gdk::SCROLL_MASK);
+       add_events (Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       set (.5, .5, 1.0, 1.0);
+       set_border_width (0);
+       _slider.set_tweaks (PixFader::NoShowUnityLine);
 
-       darea.signal_expose_event().connect (mem_fun (*this, &BarController::expose));
-       darea.signal_motion_notify_event().connect (mem_fun (*this, &BarController::motion));
-       darea.signal_button_press_event().connect (mem_fun (*this, &BarController::button_press));
-       darea.signal_button_release_event().connect (mem_fun (*this, &BarController::button_release));
-       darea.signal_scroll_event().connect (mem_fun (*this, &BarController::scroll));
+       _slider.StartGesture.connect (sigc::mem_fun(*this, &BarController::passtrhu_gesture_start));
+       _slider.StopGesture.connect (sigc::mem_fun(*this, &BarController::passtrhu_gesture_stop));
+       _slider.OnExpose.connect (sigc::mem_fun(*this, &BarController::before_expose));
+       _slider.set_name (get_name());
 
+       Gtk::SpinButton& spinner = _slider.get_spin_button();
        spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
        spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
-       spinner.set_digits (3);
-
-       add (darea);
+       spinner.set_digits (9);
+       spinner.set_numeric (true);
+       spinner.set_name ("BarControlSpinner");
+       add (_slider);
        show_all ();
 }
 
-bool
-BarController::button_press (GdkEventButton* ev)
+BarController::~BarController ()
 {
-       if (binding_proxy.button_press_handler (ev)) {
-               return true;
-       }
-
-       switch (ev->button) {
-       case 1:
-               if (ev->type == GDK_2BUTTON_PRESS) {
-                       switch_on_release = true;
-                       grabbed = false;
-                       darea.remove_modal_grab();
-               } else {
-                       switch_on_release = false;
-                       darea.add_modal_grab();
-                       grabbed = true;
-                       grab_x = ev->x;
-                       grab_window = ev->window;
-                       StartGesture ();
-               }
-               return true;
-               break;
-
-       case 2:
-       case 3:
-               break;
-
-       case 4:
-       case 5:
-               break;
-       }
-
-       return false;
 }
 
 bool
-BarController::button_release (GdkEventButton* ev)
+BarController::on_button_press_event (GdkEventButton* ev)
 {
-       switch (ev->button) {
-       case 1:
-               if (switch_on_release) {
-                       Glib::signal_idle().connect (mem_fun (*this, &BarController::switch_to_spinner));
-                       return true;
-               }
-
-               if ((ev->state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == GDK_SHIFT_MASK) {
-                       adjustment.set_value (initial_value);
-               } else {
-                       double scale;
-
-                       if (ev->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) {
-                               scale = 0.01;
-                       } else if (ev->state & GDK_CONTROL_MASK) {
-                               scale = 0.1;
-                       } else {
-                               scale = 1.0;
-                       }
-
-                       mouse_control (ev->x, ev->window, scale);
-               }
-               darea.remove_modal_grab();
-               grabbed = false;
-               StopGesture ();
-               grabbed = false;
-               break;
-
-       case 2:
-               if (true) { // XXX FIX ME
-                       /* relax */
-               } else {
-                       double fract;
-                       fract = ev->x / (darea.get_width() - 2.0);
-                       adjustment.set_value (adjustment.get_lower() + 
-                                             fract * (adjustment.get_upper() - adjustment.get_lower()));
-               }
-               return true;
-
-       case 3:
+       if (get_child() != &_slider) {
                return false;
-               
-       default:
-               break;
        }
-
-       return true;
-}
-
-bool
-BarController::scroll (GdkEventScroll* ev)
-{
-       double scale;
-
-       if (ev->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) {
-               scale = 0.01;
-       } else if (ev->state & GDK_CONTROL_MASK) {
-               scale = 0.1;
-       } else {
-               scale = 1.0;
-       }
-
-       switch (ev->direction) {
-       case GDK_SCROLL_UP:
-       case GDK_SCROLL_RIGHT:
-               adjustment.set_value (adjustment.get_value() + (scale * adjustment.get_step_increment()));
-               break;
-
-       case GDK_SCROLL_DOWN:
-       case GDK_SCROLL_LEFT:
-               adjustment.set_value (adjustment.get_value() - (scale * adjustment.get_step_increment()));
-               break;
-       }
-
-       return true;
-}
-
-bool
-BarController::motion (GdkEventMotion* ev)
-{
-       double scale;
-       
-       if (!grabbed) {
-               return TRUE;
-       }
-
-       if ((ev->state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == GDK_SHIFT_MASK) {
-               return TRUE;
-       }
-
-       if (ev->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) {
-               scale = 0.01;
-       } else if (ev->state & GDK_CONTROL_MASK) {
-               scale = 0.1;
+       if (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
+               _switch_on_release = true;
+               return true;
        } else {
-               scale = 1.0;
+               _switch_on_release = false;
        }
-
-       return mouse_control (ev->x, ev->window, scale);
-}
-
-gint
-BarController::mouse_control (double x, GdkWindow* window, double scaling)
-{
-       double fract;
-       double delta;
-
-       if (window != grab_window) {
-               grab_x = x;
-               grab_window = window;
-               return TRUE;
-       }
-
-       delta = x - grab_x;
-       grab_x = x;
-
-       switch (_style) {
-       case Line:
-       case LeftToRight:
-               fract = scaling * (delta / (darea.get_width() - 2));
-               fract = min (1.0, fract);
-               fract = max (-1.0, fract);
-               adjustment.set_value (adjustment.get_value() + fract * (adjustment.get_upper() - adjustment.get_lower()));
-               break;
-
-       default:
-               fract = 0.0;
-       }
-       
-       
-       return TRUE;
+       return false;
 }
 
 bool
-BarController::expose (GdkEventExpose* event)
+BarController::on_button_release_event (GdkEventButton* ev)
 {
-       Glib::RefPtr<Gdk::Window> win (darea.get_window());
-       Widget* parent;
-       gint x1, x2, y1, y2;
-       gint w, h;
-       double fract;
-
-       w = darea.get_width() - 2;
-       h = darea.get_height() - 2;
-
-       fract = ((adjustment.get_value() - adjustment.get_lower()) /
-                (adjustment.get_upper() - adjustment.get_lower()));
-       
-       switch (_style) {
-       case Line:
-               x1 = (gint) floor (w * fract);
-               x2 = x1;
-               y1 = 0;
-               y2 = h - 1;
-
-               if (use_parent) {
-                       parent = get_parent();
-                       
-                       if (parent) {
-                               win->draw_rectangle (parent->get_style()->get_fg_gc (parent->get_state()),
-                                                   true,
-                                                   0, 0, darea.get_width(), darea.get_height());
-                       }
-               } else {
-                       win->draw_rectangle (get_style()->get_bg_gc (get_state()),
-                                           true,
-                                           0, 0, darea.get_width(), darea.get_height());
-               }
-
-               if (fract == 0.0) {
-                       win->draw_rectangle (get_style()->get_fg_gc (get_state()),
-                                           true, x1, 1, 2, darea.get_height() - 2);
-               } else {
-                       win->draw_rectangle (get_style()->get_fg_gc (get_state()),
-                                           true, x1 - 1, 1, 3, darea.get_height() - 2);
-               }
-               break;
-
-       case CenterOut:
-               break;
-
-       case LeftToRight:
-               x1 = 0;
-               x2 = (gint) floor (w * fract);
-               y1 = 0;
-               y2 = h - 1;
-
-               win->draw_rectangle (get_style()->get_bg_gc (get_state()),
-                                   false,
-                                   0, 0, darea.get_width() - 1, darea.get_height() - 1);
-
-               /* draw active box */
-
-               win->draw_rectangle (get_style()->get_fg_gc (get_state()),
-                                   true,
-                                   1 + x1,
-                                   1 + y1,
-                                   x2,
-                                   1 + y2);
-               
-               /* draw inactive box */
-
-               win->draw_rectangle (get_style()->get_fg_gc (STATE_INSENSITIVE),
-                                   true,
-                                   1 + x2,
-                                   1 + y1,
-                                   w - x2,
-                                   1 + y2);
-
-               break;
-
-       case RightToLeft:
-               break;
-       case TopToBottom:
-               break;
-       case BottomToTop:
-               break;
-       }
-
-       if (with_text) {
-               /* draw label */
-               
-               char buf[64];
-               buf[0] = '\0';
-
-               label_callback (buf, 64);
-
-               if (buf[0] != '\0') {
-
-                       layout->set_text (buf);                 
-
-                       int width, height;
-                       layout->get_pixel_size (width, height);
-
-                       int xpos;
-
-                       xpos = max (3, 1 + (x2 - (width/2)));
-                       xpos = min (darea.get_width() - width - 3, xpos);
-                       
-                       win->draw_layout (get_style()->get_text_gc (get_state()),
-                                         xpos,
-                                         (darea.get_height()/2) - (height/2),
-                                         layout);
-               }
+       if (get_child() != &_slider) {
+               return false;
        }
-
-       return true;
-}
-
-void
-BarController::set_with_text (bool yn)
-{
-       if (with_text != yn) {
-               with_text = yn;
-               queue_draw ();
+       if (ev->button == 1 && _switch_on_release) {
+               Glib::signal_idle().connect (mem_fun (*this, &BarController::switch_to_spinner));
+               return true;
        }
+       return false;
 }
 
 void
-BarController::set_style (Style s)
+BarController::on_style_changed (const Glib::RefPtr<Gtk::Style>&)
 {
-       _style = s;
-       darea.queue_draw ();
+       _slider.set_name (get_name());
 }
 
 gint
 BarController::switch_to_bar ()
 {
-       if (switching) {
-               return FALSE;
-       }
-
-       switching = true;
-
-       if (get_child() == &darea) {
+       if (_switching || get_child() == &_slider) {
                return FALSE;
        }
-
+       _switching = true;
        remove ();
-       add (darea);
-       darea.show ();
-
-       switching = false;
+       add (_slider);
+       _slider.show ();
+       _slider.queue_draw ();
+       _switching = false;
+       SpinnerActive (false); /* EMIT SIGNAL */
        return FALSE;
 }
 
 gint
 BarController::switch_to_spinner ()
 {
-       if (switching) {
+       if (_switching || get_child() != &_slider) {
                return FALSE;
        }
 
-       switching = true;
-
-       if (get_child() == &spinner) {
-               return FALSE;
+       _switching = true;
+       Gtk::SpinButton& spinner = _slider.get_spin_button();
+       if (spinner.get_parent()) {
+               spinner.get_parent()->remove(spinner);
        }
-
        remove ();
        add (spinner);
        spinner.show ();
        spinner.select_region (0, spinner.get_text_length());
        spinner.grab_focus ();
-
-       switching = false;
+       _switching = false;
+       SpinnerActive (true); /* EMIT SIGNAL */
        return FALSE;
 }
 
 void
 BarController::entry_activated ()
 {
-       string text = spinner.get_text ();
-       float val;
-
-       if (sscanf (text.c_str(), "%f", &val) == 1) {
-               adjustment.set_value (val);
-       }
-       
        switch_to_bar ();
 }
 
 bool
-BarController::entry_focus_out (GdkEventFocus* ev)
+BarController::entry_focus_out (GdkEventFocus* /*ev*/)
 {
        entry_activated ();
        return true;
 }
 
 void
-BarController::set_use_parent (bool yn)
+BarController::before_expose ()
+{
+       double xpos = -1;
+       _slider.set_text (get_label (xpos), false, false);
+}
+
+void
+BarController::set_sensitive (bool yn)
 {
-       use_parent = yn;
-       queue_draw ();
+       Alignment::set_sensitive (yn);
+       _slider.set_sensitive (yn);
 }