summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-02-09 03:36:00 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-02-09 03:36:00 +0000
commit14543eb1374dc51834385d2f3886f1e6068223c5 (patch)
tree5194d0a983b77d79f5310f1216129e84c64f6a42
parent138b12b1dd5b7e6175b3349b8ed7fa8b16721809 (diff)
strip X specific from keyboard.cc; fix up many buttons to avoid prelight (mostly) and make transport buttons bindable (state not saved yet); use const char* not string in route order keys to avoid pointless mallocs during route sorting
git-svn-id: svn://localhost/ardour2/trunk@1437 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour2_ui.rc11
-rw-r--r--gtk2_ardour/ardour_ui.cc124
-rw-r--r--gtk2_ardour/ardour_ui.h61
-rw-r--r--gtk2_ardour/ardour_ui2.cc95
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc1
-rw-r--r--gtk2_ardour/editor.h6
-rw-r--r--gtk2_ardour/editor_canvas_events.cc1
-rw-r--r--gtk2_ardour/editor_keys.cc3
-rw-r--r--gtk2_ardour/editor_mouse.cc8
-rw-r--r--gtk2_ardour/editor_region_list.cc1
-rw-r--r--gtk2_ardour/editor_route_list.cc1
-rw-r--r--gtk2_ardour/editor_selection_list.cc1
-rw-r--r--gtk2_ardour/keyboard.cc519
-rw-r--r--gtk2_ardour/keyboard.h23
-rw-r--r--gtk2_ardour/keyboard_target.cc258
-rw-r--r--gtk2_ardour/keyboard_target.h83
-rw-r--r--gtk2_ardour/location_ui.h1
-rw-r--r--gtk2_ardour/main.cc4
-rw-r--r--gtk2_ardour/meter_bridge.h1
-rw-r--r--gtk2_ardour/mixer_strip.cc3
-rw-r--r--gtk2_ardour/mixer_strip.h3
-rw-r--r--gtk2_ardour/mixer_ui.cc1
-rw-r--r--gtk2_ardour/mixer_ui.h1
-rw-r--r--gtk2_ardour/option_editor.cc1
-rw-r--r--gtk2_ardour/public_editor.h7
-rw-r--r--gtk2_ardour/route_params_ui.h1
-rw-r--r--gtk2_ardour/route_time_axis.cc16
-rw-r--r--gtk2_ardour/route_ui.cc58
-rw-r--r--gtk2_ardour/route_ui.h3
-rw-r--r--libs/ardour/ardour/route.h15
-rw-r--r--libs/ardour/globals.cc2
-rw-r--r--libs/ardour/route.cc24
-rw-r--r--libs/gtkmm2ext/bindable_button.cc13
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/bindable_button.h35
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/stateful_button.h49
-rw-r--r--libs/gtkmm2ext/stateful_button.cc114
36 files changed, 482 insertions, 1066 deletions
diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc
index 488623ce93..62a615f190 100644
--- a/gtk2_ardour/ardour2_ui.rc
+++ b/gtk2_ardour/ardour2_ui.rc
@@ -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"
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 7e0e06e97f..5befc7c092 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -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;
}
}
@@ -1630,12 +1647,6 @@ ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
}
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;
+}
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index e1b7c55555..9d51232f6c 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -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);
diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc
index a39bcb124d..6fcfb32b6d 100644
--- a/gtk2_ardour/ardour_ui2.cc
+++ b/gtk2_ardour/ardour_ui2.cc
@@ -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;
}
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 6e5aa01ac6..a4cd3c2d99 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -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 */
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 803611b77e..2d44538cb7 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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>);
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index b2c7554a2a..fa83ac94e5 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -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"
diff --git a/gtk2_ardour/editor_keys.cc b/gtk2_ardour/editor_keys.cc
index 1bcaafd279..762a480f1f 100644
--- a/gtk2_ardour/editor_keys.cc
+++ b/gtk2_ardour/editor_keys.cc
@@ -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;
}
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index d502ee0c40..558d4b29da 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -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;
+ }
}
}
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index d8c521da20..10915df26f 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -33,6 +33,7 @@
#include "editor.h"
#include "editing.h"
+#include "keyboard.h"
#include "ardour_ui.h"
#include "gui_thread.h"
#include "actions.h"
diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc
index b1393ef5e1..b0311d24a8 100644
--- a/gtk2_ardour/editor_route_list.cc
+++ b/gtk2_ardour/editor_route_list.cc
@@ -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"
diff --git a/gtk2_ardour/editor_selection_list.cc b/gtk2_ardour/editor_selection_list.cc
index 864e527b59..49308b2140 100644
--- a/gtk2_ardour/editor_selection_list.cc
+++ b/gtk2_ardour/editor_selection_list.cc
@@ -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"
diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc
index a6a14ad55b..517ef973d4 100644
--- a/gtk2_ardour/keyboard.cc
+++ b/gtk2_ardour/keyboard.cc
@@ -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());
diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h
index c13b06afe5..c6a9cd08c7 100644
--- a/gtk2_ardour/keyboard.h
+++ b/gtk2_ardour/keyboard.h
@@ -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
index 71e4e9652e..0000000000
--- a/gtk2_ardour/keyboard_target.cc
+++ /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
index f542261b54..0000000000
--- a/gtk2_ardour/keyboard_target.h
+++ /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__ */
-
diff --git a/gtk2_ardour/location_ui.h b/gtk2_ardour/location_ui.h
index 580d47ff5d..d0a5f53334 100644
--- a/gtk2_ardour/location_ui.h
+++ b/gtk2_ardour/location_ui.h
@@ -32,7 +32,6 @@
#include <ardour/session.h>
#include "ardour_dialog.h"
-#include "keyboard_target.h"
namespace ARDOUR {
class LocationStack;
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index 2fd8e0c920..e31e098384 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -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) {
diff --git a/gtk2_ardour/meter_bridge.h b/gtk2_ardour/meter_bridge.h
index 6ceb7402fc..a3594be2c2 100644
--- a/gtk2_ardour/meter_bridge.h
+++ b/gtk2_ardour/meter_bridge.h
@@ -30,7 +30,6 @@
#include <gtkmm/fixed.h>
#include <gtkmm/frame.h>
-#include "keyboard_target.h"
#include "ardour_dialog.h"
class MeterBridgeStrip;
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index e75a7d907c..03fb941b58 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -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);
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index 430f774eb6..ea2569b644 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -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();
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index f20171f9fb..4d13367cb6 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -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"
diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h
index 2a5b416ae0..3da4beb112 100644
--- a/gtk2_ardour/mixer_ui.h
+++ b/gtk2_ardour/mixer_ui.h
@@ -38,7 +38,6 @@
#include <ardour/ardour.h>
#include <ardour/io.h>
-#include "keyboard_target.h"
#include "route_redirect_selection.h"
#include "enums.h"
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index 85cb3dab1d..13acfbf5ab 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -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"
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index e1d061e13d..0c3ae76502 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -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;
diff --git a/gtk2_ardour/route_params_ui.h b/gtk2_ardour/route_params_ui.h
index 394383de6b..197404bcc9 100644
--- a/gtk2_ardour/route_params_ui.h
+++ b/gtk2_ardour/route_params_ui.h
@@ -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"
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 573b9feb83..3d04ff6a8b 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -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;
}
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 08b6c657a5..249826d350 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -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
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index ea86041986..12b04635d2 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -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);
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 869d7eb239..d4f94ed744 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -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);
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index d0ee94dca7..c9e663e984 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -279,8 +279,6 @@ ARDOUR::init (bool use_vst, bool try_optimization)
(void) bindtextdomain(PACKAGE, LOCALEDIR);
- PBD::ID::init ();
-
setup_enum_writer ();
lrdf_init();
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 2ac94cd239..6915b32792 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -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);
}
}
diff --git a/libs/gtkmm2ext/bindable_button.cc b/libs/gtkmm2ext/bindable_button.cc
index 76b89deb02..3c3cad6e46 100644
--- a/libs/gtkmm2ext/bindable_button.cc
+++ b/libs/gtkmm2ext/bindable_button.cc
@@ -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),
@@ -90,17 +90,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)
{
if (unprompting) {
diff --git a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
index 1936125405..845d3fa49e 100644
--- a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
+++ b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
@@ -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:
diff --git a/libs/gtkmm2ext/gtkmm2ext/stateful_button.h b/libs/gtkmm2ext/gtkmm2ext/stateful_button.h
index f684903836..fc62bd2999 100644
--- a/libs/gtkmm2ext/gtkmm2ext/stateful_button.h
+++ b/libs/gtkmm2ext/gtkmm2ext/stateful_button.h
@@ -27,28 +27,55 @@
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);
+ }
};
};
diff --git a/libs/gtkmm2ext/stateful_button.cc b/libs/gtkmm2ext/stateful_button.cc
index 074d086651..6cc24de461 100644
--- a/libs/gtkmm2ext/stateful_button.cc
+++ b/libs/gtkmm2ext/stateful_button.cc
@@ -1,80 +1,104 @@
#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);
+ }
+
}