TriggerStrip: add solo,mute,pan,gain controls and meter
This commit is contained in:
parent
2b6b7226b0
commit
01c83ec122
|
@ -27,6 +27,10 @@
|
||||||
|
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
|
||||||
|
namespace Gtk {
|
||||||
|
class DrawingArea;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class Route;
|
class Route;
|
||||||
class RouteGroup;
|
class RouteGroup;
|
||||||
|
|
|
@ -910,6 +910,7 @@ MixerStrip::connect_to_pan ()
|
||||||
void
|
void
|
||||||
MixerStrip::update_panner_choices ()
|
MixerStrip::update_panner_choices ()
|
||||||
{
|
{
|
||||||
|
/* code-dup TriggerStrip::update_panner_choices */
|
||||||
ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
|
ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
|
||||||
if (!_route->panner_shell()) { return; }
|
if (!_route->panner_shell()) { return; }
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MixerStrip;
|
friend class MixerStrip;
|
||||||
|
friend class TriggerStrip;
|
||||||
friend class SendUI;
|
friend class SendUI;
|
||||||
|
|
||||||
boost::shared_ptr<ARDOUR::PannerShell> _panshell;
|
boost::shared_ptr<ARDOUR::PannerShell> _panshell;
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
#include "pbd/unwind.h"
|
#include "pbd/unwind.h"
|
||||||
|
|
||||||
#include "ardour/audio_track.h"
|
#include "ardour/audio_track.h"
|
||||||
|
#include "ardour/pannable.h"
|
||||||
|
#include "ardour/panner.h"
|
||||||
|
#include "ardour/panner_manager.h"
|
||||||
|
#include "ardour/panner_shell.h"
|
||||||
#include "ardour/profile.h"
|
#include "ardour/profile.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
|
@ -30,6 +34,7 @@
|
||||||
#include "widgets/tooltips.h"
|
#include "widgets/tooltips.h"
|
||||||
|
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
|
#include "meter_patterns.h"
|
||||||
#include "mixer_ui.h"
|
#include "mixer_ui.h"
|
||||||
#include "plugin_selector.h"
|
#include "plugin_selector.h"
|
||||||
#include "plugin_ui.h"
|
#include "plugin_ui.h"
|
||||||
|
@ -38,6 +43,8 @@
|
||||||
|
|
||||||
#include "pbd/i18n.h"
|
#include "pbd/i18n.h"
|
||||||
|
|
||||||
|
#define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ()))
|
||||||
|
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace ArdourWidgets;
|
using namespace ArdourWidgets;
|
||||||
using namespace ARDOUR_UI_UTILS;
|
using namespace ARDOUR_UI_UTILS;
|
||||||
|
@ -48,21 +55,21 @@ using namespace std;
|
||||||
|
|
||||||
PBD::Signal1<void, TriggerStrip*> TriggerStrip::CatchDeletion;
|
PBD::Signal1<void, TriggerStrip*> TriggerStrip::CatchDeletion;
|
||||||
|
|
||||||
#define PX_SCALE(pxmin, dflt) rint (std::max ((double)pxmin, (double)dflt* UIConfiguration::instance ().get_ui_scale ()))
|
|
||||||
|
|
||||||
TriggerStrip::TriggerStrip (Session* s, boost::shared_ptr<ARDOUR::Route> rt)
|
TriggerStrip::TriggerStrip (Session* s, boost::shared_ptr<ARDOUR::Route> rt)
|
||||||
: SessionHandlePtr (s)
|
: SessionHandlePtr (s)
|
||||||
, RouteUI (s)
|
, RouteUI (s)
|
||||||
|
, _clear_meters (true)
|
||||||
, _pb_selection ()
|
, _pb_selection ()
|
||||||
, _processor_box (s, boost::bind (&TriggerStrip::plugin_selector, this), _pb_selection, 0)
|
, _processor_box (s, boost::bind (&TriggerStrip::plugin_selector, this), _pb_selection, 0)
|
||||||
, _trigger_display (*rt->triggerbox ())
|
, _trigger_display (*rt->triggerbox ())
|
||||||
|
, _panners (s)
|
||||||
|
, _gain_control (ArdourKnob::default_elements, ArdourKnob::Detent)
|
||||||
|
, _level_meter (s)
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
RouteUI::set_route (rt);
|
set_route (rt);
|
||||||
|
|
||||||
/* set route */
|
|
||||||
_processor_box.set_route (rt);
|
|
||||||
|
|
||||||
|
io_changed ();
|
||||||
name_changed ();
|
name_changed ();
|
||||||
map_frozen ();
|
map_frozen ();
|
||||||
update_sensitivity ();
|
update_sensitivity ();
|
||||||
|
@ -115,13 +122,32 @@ TriggerStrip::init ()
|
||||||
_name_button.set_text_ellipsize (Pango::ELLIPSIZE_END);
|
_name_button.set_text_ellipsize (Pango::ELLIPSIZE_END);
|
||||||
_name_button.signal_size_allocate ().connect (sigc::mem_fun (*this, &TriggerStrip::name_button_resized));
|
_name_button.signal_size_allocate ().connect (sigc::mem_fun (*this, &TriggerStrip::name_button_resized));
|
||||||
|
|
||||||
/* main layout */
|
/* strip layout */
|
||||||
global_vpacker.set_spacing (2);
|
global_vpacker.set_spacing (2);
|
||||||
global_vpacker.pack_start (_name_button, Gtk::PACK_SHRINK);
|
global_vpacker.pack_start (_name_button, Gtk::PACK_SHRINK);
|
||||||
global_vpacker.pack_start (_trigger_display, true, true); // XXX
|
global_vpacker.pack_start (_trigger_display, true, true); // XXX
|
||||||
global_vpacker.pack_start (_processor_box, true, true);
|
global_vpacker.pack_start (_processor_box, true, true);
|
||||||
|
global_vpacker.pack_start (_panners, Gtk::PACK_SHRINK);
|
||||||
|
global_vpacker.pack_start (mute_solo_table, Gtk::PACK_SHRINK);
|
||||||
|
global_vpacker.pack_start (volume_table, Gtk::PACK_SHRINK);
|
||||||
|
|
||||||
/* top-level layout */
|
/* Mute & Solo */
|
||||||
|
mute_solo_table.set_homogeneous (true);
|
||||||
|
mute_solo_table.set_spacings (2);
|
||||||
|
mute_solo_table.attach (*mute_button, 0, 1, 0, 1);
|
||||||
|
mute_solo_table.attach (*solo_button, 1, 2, 0, 1);
|
||||||
|
|
||||||
|
/* Fader/Gain */
|
||||||
|
_gain_control.set_size_request (PX_SCALE (19), PX_SCALE (19));
|
||||||
|
_gain_control.set_tooltip_prefix (_("Level: "));
|
||||||
|
_gain_control.set_name ("trim knob"); // XXX
|
||||||
|
_gain_control.StartGesture.connect (sigc::mem_fun (*this, &TriggerStrip::gain_start_touch));
|
||||||
|
_gain_control.StopGesture.connect (sigc::mem_fun (*this, &TriggerStrip::gain_end_touch));
|
||||||
|
|
||||||
|
volume_table.attach (_level_meter, 0, 1, 0, 1);
|
||||||
|
volume_table.attach (_gain_control, 0, 1, 1, 2);
|
||||||
|
|
||||||
|
/* top-level */
|
||||||
global_frame.add (global_vpacker);
|
global_frame.add (global_vpacker);
|
||||||
global_frame.set_shadow_type (Gtk::SHADOW_IN);
|
global_frame.set_shadow_type (Gtk::SHADOW_IN);
|
||||||
global_frame.set_name ("BaseFrame");
|
global_frame.set_name ("BaseFrame");
|
||||||
|
@ -131,11 +157,22 @@ TriggerStrip::init ()
|
||||||
/* Signals */
|
/* Signals */
|
||||||
_name_button.signal_button_press_event ().connect (sigc::mem_fun (*this, &TriggerStrip::name_button_press), false);
|
_name_button.signal_button_press_event ().connect (sigc::mem_fun (*this, &TriggerStrip::name_button_press), false);
|
||||||
|
|
||||||
|
ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun (*this, &TriggerStrip::reset_peak_display));
|
||||||
|
ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun (*this, &TriggerStrip::reset_route_peak_display));
|
||||||
|
ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun (*this, &TriggerStrip::reset_group_peak_display));
|
||||||
|
|
||||||
/* Visibility */
|
/* Visibility */
|
||||||
_name_button.show ();
|
_name_button.show ();
|
||||||
_trigger_display.show ();
|
_trigger_display.show ();
|
||||||
_processor_box.show ();
|
_processor_box.show ();
|
||||||
|
_gain_control.show ();
|
||||||
|
_level_meter.show ();
|
||||||
|
|
||||||
|
mute_button->show ();
|
||||||
|
solo_button->show ();
|
||||||
|
|
||||||
|
mute_solo_table.show ();
|
||||||
|
volume_table.show ();
|
||||||
global_frame.show ();
|
global_frame.show ();
|
||||||
global_vpacker.show ();
|
global_vpacker.show ();
|
||||||
show ();
|
show ();
|
||||||
|
@ -149,10 +186,44 @@ TriggerStrip::init ()
|
||||||
set_size_request (width, -1);
|
set_size_request (width, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::set_route (boost::shared_ptr<Route> rt)
|
||||||
|
{
|
||||||
|
RouteUI::set_route (rt);
|
||||||
|
|
||||||
|
_processor_box.set_route (rt);
|
||||||
|
|
||||||
|
_gain_control.set_controllable (_route->gain_control ());
|
||||||
|
|
||||||
|
_level_meter.set_meter (_route->shared_peak_meter ().get ());
|
||||||
|
_level_meter.clear_meters ();
|
||||||
|
_level_meter.setup_meters (PX_SCALE (100), PX_SCALE (10), 6);
|
||||||
|
|
||||||
|
_route->input ()->changed.connect (*this, invalidator (*this), boost::bind (&TriggerStrip::io_changed, this), gui_context ());
|
||||||
|
_route->output ()->changed.connect (*this, invalidator (*this), boost::bind (&TriggerStrip::io_changed, this), gui_context ());
|
||||||
|
_route->io_changed.connect (route_connections, invalidator (*this), boost::bind (&TriggerStrip::io_changed, this), gui_context ());
|
||||||
|
|
||||||
|
if (_route->panner_shell ()) {
|
||||||
|
update_panner_choices ();
|
||||||
|
_route->panner_shell ()->Changed.connect (route_connections, invalidator (*this), boost::bind (&TriggerStrip::connect_to_pan, this), gui_context ());
|
||||||
|
}
|
||||||
|
|
||||||
|
_panners.set_panner (_route->main_outs ()->panner_shell (), _route->main_outs ()->panner ());
|
||||||
|
_panners.setup_pan ();
|
||||||
|
connect_to_pan ();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (_route->panner()) {
|
||||||
|
((Gtk::Label*)_panners.pan_automation_state_button.get_child())->set_text (GainMeterBase::short_astate_string (_route->pannable()->automation_state()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TriggerStrip::set_button_names ()
|
TriggerStrip::set_button_names ()
|
||||||
{
|
{
|
||||||
mute_button->set_text (S_("Mute|M"));
|
mute_button->set_text (_("Mute"));
|
||||||
monitor_input_button->set_text (_("In"));
|
monitor_input_button->set_text (_("In"));
|
||||||
monitor_disk_button->set_text (_("Disk"));
|
monitor_disk_button->set_text (_("Disk"));
|
||||||
|
|
||||||
|
@ -170,6 +241,45 @@ TriggerStrip::set_button_names ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::connect_to_pan ()
|
||||||
|
{
|
||||||
|
ENSURE_GUI_THREAD (*this, &TriggerStrip::connect_to_pan)
|
||||||
|
|
||||||
|
_panstate_connection.disconnect ();
|
||||||
|
|
||||||
|
if (!_route->panner ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Pannable> p = _route->pannable ();
|
||||||
|
|
||||||
|
p->automation_state_changed.connect (_panstate_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_state_changed, &_panners), gui_context ());
|
||||||
|
|
||||||
|
if (_panners._panner == 0) {
|
||||||
|
_panners.panshell_changed ();
|
||||||
|
}
|
||||||
|
update_panner_choices ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::update_panner_choices ()
|
||||||
|
{
|
||||||
|
/* code-dup TriggerStrip::update_panner_choices */
|
||||||
|
ENSURE_GUI_THREAD (*this, &TriggerStrip::update_panner_choices);
|
||||||
|
if (!_route->panner_shell ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t in = _route->output ()->n_ports ().n_audio ();
|
||||||
|
uint32_t out = in;
|
||||||
|
if (_route->panner ()) {
|
||||||
|
in = _route->panner ()->in ().n_audio ();
|
||||||
|
}
|
||||||
|
|
||||||
|
_panners.set_available_panners (PannerManager::instance ().PannerManager::get_available_panners (in, out));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TriggerStrip::route_property_changed (const PropertyChange& what_changed)
|
TriggerStrip::route_property_changed (const PropertyChange& what_changed)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +294,13 @@ TriggerStrip::route_color_changed ()
|
||||||
_name_button.modify_bg (STATE_NORMAL, color ());
|
_name_button.modify_bg (STATE_NORMAL, color ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::route_active_changed ()
|
||||||
|
{
|
||||||
|
RouteUI::route_active_changed ();
|
||||||
|
update_sensitivity ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TriggerStrip::update_sensitivity ()
|
TriggerStrip::update_sensitivity ()
|
||||||
{
|
{
|
||||||
|
@ -211,7 +328,7 @@ TriggerStrip::plugin_selector ()
|
||||||
void
|
void
|
||||||
TriggerStrip::hide_processor_editor (boost::weak_ptr<Processor> p)
|
TriggerStrip::hide_processor_editor (boost::weak_ptr<Processor> p)
|
||||||
{
|
{
|
||||||
/* TODO consolidate w/ MixerStrip::hide_processor_editor
|
/* TODO consolidate w/ TriggerStrip::hide_processor_editor
|
||||||
* -> RouteUI ?
|
* -> RouteUI ?
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Processor> processor (p.lock ());
|
boost::shared_ptr<Processor> processor (p.lock ());
|
||||||
|
@ -254,6 +371,36 @@ TriggerStrip::map_frozen ()
|
||||||
void
|
void
|
||||||
TriggerStrip::fast_update ()
|
TriggerStrip::fast_update ()
|
||||||
{
|
{
|
||||||
|
if (is_mapped ()) {
|
||||||
|
if (_clear_meters) {
|
||||||
|
_level_meter.clear_meters ();
|
||||||
|
_clear_meters = false;
|
||||||
|
}
|
||||||
|
_level_meter.update_meters ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::reset_route_peak_display (Route* route)
|
||||||
|
{
|
||||||
|
if (_route && _route.get () == route) {
|
||||||
|
reset_peak_display ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::reset_group_peak_display (RouteGroup* group)
|
||||||
|
{
|
||||||
|
if (_route && group == _route->route_group ()) {
|
||||||
|
reset_peak_display ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::reset_peak_display ()
|
||||||
|
{
|
||||||
|
//_route->shared_peak_meter ()->reset_max ();
|
||||||
|
_clear_meters = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -261,6 +408,16 @@ TriggerStrip::parameter_changed (string p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::io_changed ()
|
||||||
|
{
|
||||||
|
if (has_audio_outputs ()) {
|
||||||
|
_panners.show_all ();
|
||||||
|
} else {
|
||||||
|
_panners.hide_all ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TriggerStrip::name_changed ()
|
TriggerStrip::name_changed ()
|
||||||
{
|
{
|
||||||
|
@ -280,3 +437,15 @@ TriggerStrip::name_button_press (GdkEventButton*)
|
||||||
// TODO
|
// TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::gain_start_touch ()
|
||||||
|
{
|
||||||
|
_route->gain_control ()->start_touch (timepos_t (_session->transport_sample ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TriggerStrip::gain_end_touch ()
|
||||||
|
{
|
||||||
|
_route->gain_control ()->stop_touch (timepos_t (_session->transport_sample ()));
|
||||||
|
}
|
||||||
|
|
|
@ -29,8 +29,11 @@
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
||||||
#include "widgets/ardour_button.h"
|
#include "widgets/ardour_button.h"
|
||||||
|
#include "widgets/ardour_knob.h"
|
||||||
|
|
||||||
#include "axis_view.h"
|
#include "axis_view.h"
|
||||||
|
#include "level_meter.h"
|
||||||
|
#include "panner_ui.h"
|
||||||
#include "processor_box.h"
|
#include "processor_box.h"
|
||||||
#include "processor_selection.h"
|
#include "processor_selection.h"
|
||||||
#include "route_ui.h"
|
#include "route_ui.h"
|
||||||
|
@ -73,39 +76,58 @@ protected:
|
||||||
#if 0
|
#if 0
|
||||||
void route_rec_enable_changed ();
|
void route_rec_enable_changed ();
|
||||||
void blink_rec_display (bool onoff);
|
void blink_rec_display (bool onoff);
|
||||||
void route_active_changed ();
|
|
||||||
void map_frozen ();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init ();
|
void init ();
|
||||||
|
|
||||||
/* RouteUI */
|
/* RouteUI */
|
||||||
|
void set_route (boost::shared_ptr<ARDOUR::Route>);
|
||||||
void route_property_changed (const PBD::PropertyChange&);
|
void route_property_changed (const PBD::PropertyChange&);
|
||||||
void route_color_changed ();
|
void route_color_changed ();
|
||||||
void update_sensitivity ();
|
void update_sensitivity ();
|
||||||
void parameter_changed (std::string);
|
void parameter_changed (std::string);
|
||||||
|
void route_active_changed ();
|
||||||
void map_frozen ();
|
void map_frozen ();
|
||||||
|
|
||||||
/* Callbacks */
|
/* Callbacks */
|
||||||
|
void io_changed ();
|
||||||
void name_changed ();
|
void name_changed ();
|
||||||
void name_button_resized (Gtk::Allocation&);
|
void name_button_resized (Gtk::Allocation&);
|
||||||
bool name_button_press (GdkEventButton*);
|
bool name_button_press (GdkEventButton*);
|
||||||
|
void reset_peak_display ();
|
||||||
|
void reset_route_peak_display (ARDOUR::Route*);
|
||||||
|
void reset_group_peak_display (ARDOUR::RouteGroup*);
|
||||||
|
|
||||||
/* Plugin related */
|
/* Plugin related */
|
||||||
PluginSelector* plugin_selector ();
|
PluginSelector* plugin_selector ();
|
||||||
void hide_processor_editor (boost::weak_ptr<ARDOUR::Processor>);
|
void hide_processor_editor (boost::weak_ptr<ARDOUR::Processor>);
|
||||||
|
|
||||||
ProcessorSelection _pb_selection;
|
/* Panner */
|
||||||
|
void connect_to_pan ();
|
||||||
|
void update_panner_choices ();
|
||||||
|
|
||||||
|
/* Fader */
|
||||||
|
void gain_start_touch ();
|
||||||
|
void gain_end_touch ();
|
||||||
|
|
||||||
|
bool _clear_meters;
|
||||||
|
ProcessorSelection _pb_selection;
|
||||||
|
PBD::ScopedConnection _panstate_connection;
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
Gtk::Frame global_frame;
|
Gtk::Frame global_frame;
|
||||||
Gtk::VBox global_vpacker;
|
Gtk::VBox global_vpacker;
|
||||||
|
Gtk::Table mute_solo_table;
|
||||||
|
Gtk::Table volume_table;
|
||||||
|
|
||||||
/* Widgets */
|
/* Widgets */
|
||||||
ArdourWidgets::ArdourButton _name_button;
|
ArdourWidgets::ArdourButton _name_button;
|
||||||
ProcessorBox _processor_box;
|
ProcessorBox _processor_box;
|
||||||
TriggerBoxWidget _trigger_display;
|
TriggerBoxWidget _trigger_display;
|
||||||
|
PannerUI _panners;
|
||||||
|
ArdourWidgets::ArdourKnob _gain_control;
|
||||||
|
LevelMeterVBox _level_meter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ardour_trigger_strip__ */
|
#endif /* __ardour_trigger_strip__ */
|
||||||
|
|
Loading…
Reference in New Issue