fix Window->Common move for show-mixer
[ardour.git] / libs / surfaces / faderport / gui.cc
index 4014d0a8e36a03b42a0aeaff9b3e5c5f4bbc9a13..5b0921e9ac051f351ac57647b4e4cd9b4b3695bb 100644 (file)
@@ -26,6 +26,7 @@
 #include "pbd/file_utils.h"
 
 #include "gtkmm2ext/actions.h"
+#include "gtkmm2ext/bindings.h"
 #include "gtkmm2ext/gtk_ui.h"
 #include "gtkmm2ext/gui_thread.h"
 #include "gtkmm2ext/utils.h"
@@ -36,7 +37,7 @@
 #include "faderport.h"
 #include "gui.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace PBD;
 using namespace ARDOUR;
@@ -80,7 +81,7 @@ FaderPort::build_gui ()
 FPGUI::FPGUI (FaderPort& p)
        : fp (p)
        , table (2, 5)
-       , action_table (4, 5)
+       , action_table (5, 4)
        , ignore_active_change (false)
 {
        set_border_width (12);
@@ -110,13 +111,15 @@ FPGUI::FPGUI (FaderPort& p)
        input_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FPGUI::active_port_changed), &input_combo, true));
        output_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FPGUI::active_port_changed), &output_combo, false));
 
-       l = manage (new Gtk::Label (_("Sends MIDI to:")));
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Incoming MIDI on:")));
        l->set_alignment (1.0, 0.5);
        table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
        table.attach (input_combo, 1, 2, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
        row++;
 
-       l = manage (new Gtk::Label (_("Receives MIDI from:")));
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Outgoing MIDI on:")));
        l->set_alignment (1.0, 0.5);
        table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
        table.attach (output_combo, 1, 2, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
@@ -124,18 +127,28 @@ FPGUI::FPGUI (FaderPort& p)
 
        build_mix_action_combo (mix_combo[0], FaderPort::ButtonState(0));
        build_mix_action_combo (mix_combo[1], FaderPort::ShiftDown);
-       build_mix_action_combo (mix_combo[2], FaderPort::LongishPress);
-       build_mix_action_combo (mix_combo[3], FaderPort::LongPress);
+       build_mix_action_combo (mix_combo[2], FaderPort::LongPress);
 
        build_proj_action_combo (proj_combo[0], FaderPort::ButtonState(0));
        build_proj_action_combo (proj_combo[1], FaderPort::ShiftDown);
-       build_proj_action_combo (proj_combo[2], FaderPort::LongishPress);
-       build_proj_action_combo (proj_combo[3], FaderPort::LongPress);
+       build_proj_action_combo (proj_combo[2], FaderPort::LongPress);
 
        build_trns_action_combo (trns_combo[0], FaderPort::ButtonState(0));
        build_trns_action_combo (trns_combo[1], FaderPort::ShiftDown);
-       build_trns_action_combo (trns_combo[2], FaderPort::LongishPress);
-       build_trns_action_combo (trns_combo[3], FaderPort::LongPress);
+       build_trns_action_combo (trns_combo[2], FaderPort::LongPress);
+
+       build_available_action_menu ();
+
+       build_foot_action_combo (foot_combo[0], FaderPort::ButtonState(0));
+       build_foot_action_combo (foot_combo[1], FaderPort::ShiftDown);
+       build_foot_action_combo (foot_combo[2], FaderPort::LongPress);
+
+       /* No shift-press combo for User because that is labelled as "next"
+        * (marker)
+        */
+
+       build_user_action_combo (user_combo[0], FaderPort::ButtonState(0));
+       build_user_action_combo (user_combo[1], FaderPort::LongPress);
 
        action_table.set_row_spacings (4);
        action_table.set_col_spacings (6);
@@ -144,25 +157,22 @@ FPGUI::FPGUI (FaderPort& p)
 
        int action_row = 0;
 
-
-       l = manage (new Gtk::Label (_("Button")));
-       l->set_alignment (1.0, 0.5);
-       action_table.attach (*l, 0, 1, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
-       l = manage (new Gtk::Label (_("Press")));
-       l->set_alignment (1.0, 0.5);
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Press Action")));
+       l->set_alignment (0.5, 0.5);
        action_table.attach (*l, 1, 2, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
-       l = manage (new Gtk::Label (_("Shift")));
-       l->set_alignment (1.0, 0.5);
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Shift-Press Action")));
+       l->set_alignment (0.5, 0.5);
        action_table.attach (*l, 2, 3, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
-       l = manage (new Gtk::Label (_("Medium")));
-       l->set_alignment (1.0, 0.5);
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Long Press Action")));
+       l->set_alignment (0.5, 0.5);
        action_table.attach (*l, 3, 4, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
-       l = manage (new Gtk::Label (_("Long")));
-       l->set_alignment (1.0, 0.5);
-       action_table.attach (*l, 4, 5, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        action_row++;
 
-       l = manage (new Gtk::Label (_("Mix")));
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Mix")));
        l->set_alignment (1.0, 0.5);
        action_table.attach (*l, 0, 1, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        align = manage (new Alignment);
@@ -177,13 +187,10 @@ FPGUI::FPGUI (FaderPort& p)
        align->set (0.0, 0.5);
        align->add (mix_combo[2]);
        action_table.attach (*align, 3, 4, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
-       align = manage (new Alignment);
-       align->set (0.0, 0.5);
-       align->add (mix_combo[3]);
-       action_table.attach (*align, 4, 5, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        action_row++;
 
-       l = manage (new Gtk::Label (_("Proj")));
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Proj")));
        l->set_alignment (1.0, 0.5);
        action_table.attach (*l, 0, 1, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        align = manage (new Alignment);
@@ -198,13 +205,10 @@ FPGUI::FPGUI (FaderPort& p)
        align->set (0.0, 0.5);
        align->add (proj_combo[2]);
        action_table.attach (*align, 3, 4, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
-       align = manage (new Alignment);
-       align->set (0.0, 0.5);
-       align->add (proj_combo[3]);
-       action_table.attach (*align, 4, 5, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        action_row++;
 
-       l = manage (new Gtk::Label (_("Trns")));
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Trns")));
        l->set_alignment (1.0, 0.5);
        action_table.attach (*l, 0, 1, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        align = manage (new Alignment);
@@ -219,10 +223,39 @@ FPGUI::FPGUI (FaderPort& p)
        align->set (0.0, 0.5);
        align->add (trns_combo[2]);
        action_table.attach (*align, 3, 4, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       action_row++;
+
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("User")));
+       l->set_alignment (1.0, 0.5);
+       action_table.attach (*l, 0, 1, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       align = manage (new Alignment);
+       align->set (0.0, 0.5);
+       align->add (user_combo[0]);
+       action_table.attach (*align, 1, 2, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       /* skip shift press combo */
+       align = manage (new Alignment);
+       align->set (0.0, 0.5);
+       align->add (user_combo[1]);
+       action_table.attach (*align, 3, 4, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       action_row++;
+
+       l = manage (new Gtk::Label);
+       l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Footswitch")));
+       l->set_alignment (1.0, 0.5);
+       action_table.attach (*l, 0, 1, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        align = manage (new Alignment);
        align->set (0.0, 0.5);
-       align->add (trns_combo[3]);
-       action_table.attach (*align, 4, 5, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       align->add (foot_combo[0]);
+       action_table.attach (*align, 1, 2, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       align = manage (new Alignment);
+       align->set (0.0, 0.5);
+       align->add (foot_combo[1]);
+       action_table.attach (*align, 2, 3, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
+       align = manage (new Alignment);
+       align->set (0.0, 0.5);
+       align->add (foot_combo[2]);
+       action_table.attach (*align, 3, 4, action_row, action_row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
        action_row++;
 
        table.attach (action_table, 0, 5, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions (0));
@@ -325,12 +358,14 @@ FPGUI::build_available_action_menu ()
        vector<string> labels;
        vector<string> tooltips;
        vector<string> keys;
-       vector<AccelKey> bindings;
+       vector<Glib::RefPtr<Gtk::Action> > actions;
+
+       ActionManager::get_all_actions (paths, labels, tooltips, keys, actions);
+
        typedef std::map<string,TreeIter> NodeMap;
        NodeMap nodes;
        NodeMap::iterator r;
 
-       ActionManager::get_all_actions (labels, paths, tooltips, keys, bindings);
 
        vector<string>::iterator k;
        vector<string>::iterator p;
@@ -339,14 +374,14 @@ FPGUI::build_available_action_menu ()
 
        available_action_model->clear ();
 
-       /* Because there are button bindings built in that are not
-       in the key binding map, there needs to be a way to undo
-       a profile edit. */
        TreeIter rowp;
        TreeModel::Row parent;
+
+       /* Disabled item (row 0) */
+
        rowp = available_action_model->append();
        parent = *(rowp);
-       parent[action_columns.name] = _("Remove Binding");
+       parent[action_columns.name] = _("Disabled");
 
        /* Key aliasing */
 
@@ -420,7 +455,13 @@ FPGUI::build_available_action_menu ()
                        action_map[*l] = *p;
                }
 
-               row[action_columns.path] = (*p);
+               string path = (*p);
+               /* ControlProtocol::access_action() is not interested in the
+                  legacy "<Actions>/" prefix part of a path.
+               */
+               path = path.substr (strlen ("<Actions>/"));
+
+               row[action_columns.path] = path;
        }
 }
 
@@ -440,7 +481,7 @@ FPGUI::build_action_combo (Gtk::ComboBox& cb, vector<pair<string,string> > const
        Glib::RefPtr<Gtk::ListStore> model (Gtk::ListStore::create (action_columns));
        TreeIter rowp;
        TreeModel::Row row;
-       string current_action = fp.get_action (id, true, bs);
+       string current_action = fp.get_action (id, false, bs); /* lookup release action */
        int active_row = -1;
        int n;
        vector<pair<string,string> >::const_iterator i;
@@ -479,7 +520,9 @@ FPGUI::build_mix_action_combo (Gtk::ComboBox& cb, FaderPort::ButtonState bs)
 {
        vector<pair<string,string> > actions;
 
-       actions.push_back (make_pair (string (_("Toggle Editor & Mixer Windows")), string (X_("Common/toggle-editor-mixer"))));
+       actions.push_back (make_pair (string (_("Show Mixer Window")), string (X_("Common/show-mixer"))));
+       actions.push_back (make_pair (string (_("Show/Hide Mixer list")), string (X_("Common/ToggleMixerList"))));
+       actions.push_back (make_pair (string("Toggle Meterbridge"), string(X_("Common/toggle-meterbridge"))));
        actions.push_back (make_pair (string (_("Show/Hide Editor mixer strip")), string (X_("Editor/show-editor-mixer"))));
 
        build_action_combo (cb, actions, FaderPort::Mix, bs);
@@ -490,12 +533,14 @@ FPGUI::build_proj_action_combo (Gtk::ComboBox& cb, FaderPort::ButtonState bs)
 {
        vector<pair<string,string> > actions;
 
-       actions.push_back (make_pair (string("Toggle Meterbridge"), string(X_("Common/toggle-meterbridge"))));
-       actions.push_back (make_pair (string("Toggle Summary"), string(X_("Editor/ToggleSummary"))));
+       actions.push_back (make_pair (string (_("Show Editor Window")), string (X_("Mixer/show-editor"))));
        actions.push_back (make_pair (string("Toggle Editor Lists"), string(X_("Editor/show-editor-list"))));
+       actions.push_back (make_pair (string("Toggle Summary"), string(X_("Editor/ToggleSummary"))));
+       actions.push_back (make_pair (string("Toggle Meterbridge"), string(X_("Common/toggle-meterbridge"))));
        actions.push_back (make_pair (string (_("Zoom to Session")), string (X_("Editor/zoom-to-session"))));
-       actions.push_back (make_pair (string (_("Zoom In")), string (X_("Editor/temporal-zoom-in"))));
-       actions.push_back (make_pair (string (_("Zoom Out")), string (X_("Editor/temporal-zoom-out"))));
+
+//     actions.push_back (make_pair (string (_("Zoom In")), string (X_("Editor/temporal-zoom-in"))));
+//     actions.push_back (make_pair (string (_("Zoom Out")), string (X_("Editor/temporal-zoom-out"))));
 
        build_action_combo (cb, actions, FaderPort::Proj, bs);
 }
@@ -505,14 +550,76 @@ FPGUI::build_trns_action_combo (Gtk::ComboBox& cb, FaderPort::ButtonState bs)
 {
        vector<pair<string,string> > actions;
 
-       actions.push_back (make_pair (string("Toggle Locations"), string(X_("Window/toggle-locations"))));
+       actions.push_back (make_pair (string("Toggle Big Clock"), string(X_("Window/toggle-big-clock"))));  //note:  this would really make sense if the Big Clock had transport buttons on it
+       actions.push_back (make_pair (string("Toggle Locations window"), string(X_("Window/toggle-locations"))));
        actions.push_back (make_pair (string("Toggle Metronome"), string(X_("Transport/ToggleClick"))));
-       actions.push_back (make_pair (string("Toggle Sync"), string(X_("Transport/ToggleExternalSync"))));
-       actions.push_back (make_pair (string("Set Playhead @pointer"), string(X_("Editor/set-playhead"))));
+       actions.push_back (make_pair (string("Toggle External Sync"), string(X_("Transport/ToggleExternalSync"))));
+       actions.push_back (make_pair (string("Toggle Follow Playhead"), string(X_("Editor/toggle-follow-playhead"))));
+
+//     actions.push_back (make_pair (string("Set Playhead @pointer"), string(X_("Editor/set-playhead"))));
+
 
        build_action_combo (cb, actions, FaderPort::Trns, bs);
 }
 
+void
+FPGUI::build_foot_action_combo (Gtk::ComboBox& cb, FaderPort::ButtonState bs)
+{
+       vector<pair<string,string> > actions;
+
+       actions.push_back (make_pair (string("Toggle Roll"), string(X_("Transport/ToggleRoll"))));
+       actions.push_back (make_pair (string("Toggle Rec-Enable"), string(X_("Transport/Record"))));
+       actions.push_back (make_pair (string("Toggle Roll+Rec"), string(X_("Transport/record-roll"))));
+       actions.push_back (make_pair (string("Toggle Loop"), string(X_("Transport/Loop"))));
+       actions.push_back (make_pair (string("Toggle Click"), string(X_("Transport/ToggleClick"))));
+       actions.push_back (make_pair (string("Record with Pre-Roll"), string(X_("Transport/RecordPreroll"))));
+       actions.push_back (make_pair (string("Record with Count-In"), string(X_("Transport/RecordCountIn"))));
+
+       build_action_combo (cb, actions, FaderPort::Footswitch, bs);
+}
+
+bool
+FPGUI::find_action_in_model (const TreeModel::iterator& iter, std::string const & action_path, TreeModel::iterator* found)
+{
+       TreeModel::Row row = *iter;
+       string path = row[action_columns.path];
+
+       if (path == action_path) {
+               *found = iter;
+               return true;
+       }
+
+       return false;
+}
+
+void
+FPGUI::build_user_action_combo (Gtk::ComboBox& cb, FaderPort::ButtonState bs)
+{
+       cb.set_model (available_action_model);
+       cb.pack_start (action_columns.name);
+       cb.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FPGUI::action_changed), &cb, FaderPort::User, bs));
+
+       /* set the active "row" to the right value for the current button binding */
+
+       string current_action = fp.get_action (FaderPort::User, false, bs); /* lookup release action */
+
+       if (current_action.empty()) {
+               cb.set_active (0); /* "disabled" */
+               return;
+       }
+
+       TreeModel::iterator iter = available_action_model->children().end();
+
+       available_action_model->foreach_iter (sigc::bind (sigc::mem_fun (*this, &FPGUI::find_action_in_model), current_action, &iter));
+
+       if (iter != available_action_model->children().end()) {
+               cb.set_active (iter);
+       } else {
+               cb.set_active (0);
+       }
+
+}
+
 Glib::RefPtr<Gtk::ListStore>
 FPGUI::build_midi_port_list (vector<string> const & ports, bool for_input)
 {