TriggerStrip: add solo,mute,pan,gain controls and meter

This commit is contained in:
Robin Gareus 2021-12-02 22:21:28 +01:00
parent 2b6b7226b0
commit 01c83ec122
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
5 changed files with 210 additions and 13 deletions

View File

@ -27,6 +27,10 @@
#include <sigc++/signal.h>
namespace Gtk {
class DrawingArea;
}
namespace ARDOUR {
class Route;
class RouteGroup;

View File

@ -910,6 +910,7 @@ MixerStrip::connect_to_pan ()
void
MixerStrip::update_panner_choices ()
{
/* code-dup TriggerStrip::update_panner_choices */
ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
if (!_route->panner_shell()) { return; }

View File

@ -82,6 +82,7 @@ public:
private:
friend class MixerStrip;
friend class TriggerStrip;
friend class SendUI;
boost::shared_ptr<ARDOUR::PannerShell> _panshell;

View File

@ -23,6 +23,10 @@
#include "pbd/unwind.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 "gtkmm2ext/utils.h"
@ -30,6 +34,7 @@
#include "widgets/tooltips.h"
#include "gui_thread.h"
#include "meter_patterns.h"
#include "mixer_ui.h"
#include "plugin_selector.h"
#include "plugin_ui.h"
@ -38,6 +43,8 @@
#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 ArdourWidgets;
using namespace ARDOUR_UI_UTILS;
@ -48,21 +55,21 @@ using namespace std;
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)
: SessionHandlePtr (s)
, RouteUI (s)
, _clear_meters (true)
, _pb_selection ()
, _processor_box (s, boost::bind (&TriggerStrip::plugin_selector, this), _pb_selection, 0)
, _trigger_display (*rt->triggerbox ())
, _panners (s)
, _gain_control (ArdourKnob::default_elements, ArdourKnob::Detent)
, _level_meter (s)
{
init ();
RouteUI::set_route (rt);
/* set route */
_processor_box.set_route (rt);
set_route (rt);
io_changed ();
name_changed ();
map_frozen ();
update_sensitivity ();
@ -115,13 +122,32 @@ TriggerStrip::init ()
_name_button.set_text_ellipsize (Pango::ELLIPSIZE_END);
_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.pack_start (_name_button, Gtk::PACK_SHRINK);
global_vpacker.pack_start (_trigger_display, true, true); // XXX
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.set_shadow_type (Gtk::SHADOW_IN);
global_frame.set_name ("BaseFrame");
@ -131,11 +157,22 @@ TriggerStrip::init ()
/* Signals */
_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 */
_name_button.show ();
_trigger_display.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_vpacker.show ();
show ();
@ -149,10 +186,44 @@ TriggerStrip::init ()
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
TriggerStrip::set_button_names ()
{
mute_button->set_text (S_("Mute|M"));
mute_button->set_text (_("Mute"));
monitor_input_button->set_text (_("In"));
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
TriggerStrip::route_property_changed (const PropertyChange& what_changed)
{
@ -184,6 +294,13 @@ TriggerStrip::route_color_changed ()
_name_button.modify_bg (STATE_NORMAL, color ());
}
void
TriggerStrip::route_active_changed ()
{
RouteUI::route_active_changed ();
update_sensitivity ();
}
void
TriggerStrip::update_sensitivity ()
{
@ -211,7 +328,7 @@ TriggerStrip::plugin_selector ()
void
TriggerStrip::hide_processor_editor (boost::weak_ptr<Processor> p)
{
/* TODO consolidate w/ MixerStrip::hide_processor_editor
/* TODO consolidate w/ TriggerStrip::hide_processor_editor
* -> RouteUI ?
*/
boost::shared_ptr<Processor> processor (p.lock ());
@ -254,6 +371,36 @@ TriggerStrip::map_frozen ()
void
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
@ -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
TriggerStrip::name_changed ()
{
@ -280,3 +437,15 @@ TriggerStrip::name_button_press (GdkEventButton*)
// TODO
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 ()));
}

View File

@ -29,8 +29,11 @@
#include "ardour/types.h"
#include "widgets/ardour_button.h"
#include "widgets/ardour_knob.h"
#include "axis_view.h"
#include "level_meter.h"
#include "panner_ui.h"
#include "processor_box.h"
#include "processor_selection.h"
#include "route_ui.h"
@ -73,39 +76,58 @@ protected:
#if 0
void route_rec_enable_changed ();
void blink_rec_display (bool onoff);
void route_active_changed ();
void map_frozen ();
#endif
private:
void init ();
/* RouteUI */
void set_route (boost::shared_ptr<ARDOUR::Route>);
void route_property_changed (const PBD::PropertyChange&);
void route_color_changed ();
void update_sensitivity ();
void parameter_changed (std::string);
void route_active_changed ();
void map_frozen ();
/* Callbacks */
void io_changed ();
void name_changed ();
void name_button_resized (Gtk::Allocation&);
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 */
PluginSelector* plugin_selector ();
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 */
Gtk::Frame global_frame;
Gtk::VBox global_vpacker;
Gtk::Table mute_solo_table;
Gtk::Table volume_table;
/* Widgets */
ArdourWidgets::ArdourButton _name_button;
ProcessorBox _processor_box;
TriggerBoxWidget _trigger_display;
PannerUI _panners;
ArdourWidgets::ArdourKnob _gain_control;
LevelMeterVBox _level_meter;
};
#endif /* __ardour_trigger_strip__ */