MIDI/Controllables for monitor section, and related fixes
[ardour.git] / gtk2_ardour / utils.cc
index 0f53b0912f27f05232eef85a7d603c119a1617f4..aa57a3b773cb87a60f3ab79fd6a9542958477e93 100644 (file)
 #include "i18n.h"
 #include "rgb_macros.h"
 #include "canvas_impl.h"
+#include "gui_thread.h"
 
 using namespace std;
 using namespace Gtk;
-using namespace sigc;
 using namespace Glib;
 using namespace PBD;
+using Gtkmm2ext::Keyboard;
 
 sigc::signal<void>  DPIReset;
 
@@ -519,6 +520,12 @@ relay_key_press (GdkEventKey* ev, Gtk::Window* win)
        }
 }
 
+bool
+forward_key_press (GdkEventKey* ev)
+{
+        return PublicEditor::instance().on_key_press_event(ev);
+}
+
 bool
 key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
 {
@@ -879,6 +886,14 @@ possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
                fakekey = GDK_leftarrow;
                break;
 
+       case GDK_Return:
+               fakekey = GDK_3270_Enter;
+               break;
+
+       case GDK_KP_Enter:
+               fakekey = GDK_F35;
+               break;
+
        default:
                break;
        }
@@ -891,6 +906,42 @@ possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
        return false;
 }
 
+uint32_t
+possibly_translate_legal_accelerator_to_real_key (uint32_t keyval)
+{
+       switch (keyval) {
+       case GDK_nabla:
+               return GDK_Tab;
+               break;
+
+       case GDK_uparrow:
+               return GDK_Up;
+               break;
+
+       case GDK_downarrow:
+               return GDK_Down;
+               break;
+
+       case GDK_rightarrow:
+               return GDK_Right;
+               break;
+
+       case GDK_leftarrow:
+               return GDK_Left;
+               break;
+
+       case GDK_3270_Enter:
+               return GDK_Return;
+
+       case GDK_F35:
+               return GDK_KP_Enter;
+               break;
+       }
+
+       return keyval;
+}
+
+
 
 inline guint8
 convert_color_channel (guint8 src,
@@ -938,7 +989,7 @@ resize_window_to_proportion_of_monitor (Gtk::Window* window, int max_width, int
 }
 
 Glib::RefPtr<Gdk::Pixbuf>
-pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_width, int clip_height)
+pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_width, int clip_height, Gdk::Color fg)
 {
        static Glib::RefPtr<Gdk::Pixbuf>* empty_pixbuf = 0;
 
@@ -947,7 +998,6 @@ pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_
                        empty_pixbuf = new Glib::RefPtr<Gdk::Pixbuf>;
                        *empty_pixbuf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, clip_width, clip_height);
                }
-               cerr << "\n\nUSE EMPTY PIXBUF\n";
                return *empty_pixbuf;
        }
 
@@ -957,7 +1007,7 @@ pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_
        cairo_t* cr = cairo_create (surface);
        cairo_text_extents_t te;
        
-       cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+       cairo_set_source_rgba (cr, fg.get_red_p(), fg.get_green_p(), fg.get_blue_p(), 1.0);
        cairo_select_font_face (cr, font->get_family().c_str(),
                                CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
        cairo_set_font_size (cr,  font->get_size() / Pango::SCALE);
@@ -973,3 +1023,59 @@ pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_
 
        return buf;
 }
+
+/** Replace _ with __ in a string; for use with menu item text to make underscores displayed correctly */
+string
+escape_underscores (string const & s)
+{
+       string o;
+       string::size_type const N = s.length ();
+
+       for (string::size_type i = 0; i < N; ++i) {
+               if (s[i] == '_') {
+                       o += "__";
+               } else {
+                       o += s[i];
+               }
+       }
+
+       return o;
+}
+
+static void
+adjustment_to_controllable (Gtk::Adjustment* adj, boost::weak_ptr<Controllable> wcont)
+{
+        boost::shared_ptr<Controllable> cont = wcont.lock();
+
+        if (cont) {
+                double val = adj->get_value();
+                if (val != cont->get_value()) {
+                        cont->set_value (val);
+                }
+        }
+}
+
+static void
+controllable_to_adjustment (Gtk::Adjustment* adj, boost::weak_ptr<Controllable> wcont)
+{
+        boost::shared_ptr<Controllable> cont = wcont.lock();
+
+        if (cont) {
+                float val = cont->get_value();
+                
+                if (val != adj->get_value()) {
+                        adj->set_value (val);
+                }
+        }
+}
+
+void
+control_link (ScopedConnectionList& scl, boost::shared_ptr<Controllable> c, Gtk::Adjustment& a)
+{
+        boost::weak_ptr<Controllable> wc (c);
+
+        a.signal_value_changed().connect (sigc::bind (sigc::ptr_fun (adjustment_to_controllable), &a, wc));
+        c->Changed.connect (scl, MISSING_INVALIDATOR, boost::bind (controllable_to_adjustment, &a, wc),
+                            gui_context());
+}
+