From 4c8b414fb6ddbe671792b7a59f3fe4cdb9dd24a5 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 11 Jul 2023 00:42:32 +0200 Subject: [PATCH] Allow to numeric ctrl point edit to apply to all selected points --- gtk2_ardour/automation_line.cc | 13 ++++++++----- gtk2_ardour/automation_line.h | 2 +- gtk2_ardour/control_point_dialog.cc | 26 ++++++++++++++++++++++---- gtk2_ardour/control_point_dialog.h | 10 ++++++++-- gtk2_ardour/editor_mouse.cc | 20 ++++++++++++++++++-- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 3d483a0606..f13e38cbef 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -293,7 +293,7 @@ AutomationLine::nth (uint32_t n) const } void -AutomationLine::modify_point_y (ControlPoint& cp, double y) +AutomationLine::modify_points_y (std::vector const& cps, double y) { /* clamp y-coord appropriately. y is supposed to be a normalized fraction (0.0-1.0), and needs to be converted to a canvas unit distance. @@ -307,13 +307,16 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y) trackview.editor().session()->add_command ( new MementoCommand (memento_command_binder(), &get_state(), 0)); - cp.move_to (cp.get_x(), y, ControlPoint::Full); - alist->freeze (); - sync_model_with_view_point (cp); + for (auto const& cp : cps) { + cp->move_to (cp->get_x(), y, ControlPoint::Full); + sync_model_with_view_point (*cp); + } alist->thaw (); - reset_line_coords (cp); + for (auto const& cp : cps) { + reset_line_coords (*cp); + } if (line_points.size() > 1) { line->set_steps (line_points, is_stepped()); diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index 839f2ac20d..8aac3799f2 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -149,7 +149,7 @@ public: int set_state (const XMLNode&, int version); void set_colors(); - void modify_point_y (ControlPoint&, double); + void modify_points_y (std::vector const&, double); virtual MementoCommandBinder* memento_command_binder (); diff --git a/gtk2_ardour/control_point_dialog.cc b/gtk2_ardour/control_point_dialog.cc index 6f111d45b2..33c87f90ab 100644 --- a/gtk2_ardour/control_point_dialog.cc +++ b/gtk2_ardour/control_point_dialog.cc @@ -31,9 +31,11 @@ * @param p ControlPoint to edit. */ -ControlPointDialog::ControlPointDialog (ControlPoint* p) +ControlPointDialog::ControlPointDialog (ControlPoint* p, bool multi) : ArdourDialog (_("Control point")) , point_ (p) + , toggle_all_ (_("Change all selected points")) + , all_selected_points_ (true) { assert (point_); @@ -53,23 +55,33 @@ ControlPointDialog::ControlPointDialog (ControlPoint* p) std::size_t sep = val.find_last_of (" "); value_.set_text (val.substr (0, sep)); - value_.set_activates_default (); Gtk::HBox* b = Gtk::manage (new Gtk::HBox ()); + b->set_spacing (4); b->pack_start (*Gtk::manage (new Gtk::Label (_("Value")))); b->pack_start (value_); if (sep != std::string::npos) { b->pack_start (*Gtk::manage (new Gtk::Label (val.substr (sep + 1)))); } + get_vbox ()->pack_start (*b); + if (multi) { + toggle_all_.set_active (true); + get_vbox ()->pack_start (toggle_all_); + } - get_vbox ()->pack_end (*b); - b->show_all (); + get_vbox ()->set_spacing (4); + show_all (); add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); add_button (Gtk::Stock::APPLY, Gtk::RESPONSE_ACCEPT); set_default_response (Gtk::RESPONSE_ACCEPT); + + value_.set_activates_default (); + /* TODO: this does not work, one has to click on the entry.. */ + value_.set_can_focus (); + value_.grab_focus (); } double @@ -77,3 +89,9 @@ ControlPointDialog::get_y_fraction () const { return point_->line().string_to_fraction (value_.get_text ()); } + +bool +ControlPointDialog::all_selected_points () const +{ + return toggle_all_.get_active (); +} diff --git a/gtk2_ardour/control_point_dialog.h b/gtk2_ardour/control_point_dialog.h index 539a41c8b3..c0ef2627cb 100644 --- a/gtk2_ardour/control_point_dialog.h +++ b/gtk2_ardour/control_point_dialog.h @@ -17,19 +17,25 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "ardour_dialog.h" #include +#include + +#include "ardour_dialog.h" class ControlPoint; class ControlPointDialog : public ArdourDialog { public: - ControlPointDialog (ControlPoint *); + ControlPointDialog (ControlPoint *, bool multi); double get_y_fraction () const; + bool all_selected_points () const; + private: ControlPoint* point_; Gtk::Entry value_; + Gtk::CheckButton toggle_all_; + bool all_selected_points_; }; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index e331f54120..7ba0fa4e35 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2452,13 +2452,29 @@ Editor::edit_control_point (ArdourCanvas::Item* item) abort(); /*NOTREACHED*/ } - ControlPointDialog d (p); + std::vector cps; + + for (auto const& cp : selection->points) { + if (&cp->line() == &p->line ()) { + cps.push_back (cp); + } + } + + assert (cps.size() > 0); + + ControlPointDialog d (p, cps.size() > 1); if (d.run () != RESPONSE_ACCEPT) { return; } - p->line().modify_point_y (*p, d.get_y_fraction ()); + if (d.all_selected_points ()) { + p->line().modify_points_y (cps, d.get_y_fraction ()); + } else { + cps.clear (); + cps.push_back (p); + p->line().modify_points_y (cps, d.get_y_fraction ()); + } } void