sfdb paths are saved and restored.
[ardour.git] / gtk2_ardour / ardour_ui2.cc
index 6b256c2609cb1394faf27f44ee32d5fbe4a85215..f92201e36c543e75bb5dc42238237b7d6bc0987c 100644 (file)
@@ -29,7 +29,6 @@
 #include <pbd/error.h>
 #include <pbd/basename.h>
 #include <pbd/fastlog.h>
-#include <gtkmm2ext/pix.h>
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/click_box.h>
 #include <gtkmm2ext/tearoff.h>
@@ -48,6 +47,7 @@
 
 using namespace std;
 using namespace ARDOUR;
+using namespace PBD;
 using namespace Gtkmm2ext;
 using namespace Gtk;
 using namespace Glib;
@@ -56,8 +56,6 @@ using namespace sigc;
 int    
 ARDOUR_UI::setup_windows ()
 {
-       using namespace Menu_Helpers;
-
        if (create_editor ()) {
                error << _("UI: cannot setup editor") << endmsg;
                return -1;
@@ -117,161 +115,6 @@ ARDOUR_UI::setup_adjustables ()
        adjuster_table.attach (*mmc_id_button, 2, 3, 1, 2, FILL, FILL, 5, 5);
 }
 
-#define NEW_LOOP_XPM
-#ifdef NEW_LOOP_XPM
-
-/* XPM */
-static const gchar * loop_xpm[] = {
-"17 25 94 2",
-"      c None",
-".     c #4C4C4C",
-"+     c #555555",
-"@     c #454545",
-"#     c #242424",
-"$     c #5E5E5E",
-"%     c #000000",
-"&     c #6B6B6B",
-"*     c #484848",
-"=     c #4E4E4E",
-"-     c #6A6A6A",
-";     c #717171",
-">     c #686868",
-",     c #838383",
-"'     c #888888",
-")     c #676767",
-"!     c #4A4A4A",
-"~     c #474747",
-"{     c #939393",
-"]     c #949494",
-"^     c #9E9E9E",
-"/     c #4B4B4B",
-"(     c #A1A1A1",
-"_     c #A0A0A0",
-":     c #A5A5A5",
-"<     c #B2B2B2",
-"[     c #646464",
-"}     c #ADADAD",
-"|     c #AAAAAA",
-"1     c #B1B1B1",
-"2     c #494949",
-"3     c #9A9A9A",
-"4     c #A2A2A2",
-"5     c #A7A7A7",
-"6     c #A8A8A8",
-"7     c #C1C1C1",
-"8     c #696969",
-"9     c #656565",
-"0     c #B6B6B6",
-"a     c #404040",
-"b     c #989898",
-"c     c #9D9D9D",
-"d     c #999999",
-"e     c #A3A3A3",
-"f     c #C4C4C4",
-"g     c #707070",
-"h     c #C2C2C2",
-"i     c #9C9C9C",
-"j     c #969696",
-"k     c #A4A4A4",
-"l     c #777777",
-"m     c #979797",
-"n     c #2F2F2F",
-"o     c #A9A9A9",
-"p     c #7D7D7D",
-"q     c #6D6D6D",
-"r     c #959595",
-"s     c #AFAFAF",
-"t     c #848484",
-"u     c #7F7F7F",
-"v     c #3B3B3B",
-"w     c #9B9B9B",
-"x     c #2B2B2B",
-"y     c #BFBFBF",
-"z     c #B3B3B3",
-"A     c #8A8A8A",
-"B     c #858585",
-"C     c #2E2E2E",
-"D     c #C3C3C3",
-"E     c #B8B8B8",
-"F     c #464646",
-"G     c #8E8E8E",
-"H     c #898989",
-"I     c #8D8D8D",
-"J     c #797979",
-"K     c #BCBCBC",
-"L     c #909090",
-"M     c #8C8C8C",
-"N     c #2A2A2A",
-"O     c #747474",
-"P     c #818181",
-"Q     c #808080",
-"R     c #C6C6C6",
-"S     c #C0C0C0",
-"T     c #787878",
-"U     c #868686",
-"V     c #878787",
-"W     c #8B8B8B",
-"X     c #666666",
-"Y     c #BDBDBD",
-"Z     c #929292",
-"`     c #6C6C6C",
-" .    c #505050",
-"..    c #C8C8C8",
-"      . +                         ",
-"      @ # $                       ",
-"      @ % @ &                     ",
-"      * % % = -                   ",
-"      * % ; % = >                 ",
-"      * % , ' % = )               ",
-"* ! ! ~ % { ] ^ % / . ! * ~ * +   ",
-"~ % % % % ( _ : < % % % % % % % ) ",
-"* % $ [ % } | 1 % 2 3 ^ 4 5 6 % 7 ",
-"* % 8 9 % 0 0 % a b c d c _ e % f ",
-"* % g 8 % h % a b i b j c 4 k % 7 ",
-"* % l g % % . m i j j 3 n o o % 7 ",
-"~ % p l % q d i j r b # % 0 s % 7 ",
-"~ % t u v b w j r d x % % y z % 7 ",
-"~ % A B A b j ] d C % [ % D E % 7 ",
-"F % G H I { ] b C % q J % f K % 7 ",
-"~ % L M G { b N % O P Q % R S % 7 ",
-"+ % % % % % % % T U V W % % % % D ",
-"  X 7 D 7 7 Y = % I Z b % 7 7 K 7 ",
-"              ` = % ( : % 7       ",
-"                8 = % z % 7       ",
-"                  X / % % 7       ",
-"                    X  .% ..      ",
-"                      - 9 ..      ",
-"                        q I       "};
-
-#else 
-
-static const gchar * loop_xpm[] = {
-"19 19 3 1",
-"      c None",
-".     c #000000",
-"+     c #FFFFFF",
-"       ...         ",
-"       .+..        ",
-"       .++..       ",
-"     ...+++....    ",
-"   ...++++++++...  ",
-"  ..+++.+++..+++.. ",
-" ..++...++.....++..",
-" .++.. .+..   ..++.",
-" .+..  ...     ..+.",
-" .+.            .+.",
-" .+..     ...  ..+.",
-" .++..   ..+. ..++.",
-" ..++.....++...++..",
-"  ..+++..+++.+++.. ",
-"   ...++++++++...  ",
-"     ....+++...    ",
-"        ..++.      ",
-"         ..+.      ",
-"          ...      "};
-
-#endif
-
 void
 ARDOUR_UI::transport_stopped ()
 {
@@ -422,7 +265,7 @@ ARDOUR_UI::setup_transport ()
        w = manage (new Image (Stock::MEDIA_RECORD, ICON_SIZE_BUTTON));
        w->show();
        rec_button.add (*w);
-       w = manage (new Image (Gdk::Pixbuf::create_from_xpm_data(loop_xpm)));
+       w = manage (new Image (get_xpm("loop.xpm")));
        w->show();
        auto_loop_button.add (*w);
 
@@ -464,11 +307,12 @@ ARDOUR_UI::setup_transport ()
        ARDOUR_UI::instance()->tooltips().set_tip (speed_display_box, _("Current transport speed"));
        
        shuttle_box.set_flags (CAN_FOCUS);
-       shuttle_box.add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::POINTER_MOTION_MASK);
+       shuttle_box.add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
        shuttle_box.set_size_request (100, 15);
 
        shuttle_box.signal_button_press_event().connect (mem_fun(*this, &ARDOUR_UI::shuttle_box_button_press));
        shuttle_box.signal_button_release_event().connect (mem_fun(*this, &ARDOUR_UI::shuttle_box_button_release));
+       shuttle_box.signal_scroll_event().connect (mem_fun(*this, &ARDOUR_UI::shuttle_box_scroll));
        shuttle_box.signal_motion_notify_event().connect (mem_fun(*this, &ARDOUR_UI::shuttle_box_motion));
        shuttle_box.signal_expose_event().connect (mem_fun(*this, &ARDOUR_UI::shuttle_box_expose));
 
@@ -711,12 +555,73 @@ ARDOUR_UI::audition_blink (bool onoff)
        }
 }
 
+void
+ARDOUR_UI::build_shuttle_context_menu ()
+{
+       using namespace Menu_Helpers;
+
+       shuttle_context_menu = new Menu();
+       MenuList& items = shuttle_context_menu->items();
+
+       Menu* speed_menu = manage (new Menu());
+       MenuList& speed_items = speed_menu->items();
+
+       RadioMenuItem::Group group;
+
+       speed_items.push_back (RadioMenuElem (group, "8", bind (mem_fun (*this, &ARDOUR_UI::set_shuttle_max_speed), 8.0f)));
+       if (shuttle_max_speed == 8.0) {
+               static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();        
+       }
+       speed_items.push_back (RadioMenuElem (group, "6", bind (mem_fun (*this, &ARDOUR_UI::set_shuttle_max_speed), 6.0f)));
+       if (shuttle_max_speed == 6.0) {
+               static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();        
+       }
+       speed_items.push_back (RadioMenuElem (group, "4", bind (mem_fun (*this, &ARDOUR_UI::set_shuttle_max_speed), 4.0f)));
+       if (shuttle_max_speed == 4.0) {
+               static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();        
+       }
+       speed_items.push_back (RadioMenuElem (group, "3", bind (mem_fun (*this, &ARDOUR_UI::set_shuttle_max_speed), 3.0f)));
+       if (shuttle_max_speed == 3.0) {
+               static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();        
+       }
+       speed_items.push_back (RadioMenuElem (group, "2", bind (mem_fun (*this, &ARDOUR_UI::set_shuttle_max_speed), 2.0f)));
+       if (shuttle_max_speed == 2.0) {
+               static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();        
+       }
+       speed_items.push_back (RadioMenuElem (group, "1.5", bind (mem_fun (*this, &ARDOUR_UI::set_shuttle_max_speed), 1.5f)));
+       if (shuttle_max_speed == 1.5) {
+               static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();        
+       }
+
+       items.push_back (MenuElem (_("Maximum speed"), *speed_menu));
+}
+
+void
+ARDOUR_UI::show_shuttle_context_menu ()
+{
+       if (shuttle_context_menu == 0) {
+               build_shuttle_context_menu ();
+       }
+
+       shuttle_context_menu->popup (1, 0);
+}
+
+void
+ARDOUR_UI::set_shuttle_max_speed (float speed)
+{
+       shuttle_max_speed = speed;
+}
 
 gint
 ARDOUR_UI::shuttle_box_button_press (GdkEventButton* ev)
 {
        if (!session) {
-               return TRUE;
+               return true;
+       }
+
+       if (Keyboard::is_context_menu_event (ev)) {
+               show_shuttle_context_menu ();
+               return true;
        }
 
        switch (ev->button) {
@@ -728,44 +633,53 @@ ARDOUR_UI::shuttle_box_button_press (GdkEventButton* ev)
 
        case 2:
        case 3:
-               return TRUE;
+               return true;
                break;
        }
 
-       return TRUE;
+       return true;
 }
 
 gint
 ARDOUR_UI::shuttle_box_button_release (GdkEventButton* ev)
 {
        if (!session) {
-               return TRUE;
+               return true;
        }
-
+       
        switch (ev->button) {
        case 1:
                mouse_shuttle (ev->x, true);
                shuttle_grabbed = false;
                shuttle_box.remove_modal_grab ();
                if (shuttle_behaviour == Sprung) {
-                       shuttle_fract = SHUTTLE_FRACT_SPEED1;
-                       session->request_transport_speed (1.0);
+                       if (session->get_auto_play() || roll_button.get_state()) {
+                               shuttle_fract = SHUTTLE_FRACT_SPEED1;                           
+                               session->request_transport_speed (1.0);
+                               stop_button.set_active (false);
+                               roll_button.set_active (true);
+                       } else {
+                               shuttle_fract = 0;
+                               session->request_transport_speed (0.0);
+                       }
                        shuttle_box.queue_draw ();
                }
-               return TRUE;
+               return true;
 
        case 2:
                if (session->transport_rolling()) {
                        shuttle_fract = SHUTTLE_FRACT_SPEED1;
                        session->request_transport_speed (1.0);
+                       stop_button.set_active (false);
+                       roll_button.set_active (true);
                } else {
                        shuttle_fract = 0;
                }
                shuttle_box.queue_draw ();
-               return TRUE;
+               return true;
 
        case 3:
-               return TRUE;
+               return true;
                
        case 4:
                shuttle_fract += 0.005;
@@ -777,14 +691,39 @@ ARDOUR_UI::shuttle_box_button_release (GdkEventButton* ev)
 
        use_shuttle_fract (true);
 
-       return TRUE;
+       return true;
+}
+
+gint
+ARDOUR_UI::shuttle_box_scroll (GdkEventScroll* ev)
+{
+       if (!session) {
+               return true;
+       }
+       
+       switch (ev->direction) {
+               
+       case GDK_SCROLL_UP:
+               shuttle_fract += 0.005;
+               break;
+       case GDK_SCROLL_DOWN:
+               shuttle_fract -= 0.005;
+               break;
+       default:
+               /* scroll left/right */
+               return false;
+       }
+
+       use_shuttle_fract (true);
+
+       return true;
 }
 
 gint
 ARDOUR_UI::shuttle_box_motion (GdkEventMotion* ev)
 {
        if (!session || !shuttle_grabbed) {
-               return TRUE;
+               return true;
        }
 
        return mouse_shuttle (ev->x, false);
@@ -804,7 +743,7 @@ ARDOUR_UI::mouse_shuttle (double x, bool force)
 
        shuttle_fract = distance / half_width;
        use_shuttle_fract (force);
-       return TRUE;
+       return true;
 }
 
 void
@@ -834,7 +773,7 @@ ARDOUR_UI::use_shuttle_fract (bool force)
                fract = -fract;
        }
 
-       session->request_transport_speed (8.0 * fract); // Formula A2
+       session->request_transport_speed (shuttle_max_speed * fract); // Formula A2
        shuttle_box.queue_draw ();
 }
 
@@ -861,7 +800,7 @@ ARDOUR_UI::shuttle_box_expose (GdkEventExpose* event)
                        0,
                        x,
                        shuttle_box.get_height());
-       return TRUE;
+       return true;
 }
 
 void
@@ -878,10 +817,10 @@ ARDOUR_UI::set_shuttle_units (ShuttleUnits u)
 {
        switch ((shuttle_units = u)) {
        case Percentage:
-               static_cast<Label*>(shuttle_units_button.get_child())->set_text ("% ");
+               shuttle_units_button.set_label("% ");
                break;
        case Semitones:
-               static_cast<Label*>(shuttle_units_button.get_child())->set_text (_("st"));
+               shuttle_units_button.set_label(_("st"));
                break;
        }
 }