MCP: timeout display of value when altering with fader or pot; range ops on strip buttons should work; select logic may be broken

git-svn-id: svn://localhost/ardour2/branches/3.0@11959 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-04-13 16:11:55 +00:00
parent f511b7cc6b
commit 8f7fa7d93b
15 changed files with 228 additions and 165 deletions

View file

@ -712,8 +712,6 @@ Editor::Editor ()
ControlProtocol::Undo.connect (*this, invalidator (*this), boost::bind (&Editor::undo, this, true), gui_context()); ControlProtocol::Undo.connect (*this, invalidator (*this), boost::bind (&Editor::undo, this, true), gui_context());
ControlProtocol::Redo.connect (*this, invalidator (*this), boost::bind (&Editor::redo, this, true), gui_context()); ControlProtocol::Redo.connect (*this, invalidator (*this), boost::bind (&Editor::redo, this, true), gui_context());
ControlProtocol::ScrollTimeline.connect (*this, invalidator (*this), ui_bind (&Editor::control_scroll, this, _1), gui_context()); ControlProtocol::ScrollTimeline.connect (*this, invalidator (*this), ui_bind (&Editor::control_scroll, this, _1), gui_context());
ControlProtocol::SelectByRID.connect (*this, invalidator (*this), ui_bind (&Editor::control_select, this, _1), gui_context());
ControlProtocol::UnselectTrack.connect (*this, invalidator (*this), ui_bind (&Editor::control_unselect, this), gui_context());
ControlProtocol::GotoView.connect (*this, invalidator (*this), ui_bind (&Editor::control_view, this, _1), gui_context()); ControlProtocol::GotoView.connect (*this, invalidator (*this), ui_bind (&Editor::control_view, this, _1), gui_context());
ControlProtocol::CloseDialog.connect (*this, invalidator (*this), Keyboard::close_current_dialog, gui_context()); ControlProtocol::CloseDialog.connect (*this, invalidator (*this), Keyboard::close_current_dialog, gui_context());
ControlProtocol::VerticalZoomInAll.connect (*this, invalidator (*this), ui_bind (&Editor::control_vertical_zoom_in_all, this), gui_context()); ControlProtocol::VerticalZoomInAll.connect (*this, invalidator (*this), ui_bind (&Editor::control_vertical_zoom_in_all, this), gui_context());
@ -721,6 +719,11 @@ Editor::Editor ()
ControlProtocol::VerticalZoomInSelected.connect (*this, invalidator (*this), ui_bind (&Editor::control_vertical_zoom_in_selected, this), gui_context()); ControlProtocol::VerticalZoomInSelected.connect (*this, invalidator (*this), ui_bind (&Editor::control_vertical_zoom_in_selected, this), gui_context());
ControlProtocol::VerticalZoomOutSelected.connect (*this, invalidator (*this), ui_bind (&Editor::control_vertical_zoom_out_selected, this), gui_context()); ControlProtocol::VerticalZoomOutSelected.connect (*this, invalidator (*this), ui_bind (&Editor::control_vertical_zoom_out_selected, this), gui_context());
ControlProtocol::AddRouteToSelection.connect (*this, invalidator (*this), ui_bind (&Editor::control_select, this, _1, Selection::Add), gui_context());
ControlProtocol::RemoveRouteFromSelection.connect (*this, invalidator (*this), ui_bind (&Editor::control_select, this, _1, Selection::Toggle), gui_context());
ControlProtocol::SetRouteSelection.connect (*this, invalidator (*this), ui_bind (&Editor::control_select, this, _1, Selection::Set), gui_context());
ControlProtocol::ClearRouteSelection.connect (*this, invalidator (*this), ui_bind (&Editor::control_unselect, this), gui_context());
BasicUI::AccessAction.connect (*this, invalidator (*this), ui_bind (&Editor::access_action, this, _1, _2), gui_context()); BasicUI::AccessAction.connect (*this, invalidator (*this), ui_bind (&Editor::access_action, this, _1, _2), gui_context());
/* problematic: has to return a value and thus cannot be x-thread */ /* problematic: has to return a value and thus cannot be x-thread */
@ -966,7 +969,7 @@ Editor::control_unselect ()
} }
void void
Editor::control_select (uint32_t rid) Editor::control_select (uint32_t rid, Selection::Operation op)
{ {
/* handles the (static) signal from the ControlProtocol class that /* handles the (static) signal from the ControlProtocol class that
* requests setting the selected track to a given RID * requests setting the selected track to a given RID
@ -985,7 +988,19 @@ Editor::control_select (uint32_t rid)
TimeAxisView* tav = axis_view_from_route (r); TimeAxisView* tav = axis_view_from_route (r);
if (tav) { if (tav) {
switch (op) {
case Selection::Add:
selection->add (tav);
break;
case Selection::Toggle:
selection->toggle (tav);
break;
case Selection::Extend:
break;
case Selection::Set:
selection->set (tav); selection->set (tav);
break;
}
} else { } else {
selection->clear_tracks (); selection->clear_tracks ();
} }

View file

@ -994,7 +994,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void control_vertical_zoom_out_selected (); void control_vertical_zoom_out_selected ();
void control_view (uint32_t); void control_view (uint32_t);
void control_scroll (float); void control_scroll (float);
void control_select (uint32_t rid); void control_select (uint32_t rid, Selection::Operation);
void control_unselect (); void control_unselect ();
void access_action (std::string,std::string); void access_action (std::string,std::string);
bool deferred_control_scroll (framepos_t); bool deferred_control_scroll (framepos_t);

View file

@ -142,9 +142,6 @@ public:
boost::shared_ptr<Pannable> pannable() const { return _pannable; } boost::shared_ptr<Pannable> pannable() const { return _pannable; }
//virtual std::string describe_parameter (Evoral::Parameter);
//virtual std::string value_as_string (Evoral::Parameter, double val);
static bool equivalent (pan_t a, pan_t b) { static bool equivalent (pan_t a, pan_t b) {
return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner
} }

View file

@ -364,9 +364,13 @@ Panner1in2out::value_as_string (boost::shared_ptr<AutomationControl> ac) const
This is pretty wierd, but its the way audio engineers expect it. Just remember that This is pretty wierd, but its the way audio engineers expect it. Just remember that
the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense.
This is designed to be as narrow as possible. Dedicated
panner GUIs can do their own version of this if they need
something less compact.
*/ */
return string_compose (_("L:%1 R:%2"), (int) rint (100.0 * (1.0 - val)), return string_compose (_("L%1R%2"), (int) rint (100.0 * (1.0 - val)),
(int) rint (100.0 * val)); (int) rint (100.0 * val));
default: default:

View file

@ -478,9 +478,13 @@ Panner2in2out::value_as_string (boost::shared_ptr<AutomationControl> ac) const
This is pretty wierd, but its the way audio engineers expect it. Just remember that This is pretty wierd, but its the way audio engineers expect it. Just remember that
the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense.
This is designed to be as narrow as possible. Dedicated
panner GUIs can do their own version of this if they need
something less compact.
*/ */
return string_compose (_("L:%1 R:%2"), (int) rint (100.0 * (1.0 - val)), return string_compose (_("L%1R%2"), (int) rint (100.0 * (1.0 - val)),
(int) rint (100.0 * val)); (int) rint (100.0 * val));
case PanWidthAutomation: case PanWidthAutomation:

View file

@ -38,8 +38,6 @@ Signal0<void> ControlProtocol::Enter;
Signal0<void> ControlProtocol::Undo; Signal0<void> ControlProtocol::Undo;
Signal0<void> ControlProtocol::Redo; Signal0<void> ControlProtocol::Redo;
Signal1<void,float> ControlProtocol::ScrollTimeline; Signal1<void,float> ControlProtocol::ScrollTimeline;
Signal1<void,uint32_t> ControlProtocol::SelectByRID;
Signal0<void> ControlProtocol::UnselectTrack;
Signal1<void,uint32_t> ControlProtocol::GotoView; Signal1<void,uint32_t> ControlProtocol::GotoView;
Signal0<void> ControlProtocol::CloseDialog; Signal0<void> ControlProtocol::CloseDialog;
PBD::Signal0<void> ControlProtocol::VerticalZoomInAll; PBD::Signal0<void> ControlProtocol::VerticalZoomInAll;
@ -47,6 +45,10 @@ PBD::Signal0<void> ControlProtocol::VerticalZoomOutAll;
PBD::Signal0<void> ControlProtocol::VerticalZoomInSelected; PBD::Signal0<void> ControlProtocol::VerticalZoomInSelected;
PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected; PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
PBD::Signal1<void,RouteNotificationListPtr> ControlProtocol::TrackSelectionChanged; PBD::Signal1<void,RouteNotificationListPtr> ControlProtocol::TrackSelectionChanged;
PBD::Signal1<void,uint32_t> ControlProtocol::AddRouteToSelection;
PBD::Signal1<void,uint32_t> ControlProtocol::SetRouteSelection;
PBD::Signal1<void,uint32_t> ControlProtocol::RemoveRouteFromSelection;
PBD::Signal0<void> ControlProtocol::ClearRouteSelection;
ControlProtocol::ControlProtocol (Session& s, string str, EventLoop* evloop) ControlProtocol::ControlProtocol (Session& s, string str, EventLoop* evloop)
: BasicUI (s), : BasicUI (s),

View file

@ -67,8 +67,6 @@ class ControlProtocol : virtual public sigc::trackable, public PBD::Stateful, pu
static PBD::Signal0<void> Undo; static PBD::Signal0<void> Undo;
static PBD::Signal0<void> Redo; static PBD::Signal0<void> Redo;
static PBD::Signal1<void,float> ScrollTimeline; static PBD::Signal1<void,float> ScrollTimeline;
static PBD::Signal1<void,uint32_t> SelectByRID;
static PBD::Signal0<void> UnselectTrack;
static PBD::Signal1<void,uint32_t> GotoView; static PBD::Signal1<void,uint32_t> GotoView;
static PBD::Signal0<void> CloseDialog; static PBD::Signal0<void> CloseDialog;
static PBD::Signal0<void> VerticalZoomInAll; static PBD::Signal0<void> VerticalZoomInAll;
@ -76,6 +74,11 @@ class ControlProtocol : virtual public sigc::trackable, public PBD::Stateful, pu
static PBD::Signal0<void> VerticalZoomInSelected; static PBD::Signal0<void> VerticalZoomInSelected;
static PBD::Signal0<void> VerticalZoomOutSelected; static PBD::Signal0<void> VerticalZoomOutSelected;
static PBD::Signal1<void,uint32_t> AddRouteToSelection;
static PBD::Signal1<void,uint32_t> SetRouteSelection;
static PBD::Signal1<void,uint32_t> RemoveRouteFromSelection;
static PBD::Signal0<void> ClearRouteSelection;
/* signals that one UI (e.g. the GUI) can emit to get all other UI's to /* signals that one UI (e.g. the GUI) can emit to get all other UI's to
respond. Typically this will always be GUI->"others" - the GUI pays respond. Typically this will always be GUI->"others" - the GUI pays
no attention to these signals. no attention to these signals.

View file

@ -131,8 +131,9 @@ MIDIFunction::execute ()
if (!_argument.empty()) { if (!_argument.empty()) {
uint32_t rid; uint32_t rid;
sscanf (_argument.c_str(), "%d", &rid); sscanf (_argument.c_str(), "%d", &rid);
_ui->SelectByRID (rid); _ui->SetRouteSelection (rid);
} }
break;
case TrackSetMute: case TrackSetMute:
break; break;
case TrackSetSolo: case TrackSetSolo:

View file

@ -281,7 +281,6 @@ DeviceInfo::reload_device_info ()
if (di.set_state (*root, 3000) == 0) { /* version is ignored for now */ if (di.set_state (*root, 3000) == 0) { /* version is ignored for now */
device_info[di.name()] = di; device_info[di.name()] = di;
std::cerr << di << '\n';
} }
} }

View file

@ -389,8 +389,14 @@ MackieControlProtocol::periodic ()
return false; return false;
} }
struct timeval now;
uint64_t now_usecs;
gettimeofday (&now, 0);
now_usecs = (now.tv_sec * 1000000) + now.tv_usec;
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) { for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
(*s)->periodic (); (*s)->periodic (now_usecs);
} }
return true; return true;
@ -1060,22 +1066,6 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu
} }
} }
void
MackieControlProtocol::select_track (boost::shared_ptr<Route> r)
{
if (_modifier_state == MODIFIER_SHIFT) {
r->gain_control()->set_value (0.0);
} else {
if (_current_selected_track > 0 && r->remote_control_id() == (uint32_t) _current_selected_track) {
UnselectTrack (); /* EMIT SIGNAL */
_current_selected_track = -1;
} else {
SelectByRID (r->remote_control_id()); /* EMIT SIGNAL */
_current_selected_track = r->remote_control_id();;
}
}
}
bool bool
MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port) MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port)
{ {
@ -1210,112 +1200,91 @@ MackieControlProtocol::remove_down_select_button (int surface, int strip)
} }
} }
bool void
MackieControlProtocol::select_range () MackieControlProtocol::select_range ()
{ {
vector<boost::shared_ptr<Route> > routes; RouteList routes;
pull_route_range (_down_select_buttons, routes); pull_route_range (_down_select_buttons, routes);
if (routes.empty()) { if (!routes.empty()) {
return false; for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
if (r == routes.begin()) {
SetRouteSelection ((*r)->remote_control_id());
} else {
AddRouteToSelection ((*r)->remote_control_id());
}
}
} }
/* do something */
return true;
} }
void void
MackieControlProtocol::add_down_solo_button (int surface, int strip) MackieControlProtocol::add_down_button (AutomationType a, int surface, int strip)
{ {
_down_solo_buttons.push_back ((surface<<8)|(strip&0xf)); DownButtonMap::iterator m = _down_buttons.find (a);
if (m == _down_buttons.end()) {
_down_buttons[a] = DownButtonList();
}
_down_buttons[a].push_back ((surface<<8)|(strip&0xf));
} }
void void
MackieControlProtocol::remove_down_solo_button (int surface, int strip) MackieControlProtocol::remove_down_button (AutomationType a, int surface, int strip)
{ {
list<uint32_t>::iterator x = find (_down_solo_buttons.begin(), _down_solo_buttons.end(), (surface<<8)|(strip&0xf)); DownButtonMap::iterator m = _down_buttons.find (a);
if (x != _down_solo_buttons.end()) {
_down_solo_buttons.erase (x); if (m == _down_buttons.end()) {
return;
}
DownButtonList& l (m->second);
list<uint32_t>::iterator x = find (l.begin(), l.end(), (surface<<8)|(strip&0xf));
if (x != l.end()) {
l.erase (x);
} }
} }
bool MackieControlProtocol::ControlList
MackieControlProtocol::solo_range () MackieControlProtocol::down_controls (AutomationType p)
{ {
vector<boost::shared_ptr<Route> > routes; ControlList controls;
pull_route_range (_down_solo_buttons, routes); RouteList routes;
if (routes.empty()) { DownButtonMap::iterator m = _down_buttons.find (p);
return false;
if (m == _down_buttons.end()) {
return controls;
} }
/* do something */ pull_route_range (m->second, routes);
return true; switch (p) {
} case GainAutomation:
for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
void controls.push_back ((*r)->gain_control());
MackieControlProtocol::add_down_mute_button (int surface, int strip)
{
_down_mute_buttons.push_back ((surface<<8)|(strip&0xf));
}
void
MackieControlProtocol::remove_down_mute_button (int surface, int strip)
{
list<uint32_t>::iterator x = find (_down_mute_buttons.begin(), _down_mute_buttons.end(), (surface<<8)|(strip&0xf));
if (x != _down_mute_buttons.end()) {
_down_mute_buttons.erase (x);
} }
} break;
case SoloAutomation:
bool for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
MackieControlProtocol::mute_range () controls.push_back ((*r)->solo_control());
{ }
vector<boost::shared_ptr<Route> > routes; break;
pull_route_range (_down_mute_buttons, routes); case MuteAutomation:
for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
if (routes.empty()) { controls.push_back ((*r)->mute_control());
return false; }
break;
default:
break;
} }
/* do something */ return controls;
return true;
} }
void
MackieControlProtocol::add_down_recenable_button (int surface, int strip)
{
_down_recenable_buttons.push_back ((surface<<8)|(strip&0xf));
}
void
MackieControlProtocol::remove_down_recenable_button (int surface, int strip)
{
list<uint32_t>::iterator x = find (_down_recenable_buttons.begin(), _down_recenable_buttons.end(), (surface<<8)|(strip&0xf));
if (x != _down_recenable_buttons.end()) {
_down_recenable_buttons.erase (x);
}
}
bool
MackieControlProtocol::recenable_range ()
{
vector<boost::shared_ptr<Route> > routes;
pull_route_range (_down_recenable_buttons, routes);
if (routes.empty()) {
return false;
}
/* do something */
return true;
}
struct ButtonRangeSorter { struct ButtonRangeSorter {
bool operator() (const uint32_t& a, const uint32_t& b) { bool operator() (const uint32_t& a, const uint32_t& b) {
return (a>>8) < (b>>8) // a.surface < b.surface return (a>>8) < (b>>8) // a.surface < b.surface
@ -1325,7 +1294,7 @@ struct ButtonRangeSorter {
}; };
void void
MackieControlProtocol::pull_route_range (list<uint32_t>& down, vector<boost::shared_ptr<Route> >& selected) MackieControlProtocol::pull_route_range (list<uint32_t>& down, RouteList& selected)
{ {
ButtonRangeSorter cmp; ButtonRangeSorter cmp;

View file

@ -30,9 +30,7 @@
#include <glibmm/thread.h> #include <glibmm/thread.h>
#include "pbd/abstract_ui.h" #include "pbd/abstract_ui.h"
#include "midi++/types.h" #include "midi++/types.h"
#include "ardour/types.h" #include "ardour/types.h"
#include "control_protocol/control_protocol.h" #include "control_protocol/control_protocol.h"
@ -148,8 +146,6 @@ class MackieControlProtocol
void* get_gui () const; void* get_gui () const;
void tear_down_gui (); void tear_down_gui ();
void select_track (boost::shared_ptr<ARDOUR::Route> r);
void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState); void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);
void notify_route_added (ARDOUR::RouteList &); void notify_route_added (ARDOUR::RouteList &);
@ -184,21 +180,15 @@ class MackieControlProtocol
int modifier_state() const { return _modifier_state; } int modifier_state() const { return _modifier_state; }
typedef std::list<boost::shared_ptr<ARDOUR::AutomationControl> > ControlList;
void add_down_button (ARDOUR::AutomationType, int surface, int strip);
void remove_down_button (ARDOUR::AutomationType, int surface, int strip);
ControlList down_controls (ARDOUR::AutomationType);
void add_down_select_button (int surface, int strip); void add_down_select_button (int surface, int strip);
void remove_down_select_button (int surface, int strip); void remove_down_select_button (int surface, int strip);
bool select_range (); void select_range ();
void add_down_solo_button (int surface, int strip);
void remove_down_solo_button (int surface, int strip);
bool solo_range ();
void add_down_mute_button (int surface, int strip);
void remove_down_mute_button (int surface, int strip);
bool mute_range ();
void add_down_recenable_button (int surface, int strip);
void remove_down_recenable_button (int surface, int strip);
bool recenable_range ();
protected: protected:
// shut down the surface // shut down the surface
@ -302,14 +292,15 @@ class MackieControlProtocol
void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr); void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr);
/* BUTTON HANDLING */ /* BUTTON HANDLING */
std::list<uint32_t> _down_select_buttons; typedef std::list<uint32_t> DownButtonList;
std::list<uint32_t> _down_solo_buttons; typedef std::map<ARDOUR::AutomationType,DownButtonList> DownButtonMap;
std::list<uint32_t> _down_mute_buttons; DownButtonMap _down_buttons;
std::list<uint32_t> _down_recenable_buttons; DownButtonList _down_select_buttons;
void pull_route_range (std::list<uint32_t>& down, std::vector<boost::shared_ptr<ARDOUR::Route> >& selected); void pull_route_range (DownButtonList&, ARDOUR::RouteList&);
/* implemented button handlers */ /* implemented button handlers */
Mackie::LedState frm_left_press(Mackie::Button &); Mackie::LedState frm_left_press(Mackie::Button &);

View file

@ -21,6 +21,8 @@
#include <stdint.h> #include <stdint.h>
#include "strip.h" #include "strip.h"
#include <sys/time.h>
#include "midi++/port.h" #include "midi++/port.h"
#include "pbd/compose.h" #include "pbd/compose.h"
@ -70,6 +72,7 @@ Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefini
, _index (index) , _index (index)
, _surface (&s) , _surface (&s)
, _controls_locked (false) , _controls_locked (false)
, _reset_display_at (0)
, _last_gain_position_written (-1.0) , _last_gain_position_written (-1.0)
, _last_pan_position_written (-1.0) , _last_pan_position_written (-1.0)
{ {
@ -302,6 +305,7 @@ Strip::notify_gain_changed (bool force_update)
_surface->write (display (1, buf)); _surface->write (display (1, buf));
} }
queue_display_reset (500);
_last_gain_position_written = pos; _last_gain_position_written = pos;
} else { } else {
@ -363,11 +367,21 @@ Strip::notify_panner_changed (bool force_update)
double pos = pannable->pan_azimuth_control->internal_to_interface (pannable->pan_azimuth_control->get_value()); double pos = pannable->pan_azimuth_control->internal_to_interface (pannable->pan_azimuth_control->get_value());
if (force_update || pos != _last_pan_position_written) { if (force_update || pos != _last_pan_position_written) {
if (_surface->mcp().flip_mode()) { if (_surface->mcp().flip_mode()) {
_surface->write (_fader->set_position (pos)); _surface->write (_fader->set_position (pos));
} else { } else {
_surface->write (_vpot->set_all (pos, true, Pot::dot)); _surface->write (_vpot->set_all (pos, true, Pot::dot));
} }
if (pannable->panner()) {
string str = pannable->panner()->value_as_string (pannable->pan_azimuth_control);
_surface->write (display (1, str));
queue_display_reset (500);
}
_last_pan_position_written = pos; _last_pan_position_written = pos;
} }
} }
@ -377,7 +391,11 @@ Strip::notify_panner_changed (bool force_update)
void void
Strip::handle_button (Button& button, ButtonState bs) Strip::handle_button (Button& button, ButtonState bs)
{ {
button.set_in_use (bs == press); if (bs == press) {
button.set_in_use (true);
} else {
button.set_in_use (false);
}
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 handling button %2\n", _index, button.id())); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 handling button %2\n", _index, button.id()));
@ -397,9 +415,11 @@ Strip::handle_button (Button& button, ButtonState bs)
return; return;
} }
if (_route) { _surface->mcp().add_down_select_button (_surface->number(), _index);
_surface->mcp().select_track (_route); _surface->mcp().select_range ();
}
} else {
_surface->mcp().remove_down_select_button (_surface->number(), _index);
} }
return; return;
@ -415,10 +435,6 @@ Strip::handle_button (Button& button, ButtonState bs)
_fader->set_in_use (state); _fader->set_in_use (state);
_fader->start_touch (_surface->mcp().transport_frame(), modified); _fader->start_touch (_surface->mcp().transport_frame(), modified);
if (!_surface->mcp().device_info().has_touch_sense_faders()) {
_surface->mcp().add_in_use_timeout (*_surface, *_fader, _fader->control (modified));
}
if (bs != press) { if (bs != press) {
/* fader touch ended, revert back to label display for fader */ /* fader touch ended, revert back to label display for fader */
_surface->write (display (1, static_display_string())); _surface->write (display (1, static_display_string()));
@ -430,14 +446,37 @@ Strip::handle_button (Button& button, ButtonState bs)
boost::shared_ptr<AutomationControl> control = button.control (modified); boost::shared_ptr<AutomationControl> control = button.control (modified);
if (control) { if (control) {
if (bs == press) {
_surface->mcp().add_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index);
float new_value;
if (ms & MackieControlProtocol::MODIFIER_OPTION) { if (ms & MackieControlProtocol::MODIFIER_OPTION) {
/* reset to default/normal value */ /* reset to default/normal value */
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("reset %1 to default of %2\n", control->name(), control->normal())); new_value = control->normal();
control->set_value (control->normal());
} else { } else {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("toggle %1 to default of %2\n", control->name(), control->get_value() ? 0.0 : 1.0)); new_value = control->get_value() ? 0.0 : 1.0;
control->set_value (control->get_value() ? 0.0 : 1.0);
} }
/* get all controls that either have their
* button down or are within a range of
* several down buttons
*/
MackieControlProtocol::ControlList controls = _surface->mcp().down_controls ((AutomationType) control->parameter().type());
/* apply change */
for (MackieControlProtocol::ControlList::iterator c = controls.begin(); c != controls.end(); ++c) {
(*c)->set_value (new_value);
}
} else {
_surface->mcp().remove_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index);
}
} else { } else {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("button has no control at present (modified ? %1)\n", modified)); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("button has no control at present (modified ? %1)\n", modified));
} }
@ -483,7 +522,7 @@ Strip::handle_pot (Pot& pot, float delta)
} }
void void
Strip::periodic () Strip::periodic (uint64_t usecs)
{ {
if (!_route) { if (!_route) {
return; return;
@ -491,6 +530,10 @@ Strip::periodic ()
update_automation (); update_automation ();
update_meter (); update_meter ();
if (_reset_display_at && _reset_display_at < usecs) {
reset_display ();
}
} }
void void
@ -605,9 +648,9 @@ string
Strip::static_display_string () const Strip::static_display_string () const
{ {
if (_surface->mcp().flip_mode()) { if (_surface->mcp().flip_mode()) {
return "Pan";
} else {
return "Fader"; return "Fader";
} else {
return "Pan";
} }
} }
@ -647,3 +690,33 @@ Strip::flip_mode_changed (bool notify)
notify_all (); notify_all ();
} }
} }
void
Strip::queue_display_reset (uint32_t msecs)
{
struct timeval now;
struct timeval delta;
struct timeval when;
gettimeofday (&now, 0);
delta.tv_sec = msecs/1000;
delta.tv_usec = (msecs - ((msecs/1000) * 1000)) * 1000;
timeradd (&now, &delta, &when);
_reset_display_at = (when.tv_sec * 1000000) + when.tv_usec;
}
void
Strip::clear_display_reset ()
{
_reset_display_at = 0;
}
void
Strip::reset_display ()
{
_surface->write (display (1, static_display_string()));
clear_display_reset ();
}

View file

@ -63,7 +63,7 @@ public:
void handle_fader (Fader&, float position); void handle_fader (Fader&, float position);
void handle_pot (Pot&, float delta); void handle_pot (Pot&, float delta);
void periodic (); void periodic (uint64_t now_usecs);
MidiByteArray display (uint32_t line_number, const std::string&); MidiByteArray display (uint32_t line_number, const std::string&);
MidiByteArray blank_display (uint32_t line_number); MidiByteArray blank_display (uint32_t line_number);
@ -89,6 +89,7 @@ private:
int _index; int _index;
Surface* _surface; Surface* _surface;
bool _controls_locked; bool _controls_locked;
uint64_t _reset_display_at;
boost::shared_ptr<ARDOUR::Route> _route; boost::shared_ptr<ARDOUR::Route> _route;
PBD::ScopedConnectionList route_connections; PBD::ScopedConnectionList route_connections;
@ -109,6 +110,10 @@ private:
void update_meter (); void update_meter ();
std::string static_display_string () const; std::string static_display_string () const;
void queue_display_reset (uint32_t msecs);
void clear_display_reset ();
void reset_display ();
}; };
} }

View file

@ -618,10 +618,10 @@ Surface::zero_all ()
} }
void void
Surface::periodic () Surface::periodic (uint64_t now_usecs)
{ {
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
(*s)->periodic (); (*s)->periodic (now_usecs);
} }
} }

View file

@ -81,7 +81,7 @@ public:
const MidiByteArray& sysex_hdr() const; const MidiByteArray& sysex_hdr() const;
void periodic (); void periodic (uint64_t now_usecs);
void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t, uint32_t channel_id); void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t, uint32_t channel_id);
void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*); void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);