strip X specific from keyboard.cc; fix up many buttons to avoid prelight (mostly...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Feb 2007 03:36:00 +0000 (03:36 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Feb 2007 03:36:00 +0000 (03:36 +0000)
git-svn-id: svn://localhost/ardour2/trunk@1437 d708f5d6-7413-0410-9779-e7cbd77b26cf

36 files changed:
gtk2_ardour/ardour2_ui.rc
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui2.cc
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_keys.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_route_list.cc
gtk2_ardour/editor_selection_list.cc
gtk2_ardour/keyboard.cc
gtk2_ardour/keyboard.h
gtk2_ardour/keyboard_target.cc [deleted file]
gtk2_ardour/keyboard_target.h [deleted file]
gtk2_ardour/location_ui.h
gtk2_ardour/main.cc
gtk2_ardour/meter_bridge.h
gtk2_ardour/mixer_strip.cc
gtk2_ardour/mixer_strip.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mixer_ui.h
gtk2_ardour/option_editor.cc
gtk2_ardour/public_editor.h
gtk2_ardour/route_params_ui.h
gtk2_ardour/route_time_axis.cc
gtk2_ardour/route_ui.cc
gtk2_ardour/route_ui.h
libs/ardour/ardour/route.h
libs/ardour/globals.cc
libs/ardour/route.cc
libs/gtkmm2ext/bindable_button.cc
libs/gtkmm2ext/gtkmm2ext/bindable_button.h
libs/gtkmm2ext/gtkmm2ext/stateful_button.h
libs/gtkmm2ext/stateful_button.cc

index 488623ce93cee52359a795e52e6d9d4f99ab0cb0..62a615f190ed547c6cd6618fcb6c42ffa5c2f0d4 100644 (file)
@@ -143,7 +143,7 @@ style "transport_base" = "medium_bold_text"
 
 style "black_mackie_menu_bar"
 {
-  font_name = "sans bold 7"
+  font_name = "sans bold 9"
   fg[NORMAL] = { 1.0, 1.0, 1.0 }
   bg[NORMAL] = { 0, 0, 0 }
 }
@@ -291,7 +291,8 @@ style "time_button" = "default_buttons_menus"
 style "transport_button"
 {
        bg[ACTIVE] = { 0.50, 1.0, 0.50 }
-       fg[ACTIVE] = { 0, 0, 0 }
+       fg[ACTIVE] = { 1, 1, 1 }
+       fg[PRELIGHT] = { 1, 1, 1 }
 }
 
 style "transport_rec_button"
@@ -1078,7 +1079,7 @@ widget "*MixerRecordEnableButton" style "mixer_rec_enable_button"
 widget "*MixerRecordEnableButton*" style "mixer_rec_enable_button"
 widget "*TrackRecordEnableButton" style "track_rec_enable_button"
 widget "*TrackRecordEnableButton*" style "track_rec_enable_button"
-widget "*TrackMuteButton*" style "mute_button"
+widget "*MuteButton*" style "mute_button"
 widget "*TrackLoopButton*" style "track_loop_button"
 widget "*PanAutomationLineSelector*" style "multiline_combo"
 widget "*EditorTimeButton*" style "time_button"
@@ -1095,10 +1096,6 @@ widget "*MixerAutomationModeButton*" style "very_small_button"
 widget "*MixerAutomationModeButton.*" style "very_small_button"
 widget "*MixerAutomationPlaybackButton*" style "very_small_button"
 widget "*MixerAutomationPlaybackButton.*" style "very_small_button"
-widget "*MixerMuteButton*" style "mixer_mute_button"
-widget "*MixerMuteButton.*" style "mixer_mute_button"
-widget "*MixerSoloButton*" style "mixer_solo_button"
-widget "*MixerSoloButton.*" style "mixer_solo_button"
 widget "*MixerNameButton" style "very_small_button"
 widget "*MixerNameButtonLabel" style "very_small_button"
 widget "*MixerGroupButton" style "very_small_button"
index 7e0e06e97ffffc72e6a517404e82fd08a8232c75..5befc7c0922c8ea824f5002806a3a5daa900ce47 100644 (file)
@@ -69,7 +69,6 @@
 #include "mixer_ui.h"
 #include "prompter.h"
 #include "opts.h"
-#include "keyboard_target.h"
 #include "add_route_dialog.h"
 #include "new_session_dialog.h"
 #include "about.h"
@@ -117,16 +116,32 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
          /* transport */
 
-         time_master_button (_("time\nmaster")),
+         roll_controllable ("transport roll", *this, TransportControllable::Roll),
+         stop_controllable ("transport stop", *this, TransportControllable::Stop),
+         goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
+         goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
+         auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
+         play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
+         rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
+
+         roll_button (roll_controllable),
+         stop_button (stop_controllable),
+         goto_start_button (goto_start_controllable),
+         goto_end_button (goto_end_controllable),
+         auto_loop_button (auto_loop_controllable),
+         play_selection_button (play_selection_controllable),
+         rec_button (rec_controllable),
 
          shuttle_units_button (_("% ")),
 
          punch_in_button (_("Punch In")),
          punch_out_button (_("Punch Out")),
          auto_return_button (_("Auto Return")),
-         auto_play_button (_("Autuo Play")),
+         auto_play_button (_("Auto Play")),
          auto_input_button (_("Auto Input")),
          click_button (_("Click")),
+         time_master_button (_("time\nmaster")),
+
          auditioning_alert_button (_("AUDITION")),
          solo_alert_button (_("SOLO")),
          shown_flag (false)
@@ -1061,6 +1076,8 @@ ARDOUR_UI::remove_last_capture()
 void
 ARDOUR_UI::transport_record ()
 {
+       cerr << "transport record\n";
+
        if (session) {
                switch (session->record_status()) {
                case Session::Disabled:
@@ -1091,11 +1108,11 @@ ARDOUR_UI::transport_roll ()
 
        if (session->get_play_loop()) {
                session->request_play_loop (false);
-               auto_loop_button.set_active (false);
-               roll_button.set_active (true);
+               auto_loop_button.set_visual_state (1);
+               roll_button.set_visual_state (1);
        } else if (session->get_play_range ()) {
                session->request_play_range (false);
-               play_selection_button.set_active (false);
+               play_selection_button.set_visual_state (0);
        } else if (rolling) {
                session->request_locate (session->last_transport_start(), true);
        }
@@ -1412,7 +1429,7 @@ ARDOUR_UI::_blink (void *arg)
 void
 ARDOUR_UI::blink ()
 {
-        Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
+       Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
 }
 
 void
@@ -1605,18 +1622,18 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff)
        switch (session->record_status()) {
        case Session::Enabled:
                if (onoff) {
-                       rec_button.set_state (1);
+                       rec_button.set_visual_state (1);
                } else {
-                       rec_button.set_state (0);
+                       rec_button.set_visual_state (0);
                }
                break;
 
        case Session::Recording:
-               rec_button.set_state (2);
+               rec_button.set_visual_state (2);
                break;
 
        default:
-               rec_button.set_state (0);
+               rec_button.set_visual_state (0);
                break;
        }
 }
@@ -1629,12 +1646,6 @@ ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
        return TRUE;
 }
 
-void
-ARDOUR_UI::start_keyboard_prefix ()
-{
-       keyboard->start_prefix();
-}
-
 void
 ARDOUR_UI::save_template ()
 
@@ -2519,3 +2530,82 @@ ARDOUR_UI::store_clock_modes ()
 
 
                
+ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
+       : Controllable (name), ui (u), type(tp)
+{
+       
+}
+
+void
+ARDOUR_UI::TransportControllable::set_value (float val)
+{
+       if (val < 0.5f) {
+               /* do nothing: these are radio-style actions */
+               return;
+       }
+
+       char *action = 0;
+
+       switch (type) {
+       case Roll:
+               action = X_("Roll");
+               break;
+       case Stop:
+               action = X_("Stop");
+               break;
+       case GotoStart:
+               action = X_("Goto Start");
+               break;
+       case GotoEnd:
+               action = X_("Goto End");
+               break;
+       case AutoLoop:
+               action = X_("Loop");
+               break;
+       case PlaySelection:
+               action = X_("Play Selection");
+               break;
+       case RecordEnable:
+               action = X_("Record");
+               break;
+       default:
+               break;
+       }
+
+       if (action == 0) {
+               return;
+       }
+
+       Glib::RefPtr<Action> act = ActionManager::get_action ("transport", action);
+
+       if (act) {
+               act->activate ();
+       }
+}
+
+float
+ARDOUR_UI::TransportControllable::get_value (void) const
+{
+       float val = 0.0f;
+       
+       switch (type) {
+       case Roll:
+               break;
+       case Stop:
+               break;
+       case GotoStart:
+               break;
+       case GotoEnd:
+               break;
+       case AutoLoop:
+               break;
+       case PlaySelection:
+               break;
+       case RecordEnable:
+               break;
+       default:
+               break;
+       }
+
+       return val;
+}
index e1b7c5555595fd18b1cb7b4ae9c483ba333d1c9f..9d51232f6c2ff1f9ea850d1fe3c9bff9ac531bac 100644 (file)
@@ -55,6 +55,7 @@
 #include <gtkmm2ext/gtk_ui.h>
 #include <gtkmm2ext/click_box.h>
 #include <gtkmm2ext/stateful_button.h>
+#include <gtkmm2ext/bindable_button.h>
 #include <ardour/ardour.h>
 #include <ardour/session.h>
 
@@ -355,18 +356,43 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        Gtk::HBox                primary_clock_hbox;
        Gtk::HBox                secondary_clock_hbox;
 
-       Gtkmm2ext::StatefulButton roll_button;
-       Gtkmm2ext::StatefulButton stop_button;
-       Gtkmm2ext::StatefulButton rewind_button;
-       Gtkmm2ext::StatefulButton forward_button;
-       Gtkmm2ext::StatefulButton goto_start_button;
-       Gtkmm2ext::StatefulButton goto_end_button;
-       Gtkmm2ext::StatefulButton auto_loop_button;
-       Gtkmm2ext::StatefulButton play_selection_button;
 
-       Gtkmm2ext::StatefulButton rec_button;
+       struct TransportControllable : public PBD::Controllable {
+           enum ToggleType {
+                   Roll = 0,
+                   Stop,
+                   RecordEnable,
+                   GotoStart,
+                   GotoEnd,
+                   AutoLoop,
+                   PlaySelection
+                   
+           };
+           
+           TransportControllable (std::string name, ARDOUR_UI&, ToggleType);
+           void set_value (float);
+           float get_value (void) const;
+
+           ARDOUR_UI& ui;
+           ToggleType type;
+       };
+
+       TransportControllable roll_controllable;
+       TransportControllable stop_controllable;
+       TransportControllable goto_start_controllable;
+       TransportControllable goto_end_controllable;
+       TransportControllable auto_loop_controllable;
+       TransportControllable play_selection_controllable;
+       TransportControllable rec_controllable;
+       
+       BindableButton roll_button;
+       BindableButton stop_button;
+       BindableButton goto_start_button;
+       BindableButton goto_end_button;
+       BindableButton auto_loop_button;
+       BindableButton play_selection_button;
+       BindableButton rec_button;
 
-       Gtk::ToggleButton time_master_button;
        Gtk::ComboBoxText sync_option_combo;
 
        void sync_option_changed ();
@@ -402,12 +428,14 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        bool   shuttle_grabbed;
        double shuttle_fract;
 
-       Gtk::ToggleButton punch_in_button;
-       Gtk::ToggleButton punch_out_button;
-       Gtk::ToggleButton auto_return_button;
-       Gtk::ToggleButton auto_play_button;
-       Gtk::ToggleButton auto_input_button;
-       Gtk::ToggleButton click_button;
+       Gtkmm2ext::StatefulToggleButton punch_in_button;
+       Gtkmm2ext::StatefulToggleButton punch_out_button;
+       Gtkmm2ext::StatefulToggleButton auto_return_button;
+       Gtkmm2ext::StatefulToggleButton auto_play_button;
+       Gtkmm2ext::StatefulToggleButton auto_input_button;
+       Gtkmm2ext::StatefulToggleButton click_button;
+       Gtkmm2ext::StatefulToggleButton time_master_button;
+
        Gtk::ToggleButton auditioning_alert_button;
        Gtk::ToggleButton solo_alert_button;
 
@@ -585,7 +613,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        /* Keymap handling */
 
        void install_actions ();
-       void start_keyboard_prefix();
 
        void toggle_record_enable (uint32_t);
 
index a39bcb124d4ddbd8b60aa261b9c3e30b3386bc7b..6fcfb32b6d1303fe5e6714752a7be918110a5e13 100644 (file)
@@ -38,6 +38,7 @@
 #include <ardour/route.h>
 
 #include "ardour_ui.h"
+#include "keyboard.h"
 #include "public_editor.h"
 #include "audio_clock.h"
 #include "actions.h"
@@ -118,11 +119,11 @@ ARDOUR_UI::setup_adjustables ()
 void
 ARDOUR_UI::transport_stopped ()
 {
-       stop_button.set_active (true);
+       stop_button.set_visual_state (1);
        
-       roll_button.set_active (false);
-       play_selection_button.set_active (false);
-       auto_loop_button.set_active (false);
+       roll_button.set_visual_state (0);
+       play_selection_button.set_visual_state (0);
+       auto_loop_button.set_visual_state (0);
 
        shuttle_fract = 0;
        shuttle_box.queue_draw ();
@@ -133,22 +134,22 @@ ARDOUR_UI::transport_stopped ()
 void
 ARDOUR_UI::transport_rolling ()
 {
-       stop_button.set_active (false);
+       stop_button.set_visual_state (0);
        if (session->get_play_range()) {
-               play_selection_button.set_active (true);
-               roll_button.set_active (false);
-               auto_loop_button.set_active (false);
+               play_selection_button.set_visual_state (1);
+               roll_button.set_visual_state (0);
+               auto_loop_button.set_visual_state (0);
 
        } else if (session->get_play_loop ()) {
-               auto_loop_button.set_active (true);
-               play_selection_button.set_active (false);
-               roll_button.set_active (false);
+               auto_loop_button.set_visual_state (1);
+               play_selection_button.set_visual_state (0);
+               roll_button.set_visual_state (0);
 
        } else {
 
-               roll_button.set_active (true);
-               play_selection_button.set_active (false);
-               auto_loop_button.set_active (false);
+               roll_button.set_visual_state (1);
+               play_selection_button.set_visual_state (0);
+               auto_loop_button.set_visual_state (0);
        }
 
        /* reset shuttle controller */
@@ -160,21 +161,35 @@ ARDOUR_UI::transport_rolling ()
 void
 ARDOUR_UI::transport_rewinding ()
 {
-       stop_button.set_active(false);
-       roll_button.set_active (true);
-       play_selection_button.set_active (false);
-       auto_loop_button.set_active (false);
+       stop_button.set_visual_state (0);
+       roll_button.set_visual_state (1);
+       play_selection_button.set_visual_state (0);
+       auto_loop_button.set_visual_state (0);
 }
 
 void
 ARDOUR_UI::transport_forwarding ()
 {
-       stop_button.set_active (false);
-       roll_button.set_active (true);
-       play_selection_button.set_active (false);
-       auto_loop_button.set_active (false);
+       stop_button.set_visual_state (0);
+       roll_button.set_visual_state (1);
+       play_selection_button.set_visual_state (0);
+       auto_loop_button.set_visual_state (0);
 }
 
+bool
+messagefoo (GdkEventButton* ev)
+{
+       cerr << " roll  button pressed\n";
+       return false;
+}
+
+bool
+messagefoo2 (GdkEventButton* ev)
+{
+       cerr << " roll  button release\n";
+       return false;
+}
 void
 ARDOUR_UI::setup_transport ()
 {
@@ -207,16 +222,29 @@ ARDOUR_UI::setup_transport ()
        play_selection_button.set_name ("TransportButton");
        rec_button.set_name ("TransportRecButton");
        auto_loop_button.set_name ("TransportButton");
+
+       vector<Gdk::Color> colors;
+       Gdk::Color c;
+
+       set_color(c, rgba_from_style ("TransportButton", 0xff, 0, 0, 0, "bg", Gtk::STATE_ACTIVE, false ));
+       colors.push_back (c);
+
        auto_return_button.set_name ("TransportButton");
+       auto_return_button.set_colors (colors); 
        auto_play_button.set_name ("TransportButton");
+       auto_play_button.set_colors (colors);   
        auto_input_button.set_name ("TransportButton");
+       auto_input_button.set_colors (colors);  
        punch_in_button.set_name ("TransportButton");
+       punch_in_button.set_colors (colors);    
        punch_out_button.set_name ("TransportButton");
+       punch_out_button.set_colors (colors);   
        click_button.set_name ("TransportButton");
+       click_button.set_colors (colors);       
        time_master_button.set_name ("TransportButton");
+       time_master_button.set_colors (colors); 
 
-       vector<Gdk::Color> colors;
-       Gdk::Color c;
+       colors.clear ();
 
        /* record button has 3 color states, so we set 2 extra here */
        set_color(c, rgba_from_style ("TransportRecButton", 0xff, 0, 0, 0, "bg", Gtk::STATE_PRELIGHT, false ));
@@ -249,7 +277,7 @@ ARDOUR_UI::setup_transport ()
        
        Widget* w;
 
-       stop_button.set_active (true);
+       stop_button.set_visual_state (1);
        
        w = manage (new Image (get_icon (X_("transport_start"))));
        w->show();
@@ -275,6 +303,9 @@ ARDOUR_UI::setup_transport ()
 
        RefPtr<Action> act;
 
+       roll_button.signal_button_press_event().connect (sigc::ptr_fun (messagefoo));
+       roll_button.signal_button_release_event().connect (sigc::ptr_fun (messagefoo2));
+
        act = ActionManager::get_action (X_("Transport"), X_("Stop"));
        act->connect_proxy (stop_button);
        act = ActionManager::get_action (X_("Transport"), X_("Roll"));
@@ -298,6 +329,7 @@ ARDOUR_UI::setup_transport ()
        ARDOUR_UI::instance()->tooltips().set_tip (goto_start_button, _("Go to start of session"));
        ARDOUR_UI::instance()->tooltips().set_tip (goto_end_button, _("Go to end of session"));
        ARDOUR_UI::instance()->tooltips().set_tip (auto_loop_button, _("Play loop range"));
+
        ARDOUR_UI::instance()->tooltips().set_tip (auto_return_button, _("Return to last playback start when stopped"));
        ARDOUR_UI::instance()->tooltips().set_tip (auto_play_button, _("Start playback after any locate"));
        ARDOUR_UI::instance()->tooltips().set_tip (auto_input_button, _("Be sensible about input monitoring"));
@@ -338,12 +370,7 @@ ARDOUR_UI::setup_transport ()
        ActionManager::get_action ("Transport", "TogglePunchIn")->connect_proxy (punch_in_button);
        ActionManager::get_action ("Transport", "TogglePunchOut")->connect_proxy (punch_out_button);
 
-       preroll_button.unset_flags (CAN_FOCUS);
-       preroll_button.set_events (preroll_button.get_events() & ~(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK));
        preroll_button.set_name ("TransportButton");
-
-       postroll_button.unset_flags (CAN_FOCUS);
-       postroll_button.set_events (postroll_button.get_events() & ~(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK));
        postroll_button.set_name ("TransportButton");
 
        preroll_clock.set_mode (AudioClock::MinSec);
@@ -659,8 +686,8 @@ ARDOUR_UI::shuttle_box_button_release (GdkEventButton* ev)
                        if (Config->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);
+                               stop_button.set_visual_state (0);
+                               roll_button.set_visual_state (1);
                        } else {
                                shuttle_fract = 0;
                                session->request_transport_speed (0.0);
@@ -673,8 +700,8 @@ ARDOUR_UI::shuttle_box_button_release (GdkEventButton* ev)
                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);
+                       stop_button.set_visual_state (0);
+                       roll_button.set_visual_state (1);
                } else {
                        shuttle_fract = 0;
                }
index 6e5aa01ac62fd8ef27a1da5b40a21aa0953acd4c..a4cd3c2d9900c3b9b9881564041396cf060843c9 100644 (file)
@@ -181,7 +181,6 @@ ARDOUR_UI::install_actions ()
        
        common_actions = ActionGroup::create (X_("Common"));
        ActionManager::register_action (main_actions, X_("Windows"), _("Windows"));
-       ActionManager::register_action (common_actions, X_("Start-Prefix"), _("start prefix"), mem_fun(*this, &ARDOUR_UI::start_keyboard_prefix));
        ActionManager::register_action (common_actions, X_("Quit"), _("Quit"), (mem_fun(*this, &ARDOUR_UI::finish)));
 
         /* windows visibility actions */
index 803611b77ee68f9440ce0141922e192889cd78e7..2d44538cb7d16b8e38425a96497af704ca57ce1f 100644 (file)
@@ -147,11 +147,11 @@ class Editor : public PublicEditor
        void step_mouse_mode (bool next);
        Editing::MouseMode current_mouse_mode () { return mouse_mode; }
 
-       void add_imageframe_time_axis(const string & track_name, void*) ;
-       void add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void*) ;
+       void add_imageframe_time_axis(const std::string & track_name, void*) ;
+       void add_imageframe_marker_time_axis(const std::string & track_name, TimeAxisView* marked_track, void*) ;
        void connect_to_image_compositor() ;
        void scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item) ;
-       TimeAxisView* get_named_time_axis(const string & name) ;
+       TimeAxisView* get_named_time_axis(const std::string & name) ;
 
        void consider_auditioning (boost::shared_ptr<ARDOUR::Region>);
        void hide_a_region (boost::shared_ptr<ARDOUR::Region>);
index b2c7554a2a012f9ba40468b17b4cb6c7ab905bbb..fa83ac94e5f0ae90ab766559b535898492ad0648 100644 (file)
@@ -25,6 +25,7 @@
 #include <ardour/audioplaylist.h>
 
 #include "editor.h"
+#include "keyboard.h"
 #include "public_editor.h"
 #include "audio_region_view.h"
 #include "audio_streamview.h"
index 1bcaafd27957f1a045f801b012698b9498592630..762a480f1f798c8292b7bf68fb1e08f7a3f57f37 100644 (file)
@@ -122,6 +122,7 @@ Editor::keyboard_insert_region_list_selection ()
 int
 Editor::get_prefix (float& val, bool& was_floating)
 {
-       return Keyboard::the_keyboard().get_prefix (val, was_floating);
+       was_floating = false;
+       return 1;
 }
 
index d502ee0c401fa4152de4effb81980f2c5db026c5..558d4b29daace7b20f0d49a48a08e0fd72514f36 100644 (file)
@@ -313,9 +313,11 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
 
                if ((event->button.state & Keyboard::RelevantModifierKeyMask) && event->button.button != 1) {
                        
-                       /* no selection action on modified button-2 or button-3 events */
-                       
-                       return;
+                       /* almost no selection action on modified button-2 or button-3 events */
+               
+                       if (item_type != RegionItem && event->button.button != 2) {
+                               return;
+                       }
                }
        }
            
index d8c521da2087c9427c2255f42003684bd23ff136..10915df26f24cef7ea057568b2a8ea669f67dba1 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "editor.h"
 #include "editing.h"
+#include "keyboard.h"
 #include "ardour_ui.h"
 #include "gui_thread.h"
 #include "actions.h"
index b1393ef5e18be3317cb56b72b86ccf53e3787173..b0311d24a8efbcd77a82965f6e3b44987fbf57ef 100644 (file)
@@ -23,6 +23,7 @@
 #include <cmath>
 
 #include "editor.h"
+#include "keyboard.h"
 #include "ardour_ui.h"
 #include "audio_time_axis.h"
 #include "mixer_strip.h"
index 864e527b595d408fe6a25028b390b43caf4948c5..49308b21403de6a02297c2cfe3405d18fcb4114e 100644 (file)
@@ -31,6 +31,7 @@
 #include <gtkmm2ext/stop_signal.h>
 
 #include "editor.h"
+#include "keyboard.h"
 #include "selection.h"
 #include "time_axis_view.h"
 #include "ardour_ui.h"
index a6a14ad55b23c80494781eacbfea6841333ee275..517ef973d4cef5bc4930bb5b6d72b27b18ad3f2a 100644 (file)
@@ -25,8 +25,6 @@
 
 #include <ctype.h>
 
-#include <X11/keysymdef.h>
-#include <gdk/gdkx.h>
 #include <gdk/gdkkeysyms.h>
 #include <pbd/error.h>
 
@@ -49,14 +47,13 @@ guint Keyboard::snap_mod = GDK_MOD3_MASK;
 uint32_t Keyboard::Control = GDK_CONTROL_MASK;
 uint32_t Keyboard::Shift = GDK_SHIFT_MASK;
 uint32_t Keyboard::Alt = GDK_MOD1_MASK;
-uint32_t Keyboard::Meta = GDK_MOD2_MASK;
+uint32_t Keyboard::Meta;
 
 Keyboard* Keyboard::_the_keyboard = 0;
 
 /* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
 
-GdkModifierType Keyboard::RelevantModifierKeyMask = 
-                               GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_MOD3_MASK);
+GdkModifierType Keyboard::RelevantModifierKeyMask;
 
 
 Keyboard::Keyboard ()
@@ -65,9 +62,25 @@ Keyboard::Keyboard ()
                _the_keyboard = this;
        }
 
-       collecting_prefix = false;
+       RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask ();
 
-       get_modifier_masks ();
+       /* figure out Meta */
+
+       uint32_t possible_meta[] = { GDK_MOD2_MASK, GDK_MOD3_MASK, GDK_MOD4_MASK, GDK_MOD5_MASK, 0};
+       int i;
+
+       for (i = 0; possible_meta[i]; ++i) {
+               if (!(RelevantModifierKeyMask & possible_meta[i])) {
+                       break;
+               }
+       }
+       Meta = possible_meta[i];
+
+       if (Meta) {
+               cerr << "Using " << possible_meta[i] << " for Meta\n";
+       } else {
+               cerr << "NO Meta\n";
+       }
 
        snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this);
 
@@ -78,7 +91,6 @@ Keyboard::Keyboard ()
 Keyboard::~Keyboard ()
 {
        gtk_key_snooper_remove (snooper_id);
-       delete [] modifier_masks;
 }
 
 XMLNode& 
@@ -158,60 +170,6 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
        }
                
        if (event->type == GDK_KEY_PRESS) {
-               bool was_prefix = false;
-
-               if (collecting_prefix) {
-                       switch (keyval) {
-                       case GDK_0:
-                               current_prefix += '0';
-                               was_prefix = true;
-                               break;
-                       case GDK_1:
-                               current_prefix += '1';
-                               was_prefix = true;
-                               break;
-                       case GDK_2:
-                               current_prefix += '2';
-                               was_prefix = true;
-                               break;
-                       case GDK_3:
-                               current_prefix += '3';
-                               was_prefix = true;
-                               break;
-                       case GDK_4:
-                               current_prefix += '4';
-                               was_prefix = true;
-                               break;
-                       case GDK_5:
-                               current_prefix += '5';
-                               was_prefix = true;
-                               break;
-                       case GDK_6:
-                               current_prefix += '6';
-                               was_prefix = true;
-                               break;
-                       case GDK_7:
-                               current_prefix += '7';
-                               was_prefix = true;
-                               break;
-                       case GDK_8:
-                               current_prefix += '8';
-                               was_prefix = true;
-                               break;
-                       case GDK_9:
-                               current_prefix += '9';
-                               was_prefix = true;
-                               break;
-                       case GDK_period:
-                               current_prefix += '.';
-                               was_prefix = true;
-                               break;
-                       default:
-                               was_prefix = false;
-                               collecting_prefix = false;
-                               break;
-                       }
-               }
 
                if (find (state.begin(), state.end(), keyval) == state.end()) {
                        state.push_back (keyval);
@@ -238,441 +196,10 @@ Keyboard::key_is_down (uint32_t keyval)
        return find (state.begin(), state.end(), keyval) != state.end();
 }
 
-Keyboard::State
-Keyboard::translate_key_name (const string& name)
-
-{
-       string::size_type i;
-       string::size_type len;
-       bool at_end;
-       string::size_type hyphen;
-       string keyname;
-       string whatevers_left;
-       State result;
-       guint keycode;
-       
-       i = 0;
-       len = name.length();
-       at_end = (len == 0);
-
-       while (!at_end) {
-
-               whatevers_left = name.substr (i);
-
-               if ((hyphen = whatevers_left.find_first_of ('-')) == string::npos) {
-                       
-                        /* no hyphen, so use the whole thing */
-                       
-                       keyname = whatevers_left;
-                       at_end = true;
-
-               } else {
-
-                       /* There is a hyphen. */
-                       
-                       if (hyphen == 0 && whatevers_left.length() == 1) {
-                               /* its the first and only character */
-                       
-                               keyname = "-";
-                               at_end = true;
-
-                       } else {
-
-                               /* use the text before the hypen */
-                               
-                               keyname = whatevers_left.substr (0, hyphen);
-                               
-                               if (hyphen == len - 1) {
-                                       at_end = true;
-                               } else {
-                                       i += hyphen + 1;
-                                       at_end = (i >= len);
-                               }
-                       }
-               }
-               
-               if (keyname.length() == 1 && isupper (keyname[0])) {
-                       result.push_back (GDK_Shift_L);
-               }
-               
-               if ((keycode = gdk_keyval_from_name(get_real_keyname (keyname).c_str())) == GDK_VoidSymbol) {
-                       error << string_compose(_("KeyboardTarget: keyname \"%1\" is unknown."), keyname) << endmsg;
-                       result.clear();
-                       return result;
-               }
-               
-               result.push_back (keycode);
-       }
-
-       sort (result.begin(), result.end());
-
-       return result;
-}
-
-string
-Keyboard::get_real_keyname (const string& name)
-{
-
-       if (name == "Control" || name == "Ctrl") {
-               return "Control_L";
-       } 
-       if (name == "Meta" || name == "MetaL") {
-               return "Meta_L";
-       } 
-       if (name == "MetaR") {
-               return "Meta_R";
-       } 
-       if (name == "Alt" || name == "AltL") {
-               return "Alt_L";
-       } 
-       if (name == "AltR") {
-               return "Alt_R";
-       } 
-       if (name == "Shift") {
-               return "Shift_L";
-       }
-       if (name == "Shift_R") {
-               return "Shift_L";
-       }
-       if (name == " ") {
-               return "space";
-       }
-       if (name == "!") {
-               return "exclam";
-       }
-       if (name == "\"") {
-               return "quotedbl";
-       }
-       if (name == "#") {
-               return "numbersign";
-       }
-       if (name == "$") {
-               return "dollar";
-       }
-       if (name == "%") {
-               return "percent";
-       }
-       if (name == "&") {
-               return "ampersand";
-       }
-       if (name == "'") {
-               return "apostrophe";
-       }
-       if (name == "'") {
-               return "quoteright";
-       }
-       if (name == "(") {
-               return "parenleft";
-       }
-       if (name == ")") {
-               return "parenright";
-       }
-       if (name == "*") {
-               return "asterisk";
-       }
-       if (name == "+") {
-               return "plus";
-       }
-       if (name == ",") {
-               return "comma";
-       }
-       if (name == "-") {
-               return "minus";
-       }
-       if (name == ".") {
-               return "period";
-       }
-       if (name == "/") {
-               return "slash";
-       }
-       if (name == ":") {
-               return "colon";
-       }
-       if (name == ";") {
-               return "semicolon";
-       }
-       if (name == "<") {
-               return "less";
-       }
-       if (name == "=") {
-               return "equal";
-       }
-       if (name == ">") {
-               return "greater";
-       }
-       if (name == "?") {
-               return "question";
-       }
-       if (name == "@") {
-               return "at";
-       }
-       if (name == "[") {
-               return "bracketleft";
-       }
-       if (name == "\\") {
-               return "backslash";
-       }
-       if (name == "]") {
-               return "bracketright";
-       }
-       if (name == "^") {
-               return "asciicircum";
-       }
-       if (name == "_") {
-               return "underscore";
-       }
-       if (name == "`") {
-               return "grave";
-       }
-       if (name == "`") {
-               return "quoteleft";
-       }
-       if (name == "{") {
-               return "braceleft";
-       }
-       if (name == "|") {
-               return "bar";
-       }
-       if (name == "}") {
-               return "braceright";
-       }
-       if (name == "~") {
-               return "asciitilde";
-       }
-
-       return name;
-}
-
-int
-Keyboard::get_prefix (float& val, bool& was_floating)
-{
-       if (current_prefix.length()) {
-               if (current_prefix.find ('.') != string::npos) {
-                       was_floating = true;
-               } else {
-                       was_floating = false;
-               }
-               if (sscanf (current_prefix.c_str(), "%f", &val) == 1) {
-                       return 0;
-               }
-               current_prefix = "";
-       }
-       return -1;
-}
-
-void
-Keyboard::start_prefix ()
-{
-       collecting_prefix = true;
-       current_prefix = "";
-}
-
-void
-Keyboard::clear_modifier_state ()
-{
-       modifier_mask = 0;
-}
-
-void
-Keyboard::check_modifier_state ()
-{
-       char keys[32];
-       int i, j;
-
-       clear_modifier_state ();
-       XQueryKeymap (GDK_DISPLAY(), keys);
-
-       for (i = 0; i < 32; ++i) {
-               for (j = 0; j < 8; ++j) {
-
-                       if (keys[i] & (1<<j)) {
-                               modifier_mask |= modifier_masks[(i*8)+j];
-                       }
-               }
-       }
-}
-
-void
-Keyboard::check_meta_numlock (char keycode, guint mod, string modname)
-{
-       guint alternate_meta_mod;
-       string alternate_meta_modname;
-
-       if (mod == Meta) {
-               
-               guint keysym = XKeycodeToKeysym  (GDK_DISPLAY(), keycode, 0);
-               
-               if (keysym == GDK_Num_Lock) {
-
-                       switch (mod) {
-                       case GDK_MOD2_MASK:
-                               alternate_meta_mod = GDK_MOD3_MASK;
-                               alternate_meta_modname = "Mod3";
-                               break;
-                       case GDK_MOD3_MASK:
-                               alternate_meta_mod = GDK_MOD2_MASK;
-                               alternate_meta_modname = "Mod2";
-                               break;
-                       case GDK_MOD4_MASK:
-                               alternate_meta_mod = GDK_MOD2_MASK;
-                               alternate_meta_modname = "Mod2";
-                               break;
-                       case GDK_MOD5_MASK:
-                               alternate_meta_mod = GDK_MOD2_MASK;
-                               alternate_meta_modname = "Mod2";
-                               break;
-                       default:
-                               error << string_compose (_("Your system is completely broken - NumLock uses \"%1\""
-                                                   "as its modifier. This is madness - see the man page "
-                                                   "for xmodmap to find out how to fix this."),
-                                                 modname)
-                                     << endmsg;
-                               return;
-                       }
-
-                       warning << string_compose (_("Your system generates \"%1\" when the NumLock key "
-                                             "is pressed. This can cause problems when editing "
-                                             "so Ardour will use %2 to mean Meta rather than %1"),
-                                           modname, alternate_meta_modname)
-                               << endmsg;
-
-                       set_meta_modifier (alternate_meta_mod);
-               }
-       }
-}
-
-void
-Keyboard::get_modifier_masks ()
-{
-       XModifierKeymap *modifiers;
-       KeyCode *keycode;
-       int i;
-       int bound;
-
-       XDisplayKeycodes (GDK_DISPLAY(), &min_keycode, &max_keycode);
-
-       /* This function builds a lookup table to provide rapid answers to
-          the question: what, if any, modmask, is associated with a given
-          keycode ?
-       */
-       
-       modifiers = XGetModifierMapping (GDK_DISPLAY());
-       
-       modifier_masks = new int32_t [max_keycode+1];
-       
-       keycode = modifiers->modifiermap;
-
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* shift */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_SHIFT_MASK;
-                       // cerr << "Shift = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-               }
-               keycode++;
-       }
-    
-       for (i = 0; i < modifiers->max_keypermod; ++i) keycode++; /* skip lock */
-    
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* control */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_CONTROL_MASK;
-                       // cerr << "Control = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-               }
-               keycode++;
-       }
-
-       bound = 0;
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 1 */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_MOD1_MASK;
-                       // cerr << "Mod1 = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-                       bound++;
-               }
-               keycode++;
-       }
-#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
-       if (bound > 1) {
-               warning << string_compose (_("You have %1 keys bound to \"mod1\""), bound) << endmsg;
-       }
-#endif
-       bound = 0;
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod2 */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_MOD2_MASK;
-                       check_meta_numlock (*keycode, GDK_MOD2_MASK, "Mod2");
-                       //cerr << "Mod2 = " << std::hex << (int) *keycode << std::dec << " = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-                       bound++;
-               }
-               keycode++; 
-       }
-#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
-       if (bound > 1) {
-               warning << string_compose (_("You have %1 keys bound to \"mod2\""), bound) << endmsg;
-       }
-#endif
-       bound = 0;
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod3 */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_MOD3_MASK;
-                       check_meta_numlock (*keycode, GDK_MOD3_MASK, "Mod3");
-                       // cerr << "Mod3 = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-                       bound++;
-               }
-               keycode++; 
-       }
-#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
-       if (bound > 1) {
-               warning << string_compose (_("You have %1 keys bound to \"mod3\""), bound) << endmsg;
-       }
-#endif
-       bound = 0;
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 4 */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_MOD4_MASK;
-                       check_meta_numlock (*keycode, GDK_MOD4_MASK, "Mod4");
-                       // cerr << "Mod4 = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-                       bound++;
-               }
-               keycode++;
-       }
-#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
-       if (bound > 1) {
-               warning << string_compose (_("You have %1 keys bound to \"mod4\""), bound) << endmsg;
-       }
-#endif
-       bound = 0;
-       for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 5 */
-               if (*keycode) {
-                       modifier_masks[*keycode] = GDK_MOD5_MASK;
-                       check_meta_numlock (*keycode, GDK_MOD5_MASK, "Mod5");
-                       // cerr << "Mod5 = " << XKeysymToString (XKeycodeToKeysym  (GDK_DISPLAY(), *keycode, 0)) << endl;
-                       bound++;
-               }
-               keycode++;
-       }
-#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
-       if (bound > 1) {
-               warning << string_compose (_("You have %1 keys bound to \"mod5\""), bound) << endmsg;
-       }
-#endif
-
-       XFreeModifiermap (modifiers);
-}
-
 bool
 Keyboard::enter_window (GdkEventCrossing *ev, Gtk::Window* win)
 {
-       switch (ev->detail) {
-       case GDK_NOTIFY_INFERIOR:
-               break;
-
-       case GDK_NOTIFY_VIRTUAL:
-               /* fallthru */
-
-       default:
-               check_modifier_state ();
-       }
-
-       return FALSE;
+       return false;
 }
 
 bool
@@ -697,10 +224,9 @@ Keyboard::leave_window (GdkEventCrossing *ev, Gtk::Window* win)
                        cerr << "clearing current target\n";
                }
                state.clear ();
-               clear_modifier_state ();
        }
-       return FALSE;
 
+       return false;
 }
 
 void
@@ -754,6 +280,7 @@ Keyboard::set_snap_modifier (guint mod)
 bool
 Keyboard::is_edit_event (GdkEventButton *ev)
 {
+
        return (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_BUTTON_RELEASE) && 
                (ev->button == Keyboard::edit_button()) && 
                ((ev->state & RelevantModifierKeyMask) == Keyboard::edit_modifier());
index c13b06afe50f6dad2ff204fda0926303b713e297..c6a9cd08c77774d29e87aa9ef2b2c75c991bb80b 100644 (file)
@@ -45,13 +45,6 @@ class Keyboard : public sigc::trackable, Stateful
        int set_state (const XMLNode&);
 
        typedef vector<uint32_t> State;
-       
-       int  get_prefix(float&, bool& was_floating);
-       void start_prefix ();
-
-       static State  translate_key_name (const string&);
-       static string get_real_keyname (const string& name);
-
        typedef uint32_t ModifierMask;
 
        static uint32_t Control;
@@ -101,17 +94,8 @@ class Keyboard : public sigc::trackable, Stateful
   private:
        static Keyboard* _the_keyboard;
 
-       bool   _queue_events;
-       bool   _flush_queue;
-
        guint           snooper_id;
        State           state;
-       bool            collecting_prefix;
-       string          current_prefix;
-       int*            modifier_masks;
-       int             modifier_mask;
-       int             min_keycode;
-       int             max_keycode;
 
        static guint     edit_but;
        static guint     edit_mod;
@@ -121,13 +105,6 @@ class Keyboard : public sigc::trackable, Stateful
 
        static gint _snooper (GtkWidget*, GdkEventKey*, gpointer);
        gint snooper (GtkWidget*, GdkEventKey*);
-       
-       void queue_event (GdkEventKey*);
-       void get_modifier_masks ();
-       void check_modifier_state ();
-       void clear_modifier_state ();
-
-       void check_meta_numlock (char keycode, guint mod, string modname);
 };
 
 #endif /* __ardour_keyboard_h__ */
diff --git a/gtk2_ardour/keyboard_target.cc b/gtk2_ardour/keyboard_target.cc
deleted file mode 100644 (file)
index 71e4e96..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
-    Copyright (C) 2001-2002 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.
-
-    $Id$
-*/
-
-#include <gdk/gdkkeysyms.h>
-#include <pbd/error.h>
-
-#include "keyboard.h"
-#include "keyboard_target.h"
-
-#include "i18n.h"
-
-using std::pair;
-
-KeyboardTarget::ActionMap KeyboardTarget::actions;
-
-KeyboardTarget::KeyboardTarget (Gtk::Window& win, string name)
-       : _window (win)
-{
-       _name = name;
-       Keyboard::the_keyboard().register_target (this);
-}
-
-KeyboardTarget::~KeyboardTarget ()
-{
-       GoingAway ();
-}
-
-void
-KeyboardTarget::key_release_event (GdkEventKey *event, Keyboard::State& state)
-{
-       // relax
-}
-
-void
-KeyboardTarget::key_press_event (GdkEventKey *event, Keyboard::State& state, bool& handled)
-{
-       KeyMap::iterator result;
-       
-       if ((result = keymap.find (state)) != keymap.end()) {
-               (*result).second ();
-               handled = true;
-       }
-}
-
-int
-KeyboardTarget::add_binding (string keystring, string action)
-{
-       KeyMap::iterator existing;
-       Keyboard::State  state;
-       KeyAction key_action;
-
-       state = Keyboard::translate_key_name (keystring);
-
-       if (keystring.length() == 0) {
-               error << _("KeyboardTarget: empty string passed to add_binding.")
-                     << endmsg;
-               return -1;
-       }
-
-       if (state.size() == 0) {
-               error << string_compose(_("KeyboardTarget: no translation found for \"%1\""), keystring) << endmsg;
-               return -1;
-       }
-
-       if (find_action (action, key_action)) {
-               error << string_compose(_("KeyboardTarget: unknown action \"%1\""), action) << endmsg;
-               return -1;
-       }
-
-       /* remove any existing binding */
-
-       if ((existing = keymap.find (state)) != keymap.end()) {
-               keymap.erase (existing);
-       }
-       
-       keymap.insert (pair<Keyboard::State,KeyAction> (state, key_action));
-       bindings.insert (pair<string,string> (keystring, action));
-       return 0;
-}
-
-string
-KeyboardTarget::get_binding (string name)
-{
-       BindingMap::iterator i;
-       
-       for (i = bindings.begin(); i != bindings.end(); ++i) {
-
-               if (i->second == name) {
-
-                       /* convert keystring to GTK format */
-
-                       string str = i->first;
-                       string gtkstr;
-                       string::size_type p;
-
-                       while (1) {
-
-                               if ((p = str.find ('-')) == string::npos || (p == str.length() - 1)) {
-                                       break;
-                               }
-
-                               gtkstr += '<';
-                               gtkstr += str.substr (0, p);
-                               gtkstr += '>';
-
-                               str = str.substr (p+1);
-
-                       }
-
-                       gtkstr += str;
-
-                       if (gtkstr.length() == 0) {
-                               return i->first;
-                       } 
-
-                       return gtkstr;
-               }
-       }
-       return string ();
-}
-
-void
-KeyboardTarget::show_all_actions ()
-{
-       ActionMap::iterator i;
-       
-       for (i = actions.begin(); i != actions.end(); ++i) {
-               cout << i->first << endl;
-       }
-}
-
-int
-KeyboardTarget::add_action (string name, KeyAction action)
-{
-       pair<string,KeyAction> newpair;
-       pair<ActionMap::iterator,bool> result;
-       newpair.first = name;
-       newpair.second = action;
-
-       result = actions.insert (newpair);
-       return result.second ? 0 : -1;
-}
-
-int
-KeyboardTarget::find_action (string name, KeyAction& action)
-{
-       map<string,KeyAction>::iterator i;
-
-       if ((i = actions.find (name)) != actions.end()) {
-               action = i->second;
-               return 0;
-       } else {
-               return -1;
-       }
-}
-
-int
-KeyboardTarget::remove_action (string name)
-{
-       map<string,KeyAction>::iterator i;
-
-       if ((i = actions.find (name)) != actions.end()) {
-               actions.erase (i);
-               return 0;
-       } else {
-               return -1;
-       }
-}
-
-XMLNode&
-KeyboardTarget::get_binding_state () const
-{
-       XMLNode *node = new XMLNode ("context");
-       BindingMap::const_iterator i;
-
-       node->add_property ("name", _name);
-       
-       for (i = bindings.begin(); i != bindings.end(); ++i) {
-               XMLNode *child;
-
-               child = new XMLNode ("binding");
-               child->add_property ("keys", i->first);
-               child->add_property ("action", i->second);
-               node->add_child_nocopy (*child);
-       }
-       
-       return *node;
-}
-       
-int
-KeyboardTarget::set_binding_state (const XMLNode& node)
-{
-       XMLNodeList nlist = node.children();
-       XMLNodeConstIterator niter;
-       XMLNode *child_node;
-
-       bindings.clear ();
-       keymap.clear ();
-
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               child_node = *niter;
-
-               if (child_node->name() == "context") {
-                       XMLProperty *prop;
-                       
-                       if ((prop = child_node->property ("name")) != 0) {
-                               if (prop->value() == _name) {
-                                       return load_bindings (*child_node);
-                               }
-                       }
-               }
-       }
-
-       return 0;
-}
-
-int
-KeyboardTarget::load_bindings (const XMLNode& node)
-{
-       XMLNodeList nlist = node.children();
-       XMLNodeConstIterator niter;
-
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               XMLProperty *keys;
-               XMLProperty *action;
-               
-               keys = (*niter)->property ("keys");
-               action = (*niter)->property ("action");
-
-               if (!keys || !action) {
-                       error << _("misformed binding node - ignored") << endmsg;
-                       continue;
-               }
-
-               add_binding (keys->value(), action->value());
-                       
-       }
-
-       return 0;
-}
-
diff --git a/gtk2_ardour/keyboard_target.h b/gtk2_ardour/keyboard_target.h
deleted file mode 100644 (file)
index f542261..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-    Copyright (C) 2001 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.
-
-    $Id$
-*/
-
-#ifndef __ardour_keyboard_target_h__
-#define __ardour_keyboard_target_h__
-
-#include <map>
-#include <string>
-#include <sigc++/signal.h>
-#include <sigc++/slot.h>
-#include <gdk/gdk.h>
-#include <pbd/xml++.h>
-
-#include "keyboard.h"
-
-namespace Gtk {
-       class Window;
-}
-
-class KeyboardTarget 
-{
-  public:
-       KeyboardTarget(Gtk::Window& w, std::string name);
-       virtual ~KeyboardTarget();
-
-       sigc::signal<void> Hiding;
-       sigc::signal<void> GoingAway;
-
-       typedef sigc::slot<void> KeyAction;
-
-       std::string name() const { return _name; }
-
-       void key_press_event (GdkEventKey *, Keyboard::State&, bool& handled);
-       void key_release_event (GdkEventKey *, Keyboard::State&);
-
-       int add_binding (std::string keys, std::string name);
-       std::string get_binding (std::string name); /* returns keys bound to name */
-
-       XMLNode& get_binding_state () const;
-       int set_binding_state (const XMLNode&);
-
-       static int32_t add_action (std::string, KeyAction);
-       static int32_t find_action (std::string, KeyAction&);
-       static int32_t remove_action (std::string);
-       static void show_all_actions();
-
-       Gtk::Window& window() const { return _window; }
-       
-  protected:
-       typedef std::map<Keyboard::State,KeyAction> KeyMap;
-       typedef std::map<std::string,std::string> BindingMap;
-
-       KeyMap     keymap;
-       BindingMap bindings;
-
-  private:
-       typedef map<std::string,KeyAction> ActionMap; 
-       static ActionMap actions;
-       std::string _name;
-       Gtk::Window& _window;
-
-       int load_bindings (const XMLNode&);
-};
-
-#endif /* __ardour_keyboard_target_h__ */
-
index 580d47ff5d0eed5d4f7c265ac1b7136bcc7c1895..d0a5f533347db52d9873e83c901888309a5975dc 100644 (file)
@@ -32,7 +32,6 @@
 #include <ardour/session.h>
 
 #include "ardour_dialog.h"
-#include "keyboard_target.h"
 
 namespace ARDOUR {
        class LocationStack;
index 2fd8e0c92043de470eb291ece94b2e3641e373c1..e31e0983843e40f57a884d0f38aa09c006278cc3 100644 (file)
@@ -416,6 +416,10 @@ int main (int argc, char *argv[])
                     << endl;
        }
 
+       /* some GUI objects need this */
+
+       PBD::ID::init ();
+
         try { 
                ui = new ARDOUR_UI (&argc, &argv, which_ui_rcfile());
        } catch (failed_constructor& err) {
index 6ceb7402fcb73ec44c0fb6291195d45318dc1699..a3594be2c2c72b0717587ab06fc5a318a8300a53 100644 (file)
@@ -30,7 +30,6 @@
 #include <gtkmm/fixed.h>
 #include <gtkmm/frame.h>
 
-#include "keyboard_target.h"
 #include "ardour_dialog.h"
 
 class MeterBridgeStrip;
index e75a7d907cadca451c7850836b52d026ecfcd81c..03fb941b58a1790df0810a2eacc6e65aea9f7290 100644 (file)
@@ -155,9 +155,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
        /* XXX what is this meant to do? */
        //meter_point_button.signal_button_release_event().connect (mem_fun (gpm, &GainMeter::meter_release), false);
 
-       solo_button->set_name ("MixerSoloButton");
-       mute_button->set_name ("MixerMuteButton");
-
        hide_button.set_events (hide_button.get_events() & ~(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK));
 
        width_button.unset_flags (Gtk::CAN_FOCUS);
index 430f774eb6f68abe1845c53dd98748e3abd18ef1..ea2569b644c5dc554a8cb41cf971ba2f01b03e8f 100644 (file)
@@ -241,9 +241,6 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
 
        bool ignore_speed_adjustment;
 
-       string solo_button_name () const { return "MixerSoloButton"; }
-       string safe_solo_button_name () const { return "MixerSafeSoloButton"; }
-
        void engine_running();
        void engine_stopped();
 
index f20171f9fba1553a55712dab0f841ad65dd464e5..4d13367cb611182934f8a753ab844e1fcc6447af 100644 (file)
@@ -37,6 +37,7 @@
 #include <ardour/audio_diskstream.h>
 #include <ardour/plugin_manager.h>
 
+#include "keyboard.h"
 #include "mixer_ui.h"
 #include "mixer_strip.h"
 #include "plugin_selector.h"
index 2a5b416ae0b995e8428cd72b5f60d117c31e2f19..3da4beb112d0cbed23c2cff40e07c97c9d3c0698 100644 (file)
@@ -38,7 +38,6 @@
 #include <ardour/ardour.h>
 #include <ardour/io.h>
 
-#include "keyboard_target.h"
 #include "route_redirect_selection.h"
 #include "enums.h"
 
index 85cb3dab1d9809bc5611b74a0b436bedf1fd11b0..13acfbf5ab1284b3c6539ea85c13f82184a7cf98 100644 (file)
@@ -31,6 +31,7 @@
 #include <gtkmm2ext/utils.h>
 
 #include "public_editor.h"
+#include "keyboard.h"
 #include "mixer_ui.h"
 #include "ardour_ui.h"
 #include "io_selector.h"
index e1d061e13d0f3032cc8a05a98517fc7bbd6c46d0..0c3ae76502b7d430484d8b8cfbb4eb03724b0d3c 100644 (file)
@@ -14,7 +14,6 @@
 #include <pbd/statefuldestructible.h> 
 
 #include "editing.h"
-#include "keyboard_target.h"
 #include "canvas.h"
 #include "selection.h"
 
@@ -73,11 +72,11 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void set_mouse_mode (Editing::MouseMode, bool force = false) = 0;
        virtual void step_mouse_mode (bool next) = 0;
        virtual Editing::MouseMode current_mouse_mode () = 0;
-       virtual void add_imageframe_time_axis(const string & track_name, void*)  = 0;
-       virtual void add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void*)  = 0;
+       virtual void add_imageframe_time_axis(const std::string & track_name, void*)  = 0;
+       virtual void add_imageframe_marker_time_axis(const std::string & track_name, TimeAxisView* marked_track, void*)  = 0;
        virtual void connect_to_image_compositor()  = 0;
        virtual void scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)  = 0;
-       virtual TimeAxisView* get_named_time_axis(const string & name)  = 0;
+       virtual TimeAxisView* get_named_time_axis(const std::string & name)  = 0;
        virtual void consider_auditioning (boost::shared_ptr<ARDOUR::Region>) = 0;
        virtual void set_show_waveforms (bool yn) = 0;
        virtual bool show_waveforms() const = 0;
index 394383de6bbdf92cc12be23963f7c67244bdea11..197404bcc9d3277da670cd7214847df00735ef45 100644 (file)
@@ -41,7 +41,6 @@
 
 #include "io_selector.h"
 #include "ardour_dialog.h"
-#include "keyboard_target.h"
 #include "redirect_box.h"
 #include "route_redirect_selection.h"
 
index 573b9feb83ab9979ed835f76ec8023a0e2e0790c..3d04ff6a8b9177d63d089ab55984c9ba08f4d580 100644 (file)
@@ -105,8 +105,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
 
        ignore_toggle = false;
 
-       mute_button->set_name ("TrackMuteButton");
-       solo_button->set_name ("SoloButton");
        edit_group_button.set_name ("TrackGroupButton");
        playlist_button.set_name ("TrackPlaylistButton");
        automation_button.set_name ("TrackAutomationButton");
@@ -124,9 +122,9 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
        visual_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::visual_click));
        hide_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::hide_click));
 
-       solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press));
+       solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), true);
        solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release));
-       mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press));
+       mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), true);
        mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release));
 
        if (is_track()) {
@@ -177,15 +175,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
 
        /* remove focus from the buttons */
        
-       automation_button.unset_flags (Gtk::CAN_FOCUS);
-       solo_button->unset_flags (Gtk::CAN_FOCUS);
-       mute_button->unset_flags (Gtk::CAN_FOCUS);
-       edit_group_button.unset_flags (Gtk::CAN_FOCUS);
-       size_button.unset_flags (Gtk::CAN_FOCUS);
-       playlist_button.unset_flags (Gtk::CAN_FOCUS);
-       hide_button.unset_flags (Gtk::CAN_FOCUS);
-       visual_button.unset_flags (Gtk::CAN_FOCUS);
-
        y_position = -1;
 
        _route->redirects_changed.connect (mem_fun(*this, &RouteTimeAxisView::redirects_changed));
@@ -484,7 +473,6 @@ RouteTimeAxisView::build_display_menu ()
 
 static bool __reset_item (RadioMenuItem* item)
 {
-       cerr << "reset item to true\n";
        item->set_active ();
        return false;
 }
index 08b6c657a519a57880747d13dd8aaf6b42716217..249826d3505bcbc1a76621e09dfc152560b77ae1 100644 (file)
@@ -63,6 +63,7 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
        ignore_toggle = false;
        wait_for_release = false;
        route_active_menu_item = 0;
+       was_solo_safe = false;
 
        if (set_color_from_route()) {
                set_color (unique_random_color());
@@ -75,8 +76,23 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
         mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
         solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
 
-       // mute_button->unset_flags (Gtk::CAN_FOCUS);
-       // solo_button->unset_flags (Gtk::CAN_FOCUS);
+       mute_button->set_name ("MuteButton");
+       solo_button->set_name ("SoloButton");
+
+       vector<Gdk::Color> colors;
+       Gdk::Color c;
+
+       /* mute+solo buttons get 2 color states, so add one here to supplement the existing one */
+       ::set_color(c, rgba_from_style (X_("MuteButton"), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
+       colors.push_back (c);
+       mute_button->set_colors (colors);
+
+       colors.clear ();
+       
+       /* mute+solo buttons get 2 color states, so add one here to supplement the existing one */
+       ::set_color(c, rgba_from_style (X_("SoloButton"), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
+       colors.push_back (c);
+       solo_button->set_colors (colors);
 
        _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
        _route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
@@ -93,7 +109,17 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
                _session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
 
                rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
-               rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
+
+               colors.clear ();
+
+               /* record button has 3 color states, so we set 2 extra here */
+               ::set_color(c, rgba_from_style (X_("TrackRecordEnableButton"), 0xff, 0, 0, 0, "bg", Gtk::STATE_SELECTED, false ));
+               colors.push_back (c);
+               
+               ::set_color(c, rgba_from_style (X_("TrackRecordEnableButton"), 0xff, 0, 0, 0, "bg", Gtk::STATE_ACTIVE, false ));
+               colors.push_back (c);
+               
+               rec_enable_button->set_colors (colors);
                
                update_rec_display ();
        } 
@@ -342,6 +368,25 @@ void
 RouteUI::update_solo_display ()
 {
        bool x;
+       vector<Gdk::Color> colors;
+       Gdk::Color c;
+
+       if (_route->solo_safe() != was_solo_safe){
+
+               if (_route->solo_safe()) {
+                       /* show solo safe */
+                       ::set_color(c, rgba_from_style (safe_solo_button_name(), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
+                       solo_button->set_name(safe_solo_button_name());
+               } else {
+                       ::set_color(c, rgba_from_style (solo_button_name(), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
+                       solo_button->set_name(solo_button_name());
+               }
+
+               colors.push_back (c);
+               solo_button->set_colors (colors);
+
+               was_solo_safe = !was_solo_safe;
+       }
 
        if (solo_button->get_active() != (x = _route->soloed())){
                ignore_toggle = true;
@@ -349,13 +394,6 @@ RouteUI::update_solo_display ()
                ignore_toggle = false;
        }
        
-       /* show solo safe */
-
-       if (_route->solo_safe()){
-               solo_button->set_name(safe_solo_button_name());
-       } else {
-               solo_button->set_name(solo_button_name());
-       }
 }
 
 void
index ea860419860883ad8496b2c713fb647571654de1..12b04635d29b553c3a00f09c082a511d35e7d98d 100644 (file)
@@ -146,7 +146,10 @@ class RouteUI : public virtual AxisView
 
        void update_rec_display ();
        void update_mute_display ();
+
+       bool was_solo_safe;
        void update_solo_display ();
+
        virtual void map_frozen ();
 
        void set_remote_control_id (uint32_t id, Gtk::CheckMenuItem* item);
index 869d7eb23968f00f32c9173a5b6e789118bb4c9d..d4f94ed7445fe3d3956b8b2afe8f66c3b1f1e009 100644 (file)
@@ -78,8 +78,8 @@ class Route : public IO
        std::string comment() { return _comment; }
        void set_comment (std::string str, void *src);
 
-       long order_key(std::string name) const;
-       void set_order_key (std::string name, long n);
+       long order_key (const char* name) const;
+       void set_order_key (const char* name, long n);
 
        bool hidden() const { return _flags & Hidden; }
        bool master() const { return _flags & MasterOut; }
@@ -321,7 +321,16 @@ class Route : public IO
        void init ();
 
        static uint32_t order_key_cnt;
-       typedef std::map<std::string,long> OrderKeys;
+
+       struct ltstr
+       {
+           bool operator()(const char* s1, const char* s2) const
+           {
+                   return strcmp(s1, s2) < 0;
+           }
+       };
+
+       typedef std::map<const char*,long,ltstr> OrderKeys;
        OrderKeys order_keys;
 
        void input_change_handler (IOChange, void *src);
index d0ee94dca73c7f4d06e3871a196b30c9ae586cad..c9e663e98400aa2a09a7b4d237eac09b93deeda6 100644 (file)
@@ -279,8 +279,6 @@ ARDOUR::init (bool use_vst, bool try_optimization)
 
        (void) bindtextdomain(PACKAGE, LOCALEDIR);
 
-       PBD::ID::init ();
-
        setup_enum_writer ();
 
        lrdf_init();
index 2ac94cd239bedb3434e33fe58338e357eabd41d5..6915b3279203ad3501dd7fca37c301c44ecabbdd 100644 (file)
@@ -79,7 +79,7 @@ Route::init ()
        _soloed = false;
        _solo_safe = false;
        _phase_invert = false;
-       order_keys[N_("signal")] = order_key_cnt++;
+       order_keys[strdup (N_("signal"))] = order_key_cnt++;
        _active = true;
        _silent = false;
        _meter_point = MeterPostFader;
@@ -115,6 +115,10 @@ Route::~Route ()
 {
        clear_redirects (this);
 
+       for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) {
+               free ((void*)(i->first));
+       }
+
        if (_control_outs) {
                delete _control_outs;
        }
@@ -136,21 +140,23 @@ Route::remote_control_id() const
 }
 
 long
-Route::order_key (string name) const
+Route::order_key (const char* name) const
 {
        OrderKeys::const_iterator i;
        
-       if ((i = order_keys.find (name)) == order_keys.end()) {
-               return -1;
+       for (i = order_keys.begin(); i != order_keys.end(); ++i) {
+               if (!strcmp (name, i->first)) {
+                       return i->second;
+               }
        }
 
-       return (*i).second;
+       return -1;
 }
 
 void
-Route::set_order_key (string name, long n)
+Route::set_order_key (const char* name, long n)
 {
-       order_keys[name] = n;
+       order_keys[strdup(name)] = n;
        _session.set_dirty ();
 }
 
@@ -1396,7 +1402,7 @@ Route::state(bool full_state)
        OrderKeys::iterator x = order_keys.begin(); 
 
        while (x != order_keys.end()) {
-               order_string += (*x).first;
+               order_string += string ((*x).first);
                order_string += '=';
                snprintf (buf, sizeof(buf), "%ld", (*x).second);
                order_string += buf;
@@ -1611,7 +1617,7 @@ Route::_set_state (const XMLNode& node, bool call_base)
                                        error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
                                              << endmsg;
                                } else {
-                                       set_order_key (remaining.substr (0, equal), n);
+                                       set_order_key (remaining.substr (0, equal).c_str(), n);
                                }
                        }
 
index 76b89deb024125bbbc94c15dca32dd8f282490ad..3c3cad6e46ddd04def011484da23686568cfbe25 100644 (file)
@@ -42,7 +42,7 @@ BindableToggleButton::BindableToggleButton (MIDI::Controllable *mc)
 }
 
 BindableToggleButton::BindableToggleButton(MIDI::Controllable *mc, const string &label)
-       : ToggleButton (label),
+       : StatefulButton (label),
          prompter (Gtk::WIN_POS_MOUSE, 30000, false),
          midi_control (mc),
          bind_button (2),
@@ -89,17 +89,6 @@ BindableToggleButton::midi_learn()
        }
 }
 
-bool
-BindableToggleButton::on_button_press_event (GdkEventButton *ev)
-{
-       if ((ev->state & bind_statemask) && ev->button == bind_button) { 
-               midi_learn ();
-               return true;
-       }
-       
-       return false;
-}
-
 bool
 BindableToggleButton::prompter_hiding (GdkEventAny *ev)
 {
index 193612540551db5d4873cc4d4aa6b2a56df82f91..845d3fa49e3cbe28124d83950d419f1d5aaa0e8f 100644 (file)
@@ -30,15 +30,44 @@ namespace PBD {
        class Controllable;
 }
 
-class BindableToggleButton : public Gtk::ToggleButton
+class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
 {
    public:
        BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {}
-       explicit BindableToggleButton (PBD::Controllable& c, const std::string &label) : Gtk::ToggleButton (label), binding_proxy (c) {}
+
+       explicit BindableToggleButton (PBD::Controllable& c, const std::string &label)
+               : Gtkmm2ext::StatefulToggleButton (label), binding_proxy (c) {}
+
        virtual ~BindableToggleButton() {}
        
        bool on_button_press_event (GdkEventButton *ev) {
-               return binding_proxy.button_press_handler (ev);
+               if (!binding_proxy.button_press_handler (ev)) {
+                       return false;
+               } else {
+                       return true;
+               }
+       }
+
+  private:
+       BindingProxy binding_proxy;
+};
+
+class BindableButton : public Gtkmm2ext::StatefulButton
+{
+   public:
+       BindableButton (PBD::Controllable& c) : binding_proxy (c) {}
+
+       explicit BindableButton (PBD::Controllable& c, const std::string &label)
+               : Gtkmm2ext::StatefulButton (label), binding_proxy (c) {}
+
+       ~BindableButton() {}
+       
+       bool on_button_press_event (GdkEventButton *ev) {
+               if (!binding_proxy.button_press_handler (ev)) {
+                       return false;
+               } else {
+                       return true;
+               }
        }
 
   private:
index f684903836783735da7f4664c22a5804cd500561..fc62bd2999062bda81742daaf8d9d103ab755dae 100644 (file)
 
 namespace Gtkmm2ext {
 
-class StatefulButton : public Gtk::Button
+class StateButton 
 {
    public:
-       StatefulButton();
-       explicit StatefulButton(const std::string &label);
-       virtual ~StatefulButton() {}
+       StateButton();
+       virtual ~StateButton() {}
 
        void set_colors (const std::vector<Gdk::Color>& colors);
-       void set_state (int);
-       int  get_state () { return current_state; }
-       void set_active (bool yn) {
-               set_state (yn ? 1 : 0);
-       }
-       
+       void set_visual_state (int);
+       int  get_visual_state () { return visual_state; }
 
   protected:
        std::vector<Gdk::Color> colors;
-       int current_state;
+       int  visual_state;
        Gdk::Color saved_bg;
        bool have_saved_bg;
+       
+       virtual void bg_modify (Gtk::StateType, Gdk::Color) = 0;
+};
+
+
+class StatefulToggleButton : public StateButton, public Gtk::ToggleButton
+{
+   public:
+       StatefulToggleButton() {}
+       explicit StatefulToggleButton(const std::string &label) : Gtk::ToggleButton (label) {}
+       ~StatefulToggleButton() {}
+
+  protected:
+       void on_realize ();
+       void on_toggled ();
+
+       void bg_modify (Gtk::StateType state, Gdk::Color col) { 
+               modify_bg (state, col);
+       }
+};
 
+class StatefulButton : public StateButton, public Gtk::Button
+{
+   public:
+       StatefulButton() {}
+       explicit StatefulButton(const std::string &label) : Gtk::Button (label) {}
+       virtual ~StatefulButton() {}
+
+  protected:
        void on_realize ();
+
+       void bg_modify (Gtk::StateType state, Gdk::Color col) { 
+               modify_bg (state, col);
+       }
 };
 
 };
index 074d0866511bcd0326c42574fd6f3c2f8ae193d9..6cc24de461df4844e3f7f4356a6aaaa82bff666c 100644 (file)
 #include <string>
 #include <iostream>
-#include "gtkmm2ext/stateful_button.h"
+
+#include <gtkmm/main.h>
+
+#include <gtkmm2ext/stateful_button.h>
 
 using namespace Gtk;
 using namespace Glib;
 using namespace Gtkmm2ext;
 using namespace std;
 
-StatefulButton::StatefulButton ()
+StateButton::StateButton ()
 {
-       current_state = 0;
+       visual_state = 0;
        have_saved_bg = false;
 }
 
-StatefulButton::StatefulButton (const string& label)
-       : Button (label)
+void
+StateButton::set_colors (const vector<Gdk::Color>& c)
 {
-       current_state = 0;
-       have_saved_bg = false;
+       colors = c;
+       visual_state++; // to force transition
+       set_visual_state (visual_state - 1);
 }
 
 void
-StatefulButton::set_colors (const vector<Gdk::Color>& c)
+StateButton::set_visual_state (int n)
 {
-       colors = c;
-       current_state++; // to force transition
-       set_state (current_state - 1);
+       if (!have_saved_bg) {
+               /* not yet realized */
+               visual_state = n;
+               return;
+       }
+
+       if (n == visual_state) {
+               return;
+       }
+       
+       if (n == 0) {
+               
+               /* back to the default color */
+               
+               if (have_saved_bg) {
+                       bg_modify (STATE_NORMAL, saved_bg);
+                       bg_modify (STATE_ACTIVE, saved_bg);
+                       bg_modify (STATE_SELECTED, saved_bg);
+                       bg_modify (STATE_PRELIGHT, saved_bg);
+               }
+               
+               
+       } else {
+               
+               int index = (n-1) % colors.size ();
+               
+               bg_modify (STATE_NORMAL, colors[index]);
+               bg_modify (STATE_ACTIVE, colors[index]);
+               bg_modify (STATE_SELECTED, colors[index]);
+               bg_modify (STATE_PRELIGHT, colors[index]);
+       }
+
+       visual_state = n;
 }
 
+/* ----------------------------------------------------------------- */
+
 void
-StatefulButton::on_realize ()
+StatefulToggleButton::on_realize ()
 {
-       Button::on_realize ();
+       ToggleButton::on_realize ();
 
        if (!have_saved_bg) {
                saved_bg = get_style()->get_bg (STATE_NORMAL);
                have_saved_bg = true;
        }
 
-       current_state++; // to force transition
-       set_state (current_state - 1);
+       visual_state++; // to force transition
+       set_visual_state (visual_state - 1);
 }
 
 void
-StatefulButton::set_state (int n)
+StatefulButton::on_realize ()
 {
-       if (is_realized()) {
+       Button::on_realize ();
 
-               if (n == current_state) {
-                       return;
-               }
-               
-               if (n == 0) {
-                       
-                       /* back to the default color */
-                       
-                       if (have_saved_bg) {
-                               modify_bg (STATE_NORMAL, saved_bg);
-                               modify_bg (STATE_ACTIVE, saved_bg);
-                               modify_bg (STATE_SELECTED, saved_bg);
-                               modify_bg (STATE_PRELIGHT, saved_bg);
-                       }
-                       
-
-               } else {
-                       
-                       int index = (n-1) % colors.size ();
-                       
-                       modify_bg (STATE_NORMAL, colors[index]);
-                       modify_bg (STATE_ACTIVE, colors[index]);
-                       modify_bg (STATE_SELECTED, colors[index]);
-                       modify_bg (STATE_PRELIGHT, colors[index]);
-               }
-               
-               /* leave insensitive alone */
+       if (!have_saved_bg) {
+               saved_bg = get_style()->get_bg (STATE_NORMAL);
+               have_saved_bg = true;
        }
 
-       current_state = n;
+       visual_state++; // to force transition
+       set_visual_state (visual_state - 1);
+}
+
+void
+StatefulToggleButton::on_toggled ()
+{
+       if (get_active()) {
+               set_visual_state (1);
+       } else {
+               set_visual_state (0);
+       }
+       
 }