From ab407e385fed5a896e75db9f99d9a4bec8f0daa5 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Mon, 24 Oct 2022 15:53:39 +0200 Subject: [PATCH] PoC: Implement += -= *= /= for control point editing For example, if editing a control point at 7 dB and entering "+= 3" in the input field instead of "7", it will set the control pointto 10 dB. This is especially useful when editing multiple automation points at once. --- gtk2_ardour/automation_line.cc | 50 +++++++++++++++++++++++------ gtk2_ardour/automation_line.h | 2 +- gtk2_ardour/control_point_dialog.cc | 6 ++-- gtk2_ardour/control_point_dialog.h | 2 +- gtk2_ardour/editor_mouse.cc | 2 +- 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 4aca2e43d88..9a9648947d2 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -390,26 +390,58 @@ AutomationLine::delta_to_string (double delta) const * @return Corresponding y fraction. */ double -AutomationLine::string_to_fraction (string const & s) const +AutomationLine::string_to_fraction (string const & s, double const old_fraction) const { - double v; - sscanf (s.c_str(), "%lf", &v); - + bool is_db = false; switch (_desc.type) { case GainAutomation: case BusSendLevel: case EnvelopeAutomation: case TrimAutomation: case InsertReturnLevel: - if (s == "-inf") { /* translation */ - v = 0; - } else { - v = dB_to_coefficient (v); - } + is_db = true; break; default: break; } + double v; + if ((s.length() > 2) && index("+-*/", s[0]) && (s[1] == '=')) { + v = old_fraction; + view_to_model_coord_y (v); + if (is_db) { + v = accurate_coefficient_to_dB(v); + } + double op_v; + sscanf (s.c_str() + 2, "%lf", &op_v); + if (op_v != 0.f) { + switch (s[0]) { + case '+': + v += op_v; + break; + case '-': + v -= op_v; + break; + case '*': + v *= op_v; + break; + case '/': + if (op_v > 1.0) { + v /= op_v; + } + break; + } + } + } else { + sscanf (s.c_str(), "%lf", &v); + } + + if (is_db) { + if (s == "-inf") { /* translation */ + v = 0; + } else { + v = dB_to_coefficient (v); + } + } return model_to_view_coord_y (v); } diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index 9fa64552e4d..5d2f113ace6 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -128,7 +128,7 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible std::string get_verbose_cursor_relative_string (double, double) const; std::string fraction_to_string (double) const; std::string delta_to_string (double) const; - double string_to_fraction (std::string const &) const; + double string_to_fraction (std::string const &, double old_fraction) const; void view_to_model_coord_y (double &) const; diff --git a/gtk2_ardour/control_point_dialog.cc b/gtk2_ardour/control_point_dialog.cc index 6f111d45b2f..ac7622332a1 100644 --- a/gtk2_ardour/control_point_dialog.cc +++ b/gtk2_ardour/control_point_dialog.cc @@ -73,7 +73,9 @@ ControlPointDialog::ControlPointDialog (ControlPoint* p) } double -ControlPointDialog::get_y_fraction () const +ControlPointDialog::get_y_fraction (ControlPoint* p) const { - return point_->line().string_to_fraction (value_.get_text ()); + double const old_fraction = 1.0 - (p->get_y () / p->line().height ()); + + return point_->line().string_to_fraction (value_.get_text (), old_fraction); } diff --git a/gtk2_ardour/control_point_dialog.h b/gtk2_ardour/control_point_dialog.h index 539a41c8b3f..54a13d5e8fa 100644 --- a/gtk2_ardour/control_point_dialog.h +++ b/gtk2_ardour/control_point_dialog.h @@ -27,7 +27,7 @@ class ControlPointDialog : public ArdourDialog public: ControlPointDialog (ControlPoint *); - double get_y_fraction () const; + double get_y_fraction (ControlPoint *) const; private: ControlPoint* point_; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 85746d4b74c..1dd525c14ee 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2376,7 +2376,7 @@ Editor::edit_control_point (ArdourCanvas::Item* item) } for (ControlPoint* const & control_point : selection->points) { - control_point->line().modify_point_y (*control_point, d.get_y_fraction ()); + control_point->line().modify_point_y (*control_point, d.get_y_fraction (control_point)); } }