Use a button as controller for toggled parameters.

This commit is contained in:
David Robillard 2014-11-28 18:40:23 -05:00
parent e3da7aff8c
commit 55c616519b
3 changed files with 81 additions and 13 deletions

View File

@ -29,6 +29,7 @@
#include "ardour/session.h"
#include "ardour/tempo.h"
#include "ardour_button.h"
#include "ardour_ui.h"
#include "automation_controller.h"
#include "gui_thread.h"
@ -42,29 +43,53 @@ using namespace Gtk;
AutomationController::AutomationController(boost::shared_ptr<Automatable> printer,
boost::shared_ptr<AutomationControl> ac,
Adjustment* adj)
: BarController (*adj, ac)
, _ignore_change(false)
: _widget(NULL)
, _printer (printer)
, _controllable(ac)
, _adjustment(adj)
, _ignore_change(false)
{
assert (_printer);
set_name (X_("ProcessorControlSlider"));
if (ac->toggled()) {
ArdourButton* but = manage(new ArdourButton());
StartGesture.connect (sigc::mem_fun(*this, &AutomationController::start_touch));
StopGesture.connect (sigc::mem_fun(*this, &AutomationController::end_touch));
// Apply styles for special types
if (ac->parameter().type() == MuteAutomation) {
but->set_name("mute button");
} else if (ac->parameter().type() == SoloAutomation) {
but->set_name("solo button");
} else {
but->set_name("generic button");
}
but->signal_clicked.connect(
sigc::mem_fun(*this, &AutomationController::toggled));
signal_button_release_event().connect(
sigc::mem_fun(*this, &AutomationController::on_button_release));
_widget = but;
} else {
Gtkmm2ext::BarController* bar = manage(new Gtkmm2ext::BarController(*adj, ac));
_adjustment->signal_value_changed().connect (
sigc::mem_fun(*this, &AutomationController::value_adjusted));
bar->set_name(X_("ProcessorControlSlider"));
bar->StartGesture.connect(
sigc::mem_fun(*this, &AutomationController::start_touch));
bar->StopGesture.connect(
sigc::mem_fun(*this, &AutomationController::end_touch));
bar->signal_button_release_event().connect(
sigc::mem_fun(*this, &AutomationController::on_button_release));
_widget = bar;
}
_adjustment->signal_value_changed().connect(
sigc::mem_fun(*this, &AutomationController::value_adjusted));
_screen_update_connection = ARDOUR_UI::RapidScreenUpdate.connect (
sigc::mem_fun (*this, &AutomationController::display_effective_value));
ac->Changed.connect (_changed_connection, invalidator (*this), boost::bind (&AutomationController::value_changed, this), gui_context());
add(*_widget);
show_all();
}
AutomationController::~AutomationController()
@ -123,6 +148,13 @@ AutomationController::value_adjusted ()
{
if (!_ignore_change) {
_controllable->set_value (_controllable->interface_to_internal(_adjustment->get_value()));
} else {
/* A bar controller will automatically follow the adjustment, but for a
button we have to do it manually. */
ArdourButton* but = dynamic_cast<ArdourButton*>(_widget);
if (but) {
but->set_active(_adjustment->get_value() >= 0.5);
}
}
}
@ -130,12 +162,12 @@ void
AutomationController::start_touch()
{
_controllable->start_touch (_controllable->session().transport_frame());
StartGesture.emit(); /* EMIT SIGNAL */
}
void
AutomationController::end_touch ()
{
if (!_controllable->alist()) return;
if (_controllable->automation_state() == Touch) {
bool mark = false;
@ -148,6 +180,23 @@ AutomationController::end_touch ()
_controllable->stop_touch (mark, when);
}
StopGesture.emit(); /* EMIT SIGNAL */
}
void
AutomationController::toggled ()
{
ArdourButton* but = dynamic_cast<ArdourButton*>(_widget);
if (but) {
const bool was_active = _controllable->get_value() >= 0.5;
if (was_active) {
_adjustment->set_value(0.0);
but->set_active(false);
} else {
_adjustment->set_value(1.0);
but->set_active(true);
}
}
}
static double
@ -261,3 +310,14 @@ AutomationController::stop_updating ()
{
_screen_update_connection.disconnect ();
}
void
AutomationController::disable_vertical_scroll ()
{
Gtkmm2ext::BarController* bar = dynamic_cast<Gtkmm2ext::BarController*>(_widget);
if (bar) {
bar->set_tweaks (
Gtkmm2ext::PixFader::Tweaks(bar->tweaks() |
Gtkmm2ext::PixFader::NoVerticalScroll));
}
}

View File

@ -43,7 +43,7 @@ namespace ARDOUR {
}
/** A BarController which displays the value and allows control of an AutomationControl */
class AutomationController : public Gtkmm2ext::BarController {
class AutomationController : public Gtk::Alignment {
public:
static boost::shared_ptr<AutomationController> create(
boost::shared_ptr<ARDOUR::Automatable> parent,
@ -55,13 +55,19 @@ public:
boost::shared_ptr<ARDOUR::AutomationControl> controllable() { return _controllable; }
void disable_vertical_scroll();
Gtk::Adjustment* adjustment() { return _adjustment; }
Gtk::Widget* widget() { return _widget; }
void display_effective_value();
void value_adjusted();
void stop_updating ();
sigc::signal<void> StartGesture;
sigc::signal<void> StopGesture;
private:
AutomationController (boost::shared_ptr<ARDOUR::Automatable> printer,
boost::shared_ptr<ARDOUR::AutomationControl> ac,
@ -70,6 +76,7 @@ private:
void start_touch();
void end_touch();
void toggled();
void run_note_select_dialog();
void set_ratio(double ratio);
@ -78,12 +85,13 @@ private:
void value_changed();
bool _ignore_change;
Gtk::Widget* _widget;
boost::shared_ptr<ARDOUR::Automatable> _printer;
boost::shared_ptr<ARDOUR::AutomationControl> _controllable;
Gtk::Adjustment* _adjustment;
sigc::connection _screen_update_connection;
PBD::ScopedConnection _changed_connection;
bool _ignore_change;
};

View File

@ -219,7 +219,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
hide_button.show ();
if (_controller) {
_controller.get()->set_tweaks (PixFader::Tweaks(_controller.get()->tweaks() | PixFader::NoVerticalScroll));
_controller->disable_vertical_scroll ();
controls_table.attach (*_controller.get(), 2, 4, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
}