MCP: various work on the button binding GUI

git-svn-id: svn://localhost/ardour2/branches/3.0@11997 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-04-17 20:41:31 +00:00
parent a382da4918
commit b9ff443085
20 changed files with 857 additions and 165 deletions

View file

@ -8,7 +8,7 @@ export ARDOUR_PATH=$TOP/gtk2_ardour/icons:$TOP/gtk2_ardour/pixmaps:$TOP/build/gt
export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie
export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap
export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/gtk2_ardour:. export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/gtk2_ardour:.
export ARDOUR_MCP_DEVINFO_PATH=$TOP/mcp_devices:. export ARDOUR_MCP_PATH=$TOP/mcp:.
if test -d $HOME/gtk/inst ; then if test -d $HOME/gtk/inst ; then
export GTK_PATH=~/.ardour3:$libs/clearlooks-newer export GTK_PATH=~/.ardour3:$libs/clearlooks-newer

View file

@ -51,6 +51,7 @@ CONFIG_VARIABLE (bool, first_midi_bank_is_zero, "diplay-first-midi-bank-as-zero"
CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100) CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100)
CONFIG_VARIABLE (bool, use_tranzport, "use-tranzport", false) CONFIG_VARIABLE (bool, use_tranzport, "use-tranzport", false)
CONFIG_VARIABLE (std::string, mackie_device_name, "mackie-device-name", "Mackie Control Universal Pro") CONFIG_VARIABLE (std::string, mackie_device_name, "mackie-device-name", "Mackie Control Universal Pro")
CONFIG_VARIABLE (std::string, mackie_device_profile, "mackie-device-profile", "default")
CONFIG_VARIABLE (RemoteModel, remote_model, "remote-model", MixerOrdered) CONFIG_VARIABLE (RemoteModel, remote_model, "remote-model", MixerOrdered)
/* disk operations */ /* disk operations */

View file

@ -246,9 +246,23 @@ ActionManager::get_widget (const char * name)
RefPtr<Action> RefPtr<Action>
ActionManager::get_action (const char* path) ActionManager::get_action (const char* path)
{ {
if (!path) {
return RefPtr<Action>();
}
char copy[strlen(path)+1]; char copy[strlen(path)+1];
strcpy (copy, path);
char *slash = strchr (copy, '/'); if (*path == '/') {
const char* cslash = strchr (path, '/');
if (!cslash) {
return RefPtr<Action> ();
}
strcpy (copy, cslash+1);
} else {
strcpy (copy, path);
}
char* slash = strchr (copy, '/');
if (!slash) { if (!slash) {
return RefPtr<Action> (); return RefPtr<Action> ();
} }
@ -290,6 +304,32 @@ ActionManager::get_action (const char* group_name, const char* action_name)
return act; return act;
} }
RefPtr<Action>
ActionManager::get_action_from_name (const char* name)
{
/* the C++ API for functions used here appears to be broken in
gtkmm2.6, so we fall back to the C level.
*/
GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
GList* node;
GList* acts;
for (node = list; node; node = g_list_next (node)) {
GtkActionGroup* group = (GtkActionGroup*) node->data;
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
GtkAction* action = (GtkAction*) acts->data;
if (!strcmp (gtk_action_get_name (action), name)) {
return Glib::wrap (action, true);
}
}
}
return RefPtr<Action>();
}
void void
ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state) ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
{ {

View file

@ -43,6 +43,7 @@ namespace ActionManager {
extern Gtk::Widget* get_widget (const char * name); extern Gtk::Widget* get_widget (const char * name);
extern Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name); extern Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name);
extern Glib::RefPtr<Gtk::Action> get_action (const char* path); extern Glib::RefPtr<Gtk::Action> get_action (const char* path);
extern Glib::RefPtr<Gtk::Action> get_action_from_name (const char* name);
extern void do_action (const char* group, const char* name); extern void do_action (const char* group, const char* name);
extern void set_toggle_action (const char* group, const char* name, bool); extern void set_toggle_action (const char* group, const char* name, bool);

View file

@ -17,6 +17,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <glib.h>
#include "button.h" #include "button.h"
#include "surface.h" #include "surface.h"
#include "control_group.h" #include "control_group.h"
@ -37,102 +39,203 @@ Button::factory (Surface& surface, Button::ID bid, int id, const std::string& na
int int
Button::name_to_id (const std::string& name) Button::name_to_id (const std::string& name)
{ {
if (name == "IO") { return IO; } if (!g_strcasecmp (name.c_str(), "IO")) { return IO; }
if (name == "Sends") { return Sends; } if (!g_strcasecmp (name.c_str(), "Sends")) { return Sends; }
if (name == "Pan") { return Pan; } if (!g_strcasecmp (name.c_str(), "Pan")) { return Pan; }
if (name == "Plugin") { return Plugin; } if (!g_strcasecmp (name.c_str(), "Plugin")) { return Plugin; }
if (name == "Eq") { return Eq; } if (!g_strcasecmp (name.c_str(), "Eq")) { return Eq; }
if (name == "Dyn") { return Dyn; } if (!g_strcasecmp (name.c_str(), "Dyn")) { return Dyn; }
if (name == "Left") { return Left; } if (!g_strcasecmp (name.c_str(), "Left")) { return Left; }
if (name == "Right") { return Right; } if (!g_strcasecmp (name.c_str(), "Right")) { return Right; }
if (name == "ChannelLeft") { return ChannelLeft; } if (!g_strcasecmp (name.c_str(), "ChannelLeft")) { return ChannelLeft; }
if (name == "ChannelRight") { return ChannelRight; } if (!g_strcasecmp (name.c_str(), "ChannelRight")) { return ChannelRight; }
if (name == "Flip") { return Flip; } if (!g_strcasecmp (name.c_str(), "Flip")) { return Flip; }
if (name == "Edit") { return Edit; } if (!g_strcasecmp (name.c_str(), "Edit")) { return Edit; }
if (name == "NameValue") { return NameValue; } if (!g_strcasecmp (name.c_str(), "NameValue")) { return NameValue; }
if (name == "TimecodeBeats") { return TimecodeBeats; } if (!g_strcasecmp (name.c_str(), "TimecodeBeats")) { return TimecodeBeats; }
if (name == "F1") { return F1; } if (!g_strcasecmp (name.c_str(), "F1")) { return F1; }
if (name == "F2") { return F2; } if (!g_strcasecmp (name.c_str(), "F2")) { return F2; }
if (name == "F3") { return F3; } if (!g_strcasecmp (name.c_str(), "F3")) { return F3; }
if (name == "F4") { return F4; } if (!g_strcasecmp (name.c_str(), "F4")) { return F4; }
if (name == "F5") { return F5; } if (!g_strcasecmp (name.c_str(), "F5")) { return F5; }
if (name == "F6") { return F6; } if (!g_strcasecmp (name.c_str(), "F6")) { return F6; }
if (name == "F7") { return F7; } if (!g_strcasecmp (name.c_str(), "F7")) { return F7; }
if (name == "F8") { return F8; } if (!g_strcasecmp (name.c_str(), "F8")) { return F8; }
if (name == "F9") { return F9; } if (!g_strcasecmp (name.c_str(), "F9")) { return F9; }
if (name == "F10") { return F10; } if (!g_strcasecmp (name.c_str(), "F10")) { return F10; }
if (name == "F11") { return F11; } if (!g_strcasecmp (name.c_str(), "F11")) { return F11; }
if (name == "F12") { return F12; } if (!g_strcasecmp (name.c_str(), "F12")) { return F12; }
if (name == "F13") { return F13; } if (!g_strcasecmp (name.c_str(), "F13")) { return F13; }
if (name == "F14") { return F14; } if (!g_strcasecmp (name.c_str(), "F14")) { return F14; }
if (name == "F15") { return F15; } if (!g_strcasecmp (name.c_str(), "F15")) { return F15; }
if (name == "F16") { return F16; } if (!g_strcasecmp (name.c_str(), "F16")) { return F16; }
if (name == "Shift") { return Shift; } if (!g_strcasecmp (name.c_str(), "Shift")) { return Shift; }
if (name == "Option") { return Option; } if (!g_strcasecmp (name.c_str(), "Option")) { return Option; }
if (name == "Ctrl") { return Ctrl; } if (!g_strcasecmp (name.c_str(), "Ctrl")) { return Ctrl; }
if (name == "CmdAlt") { return CmdAlt; } if (!g_strcasecmp (name.c_str(), "CmdAlt")) { return CmdAlt; }
if (name == "On") { return On; } if (!g_strcasecmp (name.c_str(), "On")) { return On; }
if (name == "RecReady") { return RecReady; } if (!g_strcasecmp (name.c_str(), "RecReady")) { return RecReady; }
if (name == "Undo") { return Undo; } if (!g_strcasecmp (name.c_str(), "Undo")) { return Undo; }
if (name == "Save") { return Save; } if (!g_strcasecmp (name.c_str(), "Save")) { return Save; }
if (name == "Touch") { return Touch; } if (!g_strcasecmp (name.c_str(), "Touch")) { return Touch; }
if (name == "Redo") { return Redo; } if (!g_strcasecmp (name.c_str(), "Redo")) { return Redo; }
if (name == "Marker") { return Marker; } if (!g_strcasecmp (name.c_str(), "Marker")) { return Marker; }
if (name == "Enter") { return Enter; } if (!g_strcasecmp (name.c_str(), "Enter")) { return Enter; }
if (name == "Cancel") { return Cancel; } if (!g_strcasecmp (name.c_str(), "Cancel")) { return Cancel; }
if (name == "Mixer") { return Mixer; } if (!g_strcasecmp (name.c_str(), "Mixer")) { return Mixer; }
if (name == "FrmLeft") { return FrmLeft; } if (!g_strcasecmp (name.c_str(), "FrmLeft")) { return FrmLeft; }
if (name == "FrmRight") { return FrmRight; } if (!g_strcasecmp (name.c_str(), "FrmRight")) { return FrmRight; }
if (name == "Loop") { return Loop; } if (!g_strcasecmp (name.c_str(), "Loop")) { return Loop; }
if (name == "PunchIn") { return PunchIn; } if (!g_strcasecmp (name.c_str(), "PunchIn")) { return PunchIn; }
if (name == "PunchOut") { return PunchOut; } if (!g_strcasecmp (name.c_str(), "PunchOut")) { return PunchOut; }
if (name == "Home") { return Home; } if (!g_strcasecmp (name.c_str(), "Home")) { return Home; }
if (name == "End") { return End; } if (!g_strcasecmp (name.c_str(), "End")) { return End; }
if (name == "Rewind") { return Rewind; } if (!g_strcasecmp (name.c_str(), "Rewind")) { return Rewind; }
if (name == "Ffwd") { return Ffwd; } if (!g_strcasecmp (name.c_str(), "Ffwd")) { return Ffwd; }
if (name == "Stop") { return Stop; } if (!g_strcasecmp (name.c_str(), "Stop")) { return Stop; }
if (name == "Play") { return Play; } if (!g_strcasecmp (name.c_str(), "Play")) { return Play; }
if (name == "Record") { return Record; } if (!g_strcasecmp (name.c_str(), "Record")) { return Record; }
if (name == "CursorUp") { return CursorUp; } if (!g_strcasecmp (name.c_str(), "CursorUp")) { return CursorUp; }
if (name == "CursorDown") { return CursorDown; } if (!g_strcasecmp (name.c_str(), "CursorDown")) { return CursorDown; }
if (name == "CursorLeft") { return CursorLeft; } if (!g_strcasecmp (name.c_str(), "CursorLeft")) { return CursorLeft; }
if (name == "CursorRight") { return CursorRight; } if (!g_strcasecmp (name.c_str(), "CursorRight")) { return CursorRight; }
if (name == "Zoom") { return Zoom; } if (!g_strcasecmp (name.c_str(), "Zoom")) { return Zoom; }
if (name == "Scrub") { return Scrub; } if (!g_strcasecmp (name.c_str(), "Scrub")) { return Scrub; }
if (name == "UserA") { return UserA; } if (!g_strcasecmp (name.c_str(), "UserA")) { return UserA; }
if (name == "UserB") { return UserB; } if (!g_strcasecmp (name.c_str(), "UserB")) { return UserB; }
if (name == "Snapshot") { return Snapshot; } if (!g_strcasecmp (name.c_str(), "Snapshot")) { return Snapshot; }
if (name == "Read") { return Read; } if (!g_strcasecmp (name.c_str(), "Read")) { return Read; }
if (name == "Write") { return Write; } if (!g_strcasecmp (name.c_str(), "Write")) { return Write; }
if (name == "FdrGroup") { return FdrGroup; } if (!g_strcasecmp (name.c_str(), "FdrGroup")) { return FdrGroup; }
if (name == "ClearSolo") { return ClearSolo; } if (!g_strcasecmp (name.c_str(), "ClearSolo")) { return ClearSolo; }
if (name == "Track") { return Track; } if (!g_strcasecmp (name.c_str(), "Track")) { return Track; }
if (name == "Send") { return Send; } if (!g_strcasecmp (name.c_str(), "Send")) { return Send; }
if (name == "MidiTracks") { return MidiTracks; } if (!g_strcasecmp (name.c_str(), "MidiTracks")) { return MidiTracks; }
if (name == "Inputs") { return Inputs; } if (!g_strcasecmp (name.c_str(), "Inputs")) { return Inputs; }
if (name == "AudioTracks") { return AudioTracks; } if (!g_strcasecmp (name.c_str(), "AudioTracks")) { return AudioTracks; }
if (name == "AudioInstruments") { return AudioInstruments; } if (!g_strcasecmp (name.c_str(), "AudioInstruments")) { return AudioInstruments; }
if (name == "Aux") { return Aux; } if (!g_strcasecmp (name.c_str(), "Aux")) { return Aux; }
if (name == "Busses") { return Busses; } if (!g_strcasecmp (name.c_str(), "Busses")) { return Busses; }
if (name == "Outputs") { return Outputs; } if (!g_strcasecmp (name.c_str(), "Outputs")) { return Outputs; }
if (name == "User") { return User; } if (!g_strcasecmp (name.c_str(), "User")) { return User; }
if (name == "Trim") { return Trim; } if (!g_strcasecmp (name.c_str(), "Trim")) { return Trim; }
if (name == "Latch") { return Latch; } if (!g_strcasecmp (name.c_str(), "Latch")) { return Latch; }
if (name == "Grp") { return Grp; } if (!g_strcasecmp (name.c_str(), "Grp")) { return Grp; }
if (name == "Nudge") { return Nudge; } if (!g_strcasecmp (name.c_str(), "Nudge")) { return Nudge; }
if (name == "Drop") { return Drop; } if (!g_strcasecmp (name.c_str(), "Drop")) { return Drop; }
if (name == "Replace") { return Replace; } if (!g_strcasecmp (name.c_str(), "Replace")) { return Replace; }
if (name == "Click") { return Click; } if (!g_strcasecmp (name.c_str(), "Click")) { return Click; }
if (name == "View") { return View; } if (!g_strcasecmp (name.c_str(), "View")) { return View; }
/* Strip buttons */ /* Strip buttons */
if (name == "RecEnable") { return RecEnable; } if (!g_strcasecmp (name.c_str(), "RecEnable")) { return RecEnable; }
if (name == "Solo") { return Solo; } if (!g_strcasecmp (name.c_str(), "Solo")) { return Solo; }
if (name == "Mute") { return Mute; } if (!g_strcasecmp (name.c_str(), "Mute")) { return Mute; }
if (name == "Select") { return Select; } if (!g_strcasecmp (name.c_str(), "Select")) { return Select; }
if (name == "VSelect") { return VSelect; } if (!g_strcasecmp (name.c_str(), "VSelect")) { return VSelect; }
if (name == "FaderTouch") { return FaderTouch; } if (!g_strcasecmp (name.c_str(), "FaderTouch")) { return FaderTouch; }
return -1; return -1;
} }
std::string
Button::id_to_name (Button::ID id)
{
if (id == IO) { return "IO"; }
if (id == Sends) { return "Sends"; }
if (id == Pan) { return "Pan"; }
if (id == Plugin) { return "Plugin"; }
if (id == Eq) { return "Eq"; }
if (id == Dyn) { return "Dyn"; }
if (id == Left) { return "Bank Left"; }
if (id == Right) { return "Bank Right"; }
if (id == ChannelLeft) { return "Channel Left"; }
if (id == ChannelRight) { return "Channel Right"; }
if (id == Flip) { return "Flip"; }
if (id == Edit) { return "Edit"; }
if (id == NameValue) { return "Name/Value"; }
if (id == TimecodeBeats) { return "Timecode/Beats"; }
if (id == F1) { return "F1"; }
if (id == F2) { return "F2"; }
if (id == F3) { return "F3"; }
if (id == F4) { return "F4"; }
if (id == F5) { return "F5"; }
if (id == F6) { return "F6"; }
if (id == F7) { return "F7"; }
if (id == F8) { return "F8"; }
if (id == F9) { return "F9"; }
if (id == F10) { return "F10"; }
if (id == F11) { return "F11"; }
if (id == F12) { return "F12"; }
if (id == F13) { return "F13"; }
if (id == F14) { return "F14"; }
if (id == F15) { return "F15"; }
if (id == F16) { return "F16"; }
if (id == Shift) { return "Shift"; }
if (id == Option) { return "Option"; }
if (id == Ctrl) { return "Ctrl"; }
if (id == CmdAlt) { return "CmdAlt"; }
if (id == On) { return "On"; }
if (id == RecReady) { return "Record"; }
if (id == Undo) { return "Undo"; }
if (id == Save) { return "Save"; }
if (id == Touch) { return "Touch"; }
if (id == Redo) { return "Redo"; }
if (id == Marker) { return "Marker"; }
if (id == Enter) { return "Enter"; }
if (id == Cancel) { return "Cancel"; }
if (id == Mixer) { return "Mixer"; }
if (id == FrmLeft) { return "Frm Left"; }
if (id == FrmRight) { return "Frm Right"; }
if (id == Loop) { return "Loop"; }
if (id == PunchIn) { return "Punch In"; }
if (id == PunchOut) { return "Punch Out"; }
if (id == Home) { return "Home"; }
if (id == End) { return "End"; }
if (id == Rewind) { return "Rewind"; }
if (id == Ffwd) { return "FFwd"; }
if (id == Stop) { return "Stop"; }
if (id == Play) { return "Play"; }
if (id == Record) { return "Record"; }
if (id == CursorUp) { return "Cursor Up"; }
if (id == CursorDown) { return "Cursor Down"; }
if (id == CursorLeft) { return "Cursor Left"; }
if (id == CursorRight) { return "Cursor Right"; }
if (id == Zoom) { return "Zoom"; }
if (id == Scrub) { return "Scrub"; }
if (id == UserA) { return "User A"; }
if (id == UserB) { return "User B"; }
if (id == Snapshot) { return "Snapshot"; }
if (id == Read) { return "Read"; }
if (id == Write) { return "Write"; }
if (id == FdrGroup) { return "Fader Group"; }
if (id == ClearSolo) { return "Clear Solo"; }
if (id == Track) { return "Track"; }
if (id == Send) { return "Send"; }
if (id == MidiTracks) { return "Midi Tracks"; }
if (id == Inputs) { return "Inputs"; }
if (id == AudioTracks) { return "Audio Tracks"; }
if (id == AudioInstruments) { return "Audio Instruments"; }
if (id == Aux) { return "Aux"; }
if (id == Busses) { return "Busses"; }
if (id == Outputs) { return "Outputs"; }
if (id == User) { return "User"; }
if (id == Trim) { return "Trim"; }
if (id == Latch) { return "Latch"; }
if (id == Grp) { return "Group"; }
if (id == Nudge) { return "Nudge"; }
if (id == Drop) { return "Drop"; }
if (id == Replace) { return "Replace"; }
if (id == Click) { return "Click"; }
if (id == View) { return "View"; }
if (id == RecEnable) { return "Record Enable"; }
if (id == Solo) { return "Solo"; }
if (id == Mute) { return "Mute"; }
if (id == Select) { return "Select"; }
if (id == VSelect) { return "V-Pot"; }
if (id == FaderTouch) { return "Fader Touch"; }
return "???";
}

View file

@ -120,12 +120,14 @@ public:
Trim, Trim,
Latch, Latch,
Grp, Grp,
Nudge, Nudge,
Drop, Drop,
Replace, Replace,
Click, Click,
View, View,
FinalGlobalButton,
/* Strip buttons */ /* Strip buttons */
RecEnable, RecEnable,
@ -149,6 +151,7 @@ public:
static Control* factory (Surface& surface, Button::ID bid, int id, const std::string&, Group& group); static Control* factory (Surface& surface, Button::ID bid, int id, const std::string&, Group& group);
static int name_to_id (const std::string& name); static int name_to_id (const std::string& name);
static std::string id_to_name (Button::ID);
private: private:
ID _bid; /* device independent button ID */ ID _bid; /* device independent button ID */

View file

@ -182,7 +182,7 @@ DeviceInfo::shared_buttons ()
_global_buttons[Button::UserA] = GlobalButtonInfo ("user a", "user", 0x66); _global_buttons[Button::UserA] = GlobalButtonInfo ("user a", "user", 0x66);
_global_buttons[Button::UserB] = GlobalButtonInfo ("user b", "user", 0x67); _global_buttons[Button::UserB] = GlobalButtonInfo ("user b", "user", 0x67);
_strip_buttons[Button::RecEnable], StripButtonInfo (0x0, "recenable"); _strip_buttons[Button::RecEnable] = StripButtonInfo (0x0, "recenable");
_strip_buttons[Button::Solo] = StripButtonInfo (0x08, "solo"); _strip_buttons[Button::Solo] = StripButtonInfo (0x08, "solo");
_strip_buttons[Button::Mute] = StripButtonInfo (0x10, "mute"); _strip_buttons[Button::Mute] = StripButtonInfo (0x10, "mute");
_strip_buttons[Button::Select] = StripButtonInfo (0x18, "select"); _strip_buttons[Button::Select] = StripButtonInfo (0x18, "select");
@ -387,9 +387,9 @@ DeviceInfo::has_touch_sense_faders () const
return _has_touch_sense_faders; return _has_touch_sense_faders;
} }
static const char * const devinfo_env_variable_name = "ARDOUR_MCP_DEVINFO_PATH"; static const char * const devinfo_env_variable_name = "ARDOUR_MCP_PATH";
static const char* const devinfo_dir_name = "mcp_devices"; static const char* const devinfo_dir_name = "mcp";
static const char* const devinfo_suffix = ".xml"; static const char* const devinfo_suffix = ".device";
static sys::path static sys::path
system_devinfo_search_path () system_devinfo_search_path ()

View file

@ -96,27 +96,6 @@ class DeviceInfo
void shared_buttons (); void shared_buttons ();
}; };
class DeviceProfile
{
public:
DeviceProfile (DeviceInfo& info);
~DeviceProfile();
const std::string& get_f_action (uint32_t fn, int modifier_state);
void set_f_action (uint32_t fn, int modifier_state, const std::string&);
private:
struct KeyActions {
std::string plain;
std::string control;
std::string shift;
std::string option;
std::string cmdalt;
std::string shiftcontrol;
};
typedef std::map<Button::ID,KeyActions> KeyActionMap;
};
} }

View file

@ -0,0 +1,323 @@
/*
Copyright (C) 2006,2007 John Anderson
Copyright (C) 2012 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.
*/
#include <cstdlib>
#include <cstring>
#include <glibmm/miscutils.h>
#include "pbd/xml++.h"
#include "pbd/error.h"
#include "pbd/pathscanner.h"
#include "ardour/filesystem_paths.h"
#include "mackie_control_protocol.h"
#include "device_profile.h"
#include "i18n.h"
using namespace Mackie;
using namespace PBD;
using namespace ARDOUR;
using std::string;
using std::vector;
std::map<std::string,DeviceProfile> DeviceProfile::device_profiles;
DeviceProfile::DeviceProfile (const string& n)
: _name (n)
{
}
DeviceProfile::~DeviceProfile()
{
}
static const char * const devprofile_env_variable_name = "ARDOUR_MCP_PATH";
static const char* const devprofile_dir_name = "mcp";
static const char* const devprofile_suffix = ".profile";
static sys::path
system_devprofile_search_path ()
{
bool devprofile_path_defined = false;
sys::path spath_env (Glib::getenv (devprofile_env_variable_name, devprofile_path_defined));
if (devprofile_path_defined) {
return spath_env;
}
SearchPath spath (system_data_search_path());
spath.add_subdirectory_to_paths(devprofile_dir_name);
// just return the first directory in the search path that exists
SearchPath::const_iterator i = std::find_if(spath.begin(), spath.end(), sys::exists);
if (i == spath.end()) return sys::path();
return *i;
}
static sys::path
user_devprofile_directory ()
{
sys::path p(user_config_directory());
p /= devprofile_dir_name;
return p;
}
static bool
devprofile_filter (const string &str, void */*arg*/)
{
return (str.length() > strlen(devprofile_suffix) &&
str.find (devprofile_suffix) == (str.length() - strlen (devprofile_suffix)));
}
void
DeviceProfile::reload_device_profiles ()
{
DeviceProfile dp;
vector<string> s;
vector<string *> *devprofiles;
PathScanner scanner;
SearchPath spath (system_devprofile_search_path());
spath += user_devprofile_directory ();
devprofiles = scanner (spath.to_string(), devprofile_filter, 0, false, true);
device_profiles.clear ();
if (!devprofiles) {
error << "No MCP device info files found using " << spath.to_string() << endmsg;
std::cerr << "No MCP device info files found using " << spath.to_string() << std::endl;
return;
}
if (devprofiles->empty()) {
error << "No MCP device info files found using " << spath.to_string() << endmsg;
std::cerr << "No MCP device info files found using " << spath.to_string() << std::endl;
return;
}
for (vector<string*>::iterator i = devprofiles->begin(); i != devprofiles->end(); ++i) {
string fullpath = *(*i);
XMLTree tree;
std::cerr << "Loading " << fullpath << std::endl;
if (!tree.read (fullpath.c_str())) {
std::cerr << "XML read failed\n";
continue;
}
XMLNode* root = tree.root ();
if (!root) {
std::cerr << "no root\n";
continue;
}
if (dp.set_state (*root, 3000) == 0) { /* version is ignored for now */
std::cerr << "saved profile " << dp.name() << std::endl;
device_profiles[dp.name()] = dp;
}
}
delete devprofiles;
}
int
DeviceProfile::set_state (const XMLNode& node, int /* version */)
{
const XMLProperty* prop;
const XMLNode* child;
if (node.name() != "MackieDeviceProfile") {
std::cerr << "wrong root\n";
return -1;
}
/* name is mandatory */
if ((child = node.child ("Name")) == 0 || (prop = child->property ("value")) == 0) {
std::cerr << "no name\n";
return -1;
} else {
_name = prop->value();
std::cerr << "got name " << _name << std::endl;
}
if ((child = node.child ("Buttons")) != 0) {
XMLNodeConstIterator i;
const XMLNodeList& nlist (child->children());
for (i = nlist.begin(); i != nlist.end(); ++i) {
if ((*i)->name() == "Button") {
std::cerr << "foudn a button\n";
if ((prop = (*i)->property ("name")) == 0) {
error << string_compose ("Button without name in device profile \"%1\" - ignored", _name) << endmsg;
continue;
}
int id = Button::name_to_id (prop->value());
if (id < 0) {
error << string_compose ("Unknow button ID \"%1\"", prop->value()) << endmsg;
continue;
}
Button::ID bid = (Button::ID) id;
ButtonActionMap::iterator b = _button_map.find (bid);
if (b == _button_map.end()) {
b = _button_map.insert (_button_map.end(), std::pair<Button::ID,ButtonActions> (bid, ButtonActions()));
}
std::cerr << "checking bindings for button " << bid << std::endl;
if ((prop = (*i)->property ("plain")) != 0) {
std::cerr << "Loaded binding between " << bid << " and " << prop->value() << std::endl;
b->second.plain = prop->value ();
}
if ((prop = (*i)->property ("control")) != 0) {
b->second.control = prop->value ();
}
if ((prop = (*i)->property ("shift")) != 0) {
b->second.shift = prop->value ();
}
if ((prop = (*i)->property ("option")) != 0) {
b->second.option = prop->value ();
}
if ((prop = (*i)->property ("cmdalt")) != 0) {
b->second.cmdalt = prop->value ();
}
if ((prop = (*i)->property ("shiftcontrol")) != 0) {
b->second.shiftcontrol = prop->value ();
}
}
}
} else {
std::cerr << " no buttons\n";
}
return 0;
}
XMLNode&
DeviceProfile::get_state () const
{
XMLNode* node = new XMLNode ("MackieDeviceProfile");
node->add_property ("name", _name);
if (_button_map.empty()) {
return *node;
}
XMLNode* buttons = new XMLNode ("Buttons");
node->add_child_nocopy (*buttons);
for (ButtonActionMap::const_iterator b = _button_map.begin(); b != _button_map.end(); ++b) {
XMLNode* n = new XMLNode ("Button");
n->add_property ("name", b->first);
if (!b->second.plain.empty()) {
n->add_property ("plain", b->second.plain);
}
if (!b->second.control.empty()) {
n->add_property ("control", b->second.control);
}
if (!b->second.shift.empty()) {
n->add_property ("shift", b->second.shift);
}
if (!b->second.option.empty()) {
n->add_property ("option", b->second.option);
}
if (!b->second.cmdalt.empty()) {
n->add_property ("cmdalt", b->second.cmdalt);
}
if (!b->second.shiftcontrol.empty()) {
n->add_property ("shiftcontrol", b->second.shiftcontrol);
}
buttons->add_child_nocopy (*n);
}
return *node;
}
string
DeviceProfile::get_button_action (Button::ID id, int modifier_state) const
{
ButtonActionMap::const_iterator i = _button_map.find (id);
if (i == _button_map.end()) {
return string();
}
if (modifier_state == MackieControlProtocol::MODIFIER_CONTROL) {
return i->second.control;
} else if (modifier_state == MackieControlProtocol::MODIFIER_SHIFT) {
return i->second.shift;
} else if (modifier_state == MackieControlProtocol::MODIFIER_OPTION) {
return i->second.option;
} else if (modifier_state == MackieControlProtocol::MODIFIER_CMDALT) {
return i->second.cmdalt;
} else if (modifier_state == (MackieControlProtocol::MODIFIER_CONTROL|MackieControlProtocol::MODIFIER_SHIFT)) {
return i->second.shiftcontrol;
}
return i->second.plain;
}
void
DeviceProfile::set_button_action (Button::ID id, int modifier_state, const string& action)
{
ButtonActionMap::iterator i = _button_map.find (id);
if (i == _button_map.end()) {
return;
}
if (modifier_state == MackieControlProtocol::MODIFIER_CONTROL) {
i->second.control = action;
} else if (modifier_state == MackieControlProtocol::MODIFIER_SHIFT) {
i->second.shift = action;
} else if (modifier_state == MackieControlProtocol::MODIFIER_OPTION) {
i->second.option = action;
} else if (modifier_state == MackieControlProtocol::MODIFIER_CMDALT) {
i->second.cmdalt = action;
} else if (modifier_state == (MackieControlProtocol::MODIFIER_CONTROL|MackieControlProtocol::MODIFIER_SHIFT)) {
i->second.shiftcontrol = action;
}
if (modifier_state == 0) {
i->second.plain = action;
}
}
const string&
DeviceProfile::name() const
{
return _name;
}

View file

@ -0,0 +1,68 @@
/*
Copyright (C) 2012 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.
*/
#ifndef __ardour_mackie_control_protocol_device_profile_h__
#define __ardour_mackie_control_protocol_device_profile_h__
#include <iostream>
#include <stdint.h>
#include <string>
#include <map>
#include "button.h"
class XMLNode;
namespace Mackie {
class DeviceProfile
{
public:
DeviceProfile (const std::string& name = "");
~DeviceProfile();
std::string get_button_action (Button::ID, int modifier_state) const;
void set_button_action (Button::ID, int modifier_state, const std::string&);
const std::string& name() const;
static void reload_device_profiles ();
static std::map<std::string,DeviceProfile> device_profiles;
private:
struct ButtonActions {
std::string plain;
std::string control;
std::string shift;
std::string option;
std::string cmdalt;
std::string shiftcontrol;
};
typedef std::map<Button::ID,ButtonActions> ButtonActionMap;
std::string _name;
ButtonActionMap _button_map;
int set_state (const XMLNode&, int version);
XMLNode& get_state () const;
};
}
#endif /* __ardour_mackie_control_protocol_device_profile_h__ */

View file

@ -71,19 +71,32 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
Gtk::Table* table = Gtk::manage (new Gtk::Table (2, 2)); Gtk::Table* table = Gtk::manage (new Gtk::Table (2, 2));
table->set_spacings (4); table->set_spacings (4);
table->attach (*manage (new Gtk::Label (_("Surface type:"))), 0, 1, 0, 1, AttachOptions(FILL|EXPAND), AttachOptions(0)); table->attach (*manage (new Gtk::Label (_("Device Type:"))), 0, 1, 0, 1, AttachOptions(FILL|EXPAND), AttachOptions(0));
table->attach (_surface_combo, 1, 2, 0, 1, AttachOptions(FILL|EXPAND), AttachOptions(0)); table->attach (_surface_combo, 1, 2, 0, 1, AttachOptions(FILL|EXPAND), AttachOptions(0));
table->attach (*manage (new Gtk::Label (_("Profile/Settings:"))), 0, 1, 1, 2, AttachOptions(FILL|EXPAND), AttachOptions(0));
table->attach (_profile_combo, 1, 2, 1, 2, AttachOptions(FILL|EXPAND), AttachOptions(0));
vector<string> surfaces; vector<string> surfaces;
for (std::map<std::string,DeviceInfo>::iterator i = DeviceInfo::device_info.begin(); i != DeviceInfo::device_info.end(); ++i) { for (std::map<std::string,DeviceInfo>::iterator i = DeviceInfo::device_info.begin(); i != DeviceInfo::device_info.end(); ++i) {
std::cerr << "Dveice known: " << i->first << endl;
surfaces.push_back (i->first); surfaces.push_back (i->first);
} }
Gtkmm2ext::set_popdown_strings (_surface_combo, surfaces); Gtkmm2ext::set_popdown_strings (_surface_combo, surfaces);
_surface_combo.set_active_text (p.device_info().name()); _surface_combo.set_active_text (p.device_info().name());
_surface_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::surface_combo_changed)); _surface_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::surface_combo_changed));
vector<string> profiles;
profiles.push_back ("default");
for (std::map<std::string,DeviceProfile>::iterator i = DeviceProfile::device_profiles.begin(); i != DeviceProfile::device_profiles.end(); ++i) {
profiles.push_back (i->first);
}
Gtkmm2ext::set_popdown_strings (_profile_combo, profiles);
_profile_combo.set_active_text (p.device_profile().name());
_profile_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::profile_combo_changed));
append_page (*table, _("Device Selection")); append_page (*table, _("Device Selection"));
table->show_all(); table->show_all();
@ -92,7 +105,9 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
append_page (function_key_scroller, _("Function Keys")); append_page (function_key_scroller, _("Function Keys"));
function_key_scroller.add (function_key_editor); function_key_scroller.add (function_key_editor);
rebuild_function_key_editor (); build_available_action_menu ();
build_function_key_editor ();
refresh_function_key_editor ();
function_key_scroller.show_all(); function_key_scroller.show_all();
} }
@ -110,7 +125,7 @@ MackieControlProtocolGUI::make_action_renderer (Glib::RefPtr<TreeStore> model, G
} }
void void
MackieControlProtocolGUI::rebuild_function_key_editor () MackieControlProtocolGUI::build_available_action_menu ()
{ {
/* build a model of all available actions (needs to be tree structured /* build a model of all available actions (needs to be tree structured
* more) * more)
@ -186,16 +201,21 @@ MackieControlProtocolGUI::rebuild_function_key_editor ()
if (l->empty ()) { if (l->empty ()) {
row[available_action_columns.name] = *t; row[available_action_columns.name] = *t;
action_map[*t] = *p;
} else { } else {
row[available_action_columns.name] = *l; row[available_action_columns.name] = *l;
action_map[*l] = *p;
} }
row[available_action_columns.path] = (*p); row[available_action_columns.path] = (*p);
} }
}
void
MackieControlProtocolGUI::build_function_key_editor ()
{
function_key_editor.append_column (_("Key"), function_key_columns.name); function_key_editor.append_column (_("Key"), function_key_columns.name);
TreeViewColumn* col; TreeViewColumn* col;
CellRendererCombo* renderer; CellRendererCombo* renderer;
@ -229,23 +249,106 @@ MackieControlProtocolGUI::rebuild_function_key_editor ()
col->add_attribute (renderer->property_text(), function_key_columns.shiftcontrol); col->add_attribute (renderer->property_text(), function_key_columns.shiftcontrol);
function_key_editor.append_column (*col); function_key_editor.append_column (*col);
function_key_model = ListStore::create (function_key_columns);
function_key_editor.set_model (function_key_model);
}
void
MackieControlProtocolGUI::refresh_function_key_editor ()
{
function_key_editor.set_model (Glib::RefPtr<TreeModel>());
function_key_model->clear ();
/* now fill with data */ /* now fill with data */
function_key_model = ListStore::create (function_key_columns);
TreeModel::Row row; TreeModel::Row row;
DeviceProfile dp (_cp.device_profile());
for (uint32_t n = 0; n < 16; ++n) {
for (int n = 0; n < Mackie::Button::FinalGlobalButton; ++n) {
Mackie::Button::ID bid = (Mackie::Button::ID) n;
row = *(function_key_model->append()); row = *(function_key_model->append());
row[function_key_columns.name] = string_compose ("F%1", n+1); row[function_key_columns.name] = Mackie::Button::id_to_name (bid);
row[function_key_columns.number] = n; row[function_key_columns.id] = bid;
row[function_key_columns.plain] = ""; // _cp.f_action (n, 0);
row[function_key_columns.control] = "c"; Glib::RefPtr<Gtk::Action> act;
row[function_key_columns.option] = "o"; string action;
row[function_key_columns.shift] = "s"; const string defstring = "def";
row[function_key_columns.cmdalt] = "ca";
row[function_key_columns.shiftcontrol] = "sc"; action = dp.get_button_action (bid, 0);
if (action.empty()) {
row[function_key_columns.plain] = defstring;
} else {
std::cerr << "action = " << action << '\n';
act = ActionManager::get_action (action.c_str());
std::cerr << " action = " << act << endl;
if (act) {
row[function_key_columns.plain] = act->get_label();
} else {
row[function_key_columns.plain] = defstring;
}
}
action = dp.get_button_action (bid, MackieControlProtocol::MODIFIER_CONTROL);
if (action.empty()) {
row[function_key_columns.control] = defstring;
} else {
act = ActionManager::get_action (action.c_str());
if (act) {
row[function_key_columns.control] = act->get_label();
} else {
row[function_key_columns.control] = defstring;
}
}
action = dp.get_button_action (bid, MackieControlProtocol::MODIFIER_SHIFT);
if (action.empty()) {
row[function_key_columns.shift] = defstring;
} else {
act = ActionManager::get_action (action.c_str());
if (act) {
row[function_key_columns.shift] = act->get_label();
} else {
row[function_key_columns.shift] = defstring;
}
}
action = dp.get_button_action (bid, MackieControlProtocol::MODIFIER_OPTION);
if (action.empty()) {
row[function_key_columns.option] = defstring;
} else {
act = ActionManager::get_action (action.c_str());
if (act) {
row[function_key_columns.option] = act->get_label();
} else {
row[function_key_columns.option] = defstring;
}
}
action = dp.get_button_action (bid, MackieControlProtocol::MODIFIER_CMDALT);
if (action.empty()) {
row[function_key_columns.cmdalt] = defstring;
} else {
act = ActionManager::get_action (action.c_str());
if (act) {
row[function_key_columns.cmdalt] = act->get_label();
} else {
row[function_key_columns.cmdalt] = defstring;
}
}
action = dp.get_button_action (bid, (MackieControlProtocol::MODIFIER_SHIFT|MackieControlProtocol::MODIFIER_CONTROL));
if (action.empty()) {
row[function_key_columns.shiftcontrol] = defstring;
} else {
act = ActionManager::get_action (action.c_str());
if (act) {
row[function_key_columns.shiftcontrol] = act->get_label();
} else {
row[function_key_columns.shiftcontrol] = defstring;
}
}
} }
function_key_editor.set_model (function_key_model); function_key_editor.set_model (function_key_model);
@ -257,10 +360,19 @@ MackieControlProtocolGUI::action_changed (const Glib::ustring &sPath, const Glib
Gtk::TreePath path(sPath); Gtk::TreePath path(sPath);
Gtk::TreeModel::iterator row = function_key_model->get_iter(path); Gtk::TreeModel::iterator row = function_key_model->get_iter(path);
cerr << sPath << '-' << col.index() << " changed to " << text << endl;
if (row) { if (row) {
(*row).set_value (col.index(), text);
std::map<std::string,std::string>::iterator i = action_map.find (text);
if (i == action_map.end()) {
return;
}
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (i->second.c_str());
if (act) {
(*row).set_value (col.index(), text);
}
} }
} }
@ -270,4 +382,11 @@ MackieControlProtocolGUI::surface_combo_changed ()
_cp.set_device (_surface_combo.get_active_text()); _cp.set_device (_surface_combo.get_active_text());
} }
void
MackieControlProtocolGUI::profile_combo_changed ()
{
_cp.set_profile (_profile_combo.get_active_text());
refresh_function_key_editor ();
}

View file

@ -1,19 +1,19 @@
/* /*
Copyright (C) 2010 Paul Davis Copyright (C) 2010-2012 Paul Davis
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
@ -32,18 +32,19 @@ namespace Gtk {
class MackieControlProtocol; class MackieControlProtocol;
#include "button.h"
#include "i18n.h" #include "i18n.h"
class MackieControlProtocolGUI : public Gtk::Notebook class MackieControlProtocolGUI : public Gtk::Notebook
{ {
public: public:
MackieControlProtocolGUI (MackieControlProtocol &); MackieControlProtocolGUI (MackieControlProtocol &);
private: private:
void surface_combo_changed ();
MackieControlProtocol& _cp; MackieControlProtocol& _cp;
Gtk::ComboBoxText _surface_combo; Gtk::ComboBoxText _surface_combo;
Gtk::ComboBoxText _profile_combo;
struct AvailableActionColumns : public Gtk::TreeModel::ColumnRecord { struct AvailableActionColumns : public Gtk::TreeModel::ColumnRecord {
AvailableActionColumns() { AvailableActionColumns() {
@ -57,7 +58,7 @@ class MackieControlProtocolGUI : public Gtk::Notebook
struct FunctionKeyColumns : public Gtk::TreeModel::ColumnRecord { struct FunctionKeyColumns : public Gtk::TreeModel::ColumnRecord {
FunctionKeyColumns() { FunctionKeyColumns() {
add (name); add (name);
add (number); add (id);
add (plain); add (plain);
add (shift); add (shift);
add (control); add (control);
@ -66,7 +67,7 @@ class MackieControlProtocolGUI : public Gtk::Notebook
add (shiftcontrol); add (shiftcontrol);
}; };
Gtk::TreeModelColumn<std::string> name; Gtk::TreeModelColumn<std::string> name;
Gtk::TreeModelColumn<uint32_t> number; Gtk::TreeModelColumn<Mackie::Button::ID> id;
Gtk::TreeModelColumn<std::string> plain; Gtk::TreeModelColumn<std::string> plain;
Gtk::TreeModelColumn<std::string> shift; Gtk::TreeModelColumn<std::string> shift;
Gtk::TreeModelColumn<std::string> control; Gtk::TreeModelColumn<std::string> control;
@ -83,8 +84,15 @@ class MackieControlProtocolGUI : public Gtk::Notebook
Glib::RefPtr<Gtk::ListStore> function_key_model; Glib::RefPtr<Gtk::ListStore> function_key_model;
Glib::RefPtr<Gtk::TreeStore> available_action_model; Glib::RefPtr<Gtk::TreeStore> available_action_model;
void rebuild_function_key_editor (); void build_available_action_menu ();
void refresh_function_key_editor ();
void build_function_key_editor ();
void action_changed (const Glib::ustring &sPath, const Glib::ustring &text, Gtk::TreeModelColumnBase); void action_changed (const Glib::ustring &sPath, const Glib::ustring &text, Gtk::TreeModelColumnBase);
Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr<Gtk::TreeStore> model, Gtk::TreeModelColumnBase); Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr<Gtk::TreeStore> model, Gtk::TreeModelColumnBase);
void surface_combo_changed ();
void profile_combo_changed ();
std::map<std::string,std::string> action_map; // map from action names to paths
}; };

View file

@ -57,6 +57,7 @@
#include "midi_byte_array.h" #include "midi_byte_array.h"
#include "mackie_control_exception.h" #include "mackie_control_exception.h"
#include "device_profile.h"
#include "surface_port.h" #include "surface_port.h"
#include "surface.h" #include "surface.h"
#include "strip.h" #include "strip.h"
@ -108,7 +109,10 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n"); DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
DeviceInfo::reload_device_info (); DeviceInfo::reload_device_info ();
DeviceProfile::reload_device_profiles ();
set_device (Config->get_mackie_device_name()); set_device (Config->get_mackie_device_name());
set_profile (Config->get_mackie_device_profile());
AudioEngine::instance()->PortConnectedOrDisconnected.connect ( AudioEngine::instance()->PortConnectedOrDisconnected.connect (
audio_engine_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5), audio_engine_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
@ -506,6 +510,23 @@ MackieControlProtocol::connect_session_signals()
} }
} }
void
MackieControlProtocol::set_profile (const string& profile_name)
{
if (profile_name == "default") {
/* reset to default */
_device_profile = DeviceProfile (profile_name);
}
map<string,DeviceProfile>::iterator d = DeviceProfile::device_profiles.find (profile_name);
if (d == DeviceProfile::device_profiles.end()) {
return;
}
_device_profile = d->second;
}
void void
MackieControlProtocol::set_device (const string& device_name) MackieControlProtocol::set_device (const string& device_name)
{ {
@ -1016,6 +1037,22 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2\n", (bs == press ? "press" : "release"), button.id())); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2\n", (bs == press ? "press" : "release"), button.id()));
/* check profile first */
string action = _device_profile.get_button_action (button.bid(), _modifier_state);
if (!action.empty()) {
/* if there is a bound action for this button, and this is a press event,
carry out the action. If its a release event, do nothing since we
don't bind to them at all but don't want any other handling to
occur either.
*/
if (bs == press) {
access_action (action);
}
return;
}
/* lookup using the device-INDEPENDENT button ID */ /* lookup using the device-INDEPENDENT button ID */
ButtonMap::iterator b = button_map.find (button.bid()); ButtonMap::iterator b = button_map.find (button.bid());

View file

@ -41,6 +41,7 @@
#include "mackie_jog_wheel.h" #include "mackie_jog_wheel.h"
#include "timer.h" #include "timer.h"
#include "device_info.h" #include "device_info.h"
#include "device_profile.h"
namespace ARDOUR { namespace ARDOUR {
class AutomationControl; class AutomationControl;
@ -118,9 +119,11 @@ class MackieControlProtocol
static MackieControlProtocol* instance() { return _instance; } static MackieControlProtocol* instance() { return _instance; }
const Mackie::DeviceInfo& device_info() const { return _device_info; } const Mackie::DeviceInfo& device_info() const { return _device_info; }
const Mackie::DeviceProfile& device_profile() const { return _device_profile; }
int set_active (bool yn); int set_active (bool yn);
void set_device (const std::string&); void set_device (const std::string&);
void set_profile (const std::string&);
bool flip_mode () const { return _flip_mode; } bool flip_mode () const { return _flip_mode; }
ViewMode view_mode () const { return _view_mode; } ViewMode view_mode () const { return _view_mode; }
@ -249,6 +252,7 @@ class MackieControlProtocol
static MackieControlProtocol* _instance; static MackieControlProtocol* _instance;
Mackie::DeviceInfo _device_info; Mackie::DeviceInfo _device_info;
Mackie::DeviceProfile _device_profile;
sigc::connection periodic_connection; sigc::connection periodic_connection;
uint32_t _current_initial_bank; uint32_t _current_initial_bank;
PBD::ScopedConnectionList audio_engine_connections; PBD::ScopedConnectionList audio_engine_connections;

View file

@ -88,7 +88,10 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<Button::
_meter = dynamic_cast<Meter*> (Meter::factory (*_surface, index, "meter", *this)); _meter = dynamic_cast<Meter*> (Meter::factory (*_surface, index, "meter", *this));
for (map<Button::ID,StripButtonInfo>::const_iterator b = strip_buttons.begin(); b != strip_buttons.end(); ++b) { for (map<Button::ID,StripButtonInfo>::const_iterator b = strip_buttons.begin(); b != strip_buttons.end(); ++b) {
(void) Button::factory (*_surface, b->first, b->second.base_id + index, b->second.name, *this); Button* bb = dynamic_cast<Button*> (Button::factory (*_surface, b->first, b->second.base_id + index, b->second.name, *this));
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface %1 strip %2 new button BID %3 id %4 from base %5\n",
_surface->number(), index, Button::id_to_name (bb->bid()),
bb->id(), b->second.base_id));
} }
} }

View file

@ -199,6 +199,8 @@ Surface::init_strips (uint32_t n)
snprintf (name, sizeof (name), "strip_%d", (8* _number) + i); snprintf (name, sizeof (name), "strip_%d", (8* _number) + i);
std::cerr << "*** Surface " << _number << " Setup strips for index " << i << endl;
Strip* strip = new Strip (*this, name, i, strip_buttons); Strip* strip = new Strip (*this, name, i, strip_buttons);
groups[name] = strip; groups[name] = strip;

View file

@ -24,6 +24,7 @@ def build(bld):
button.cc button.cc
controls.cc controls.cc
device_info.cc device_info.cc
device_profile.cc
fader.cc fader.cc
gui.cc gui.cc
interface.cc interface.cc