Use a timeout to reset faders' in_use flags when in BCF mode (ie with faders that don't support touch).
git-svn-id: svn://localhost/ardour2/branches/3.0@9469 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
f01dc1bfd5
commit
91d512174e
|
@ -111,7 +111,6 @@ Control::Control( int id, int ordinal, std::string name, Group & group )
|
|||
, _name( name )
|
||||
, _group( group )
|
||||
, _in_use( false )
|
||||
, _in_use_timeout( 250 )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -178,15 +177,22 @@ Button & Strip::fader_touch()
|
|||
return *_fader_touch;
|
||||
}
|
||||
|
||||
bool Control::in_use() const
|
||||
/** @return true if the control is in use, or false otherwise.
|
||||
Buttons are `in use' when they are held down.
|
||||
Faders with touch support are `in use' when they are being touched.
|
||||
Pots, or faders without touch support, are `in use' from the first move
|
||||
event until a timeout after the last move event.
|
||||
*/
|
||||
bool
|
||||
Control::in_use () const
|
||||
{
|
||||
return _in_use;
|
||||
}
|
||||
|
||||
Control & Control::in_use( bool rhs )
|
||||
void
|
||||
Control::set_in_use (bool in_use)
|
||||
{
|
||||
_in_use = rhs;
|
||||
return *this;
|
||||
_in_use = in_use;
|
||||
}
|
||||
|
||||
ostream & Mackie::operator << ( ostream & os, const Mackie::Control & control )
|
||||
|
|
|
@ -214,21 +214,16 @@ public:
|
|||
/// Return true if this control is the one and only Jog Wheel
|
||||
virtual bool is_jog() const { return false; }
|
||||
|
||||
/**
|
||||
Return true if the control is in use, or false otherwise. For buttons
|
||||
this returns true if the button is currently being held down. For
|
||||
faders, the touch button has not been released. For pots, this returns
|
||||
true from the first move event until a timeout after the last move event.
|
||||
*/
|
||||
virtual bool in_use() const;
|
||||
virtual Control & in_use( bool );
|
||||
bool in_use () const;
|
||||
void set_in_use (bool);
|
||||
|
||||
/// The timeout value for this control. Normally defaulted to 250ms, but
|
||||
/// certain controls (ie jog wheel) may want to override it.
|
||||
virtual unsigned int in_use_timeout() { return _in_use_timeout; }
|
||||
|
||||
/// Keep track of the timeout so it can be updated with more incoming events
|
||||
sigc::connection in_use_connection;
|
||||
|
||||
/** If we are doing an in_use timeout for a fader without touch, this
|
||||
* is its touch button control; otherwise 0.
|
||||
*/
|
||||
Control* in_use_touch_control;
|
||||
|
||||
private:
|
||||
int _id;
|
||||
|
@ -236,7 +231,6 @@ private:
|
|||
std::string _name;
|
||||
Group & _group;
|
||||
bool _in_use;
|
||||
unsigned int _in_use_timeout;
|
||||
};
|
||||
|
||||
std::ostream & operator << ( std::ostream & os, const Control & control );
|
||||
|
|
|
@ -397,7 +397,7 @@ MackieControlProtocol::set_active (bool yn)
|
|||
}
|
||||
|
||||
bool
|
||||
MackieControlProtocol::handle_strip_button (Control & control, ButtonState bs, boost::shared_ptr<Route> route)
|
||||
MackieControlProtocol::handle_strip_button (SurfacePort & port, Control & control, ButtonState bs, boost::shared_ptr<Route> route)
|
||||
{
|
||||
bool state = false;
|
||||
|
||||
|
@ -433,7 +433,14 @@ MackieControlProtocol::handle_strip_button (Control & control, ButtonState bs, b
|
|||
if (control.name() == "fader_touch")
|
||||
{
|
||||
state = bs == press;
|
||||
control.strip().gain().in_use (state);
|
||||
control.strip().gain().set_in_use (state);
|
||||
|
||||
if (ARDOUR::Config->get_mackie_emulation() == "bcf" && state) {
|
||||
/* BCF faders don't support touch, so add a timeout to reset
|
||||
their `in_use' state.
|
||||
*/
|
||||
port.add_in_use_timeout (control.strip().gain(), &control.strip().fader_touch());
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -803,6 +810,11 @@ MackieControlProtocol::handle_control_event (SurfacePort & port, Control & contr
|
|||
{
|
||||
route->gain_control()->set_value (state.pos);
|
||||
|
||||
if (ARDOUR::Config->get_mackie_emulation() == "bcf") {
|
||||
/* reset the timeout while we're still moving the fader */
|
||||
port.add_in_use_timeout (control, control.in_use_touch_control);
|
||||
}
|
||||
|
||||
// must echo bytes back to slider now, because
|
||||
// the notifier only works if the fader is not being
|
||||
// touched. Which it is if we're getting input.
|
||||
|
@ -814,7 +826,7 @@ MackieControlProtocol::handle_control_event (SurfacePort & port, Control & contr
|
|||
if (control.group().is_strip()) {
|
||||
// strips
|
||||
if (route != 0) {
|
||||
handle_strip_button (control, state.button_state, route);
|
||||
handle_strip_button (port, control, state.button_state, route);
|
||||
} else {
|
||||
// no route so always switch the light off
|
||||
// because no signals will be emitted by a non-route
|
||||
|
@ -823,7 +835,7 @@ MackieControlProtocol::handle_control_event (SurfacePort & port, Control & contr
|
|||
} else if (control.group().is_master()) {
|
||||
// master fader touch
|
||||
if (route != 0) {
|
||||
handle_strip_button (control, state.button_state, route);
|
||||
handle_strip_button (port, control, state.button_state, route);
|
||||
}
|
||||
} else {
|
||||
// handle all non-strip buttons
|
||||
|
|
|
@ -270,7 +270,7 @@ class MackieControlProtocol
|
|||
Handle a button press for the control and return whether
|
||||
the corresponding light should be on or off.
|
||||
*/
|
||||
bool handle_strip_button(Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
|
||||
bool handle_strip_button (Mackie::SurfacePort &, Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
|
||||
|
||||
void add_port (MIDI::Port &, MIDI::Port &, int number);
|
||||
|
||||
|
|
|
@ -374,17 +374,6 @@ Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
|
|||
return *control;
|
||||
}
|
||||
|
||||
bool MackiePort::handle_control_timeout_event ( Control * control )
|
||||
{
|
||||
// empty control_state
|
||||
ControlState control_state;
|
||||
control->in_use( false );
|
||||
control_event( *this, *control, control_state );
|
||||
|
||||
// only call this method once from the timer
|
||||
return false;
|
||||
}
|
||||
|
||||
// converts midi messages into control_event signals
|
||||
// it might be worth combining this with lookup_control
|
||||
// because they have similar logic flows.
|
||||
|
@ -407,7 +396,7 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
|
|||
}
|
||||
|
||||
Control & control = lookup_control( raw_bytes, count );
|
||||
control.in_use( true );
|
||||
control.set_in_use (true);
|
||||
|
||||
// This handles incoming bytes. Outgoing bytes
|
||||
// are sent by the signal handlers.
|
||||
|
@ -429,7 +418,7 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
|
|||
case Control::type_button:
|
||||
{
|
||||
ControlState control_state( raw_bytes[2] == 0x7f ? press : release );
|
||||
control.in_use( control_state.button_state == press );
|
||||
control.set_in_use (control_state.button_state == press);
|
||||
control_event( *this, control, control_state );
|
||||
|
||||
break;
|
||||
|
@ -452,26 +441,12 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
|
|||
}
|
||||
state.delta = float( state.ticks ) / float( 0x3f );
|
||||
|
||||
/*
|
||||
Pots only emit events when they move, not when they
|
||||
stop moving. So to get a stop event, we need to use a timeout.
|
||||
/* Pots only emit events when they move, not when they
|
||||
stop moving. So to get a stop event, we need to use a timeout.
|
||||
*/
|
||||
// this is set to false ...
|
||||
control.in_use( true );
|
||||
|
||||
// ... by this timeout
|
||||
|
||||
// first disconnect any previous timeouts
|
||||
control.in_use_connection.disconnect();
|
||||
|
||||
// now connect a new timeout to call handle_control_timeout_event
|
||||
// XXX should this use the GUI event loop (default) or the
|
||||
// MIDI UI event loop ?
|
||||
|
||||
sigc::slot<bool> timeout_slot = sigc::bind
|
||||
(sigc::mem_fun( *this, &MackiePort::handle_control_timeout_event), &control);
|
||||
|
||||
control.in_use_connection = Glib::signal_timeout().connect (timeout_slot , control.in_use_timeout());
|
||||
control.set_in_use (true);
|
||||
add_in_use_timeout (control, &control);
|
||||
|
||||
// emit the control event
|
||||
control_event( *this, control, state );
|
||||
|
@ -489,3 +464,4 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
|
|||
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("finished MackiePort::handle_midi_any %1\n", bytes));
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
/// Connect the any signal from the parser to handle_midi_any
|
||||
/// unless it's already connected
|
||||
void connect_any();
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
The initialisation sequence is fairly complex. First a lock is acquired
|
||||
|
@ -107,10 +107,6 @@ protected:
|
|||
*/
|
||||
void probe_emulation( const MidiByteArray & bytes );
|
||||
|
||||
/// Handle timeout events set for controls that don't emit
|
||||
/// an off event
|
||||
bool handle_control_timeout_event ( Control * );
|
||||
|
||||
private:
|
||||
MackieControlProtocol & _mcp;
|
||||
port_type_t _port_type;
|
||||
|
|
|
@ -178,3 +178,43 @@ ostream & Mackie::operator << ( ostream & os, const SurfacePort & port )
|
|||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
/** Handle timeouts to reset in_use for controls that can't
|
||||
* do this by themselves (e.g. pots, and faders without touch support).
|
||||
* @param in_use_control the control whose in_use flag to reset.
|
||||
* @param touch_control a touch control to emit an event for, or 0.
|
||||
*/
|
||||
bool
|
||||
SurfacePort::control_in_use_timeout (Control* in_use_control, Control* touch_control)
|
||||
{
|
||||
in_use_control->set_in_use (false);
|
||||
|
||||
if (touch_control) {
|
||||
// empty control_state
|
||||
ControlState control_state;
|
||||
control_event (*this, *touch_control, control_state);
|
||||
}
|
||||
|
||||
// only call this method once from the timer
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Add a timeout so that a control's in_use flag will be reset some time in the future.
|
||||
* @param in_use_control the control whose in_use flag to reset.
|
||||
* @param touch_control a touch control to emit an event for, or 0.
|
||||
*/
|
||||
void
|
||||
SurfacePort::add_in_use_timeout (Control& in_use_control, Control* touch_control)
|
||||
{
|
||||
in_use_control.in_use_connection.disconnect ();
|
||||
|
||||
/* XXX should this use the GUI event loop (default) or the MIDI UI event loop? */
|
||||
|
||||
/* timeout after 250ms */
|
||||
in_use_control.in_use_connection = Glib::signal_timeout().connect (
|
||||
sigc::bind (sigc::mem_fun (*this, &SurfacePort::control_in_use_timeout), &in_use_control, touch_control),
|
||||
250
|
||||
);
|
||||
|
||||
in_use_control.in_use_touch_control = touch_control;
|
||||
}
|
||||
|
|
|
@ -86,12 +86,16 @@ public:
|
|||
|
||||
virtual bool active() const { return _active; }
|
||||
virtual void active( bool yn ) { _active = yn; }
|
||||
|
||||
void add_in_use_timeout (Control &, Control *);
|
||||
|
||||
protected:
|
||||
/// Only for use by DummyPort
|
||||
SurfacePort();
|
||||
|
||||
private:
|
||||
bool control_in_use_timeout (Control *, Control *);
|
||||
|
||||
MIDI::Port * _input_port;
|
||||
MIDI::Port * _output_port;
|
||||
int _number;
|
||||
|
|
Loading…
Reference in New Issue
Block a user