diff --git a/gtk2_ardour/mono_panner.cc b/gtk2_ardour/mono_panner.cc index 8ba9c411bd..8b28d7f1a4 100644 --- a/gtk2_ardour/mono_panner.cc +++ b/gtk2_ardour/mono_panner.cc @@ -38,6 +38,7 @@ #include "ardour_ui.h" #include "global_signals.h" #include "mono_panner.h" +#include "mono_panner_editor.h" #include "rgb_macros.h" #include "utils.h" @@ -246,6 +247,10 @@ MonoPanner::on_expose_event (GdkEventExpose*) bool MonoPanner::on_button_press_event (GdkEventButton* ev) { + if (PannerInterface::on_button_press_event (ev)) { + return true; + } + drag_start_x = ev->x; last_drag_x = ev->x; @@ -304,6 +309,10 @@ MonoPanner::on_button_press_event (GdkEventButton* ev) bool MonoPanner::on_button_release_event (GdkEventButton* ev) { + if (PannerInterface::on_button_release_event (ev)) { + return true; + } + if (ev->button != 1) { return false; } @@ -440,3 +449,8 @@ MonoPanner::color_handler () queue_draw (); } +PannerEditor* +MonoPanner::editor () +{ + return new MonoPannerEditor (this); +} diff --git a/gtk2_ardour/mono_panner.h b/gtk2_ardour/mono_panner.h index ec47aa309d..3b7a37c993 100644 --- a/gtk2_ardour/mono_panner.h +++ b/gtk2_ardour/mono_panner.h @@ -52,6 +52,8 @@ class MonoPanner : public PannerInterface bool on_key_press_event (GdkEventKey*); private: + PannerEditor* editor (); + boost::shared_ptr position_control; PBD::ScopedConnectionList connections; int drag_start_x; diff --git a/gtk2_ardour/mono_panner_editor.cc b/gtk2_ardour/mono_panner_editor.cc new file mode 100644 index 0000000000..cf8c57a8e1 --- /dev/null +++ b/gtk2_ardour/mono_panner_editor.cc @@ -0,0 +1,119 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/gui_thread.h" +#include "pbd/controllable.h" +#include "mono_panner_editor.h" +#include "mono_panner.h" +#include "i18n.h" + +using namespace Gtk; +using namespace Gtkmm2ext; + +MonoPannerEditor::MonoPannerEditor (MonoPanner* p) + : PannerEditor (_("Mono Panner")) + , _panner (p) + , _ignore_changes (false) +{ + Table* t = manage (new Table (2, 3)); + t->set_spacings (6); + + int n = 0; + + t->attach (*manage (left_aligned_label (_("Left"))), 0, 1, n, n + 1); + t->attach (_left, 1, 2, n, n + 1); + t->attach (*manage (left_aligned_label (_("%"))), 2, 3, n, n + 1); + ++n; + + t->attach (*manage (left_aligned_label (_("Right"))), 0, 1, n, n + 1); + t->attach (_right, 1, 2, n, n + 1); + t->attach (*manage (left_aligned_label (_("%"))), 2, 3, n, n + 1); + ++n; + + get_vbox()->pack_start (*manage (t)); + get_vbox()->set_spacing (6); + + _left.set_increments (1, 10); + _left.set_range (0, 100); + _right.set_increments (1, 10); + _right.set_range (0, 100); + + _panner->get_controllable()->Changed.connect (_connections, invalidator (*this), boost::bind (&MonoPannerEditor::update_editor, this), gui_context ()); + _panner->DropReferences.connect (_connections, invalidator (*this), boost::bind (&MonoPannerEditor::panner_going_away, this), gui_context ()); + _left.signal_value_changed().connect (sigc::mem_fun (*this, &MonoPannerEditor::left_changed)); + _right.signal_value_changed().connect (sigc::mem_fun (*this, &MonoPannerEditor::right_changed)); + + show_all (); + update_editor (); +} + +void +MonoPannerEditor::panner_going_away () +{ + _panner = 0; +} + +void +MonoPannerEditor::update_editor () +{ + if (!_panner) { + return; + } + + float const v = _panner->get_controllable()->get_value(); + + _ignore_changes = true; + _left.set_value (100 * (1 - v)); + _right.set_value (100 * v); + _ignore_changes = false; +} + +void +MonoPannerEditor::left_changed () +{ + if (_ignore_changes || !_panner) { + return; + } + + float const v = 1 - _left.get_value () / 100; + + _ignore_changes = true; + _right.set_value (100 * v); + _panner->get_controllable()->set_value (v); + _ignore_changes = false; +} + +void +MonoPannerEditor::right_changed () +{ + if (_ignore_changes || !_panner) { + return; + } + + float const v = _right.get_value () / 100; + + _ignore_changes = true; + _left.set_value (100 * (1 - v)); + _panner->get_controllable()->set_value (v); + _ignore_changes = false; +} + diff --git a/gtk2_ardour/mono_panner_editor.h b/gtk2_ardour/mono_panner_editor.h new file mode 100644 index 0000000000..eb4e857e96 --- /dev/null +++ b/gtk2_ardour/mono_panner_editor.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "panner_editor.h" + +class MonoPanner; + +/** Editor dialog for the mono panner */ +class MonoPannerEditor : public PannerEditor +{ +public: + MonoPannerEditor (MonoPanner *); + +private: + void panner_going_away (); + void update_editor (); + void left_changed (); + void right_changed (); + + MonoPanner* _panner; + Gtk::SpinButton _left; + Gtk::SpinButton _right; + bool _ignore_changes; + + PBD::ScopedConnectionList _connections; +}; diff --git a/gtk2_ardour/panner_editor.cc b/gtk2_ardour/panner_editor.cc new file mode 100644 index 0000000000..0a1d9e8fa2 --- /dev/null +++ b/gtk2_ardour/panner_editor.cc @@ -0,0 +1,37 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "panner_editor.h" +#include "i18n.h" + +using namespace std; +using namespace Gtk; + +PannerEditor::PannerEditor (string t) + : ArdourDialog (t) +{ + Button* b = add_button (_("Close"), RESPONSE_CANCEL); + b->signal_clicked().connect (sigc::mem_fun(*this, &PannerEditor::close_button_clicked)); +} + +void +PannerEditor::close_button_clicked () +{ + hide (); +} diff --git a/gtk2_ardour/panner_editor.h b/gtk2_ardour/panner_editor.h new file mode 100644 index 0000000000..d538b78a1f --- /dev/null +++ b/gtk2_ardour/panner_editor.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "ardour_dialog.h" + +class PannerEditor : public ArdourDialog +{ +public: + PannerEditor (std::string); + +private: + void close_button_clicked (); +}; diff --git a/gtk2_ardour/panner_interface.cc b/gtk2_ardour/panner_interface.cc index 53a7535f4d..09155c6b79 100644 --- a/gtk2_ardour/panner_interface.cc +++ b/gtk2_ardour/panner_interface.cc @@ -20,6 +20,7 @@ #include #include "gtkmm2ext/keyboard.h" #include "panner_interface.h" +#include "panner_editor.h" #include "global_signals.h" #include "i18n.h" @@ -34,6 +35,7 @@ PannerInterface::PannerInterface (boost::shared_ptr p) , _drag_data_window (0) , _drag_data_label (0) , _dragging (false) + , _editor (0) { set_flags (Gtk::CAN_FOCUS); @@ -48,6 +50,7 @@ PannerInterface::PannerInterface (boost::shared_ptr p) PannerInterface::~PannerInterface () { delete _drag_data_window; + delete _editor; } void @@ -135,3 +138,32 @@ PannerInterface::value_change () queue_draw (); } +bool +PannerInterface::on_button_press_event (GdkEventButton* ev) +{ + if (Gtkmm2ext::Keyboard::is_edit_event (ev)) { + edit (); + return true; + } + + return false; +} + +bool +PannerInterface::on_button_release_event (GdkEventButton* ev) +{ + if (Gtkmm2ext::Keyboard::is_edit_event (ev)) { + /* We edited on the press, so claim the release */ + return true; + } + + return false; +} + +void +PannerInterface::edit () +{ + delete _editor; + _editor = editor (); + _editor->show (); +} diff --git a/gtk2_ardour/panner_interface.h b/gtk2_ardour/panner_interface.h index 167ea6d7be..8dd19d1a14 100644 --- a/gtk2_ardour/panner_interface.h +++ b/gtk2_ardour/panner_interface.h @@ -23,21 +23,30 @@ #include #include #include +#include "pbd/destructible.h" namespace ARDOUR { class Panner; } +class PannerEditor; + /** Parent class for some panner UI classes that contains some common code */ -class PannerInterface : public Gtk::DrawingArea +class PannerInterface : public Gtk::DrawingArea, public PBD::Destructible { public: PannerInterface (boost::shared_ptr); virtual ~PannerInterface (); + boost::shared_ptr panner () { + return _panner; + } + + void edit (); + protected: virtual void set_drag_data () = 0; - + void show_drag_data_window (); void hide_drag_data_window (); void value_change (); @@ -45,6 +54,8 @@ protected: bool on_enter_notify_event (GdkEventCrossing *); bool on_leave_notify_event (GdkEventCrossing *); bool on_key_release_event (GdkEventKey *); + bool on_button_press_event (GdkEventButton*); + bool on_button_release_event (GdkEventButton*); boost::shared_ptr _panner; Gtk::Window* _drag_data_window; @@ -54,6 +65,9 @@ protected: private: bool drag_data_timeout (); sigc::connection _drag_data_timeout; + + virtual PannerEditor* editor () = 0; + PannerEditor* _editor; }; #endif diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc index 239a64ccb7..433b5b0c02 100644 --- a/gtk2_ardour/panner_ui.cc +++ b/gtk2_ardour/panner_ui.cc @@ -37,7 +37,6 @@ #include "stereo_panner.h" #include "mono_panner.h" - #include "i18n.h" using namespace std; @@ -388,6 +387,7 @@ PannerUI::build_pan_menu () bypass_menu_item->signal_toggled().connect (sigc::mem_fun(*this, &PannerUI::pan_bypass_toggle)); items.push_back (MenuElem (_("Reset"), sigc::mem_fun (*this, &PannerUI::pan_reset))); + items.push_back (MenuElem (_("Edit..."), sigc::mem_fun (*this, &PannerUI::pan_edit))); } void @@ -398,6 +398,16 @@ PannerUI::pan_bypass_toggle () } } +void +PannerUI::pan_edit () +{ + if (_mono_panner) { + _mono_panner->edit (); + } else if (_stereo_panner) { + _stereo_panner->edit (); + } +} + void PannerUI::pan_reset () { diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h index 046e23cd7a..de93d49956 100644 --- a/gtk2_ardour/panner_ui.h +++ b/gtk2_ardour/panner_ui.h @@ -140,6 +140,7 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr void build_pan_menu (); void pan_reset (); void pan_bypass_toggle (); + void pan_edit (); void pan_automation_state_changed(); void pan_automation_style_changed(); diff --git a/gtk2_ardour/stereo_panner.cc b/gtk2_ardour/stereo_panner.cc index 96e1821ee6..5ee75ecc19 100644 --- a/gtk2_ardour/stereo_panner.cc +++ b/gtk2_ardour/stereo_panner.cc @@ -37,6 +37,7 @@ #include "ardour_ui.h" #include "global_signals.h" #include "stereo_panner.h" +#include "stereo_panner_editor.h" #include "rgb_macros.h" #include "utils.h" @@ -263,6 +264,10 @@ StereoPanner::on_expose_event (GdkEventExpose*) bool StereoPanner::on_button_press_event (GdkEventButton* ev) { + if (PannerInterface::on_button_press_event (ev)) { + return true; + } + drag_start_x = ev->x; last_drag_x = ev->x; @@ -398,6 +403,10 @@ StereoPanner::on_button_press_event (GdkEventButton* ev) bool StereoPanner::on_button_release_event (GdkEventButton* ev) { + if (PannerInterface::on_button_release_event (ev)) { + return true; + } + if (ev->button != 1) { return false; } @@ -631,3 +640,9 @@ StereoPanner::color_handler () set_colors (); queue_draw (); } + +PannerEditor* +StereoPanner::editor () +{ + return new StereoPannerEditor (this); +} diff --git a/gtk2_ardour/stereo_panner.h b/gtk2_ardour/stereo_panner.h index 8d76442724..19fa0c056e 100644 --- a/gtk2_ardour/stereo_panner.h +++ b/gtk2_ardour/stereo_panner.h @@ -38,6 +38,9 @@ class StereoPanner : public PannerInterface StereoPanner (boost::shared_ptr); ~StereoPanner (); + boost::shared_ptr get_position_controllable() const { return position_control; } + boost::shared_ptr get_width_controllable() const { return width_control; } + sigc::signal StartPositionGesture; sigc::signal StopPositionGesture; sigc::signal StartWidthGesture; @@ -52,6 +55,8 @@ class StereoPanner : public PannerInterface bool on_key_press_event (GdkEventKey*); private: + PannerEditor* editor (); + boost::shared_ptr position_control; boost::shared_ptr width_control; PBD::ScopedConnectionList connections; diff --git a/gtk2_ardour/stereo_panner_editor.cc b/gtk2_ardour/stereo_panner_editor.cc new file mode 100644 index 0000000000..0cc856f500 --- /dev/null +++ b/gtk2_ardour/stereo_panner_editor.cc @@ -0,0 +1,138 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/gui_thread.h" +#include "ardour/panner.h" +#include "pbd/controllable.h" +#include "stereo_panner_editor.h" +#include "stereo_panner.h" +#include "i18n.h" + +using namespace std; +using namespace Gtk; +using namespace Gtkmm2ext; + +StereoPannerEditor::StereoPannerEditor (StereoPanner* p) + : PannerEditor (_("Stereo Panner")) + , _panner (p) + , _ignore_changes (false) +{ + Table* t = manage (new Table (2, 3)); + t->set_spacings (6); + + int n = 0; + + t->attach (*manage (left_aligned_label (_("Position"))), 0, 1, n, n + 1); + t->attach (_position, 1, 2, n, n + 1); + t->attach (*manage (left_aligned_label (_("%"))), 2, 3, n, n + 1); + ++n; + + t->attach (*manage (left_aligned_label (_("Width"))), 0, 1, n, n + 1); + t->attach (_width, 1, 2, n, n + 1); + t->attach (*manage (left_aligned_label (_("%"))), 2, 3, n, n + 1); + ++n; + + get_vbox()->pack_start (*manage (t)); + get_vbox()->set_spacing (6); + + _position.set_increments (1, 10); + _width.set_increments (1, 10); + set_position_range (); + set_width_range (); + + _panner->get_position_controllable()->Changed.connect ( + _connections, invalidator (*this), boost::bind (&StereoPannerEditor::update_editor, this), gui_context () + ); + + _panner->get_width_controllable()->Changed.connect ( + _connections, invalidator (*this), boost::bind (&StereoPannerEditor::update_editor, this), gui_context () + ); + + _panner->DropReferences.connect (_connections, invalidator (*this), boost::bind (&StereoPannerEditor::panner_going_away, this), gui_context ()); + _position.signal_value_changed().connect (sigc::mem_fun (*this, &StereoPannerEditor::position_changed)); + _width.signal_value_changed().connect (sigc::mem_fun (*this, &StereoPannerEditor::width_changed)); + + show_all (); + update_editor (); +} + +void +StereoPannerEditor::panner_going_away () +{ + _panner = 0; +} + +void +StereoPannerEditor::update_editor () +{ + if (!_panner) { + return; + } + + _ignore_changes = true; + _position.set_value (100 * _panner->get_position_controllable()->get_value ()); + _width.set_value (100 * _panner->get_width_controllable()->get_value ()); + _ignore_changes = false; +} + +void +StereoPannerEditor::position_changed () +{ + if (_ignore_changes || !_panner) { + return; + } + + _ignore_changes = true; + double const v = _position.get_value() / 100; + _panner->get_position_controllable()->set_value (v); + set_width_range (); + _ignore_changes = false; +} + +void +StereoPannerEditor::width_changed () +{ + if (_ignore_changes || !_panner) { + return; + } + + _ignore_changes = true; + double const v = _width.get_value() / 100; + _panner->get_width_controllable()->set_value (v); + set_position_range (); + _ignore_changes = false; +} + +void +StereoPannerEditor::set_position_range () +{ + pair const pr = _panner->panner()->position_range (); + _position.set_range (pr.first * 100, pr.second * 100); +} + +void +StereoPannerEditor::set_width_range () +{ + pair const wr = _panner->panner()->width_range (); + _width.set_range (wr.first * 100, wr.second * 100); +} + diff --git a/gtk2_ardour/stereo_panner_editor.h b/gtk2_ardour/stereo_panner_editor.h new file mode 100644 index 0000000000..8c561e5545 --- /dev/null +++ b/gtk2_ardour/stereo_panner_editor.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "panner_editor.h" + +class StereoPanner; + +/** Editor dialog for the stereo panner */ +class StereoPannerEditor : public PannerEditor +{ +public: + StereoPannerEditor (StereoPanner *); + +private: + void panner_going_away (); + void update_editor (); + void position_changed (); + void width_changed (); + void set_position_range (); + void set_width_range (); + + StereoPanner* _panner; + Gtk::SpinButton _position; + Gtk::SpinButton _width; + bool _ignore_changes; + + PBD::ScopedConnectionList _connections; +}; diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 99a668641c..2fb8f0ddd9 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -155,6 +155,7 @@ gtk2_ardour_sources = [ 'mixer_ui.cc', 'monitor_section.cc', 'mono_panner.cc', + 'mono_panner_editor.cc', 'mouse_cursors.cc', 'nag.cc', 'new_plugin_preset_dialog.cc', @@ -163,6 +164,7 @@ gtk2_ardour_sources = [ 'option_editor.cc', 'opts.cc', 'panner2d.cc', + 'panner_editor.cc', 'panner_interface.cc', 'panner_ui.cc', 'piano_roll_header.cc', @@ -215,6 +217,7 @@ gtk2_ardour_sources = [ 'step_editor.cc', 'step_entry.cc', 'stereo_panner.cc', + 'stereo_panner_editor.cc', 'streamview.cc', 'strip_silence_dialog.cc', 'tape_region_view.cc', diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 4c585f8b31..b30b1859a3 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -71,6 +71,10 @@ public: virtual bool clamp_width (double&) { return true; } virtual bool clamp_elevation (double&) { return true; } + virtual std::pair position_range () const { return std::make_pair (-DBL_MAX, DBL_MAX); } + virtual std::pair width_range () const { return std::make_pair (-DBL_MAX, DBL_MAX); } + virtual std::pair elevation_range () const { return std::make_pair (-DBL_MAX, DBL_MAX); } + virtual void set_position (double) { } virtual void set_width (double) { } virtual void set_elevation (double) { } diff --git a/libs/panners/1in2out/panner_1in2out.cc b/libs/panners/1in2out/panner_1in2out.cc index d84af57ade..4524ed560b 100644 --- a/libs/panners/1in2out/panner_1in2out.cc +++ b/libs/panners/1in2out/panner_1in2out.cc @@ -121,6 +121,12 @@ Panner1in2out::clamp_position (double& p) return true; } +pair +Panner1in2out::position_range () const +{ + return make_pair (0, 1); +} + double Panner1in2out::position () const { diff --git a/libs/panners/1in2out/panner_1in2out.h b/libs/panners/1in2out/panner_1in2out.h index 13b48fa839..97d23495c7 100644 --- a/libs/panners/1in2out/panner_1in2out.h +++ b/libs/panners/1in2out/panner_1in2out.h @@ -43,6 +43,7 @@ class Panner1in2out : public Panner void set_position (double); bool clamp_position (double&); + std::pair position_range () const; double position() const; diff --git a/libs/panners/2in2out/panner_2in2out.cc b/libs/panners/2in2out/panner_2in2out.cc index 57b8836787..a316b764c7 100644 --- a/libs/panners/2in2out/panner_2in2out.cc +++ b/libs/panners/2in2out/panner_2in2out.cc @@ -152,8 +152,8 @@ Panner2in2out::update () */ float pos[2]; - double width = _pannable->pan_width_control->get_value(); - const double direction_as_lr_fract = _pannable->pan_azimuth_control->get_value(); + double width = this->width (); + const double direction_as_lr_fract = position (); if (width < 0.0) { width = -width; @@ -189,17 +189,30 @@ Panner2in2out::update () bool Panner2in2out::clamp_position (double& p) { - double w = _pannable->pan_width_control->get_value(); + double w = width (); return clamp_stereo_pan (p, w); } bool Panner2in2out::clamp_width (double& w) { - double p = _pannable->pan_azimuth_control->get_value(); + double p = position (); return clamp_stereo_pan (p, w); } +pair +Panner2in2out::position_range () const +{ + return make_pair (0.5 - (1 - width()) / 2, 0.5 + (1 - width()) / 2); +} + +pair +Panner2in2out::width_range () const +{ + double const w = min (position(), (1 - position())) * 2; + return make_pair (-w, w); +} + bool Panner2in2out::clamp_stereo_pan (double& direction_as_lr_fract, double& width) { diff --git a/libs/panners/2in2out/panner_2in2out.h b/libs/panners/2in2out/panner_2in2out.h index 001d3064e8..a34556d463 100644 --- a/libs/panners/2in2out/panner_2in2out.h +++ b/libs/panners/2in2out/panner_2in2out.h @@ -49,6 +49,9 @@ class Panner2in2out : public Panner bool clamp_position (double&); bool clamp_width (double&); + std::pair position_range () const; + std::pair width_range () const; + void set_position (double); void set_width (double);