mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
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
This commit is contained in:
parent
138b12b1dd
commit
14543eb137
36 changed files with 489 additions and 1073 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,17 +222,30 @@ ARDOUR_UI::setup_transport ()
|
|||
play_selection_button.set_name ("TransportButton");
|
||||
rec_button.set_name ("TransportRecButton");
|
||||
auto_loop_button.set_name ("TransportButton");
|
||||
auto_return_button.set_name ("TransportButton");
|
||||
auto_play_button.set_name ("TransportButton");
|
||||
auto_input_button.set_name ("TransportButton");
|
||||
punch_in_button.set_name ("TransportButton");
|
||||
punch_out_button.set_name ("TransportButton");
|
||||
click_button.set_name ("TransportButton");
|
||||
time_master_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);
|
||||
|
||||
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 ));
|
||||
colors.push_back (c);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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>);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "editor.h"
|
||||
#include "editing.h"
|
||||
#include "keyboard.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "gui_thread.h"
|
||||
#include "actions.h"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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__ */
|
||||
|
||||
|
|
@ -32,7 +32,6 @@
|
|||
#include <ardour/session.h>
|
||||
|
||||
#include "ardour_dialog.h"
|
||||
#include "keyboard_target.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class LocationStack;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include <gtkmm/fixed.h>
|
||||
#include <gtkmm/frame.h>
|
||||
|
||||
#include "keyboard_target.h"
|
||||
#include "ardour_dialog.h"
|
||||
|
||||
class MeterBridgeStrip;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
#include <ardour/ardour.h>
|
||||
#include <ardour/io.h>
|
||||
|
||||
#include "keyboard_target.h"
|
||||
#include "route_redirect_selection.h"
|
||||
#include "enums.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -279,8 +279,6 @@ ARDOUR::init (bool use_vst, bool try_optimization)
|
|||
|
||||
(void) bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
||||
PBD::ID::init ();
|
||||
|
||||
setup_enum_writer ();
|
||||
|
||||
lrdf_init();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,31 +1,81 @@
|
|||
#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;
|
||||
have_saved_bg = false;
|
||||
}
|
||||
|
||||
StatefulButton::StatefulButton (const string& label)
|
||||
: Button (label)
|
||||
{
|
||||
current_state = 0;
|
||||
visual_state = 0;
|
||||
have_saved_bg = false;
|
||||
}
|
||||
|
||||
void
|
||||
StatefulButton::set_colors (const vector<Gdk::Color>& c)
|
||||
StateButton::set_colors (const vector<Gdk::Color>& c)
|
||||
{
|
||||
colors = c;
|
||||
current_state++; // to force transition
|
||||
set_state (current_state - 1);
|
||||
visual_state++; // to force transition
|
||||
set_visual_state (visual_state - 1);
|
||||
}
|
||||
|
||||
void
|
||||
StateButton::set_visual_state (int n)
|
||||
{
|
||||
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
|
||||
StatefulToggleButton::on_realize ()
|
||||
{
|
||||
ToggleButton::on_realize ();
|
||||
|
||||
if (!have_saved_bg) {
|
||||
saved_bg = get_style()->get_bg (STATE_NORMAL);
|
||||
have_saved_bg = true;
|
||||
}
|
||||
|
||||
visual_state++; // to force transition
|
||||
set_visual_state (visual_state - 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -38,43 +88,17 @@ StatefulButton::on_realize ()
|
|||
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)
|
||||
StatefulToggleButton::on_toggled ()
|
||||
{
|
||||
if (is_realized()) {
|
||||
|
||||
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 (get_active()) {
|
||||
set_visual_state (1);
|
||||
} else {
|
||||
set_visual_state (0);
|
||||
}
|
||||
|
||||
current_state = n;
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue