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:
Paul Davis 2007-02-09 03:36:00 +00:00
parent 138b12b1dd
commit 14543eb137
36 changed files with 489 additions and 1073 deletions

View file

@ -143,7 +143,7 @@ style "transport_base" = "medium_bold_text"
style "black_mackie_menu_bar"
{
font_name = "sans bold 7"
font_name = "sans bold 9"
fg[NORMAL] = { 1.0, 1.0, 1.0 }
bg[NORMAL] = { 0, 0, 0 }
}
@ -291,7 +291,8 @@ style "time_button" = "default_buttons_menus"
style "transport_button"
{
bg[ACTIVE] = { 0.50, 1.0, 0.50 }
fg[ACTIVE] = { 0, 0, 0 }
fg[ACTIVE] = { 1, 1, 1 }
fg[PRELIGHT] = { 1, 1, 1 }
}
style "transport_rec_button"
@ -1078,7 +1079,7 @@ widget "*MixerRecordEnableButton" style "mixer_rec_enable_button"
widget "*MixerRecordEnableButton*" style "mixer_rec_enable_button"
widget "*TrackRecordEnableButton" style "track_rec_enable_button"
widget "*TrackRecordEnableButton*" style "track_rec_enable_button"
widget "*TrackMuteButton*" style "mute_button"
widget "*MuteButton*" style "mute_button"
widget "*TrackLoopButton*" style "track_loop_button"
widget "*PanAutomationLineSelector*" style "multiline_combo"
widget "*EditorTimeButton*" style "time_button"
@ -1095,10 +1096,6 @@ widget "*MixerAutomationModeButton*" style "very_small_button"
widget "*MixerAutomationModeButton.*" style "very_small_button"
widget "*MixerAutomationPlaybackButton*" style "very_small_button"
widget "*MixerAutomationPlaybackButton.*" style "very_small_button"
widget "*MixerMuteButton*" style "mixer_mute_button"
widget "*MixerMuteButton.*" style "mixer_mute_button"
widget "*MixerSoloButton*" style "mixer_solo_button"
widget "*MixerSoloButton.*" style "mixer_solo_button"
widget "*MixerNameButton" style "very_small_button"
widget "*MixerNameButtonLabel" style "very_small_button"
widget "*MixerGroupButton" style "very_small_button"

View file

@ -69,7 +69,6 @@
#include "mixer_ui.h"
#include "prompter.h"
#include "opts.h"
#include "keyboard_target.h"
#include "add_route_dialog.h"
#include "new_session_dialog.h"
#include "about.h"
@ -117,16 +116,32 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
/* transport */
time_master_button (_("time\nmaster")),
roll_controllable ("transport roll", *this, TransportControllable::Roll),
stop_controllable ("transport stop", *this, TransportControllable::Stop),
goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
roll_button (roll_controllable),
stop_button (stop_controllable),
goto_start_button (goto_start_controllable),
goto_end_button (goto_end_controllable),
auto_loop_button (auto_loop_controllable),
play_selection_button (play_selection_controllable),
rec_button (rec_controllable),
shuttle_units_button (_("% ")),
punch_in_button (_("Punch In")),
punch_out_button (_("Punch Out")),
auto_return_button (_("Auto Return")),
auto_play_button (_("Autuo Play")),
auto_play_button (_("Auto Play")),
auto_input_button (_("Auto Input")),
click_button (_("Click")),
time_master_button (_("time\nmaster")),
auditioning_alert_button (_("AUDITION")),
solo_alert_button (_("SOLO")),
shown_flag (false)
@ -1061,6 +1076,8 @@ ARDOUR_UI::remove_last_capture()
void
ARDOUR_UI::transport_record ()
{
cerr << "transport record\n";
if (session) {
switch (session->record_status()) {
case Session::Disabled:
@ -1091,11 +1108,11 @@ ARDOUR_UI::transport_roll ()
if (session->get_play_loop()) {
session->request_play_loop (false);
auto_loop_button.set_active (false);
roll_button.set_active (true);
auto_loop_button.set_visual_state (1);
roll_button.set_visual_state (1);
} else if (session->get_play_range ()) {
session->request_play_range (false);
play_selection_button.set_active (false);
play_selection_button.set_visual_state (0);
} else if (rolling) {
session->request_locate (session->last_transport_start(), true);
}
@ -1412,7 +1429,7 @@ ARDOUR_UI::_blink (void *arg)
void
ARDOUR_UI::blink ()
{
Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
}
void
@ -1605,18 +1622,18 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff)
switch (session->record_status()) {
case Session::Enabled:
if (onoff) {
rec_button.set_state (1);
rec_button.set_visual_state (1);
} else {
rec_button.set_state (0);
rec_button.set_visual_state (0);
}
break;
case Session::Recording:
rec_button.set_state (2);
rec_button.set_visual_state (2);
break;
default:
rec_button.set_state (0);
rec_button.set_visual_state (0);
break;
}
}
@ -1629,12 +1646,6 @@ ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
return TRUE;
}
void
ARDOUR_UI::start_keyboard_prefix ()
{
keyboard->start_prefix();
}
void
ARDOUR_UI::save_template ()
@ -2519,3 +2530,82 @@ ARDOUR_UI::store_clock_modes ()
ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
: Controllable (name), ui (u), type(tp)
{
}
void
ARDOUR_UI::TransportControllable::set_value (float val)
{
if (val < 0.5f) {
/* do nothing: these are radio-style actions */
return;
}
char *action = 0;
switch (type) {
case Roll:
action = X_("Roll");
break;
case Stop:
action = X_("Stop");
break;
case GotoStart:
action = X_("Goto Start");
break;
case GotoEnd:
action = X_("Goto End");
break;
case AutoLoop:
action = X_("Loop");
break;
case PlaySelection:
action = X_("Play Selection");
break;
case RecordEnable:
action = X_("Record");
break;
default:
break;
}
if (action == 0) {
return;
}
Glib::RefPtr<Action> act = ActionManager::get_action ("transport", action);
if (act) {
act->activate ();
}
}
float
ARDOUR_UI::TransportControllable::get_value (void) const
{
float val = 0.0f;
switch (type) {
case Roll:
break;
case Stop:
break;
case GotoStart:
break;
case GotoEnd:
break;
case AutoLoop:
break;
case PlaySelection:
break;
case RecordEnable:
break;
default:
break;
}
return val;
}

View file

@ -55,6 +55,7 @@
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/click_box.h>
#include <gtkmm2ext/stateful_button.h>
#include <gtkmm2ext/bindable_button.h>
#include <ardour/ardour.h>
#include <ardour/session.h>
@ -355,18 +356,43 @@ class ARDOUR_UI : public Gtkmm2ext::UI
Gtk::HBox primary_clock_hbox;
Gtk::HBox secondary_clock_hbox;
Gtkmm2ext::StatefulButton roll_button;
Gtkmm2ext::StatefulButton stop_button;
Gtkmm2ext::StatefulButton rewind_button;
Gtkmm2ext::StatefulButton forward_button;
Gtkmm2ext::StatefulButton goto_start_button;
Gtkmm2ext::StatefulButton goto_end_button;
Gtkmm2ext::StatefulButton auto_loop_button;
Gtkmm2ext::StatefulButton play_selection_button;
Gtkmm2ext::StatefulButton rec_button;
struct TransportControllable : public PBD::Controllable {
enum ToggleType {
Roll = 0,
Stop,
RecordEnable,
GotoStart,
GotoEnd,
AutoLoop,
PlaySelection
};
TransportControllable (std::string name, ARDOUR_UI&, ToggleType);
void set_value (float);
float get_value (void) const;
ARDOUR_UI& ui;
ToggleType type;
};
TransportControllable roll_controllable;
TransportControllable stop_controllable;
TransportControllable goto_start_controllable;
TransportControllable goto_end_controllable;
TransportControllable auto_loop_controllable;
TransportControllable play_selection_controllable;
TransportControllable rec_controllable;
BindableButton roll_button;
BindableButton stop_button;
BindableButton goto_start_button;
BindableButton goto_end_button;
BindableButton auto_loop_button;
BindableButton play_selection_button;
BindableButton rec_button;
Gtk::ToggleButton time_master_button;
Gtk::ComboBoxText sync_option_combo;
void sync_option_changed ();
@ -402,12 +428,14 @@ class ARDOUR_UI : public Gtkmm2ext::UI
bool shuttle_grabbed;
double shuttle_fract;
Gtk::ToggleButton punch_in_button;
Gtk::ToggleButton punch_out_button;
Gtk::ToggleButton auto_return_button;
Gtk::ToggleButton auto_play_button;
Gtk::ToggleButton auto_input_button;
Gtk::ToggleButton click_button;
Gtkmm2ext::StatefulToggleButton punch_in_button;
Gtkmm2ext::StatefulToggleButton punch_out_button;
Gtkmm2ext::StatefulToggleButton auto_return_button;
Gtkmm2ext::StatefulToggleButton auto_play_button;
Gtkmm2ext::StatefulToggleButton auto_input_button;
Gtkmm2ext::StatefulToggleButton click_button;
Gtkmm2ext::StatefulToggleButton time_master_button;
Gtk::ToggleButton auditioning_alert_button;
Gtk::ToggleButton solo_alert_button;
@ -585,7 +613,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
/* Keymap handling */
void install_actions ();
void start_keyboard_prefix();
void toggle_record_enable (uint32_t);

View file

@ -38,6 +38,7 @@
#include <ardour/route.h>
#include "ardour_ui.h"
#include "keyboard.h"
#include "public_editor.h"
#include "audio_clock.h"
#include "actions.h"
@ -118,11 +119,11 @@ ARDOUR_UI::setup_adjustables ()
void
ARDOUR_UI::transport_stopped ()
{
stop_button.set_active (true);
stop_button.set_visual_state (1);
roll_button.set_active (false);
play_selection_button.set_active (false);
auto_loop_button.set_active (false);
roll_button.set_visual_state (0);
play_selection_button.set_visual_state (0);
auto_loop_button.set_visual_state (0);
shuttle_fract = 0;
shuttle_box.queue_draw ();
@ -133,22 +134,22 @@ ARDOUR_UI::transport_stopped ()
void
ARDOUR_UI::transport_rolling ()
{
stop_button.set_active (false);
stop_button.set_visual_state (0);
if (session->get_play_range()) {
play_selection_button.set_active (true);
roll_button.set_active (false);
auto_loop_button.set_active (false);
play_selection_button.set_visual_state (1);
roll_button.set_visual_state (0);
auto_loop_button.set_visual_state (0);
} else if (session->get_play_loop ()) {
auto_loop_button.set_active (true);
play_selection_button.set_active (false);
roll_button.set_active (false);
auto_loop_button.set_visual_state (1);
play_selection_button.set_visual_state (0);
roll_button.set_visual_state (0);
} else {
roll_button.set_active (true);
play_selection_button.set_active (false);
auto_loop_button.set_active (false);
roll_button.set_visual_state (1);
play_selection_button.set_visual_state (0);
auto_loop_button.set_visual_state (0);
}
/* reset shuttle controller */
@ -160,21 +161,35 @@ ARDOUR_UI::transport_rolling ()
void
ARDOUR_UI::transport_rewinding ()
{
stop_button.set_active(false);
roll_button.set_active (true);
play_selection_button.set_active (false);
auto_loop_button.set_active (false);
stop_button.set_visual_state (0);
roll_button.set_visual_state (1);
play_selection_button.set_visual_state (0);
auto_loop_button.set_visual_state (0);
}
void
ARDOUR_UI::transport_forwarding ()
{
stop_button.set_active (false);
roll_button.set_active (true);
play_selection_button.set_active (false);
auto_loop_button.set_active (false);
stop_button.set_visual_state (0);
roll_button.set_visual_state (1);
play_selection_button.set_visual_state (0);
auto_loop_button.set_visual_state (0);
}
bool
messagefoo (GdkEventButton* ev)
{
cerr << " roll button pressed\n";
return false;
}
bool
messagefoo2 (GdkEventButton* ev)
{
cerr << " roll button release\n";
return false;
}
void
ARDOUR_UI::setup_transport ()
{
@ -207,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;
}

View file

@ -181,7 +181,6 @@ ARDOUR_UI::install_actions ()
common_actions = ActionGroup::create (X_("Common"));
ActionManager::register_action (main_actions, X_("Windows"), _("Windows"));
ActionManager::register_action (common_actions, X_("Start-Prefix"), _("start prefix"), mem_fun(*this, &ARDOUR_UI::start_keyboard_prefix));
ActionManager::register_action (common_actions, X_("Quit"), _("Quit"), (mem_fun(*this, &ARDOUR_UI::finish)));
/* windows visibility actions */

View file

@ -147,11 +147,11 @@ class Editor : public PublicEditor
void step_mouse_mode (bool next);
Editing::MouseMode current_mouse_mode () { return mouse_mode; }
void add_imageframe_time_axis(const string & track_name, void*) ;
void add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void*) ;
void add_imageframe_time_axis(const std::string & track_name, void*) ;
void add_imageframe_marker_time_axis(const std::string & track_name, TimeAxisView* marked_track, void*) ;
void connect_to_image_compositor() ;
void scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item) ;
TimeAxisView* get_named_time_axis(const string & name) ;
TimeAxisView* get_named_time_axis(const std::string & name) ;
void consider_auditioning (boost::shared_ptr<ARDOUR::Region>);
void hide_a_region (boost::shared_ptr<ARDOUR::Region>);

View file

@ -25,6 +25,7 @@
#include <ardour/audioplaylist.h>
#include "editor.h"
#include "keyboard.h"
#include "public_editor.h"
#include "audio_region_view.h"
#include "audio_streamview.h"

View file

@ -122,6 +122,7 @@ Editor::keyboard_insert_region_list_selection ()
int
Editor::get_prefix (float& val, bool& was_floating)
{
return Keyboard::the_keyboard().get_prefix (val, was_floating);
was_floating = false;
return 1;
}

View file

@ -313,9 +313,11 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
if ((event->button.state & Keyboard::RelevantModifierKeyMask) && event->button.button != 1) {
/* no selection action on modified button-2 or button-3 events */
return;
/* almost no selection action on modified button-2 or button-3 events */
if (item_type != RegionItem && event->button.button != 2) {
return;
}
}
}

View file

@ -33,6 +33,7 @@
#include "editor.h"
#include "editing.h"
#include "keyboard.h"
#include "ardour_ui.h"
#include "gui_thread.h"
#include "actions.h"

View file

@ -23,6 +23,7 @@
#include <cmath>
#include "editor.h"
#include "keyboard.h"
#include "ardour_ui.h"
#include "audio_time_axis.h"
#include "mixer_strip.h"

View file

@ -31,6 +31,7 @@
#include <gtkmm2ext/stop_signal.h>
#include "editor.h"
#include "keyboard.h"
#include "selection.h"
#include "time_axis_view.h"
#include "ardour_ui.h"

View file

@ -25,8 +25,6 @@
#include <ctype.h>
#include <X11/keysymdef.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <pbd/error.h>
@ -49,14 +47,13 @@ guint Keyboard::snap_mod = GDK_MOD3_MASK;
uint32_t Keyboard::Control = GDK_CONTROL_MASK;
uint32_t Keyboard::Shift = GDK_SHIFT_MASK;
uint32_t Keyboard::Alt = GDK_MOD1_MASK;
uint32_t Keyboard::Meta = GDK_MOD2_MASK;
uint32_t Keyboard::Meta;
Keyboard* Keyboard::_the_keyboard = 0;
/* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
GdkModifierType Keyboard::RelevantModifierKeyMask =
GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_MOD3_MASK);
GdkModifierType Keyboard::RelevantModifierKeyMask;
Keyboard::Keyboard ()
@ -65,9 +62,25 @@ Keyboard::Keyboard ()
_the_keyboard = this;
}
collecting_prefix = false;
RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask ();
get_modifier_masks ();
/* figure out Meta */
uint32_t possible_meta[] = { GDK_MOD2_MASK, GDK_MOD3_MASK, GDK_MOD4_MASK, GDK_MOD5_MASK, 0};
int i;
for (i = 0; possible_meta[i]; ++i) {
if (!(RelevantModifierKeyMask & possible_meta[i])) {
break;
}
}
Meta = possible_meta[i];
if (Meta) {
cerr << "Using " << possible_meta[i] << " for Meta\n";
} else {
cerr << "NO Meta\n";
}
snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this);
@ -78,7 +91,6 @@ Keyboard::Keyboard ()
Keyboard::~Keyboard ()
{
gtk_key_snooper_remove (snooper_id);
delete [] modifier_masks;
}
XMLNode&
@ -158,60 +170,6 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
}
if (event->type == GDK_KEY_PRESS) {
bool was_prefix = false;
if (collecting_prefix) {
switch (keyval) {
case GDK_0:
current_prefix += '0';
was_prefix = true;
break;
case GDK_1:
current_prefix += '1';
was_prefix = true;
break;
case GDK_2:
current_prefix += '2';
was_prefix = true;
break;
case GDK_3:
current_prefix += '3';
was_prefix = true;
break;
case GDK_4:
current_prefix += '4';
was_prefix = true;
break;
case GDK_5:
current_prefix += '5';
was_prefix = true;
break;
case GDK_6:
current_prefix += '6';
was_prefix = true;
break;
case GDK_7:
current_prefix += '7';
was_prefix = true;
break;
case GDK_8:
current_prefix += '8';
was_prefix = true;
break;
case GDK_9:
current_prefix += '9';
was_prefix = true;
break;
case GDK_period:
current_prefix += '.';
was_prefix = true;
break;
default:
was_prefix = false;
collecting_prefix = false;
break;
}
}
if (find (state.begin(), state.end(), keyval) == state.end()) {
state.push_back (keyval);
@ -238,441 +196,10 @@ Keyboard::key_is_down (uint32_t keyval)
return find (state.begin(), state.end(), keyval) != state.end();
}
Keyboard::State
Keyboard::translate_key_name (const string& name)
{
string::size_type i;
string::size_type len;
bool at_end;
string::size_type hyphen;
string keyname;
string whatevers_left;
State result;
guint keycode;
i = 0;
len = name.length();
at_end = (len == 0);
while (!at_end) {
whatevers_left = name.substr (i);
if ((hyphen = whatevers_left.find_first_of ('-')) == string::npos) {
/* no hyphen, so use the whole thing */
keyname = whatevers_left;
at_end = true;
} else {
/* There is a hyphen. */
if (hyphen == 0 && whatevers_left.length() == 1) {
/* its the first and only character */
keyname = "-";
at_end = true;
} else {
/* use the text before the hypen */
keyname = whatevers_left.substr (0, hyphen);
if (hyphen == len - 1) {
at_end = true;
} else {
i += hyphen + 1;
at_end = (i >= len);
}
}
}
if (keyname.length() == 1 && isupper (keyname[0])) {
result.push_back (GDK_Shift_L);
}
if ((keycode = gdk_keyval_from_name(get_real_keyname (keyname).c_str())) == GDK_VoidSymbol) {
error << string_compose(_("KeyboardTarget: keyname \"%1\" is unknown."), keyname) << endmsg;
result.clear();
return result;
}
result.push_back (keycode);
}
sort (result.begin(), result.end());
return result;
}
string
Keyboard::get_real_keyname (const string& name)
{
if (name == "Control" || name == "Ctrl") {
return "Control_L";
}
if (name == "Meta" || name == "MetaL") {
return "Meta_L";
}
if (name == "MetaR") {
return "Meta_R";
}
if (name == "Alt" || name == "AltL") {
return "Alt_L";
}
if (name == "AltR") {
return "Alt_R";
}
if (name == "Shift") {
return "Shift_L";
}
if (name == "Shift_R") {
return "Shift_L";
}
if (name == " ") {
return "space";
}
if (name == "!") {
return "exclam";
}
if (name == "\"") {
return "quotedbl";
}
if (name == "#") {
return "numbersign";
}
if (name == "$") {
return "dollar";
}
if (name == "%") {
return "percent";
}
if (name == "&") {
return "ampersand";
}
if (name == "'") {
return "apostrophe";
}
if (name == "'") {
return "quoteright";
}
if (name == "(") {
return "parenleft";
}
if (name == ")") {
return "parenright";
}
if (name == "*") {
return "asterisk";
}
if (name == "+") {
return "plus";
}
if (name == ",") {
return "comma";
}
if (name == "-") {
return "minus";
}
if (name == ".") {
return "period";
}
if (name == "/") {
return "slash";
}
if (name == ":") {
return "colon";
}
if (name == ";") {
return "semicolon";
}
if (name == "<") {
return "less";
}
if (name == "=") {
return "equal";
}
if (name == ">") {
return "greater";
}
if (name == "?") {
return "question";
}
if (name == "@") {
return "at";
}
if (name == "[") {
return "bracketleft";
}
if (name == "\\") {
return "backslash";
}
if (name == "]") {
return "bracketright";
}
if (name == "^") {
return "asciicircum";
}
if (name == "_") {
return "underscore";
}
if (name == "`") {
return "grave";
}
if (name == "`") {
return "quoteleft";
}
if (name == "{") {
return "braceleft";
}
if (name == "|") {
return "bar";
}
if (name == "}") {
return "braceright";
}
if (name == "~") {
return "asciitilde";
}
return name;
}
int
Keyboard::get_prefix (float& val, bool& was_floating)
{
if (current_prefix.length()) {
if (current_prefix.find ('.') != string::npos) {
was_floating = true;
} else {
was_floating = false;
}
if (sscanf (current_prefix.c_str(), "%f", &val) == 1) {
return 0;
}
current_prefix = "";
}
return -1;
}
void
Keyboard::start_prefix ()
{
collecting_prefix = true;
current_prefix = "";
}
void
Keyboard::clear_modifier_state ()
{
modifier_mask = 0;
}
void
Keyboard::check_modifier_state ()
{
char keys[32];
int i, j;
clear_modifier_state ();
XQueryKeymap (GDK_DISPLAY(), keys);
for (i = 0; i < 32; ++i) {
for (j = 0; j < 8; ++j) {
if (keys[i] & (1<<j)) {
modifier_mask |= modifier_masks[(i*8)+j];
}
}
}
}
void
Keyboard::check_meta_numlock (char keycode, guint mod, string modname)
{
guint alternate_meta_mod;
string alternate_meta_modname;
if (mod == Meta) {
guint keysym = XKeycodeToKeysym (GDK_DISPLAY(), keycode, 0);
if (keysym == GDK_Num_Lock) {
switch (mod) {
case GDK_MOD2_MASK:
alternate_meta_mod = GDK_MOD3_MASK;
alternate_meta_modname = "Mod3";
break;
case GDK_MOD3_MASK:
alternate_meta_mod = GDK_MOD2_MASK;
alternate_meta_modname = "Mod2";
break;
case GDK_MOD4_MASK:
alternate_meta_mod = GDK_MOD2_MASK;
alternate_meta_modname = "Mod2";
break;
case GDK_MOD5_MASK:
alternate_meta_mod = GDK_MOD2_MASK;
alternate_meta_modname = "Mod2";
break;
default:
error << string_compose (_("Your system is completely broken - NumLock uses \"%1\""
"as its modifier. This is madness - see the man page "
"for xmodmap to find out how to fix this."),
modname)
<< endmsg;
return;
}
warning << string_compose (_("Your system generates \"%1\" when the NumLock key "
"is pressed. This can cause problems when editing "
"so Ardour will use %2 to mean Meta rather than %1"),
modname, alternate_meta_modname)
<< endmsg;
set_meta_modifier (alternate_meta_mod);
}
}
}
void
Keyboard::get_modifier_masks ()
{
XModifierKeymap *modifiers;
KeyCode *keycode;
int i;
int bound;
XDisplayKeycodes (GDK_DISPLAY(), &min_keycode, &max_keycode);
/* This function builds a lookup table to provide rapid answers to
the question: what, if any, modmask, is associated with a given
keycode ?
*/
modifiers = XGetModifierMapping (GDK_DISPLAY());
modifier_masks = new int32_t [max_keycode+1];
keycode = modifiers->modifiermap;
for (i = 0; i < modifiers->max_keypermod; ++i) { /* shift */
if (*keycode) {
modifier_masks[*keycode] = GDK_SHIFT_MASK;
// cerr << "Shift = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
}
keycode++;
}
for (i = 0; i < modifiers->max_keypermod; ++i) keycode++; /* skip lock */
for (i = 0; i < modifiers->max_keypermod; ++i) { /* control */
if (*keycode) {
modifier_masks[*keycode] = GDK_CONTROL_MASK;
// cerr << "Control = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
}
keycode++;
}
bound = 0;
for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 1 */
if (*keycode) {
modifier_masks[*keycode] = GDK_MOD1_MASK;
// cerr << "Mod1 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
bound++;
}
keycode++;
}
#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
if (bound > 1) {
warning << string_compose (_("You have %1 keys bound to \"mod1\""), bound) << endmsg;
}
#endif
bound = 0;
for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod2 */
if (*keycode) {
modifier_masks[*keycode] = GDK_MOD2_MASK;
check_meta_numlock (*keycode, GDK_MOD2_MASK, "Mod2");
//cerr << "Mod2 = " << std::hex << (int) *keycode << std::dec << " = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
bound++;
}
keycode++;
}
#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
if (bound > 1) {
warning << string_compose (_("You have %1 keys bound to \"mod2\""), bound) << endmsg;
}
#endif
bound = 0;
for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod3 */
if (*keycode) {
modifier_masks[*keycode] = GDK_MOD3_MASK;
check_meta_numlock (*keycode, GDK_MOD3_MASK, "Mod3");
// cerr << "Mod3 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
bound++;
}
keycode++;
}
#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
if (bound > 1) {
warning << string_compose (_("You have %1 keys bound to \"mod3\""), bound) << endmsg;
}
#endif
bound = 0;
for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 4 */
if (*keycode) {
modifier_masks[*keycode] = GDK_MOD4_MASK;
check_meta_numlock (*keycode, GDK_MOD4_MASK, "Mod4");
// cerr << "Mod4 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
bound++;
}
keycode++;
}
#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
if (bound > 1) {
warning << string_compose (_("You have %1 keys bound to \"mod4\""), bound) << endmsg;
}
#endif
bound = 0;
for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 5 */
if (*keycode) {
modifier_masks[*keycode] = GDK_MOD5_MASK;
check_meta_numlock (*keycode, GDK_MOD5_MASK, "Mod5");
// cerr << "Mod5 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl;
bound++;
}
keycode++;
}
#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS
if (bound > 1) {
warning << string_compose (_("You have %1 keys bound to \"mod5\""), bound) << endmsg;
}
#endif
XFreeModifiermap (modifiers);
}
bool
Keyboard::enter_window (GdkEventCrossing *ev, Gtk::Window* win)
{
switch (ev->detail) {
case GDK_NOTIFY_INFERIOR:
break;
case GDK_NOTIFY_VIRTUAL:
/* fallthru */
default:
check_modifier_state ();
}
return FALSE;
return false;
}
bool
@ -697,10 +224,9 @@ Keyboard::leave_window (GdkEventCrossing *ev, Gtk::Window* win)
cerr << "clearing current target\n";
}
state.clear ();
clear_modifier_state ();
}
return FALSE;
return false;
}
void
@ -754,6 +280,7 @@ Keyboard::set_snap_modifier (guint mod)
bool
Keyboard::is_edit_event (GdkEventButton *ev)
{
return (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_BUTTON_RELEASE) &&
(ev->button == Keyboard::edit_button()) &&
((ev->state & RelevantModifierKeyMask) == Keyboard::edit_modifier());

View file

@ -45,13 +45,6 @@ class Keyboard : public sigc::trackable, Stateful
int set_state (const XMLNode&);
typedef vector<uint32_t> State;
int get_prefix(float&, bool& was_floating);
void start_prefix ();
static State translate_key_name (const string&);
static string get_real_keyname (const string& name);
typedef uint32_t ModifierMask;
static uint32_t Control;
@ -101,17 +94,8 @@ class Keyboard : public sigc::trackable, Stateful
private:
static Keyboard* _the_keyboard;
bool _queue_events;
bool _flush_queue;
guint snooper_id;
State state;
bool collecting_prefix;
string current_prefix;
int* modifier_masks;
int modifier_mask;
int min_keycode;
int max_keycode;
static guint edit_but;
static guint edit_mod;
@ -121,13 +105,6 @@ class Keyboard : public sigc::trackable, Stateful
static gint _snooper (GtkWidget*, GdkEventKey*, gpointer);
gint snooper (GtkWidget*, GdkEventKey*);
void queue_event (GdkEventKey*);
void get_modifier_masks ();
void check_modifier_state ();
void clear_modifier_state ();
void check_meta_numlock (char keycode, guint mod, string modname);
};
#endif /* __ardour_keyboard_h__ */

View file

@ -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;
}

View file

@ -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__ */

View file

@ -32,7 +32,6 @@
#include <ardour/session.h>
#include "ardour_dialog.h"
#include "keyboard_target.h"
namespace ARDOUR {
class LocationStack;

View file

@ -416,6 +416,10 @@ int main (int argc, char *argv[])
<< endl;
}
/* some GUI objects need this */
PBD::ID::init ();
try {
ui = new ARDOUR_UI (&argc, &argv, which_ui_rcfile());
} catch (failed_constructor& err) {

View file

@ -30,7 +30,6 @@
#include <gtkmm/fixed.h>
#include <gtkmm/frame.h>
#include "keyboard_target.h"
#include "ardour_dialog.h"
class MeterBridgeStrip;

View file

@ -155,9 +155,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
/* XXX what is this meant to do? */
//meter_point_button.signal_button_release_event().connect (mem_fun (gpm, &GainMeter::meter_release), false);
solo_button->set_name ("MixerSoloButton");
mute_button->set_name ("MixerMuteButton");
hide_button.set_events (hide_button.get_events() & ~(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK));
width_button.unset_flags (Gtk::CAN_FOCUS);

View file

@ -241,9 +241,6 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
bool ignore_speed_adjustment;
string solo_button_name () const { return "MixerSoloButton"; }
string safe_solo_button_name () const { return "MixerSafeSoloButton"; }
void engine_running();
void engine_stopped();

View file

@ -37,6 +37,7 @@
#include <ardour/audio_diskstream.h>
#include <ardour/plugin_manager.h>
#include "keyboard.h"
#include "mixer_ui.h"
#include "mixer_strip.h"
#include "plugin_selector.h"

View file

@ -38,7 +38,6 @@
#include <ardour/ardour.h>
#include <ardour/io.h>
#include "keyboard_target.h"
#include "route_redirect_selection.h"
#include "enums.h"

View file

@ -31,6 +31,7 @@
#include <gtkmm2ext/utils.h>
#include "public_editor.h"
#include "keyboard.h"
#include "mixer_ui.h"
#include "ardour_ui.h"
#include "io_selector.h"

View file

@ -14,7 +14,6 @@
#include <pbd/statefuldestructible.h>
#include "editing.h"
#include "keyboard_target.h"
#include "canvas.h"
#include "selection.h"
@ -73,11 +72,11 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual void set_mouse_mode (Editing::MouseMode, bool force = false) = 0;
virtual void step_mouse_mode (bool next) = 0;
virtual Editing::MouseMode current_mouse_mode () = 0;
virtual void add_imageframe_time_axis(const string & track_name, void*) = 0;
virtual void add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void*) = 0;
virtual void add_imageframe_time_axis(const std::string & track_name, void*) = 0;
virtual void add_imageframe_marker_time_axis(const std::string & track_name, TimeAxisView* marked_track, void*) = 0;
virtual void connect_to_image_compositor() = 0;
virtual void scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item) = 0;
virtual TimeAxisView* get_named_time_axis(const string & name) = 0;
virtual TimeAxisView* get_named_time_axis(const std::string & name) = 0;
virtual void consider_auditioning (boost::shared_ptr<ARDOUR::Region>) = 0;
virtual void set_show_waveforms (bool yn) = 0;
virtual bool show_waveforms() const = 0;

View file

@ -41,7 +41,6 @@
#include "io_selector.h"
#include "ardour_dialog.h"
#include "keyboard_target.h"
#include "redirect_box.h"
#include "route_redirect_selection.h"

View file

@ -105,8 +105,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
ignore_toggle = false;
mute_button->set_name ("TrackMuteButton");
solo_button->set_name ("SoloButton");
edit_group_button.set_name ("TrackGroupButton");
playlist_button.set_name ("TrackPlaylistButton");
automation_button.set_name ("TrackAutomationButton");
@ -124,9 +122,9 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
visual_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::visual_click));
hide_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::hide_click));
solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press));
solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), true);
solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release));
mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press));
mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), true);
mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release));
if (is_track()) {
@ -177,15 +175,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
/* remove focus from the buttons */
automation_button.unset_flags (Gtk::CAN_FOCUS);
solo_button->unset_flags (Gtk::CAN_FOCUS);
mute_button->unset_flags (Gtk::CAN_FOCUS);
edit_group_button.unset_flags (Gtk::CAN_FOCUS);
size_button.unset_flags (Gtk::CAN_FOCUS);
playlist_button.unset_flags (Gtk::CAN_FOCUS);
hide_button.unset_flags (Gtk::CAN_FOCUS);
visual_button.unset_flags (Gtk::CAN_FOCUS);
y_position = -1;
_route->redirects_changed.connect (mem_fun(*this, &RouteTimeAxisView::redirects_changed));
@ -484,7 +473,6 @@ RouteTimeAxisView::build_display_menu ()
static bool __reset_item (RadioMenuItem* item)
{
cerr << "reset item to true\n";
item->set_active ();
return false;
}

View file

@ -63,6 +63,7 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
ignore_toggle = false;
wait_for_release = false;
route_active_menu_item = 0;
was_solo_safe = false;
if (set_color_from_route()) {
set_color (unique_random_color());
@ -75,8 +76,23 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
// mute_button->unset_flags (Gtk::CAN_FOCUS);
// solo_button->unset_flags (Gtk::CAN_FOCUS);
mute_button->set_name ("MuteButton");
solo_button->set_name ("SoloButton");
vector<Gdk::Color> colors;
Gdk::Color c;
/* mute+solo buttons get 2 color states, so add one here to supplement the existing one */
::set_color(c, rgba_from_style (X_("MuteButton"), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
colors.push_back (c);
mute_button->set_colors (colors);
colors.clear ();
/* mute+solo buttons get 2 color states, so add one here to supplement the existing one */
::set_color(c, rgba_from_style (X_("SoloButton"), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
colors.push_back (c);
solo_button->set_colors (colors);
_route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
_route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
@ -93,7 +109,17 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
_session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
colors.clear ();
/* record button has 3 color states, so we set 2 extra here */
::set_color(c, rgba_from_style (X_("TrackRecordEnableButton"), 0xff, 0, 0, 0, "bg", Gtk::STATE_SELECTED, false ));
colors.push_back (c);
::set_color(c, rgba_from_style (X_("TrackRecordEnableButton"), 0xff, 0, 0, 0, "bg", Gtk::STATE_ACTIVE, false ));
colors.push_back (c);
rec_enable_button->set_colors (colors);
update_rec_display ();
}
@ -342,6 +368,25 @@ void
RouteUI::update_solo_display ()
{
bool x;
vector<Gdk::Color> colors;
Gdk::Color c;
if (_route->solo_safe() != was_solo_safe){
if (_route->solo_safe()) {
/* show solo safe */
::set_color(c, rgba_from_style (safe_solo_button_name(), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
solo_button->set_name(safe_solo_button_name());
} else {
::set_color(c, rgba_from_style (solo_button_name(), 0x7f, 0xff, 0x7f, 0, "bg", Gtk::STATE_ACTIVE, false ));
solo_button->set_name(solo_button_name());
}
colors.push_back (c);
solo_button->set_colors (colors);
was_solo_safe = !was_solo_safe;
}
if (solo_button->get_active() != (x = _route->soloed())){
ignore_toggle = true;
@ -349,13 +394,6 @@ RouteUI::update_solo_display ()
ignore_toggle = false;
}
/* show solo safe */
if (_route->solo_safe()){
solo_button->set_name(safe_solo_button_name());
} else {
solo_button->set_name(solo_button_name());
}
}
void

View file

@ -146,7 +146,10 @@ class RouteUI : public virtual AxisView
void update_rec_display ();
void update_mute_display ();
bool was_solo_safe;
void update_solo_display ();
virtual void map_frozen ();
void set_remote_control_id (uint32_t id, Gtk::CheckMenuItem* item);

View file

@ -78,8 +78,8 @@ class Route : public IO
std::string comment() { return _comment; }
void set_comment (std::string str, void *src);
long order_key(std::string name) const;
void set_order_key (std::string name, long n);
long order_key (const char* name) const;
void set_order_key (const char* name, long n);
bool hidden() const { return _flags & Hidden; }
bool master() const { return _flags & MasterOut; }
@ -321,7 +321,16 @@ class Route : public IO
void init ();
static uint32_t order_key_cnt;
typedef std::map<std::string,long> OrderKeys;
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
typedef std::map<const char*,long,ltstr> OrderKeys;
OrderKeys order_keys;
void input_change_handler (IOChange, void *src);

View file

@ -279,8 +279,6 @@ ARDOUR::init (bool use_vst, bool try_optimization)
(void) bindtextdomain(PACKAGE, LOCALEDIR);
PBD::ID::init ();
setup_enum_writer ();
lrdf_init();

View file

@ -79,7 +79,7 @@ Route::init ()
_soloed = false;
_solo_safe = false;
_phase_invert = false;
order_keys[N_("signal")] = order_key_cnt++;
order_keys[strdup (N_("signal"))] = order_key_cnt++;
_active = true;
_silent = false;
_meter_point = MeterPostFader;
@ -115,6 +115,10 @@ Route::~Route ()
{
clear_redirects (this);
for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) {
free ((void*)(i->first));
}
if (_control_outs) {
delete _control_outs;
}
@ -136,21 +140,23 @@ Route::remote_control_id() const
}
long
Route::order_key (string name) const
Route::order_key (const char* name) const
{
OrderKeys::const_iterator i;
if ((i = order_keys.find (name)) == order_keys.end()) {
return -1;
for (i = order_keys.begin(); i != order_keys.end(); ++i) {
if (!strcmp (name, i->first)) {
return i->second;
}
}
return (*i).second;
return -1;
}
void
Route::set_order_key (string name, long n)
Route::set_order_key (const char* name, long n)
{
order_keys[name] = n;
order_keys[strdup(name)] = n;
_session.set_dirty ();
}
@ -1396,7 +1402,7 @@ Route::state(bool full_state)
OrderKeys::iterator x = order_keys.begin();
while (x != order_keys.end()) {
order_string += (*x).first;
order_string += string ((*x).first);
order_string += '=';
snprintf (buf, sizeof(buf), "%ld", (*x).second);
order_string += buf;
@ -1611,7 +1617,7 @@ Route::_set_state (const XMLNode& node, bool call_base)
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
set_order_key (remaining.substr (0, equal), n);
set_order_key (remaining.substr (0, equal).c_str(), n);
}
}

View file

@ -42,7 +42,7 @@ BindableToggleButton::BindableToggleButton (MIDI::Controllable *mc)
}
BindableToggleButton::BindableToggleButton(MIDI::Controllable *mc, const string &label)
: ToggleButton (label),
: StatefulButton (label),
prompter (Gtk::WIN_POS_MOUSE, 30000, false),
midi_control (mc),
bind_button (2),
@ -89,17 +89,6 @@ BindableToggleButton::midi_learn()
}
}
bool
BindableToggleButton::on_button_press_event (GdkEventButton *ev)
{
if ((ev->state & bind_statemask) && ev->button == bind_button) {
midi_learn ();
return true;
}
return false;
}
bool
BindableToggleButton::prompter_hiding (GdkEventAny *ev)
{

View file

@ -30,15 +30,44 @@ namespace PBD {
class Controllable;
}
class BindableToggleButton : public Gtk::ToggleButton
class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
{
public:
BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {}
explicit BindableToggleButton (PBD::Controllable& c, const std::string &label) : Gtk::ToggleButton (label), binding_proxy (c) {}
explicit BindableToggleButton (PBD::Controllable& c, const std::string &label)
: Gtkmm2ext::StatefulToggleButton (label), binding_proxy (c) {}
virtual ~BindableToggleButton() {}
bool on_button_press_event (GdkEventButton *ev) {
return binding_proxy.button_press_handler (ev);
if (!binding_proxy.button_press_handler (ev)) {
return false;
} else {
return true;
}
}
private:
BindingProxy binding_proxy;
};
class BindableButton : public Gtkmm2ext::StatefulButton
{
public:
BindableButton (PBD::Controllable& c) : binding_proxy (c) {}
explicit BindableButton (PBD::Controllable& c, const std::string &label)
: Gtkmm2ext::StatefulButton (label), binding_proxy (c) {}
~BindableButton() {}
bool on_button_press_event (GdkEventButton *ev) {
if (!binding_proxy.button_press_handler (ev)) {
return false;
} else {
return true;
}
}
private:

View file

@ -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);
}
};
};

View file

@ -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;
}