mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-01 03:17:39 +01:00
[Summary] Made panners to move relatively on selected tracks
[Reviewed by QA] Andriy Mishyn
This commit is contained in:
parent
0334c46596
commit
416bfc5aab
6 changed files with 199 additions and 52 deletions
|
|
@ -1730,7 +1730,7 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
|
|||
uint32_t const in = _current_delivery->pans_required();
|
||||
uint32_t const out = _current_delivery->pan_outs();
|
||||
|
||||
panner_ui().set_panner (_current_delivery->panner_shell(), _current_delivery->panner());
|
||||
panner_ui().set_panner (boost::shared_ptr<Route>(), _current_delivery->panner_shell(), _current_delivery->panner());
|
||||
panner_ui().set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
|
||||
panner_ui().setup_pan ();
|
||||
panner_ui().show_all ();
|
||||
|
|
@ -1756,7 +1756,7 @@ MixerStrip::revert_to_default_display ()
|
|||
gain_meter().set_controls (_route, _route->shared_peak_meter(), _route->amp());
|
||||
gain_meter().setup_meters ();
|
||||
|
||||
panner_ui().set_panner (_route->main_outs()->panner_shell(), _route->main_outs()->panner());
|
||||
panner_ui().set_panner (_route, _route->main_outs()->panner_shell(), _route->main_outs()->panner());
|
||||
update_panner_choices();
|
||||
panner_ui().setup_pan ();
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "ardour/panner.h"
|
||||
#include "ardour/panner_shell.h"
|
||||
|
||||
#include "public_editor.h"
|
||||
#include "selection.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "global_signals.h"
|
||||
#include "mono_panner.h"
|
||||
|
|
@ -53,6 +55,7 @@ using namespace Gtkmm2ext;
|
|||
using namespace ARDOUR_UI_UTILS;
|
||||
|
||||
Gdk::Cursor* MonoPanner::__touch_cursor;
|
||||
double MonoPanner::DEFAULT_VALUE = 0.5;
|
||||
|
||||
MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::PannerShell> p)
|
||||
: PannerInterface (p->panner())
|
||||
|
|
@ -65,26 +68,22 @@ MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::PannerShell> p)
|
|||
, position_binder (position_control)
|
||||
, _dragging (false)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
if (_knob_image[0] == 0) {
|
||||
for (size_t i=0; i < (sizeof(_knob_image)/sizeof(_knob_image[0])); i++) {
|
||||
_knob_image[i] = load_pixbuf (_knob_image_files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (__touch_cursor == 0) {
|
||||
__touch_cursor = new Gdk::Cursor (Gdk::Display::get_default(),
|
||||
::get_icon ("panner_touch_cursor"),
|
||||
12,
|
||||
12);
|
||||
}
|
||||
|
||||
position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context());
|
||||
|
||||
_panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::bypass_handler, this), gui_context());
|
||||
_panner_shell->PannableChanged.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::pannable_handler, this), gui_context());
|
||||
|
||||
set_tooltip ();
|
||||
MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::Route> route, boost::shared_ptr<ARDOUR::PannerShell> p)
|
||||
: PannerInterface (p->panner())
|
||||
, _route (route)
|
||||
, _panner_shell (p)
|
||||
, position_control (_panner->pannable()->pan_azimuth_control)
|
||||
, drag_start_y (0)
|
||||
, last_drag_y (0)
|
||||
, accumulated_delta (0)
|
||||
, detented (false)
|
||||
, position_binder (position_control)
|
||||
, _dragging (false)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
MonoPanner::~MonoPanner ()
|
||||
|
|
@ -92,6 +91,30 @@ MonoPanner::~MonoPanner ()
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
MonoPanner::init ()
|
||||
{
|
||||
if (_knob_image[0] == 0) {
|
||||
for (size_t i=0; i < (sizeof(_knob_image)/sizeof(_knob_image[0])); i++) {
|
||||
_knob_image[i] = load_pixbuf (_knob_image_files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (__touch_cursor == 0) {
|
||||
__touch_cursor = new Gdk::Cursor (Gdk::Display::get_default(),
|
||||
::get_icon ("panner_touch_cursor"),
|
||||
12,
|
||||
12);
|
||||
}
|
||||
|
||||
position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context());
|
||||
|
||||
_panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::bypass_handler, this), gui_context());
|
||||
_panner_shell->PannableChanged.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::pannable_handler, this), gui_context());
|
||||
|
||||
set_tooltip ();
|
||||
}
|
||||
|
||||
void
|
||||
MonoPanner::set_tooltip ()
|
||||
{
|
||||
|
|
@ -174,7 +197,36 @@ MonoPanner::on_button_press_event (GdkEventButton* ev)
|
|||
|
||||
if (ev->type == GDK_BUTTON_PRESS) {
|
||||
if (Keyboard::modifier_state_contains (ev->state, alt_modifier)) {
|
||||
position_control->set_value (0.5);
|
||||
|
||||
// reset panner to default value
|
||||
if (_route && _route->main_outs()->panner() == _panner) {
|
||||
|
||||
// determine if we deal with selection
|
||||
PublicEditor& editor = ARDOUR_UI::instance()->the_editor();
|
||||
Selection& selection = editor.get_selection();
|
||||
TimeAxisView* tv = editor.get_route_view_by_route_id (_route->id() );
|
||||
|
||||
if (tv && selection.selected(tv) && selection.tracks.size() > 1 ) {
|
||||
boost::shared_ptr<ARDOUR::RouteList> routes = get_selected_routes ();
|
||||
|
||||
ARDOUR::RouteList::const_iterator iter = routes->begin();
|
||||
for (; iter != routes->end(); ++iter) {
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> control;
|
||||
control = (*iter)->panner()->pannable()->pan_azimuth_control;
|
||||
control->set_value (DEFAULT_VALUE);
|
||||
}
|
||||
} else {
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> control;
|
||||
control = _route->panner()->pannable()->pan_azimuth_control;
|
||||
control->set_value (DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
} else {
|
||||
position_control->set_value (DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
_dragging = false;
|
||||
_tooltip.target_stop_drag ();
|
||||
} else {
|
||||
|
|
@ -265,33 +317,111 @@ MonoPanner::on_motion_notify_event (GdkEventMotion* ev)
|
|||
int w = get_width();
|
||||
double delta = (last_drag_y - ev->y) / (double) w;
|
||||
|
||||
/* create a detent close to the center */
|
||||
|
||||
if (!detented && ARDOUR::Panner::equivalent (position_control->get_value(), 0.5)) {
|
||||
detented = true;
|
||||
/* snap to center */
|
||||
position_control->set_value (0.5);
|
||||
}
|
||||
|
||||
if (detented) {
|
||||
accumulated_delta += delta;
|
||||
|
||||
/* have we pulled far enough to escape ? */
|
||||
|
||||
if (fabs (accumulated_delta) >= 0.025) {
|
||||
position_control->set_value (position_control->get_value() + accumulated_delta);
|
||||
detented = false;
|
||||
accumulated_delta = false;
|
||||
}
|
||||
} else {
|
||||
double pv = position_control->get_value(); // 0..1.0 ; 0 = left
|
||||
position_control->set_value (pv + delta);
|
||||
}
|
||||
adjust_pan_value_by (delta);
|
||||
|
||||
last_drag_y = ev->y;
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::shared_ptr<ARDOUR::RouteList>
|
||||
MonoPanner::get_selected_routes ()
|
||||
{
|
||||
Selection& selection = ARDOUR_UI::instance()->the_editor().get_selection();
|
||||
|
||||
boost::shared_ptr<ARDOUR::RouteList> routes (new ARDOUR::RouteList);
|
||||
|
||||
TrackViewList track_list = selection.tracks;
|
||||
TrackViewList::const_iterator iter = track_list.begin ();
|
||||
for (; iter != track_list.end(); ++iter) {
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*iter);
|
||||
|
||||
if (rtv) {
|
||||
routes->push_back(rtv->route() );
|
||||
}
|
||||
}
|
||||
|
||||
return routes;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MonoPanner::adjust_pan_value_by (double delta)
|
||||
{
|
||||
// first, calculate correct increment delta value
|
||||
double update_by_delta = 0;
|
||||
|
||||
/* create a detent close to the center */
|
||||
if (!detented && ARDOUR::Panner::equivalent (position_control->get_value(), DEFAULT_VALUE)) {
|
||||
detented = true;
|
||||
}
|
||||
|
||||
if (detented) {
|
||||
accumulated_delta += delta;
|
||||
|
||||
/* have we pulled far enough to escape ? */
|
||||
|
||||
if (fabs (accumulated_delta) >= 0.025) {
|
||||
update_by_delta = accumulated_delta;
|
||||
detented = false;
|
||||
accumulated_delta = 0;
|
||||
}
|
||||
} else {
|
||||
update_by_delta = delta;
|
||||
}
|
||||
|
||||
// we've reached the bottom or the top, so don't move in this direction any more
|
||||
double original_val = position_control->get_value();
|
||||
if ( (update_by_delta > 0 && original_val >= 1 ) ||
|
||||
(update_by_delta < 0 && original_val <= 0 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure that calculated delta won't exceed the value we need to reach the top
|
||||
// or make us to go lower then the the bottom
|
||||
double result_value = original_val + update_by_delta;
|
||||
if (result_value < 0 ) {
|
||||
update_by_delta = update_by_delta - result_value;
|
||||
} else if (result_value > 1) {
|
||||
update_by_delta = update_by_delta - (result_value - 1);
|
||||
}
|
||||
|
||||
// apply change to the associated route if we have it
|
||||
if (_route && _route->main_outs()->panner() == _panner) {
|
||||
|
||||
// determine if we deal with selection
|
||||
PublicEditor& editor = ARDOUR_UI::instance()->the_editor();
|
||||
Selection& selection = editor.get_selection();
|
||||
TimeAxisView* tv = editor.get_route_view_by_route_id (_route->id() );
|
||||
|
||||
if (tv && selection.selected(tv) && selection.tracks.size() > 1 ) {
|
||||
boost::shared_ptr<ARDOUR::RouteList> routes = get_selected_routes ();
|
||||
|
||||
// apply the change
|
||||
ARDOUR::RouteList::const_iterator iter = routes->begin();
|
||||
for (; iter != routes->end(); ++iter) {
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> control;
|
||||
control = (*iter)->panner()->pannable()->pan_azimuth_control;
|
||||
|
||||
double pv = control->get_value(); // 0..1.0 ; 0 = left
|
||||
control->set_value (pv + update_by_delta);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> control;
|
||||
control = _route->panner()->pannable()->pan_azimuth_control;
|
||||
|
||||
double pv = control->get_value(); // 0..1.0 ; 0 = left
|
||||
control->set_value (pv + update_by_delta);
|
||||
}
|
||||
|
||||
} else { // apply change to the panner directly
|
||||
double pv = position_control->get_value(); // 0..1.0 ; 0 = left
|
||||
position_control->set_value (pv + update_by_delta);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MonoPanner::on_key_press_event (GdkEventKey* ev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "panner_interface.h"
|
||||
|
||||
#include "ardour/route.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class PannerShell;
|
||||
}
|
||||
|
|
@ -39,7 +41,12 @@ namespace PBD {
|
|||
class MonoPanner : public PannerInterface
|
||||
{
|
||||
public:
|
||||
|
||||
static double DEFAULT_VALUE;
|
||||
|
||||
MonoPanner (boost::shared_ptr<ARDOUR::PannerShell>);
|
||||
MonoPanner (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::PannerShell>);
|
||||
|
||||
~MonoPanner ();
|
||||
|
||||
boost::shared_ptr<PBD::Controllable> get_controllable() const { return position_control; }
|
||||
|
|
@ -54,9 +61,15 @@ class MonoPanner : public PannerInterface
|
|||
bool on_motion_notify_event (GdkEventMotion*);
|
||||
bool on_scroll_event (GdkEventScroll*);
|
||||
bool on_key_press_event (GdkEventKey*);
|
||||
|
||||
void adjust_pan_value_by (double);
|
||||
|
||||
private:
|
||||
void init ();
|
||||
boost::shared_ptr<ARDOUR::RouteList> get_selected_routes ();
|
||||
|
||||
PannerEditor* editor ();
|
||||
boost::shared_ptr<ARDOUR::Route> _route;
|
||||
boost::shared_ptr<ARDOUR::PannerShell> _panner_shell;
|
||||
|
||||
boost::shared_ptr<PBD::Controllable> position_control;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ PannerUI::PannerUI (Session* s)
|
|||
}
|
||||
|
||||
void
|
||||
PannerUI::set_panner (boost::shared_ptr<PannerShell> ps, boost::shared_ptr<Panner> p)
|
||||
PannerUI::set_panner (boost::shared_ptr<ARDOUR::Route> route, boost::shared_ptr<PannerShell> ps, boost::shared_ptr<Panner> p)
|
||||
{
|
||||
/* note that the panshell might not change here (i.e. ps == _panshell)
|
||||
*/
|
||||
|
|
@ -115,6 +115,9 @@ PannerUI::set_panner (boost::shared_ptr<PannerShell> ps, boost::shared_ptr<Panne
|
|||
delete _mono_panner;
|
||||
_mono_panner = 0;
|
||||
|
||||
_route.reset();
|
||||
_route = route;
|
||||
|
||||
if (!_panner) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -204,7 +207,7 @@ PannerUI::~PannerUI ()
|
|||
void
|
||||
PannerUI::panshell_changed ()
|
||||
{
|
||||
set_panner (_panshell, _panshell->panner());
|
||||
set_panner (_route, _panshell, _panshell->panner());
|
||||
setup_pan ();
|
||||
}
|
||||
|
||||
|
|
@ -275,8 +278,8 @@ PannerUI::setup_pan ()
|
|||
boost::shared_ptr<Pannable> pannable = _panner->pannable();
|
||||
boost::shared_ptr<AutomationControl> ac = pannable->pan_azimuth_control;
|
||||
|
||||
_mono_panner = new MonoPanner (_panshell);
|
||||
|
||||
_mono_panner = new MonoPanner (_route, _panshell);
|
||||
|
||||
_mono_panner->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch),
|
||||
boost::weak_ptr<AutomationControl> (ac)));
|
||||
_mono_panner->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch),
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr
|
|||
PannerUI (ARDOUR::Session*);
|
||||
~PannerUI ();
|
||||
|
||||
virtual void set_panner (boost::shared_ptr<ARDOUR::PannerShell>, boost::shared_ptr<ARDOUR::Panner>);
|
||||
virtual void set_panner (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::PannerShell>, boost::shared_ptr<ARDOUR::Panner>);
|
||||
|
||||
void panshell_changed ();
|
||||
|
||||
|
|
@ -110,7 +110,8 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr
|
|||
|
||||
StereoPanner* _stereo_panner;
|
||||
MonoPanner* _mono_panner;
|
||||
|
||||
boost::shared_ptr<ARDOUR::Route> _route;
|
||||
|
||||
bool _ignore_width_change;
|
||||
bool _ignore_position_change;
|
||||
void width_adjusted ();
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ SendUI::SendUI (Gtk::Window* parent, boost::shared_ptr<Send> s, Session* session
|
|||
{
|
||||
assert (_send);
|
||||
|
||||
_panners.set_panner (s->panner_shell(), s->panner());
|
||||
_panners.set_panner (boost::shared_ptr<Route>(), s->panner_shell(), s->panner());
|
||||
_gpm.set_controls (boost::shared_ptr<Route>(), s->meter(), s->amp());
|
||||
|
||||
_hbox.pack_start (_gpm, true, true);
|
||||
|
|
@ -104,7 +104,7 @@ SendUI::outs_changed (IOChange change, void* /*ignored*/)
|
|||
uint32_t const in = _send->pans_required();
|
||||
uint32_t const out = _send->pan_outs();
|
||||
if (_panners._panner == 0) {
|
||||
_panners.set_panner (_send->panner_shell(), _send->panner());
|
||||
_panners.set_panner (boost::shared_ptr<Route>(), _send->panner_shell(), _send->panner());
|
||||
}
|
||||
_panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
|
||||
_panners.setup_pan ();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue