Move panner bypass state up to the PannerShell so that it is preserved even when...
[ardour.git] / gtk2_ardour / panner2d.cc
index a4801f905d1d0c4307b687453cce77428d13526a..d61471d19e1ccadbc7e4ae8184e50969ecc8ec21 100644 (file)
@@ -29,6 +29,7 @@
 #include "pbd/error.h"
 #include "pbd/cartesian.h"
 #include "ardour/panner.h"
+#include "ardour/panner_shell.h"
 #include "ardour/pannable.h"
 #include "ardour/speakers.h"
 
@@ -67,17 +68,17 @@ Panner2d::Target::set_text (const char* txt)
        text = txt;
 }
 
-Panner2d::Panner2d (boost::shared_ptr<Panner> p, int32_t h)
-       : panner (p)
+Panner2d::Panner2d (boost::shared_ptr<PannerShell> p, int32_t h)
+       : panner_shell (p)
         , position (AngularVector (0.0, 0.0), "")
         , width (0)
         , height (h)
         , last_width (0)
 {
-       panner->StateChanged.connect (connections, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context());
+       panner_shell->Changed.connect (connections, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context());
 
-        panner->pannable()->pan_azimuth_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
-        panner->pannable()->pan_width_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
+        panner_shell->pannable()->pan_azimuth_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
+        panner_shell->pannable()->pan_width_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
 
        drag_target = 0;
        set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
@@ -95,7 +96,7 @@ Panner2d::~Panner2d()
 void
 Panner2d::reset (uint32_t n_inputs)
 {
-        uint32_t nouts = panner->out().n_audio();
+        uint32_t nouts = panner_shell->panner()->out().n_audio();
 
        /* signals */
 
@@ -110,11 +111,11 @@ Panner2d::reset (uint32_t n_inputs)
 
                signals.resize (n_inputs);
        }
-                                               
+
         label_signals ();
 
         for (uint32_t i = 0; i < n_inputs; ++i) {
-                signals[i]->position = panner->signal_position (i);
+                signals[i]->position = panner_shell->panner()->signal_position (i);
         }
 
        /* add all outputs */
@@ -134,8 +135,8 @@ Panner2d::reset (uint32_t n_inputs)
        for (Targets::iterator x = speakers.begin(); x != speakers.end(); ++x) {
                (*x)->visible = false;
        }
-        
-        vector<Speaker>& the_speakers (panner->get_speakers()->speakers());
+
+        vector<Speaker>& the_speakers (panner_shell->panner()->get_speakers()->speakers());
 
        for (uint32_t n = 0; n < nouts; ++n) {
                char buf[16];
@@ -204,7 +205,7 @@ Panner2d::handle_state_change ()
 void
 Panner2d::label_signals ()
 {
-        double w = panner->pannable()->pan_width_control->get_value();
+        double w = panner_shell->pannable()->pan_width_control->get_value();
         uint32_t sz = signals.size();
 
        switch (sz) {
@@ -243,12 +244,12 @@ void
 Panner2d::handle_position_change ()
 {
        uint32_t n;
-        double w = panner->pannable()->pan_width_control->get_value();
+        double w = panner_shell->pannable()->pan_width_control->get_value();
 
-        position.position = AngularVector (panner->pannable()->pan_azimuth_control->get_value() * 360.0, 0.0);
+        position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0, 0.0);
 
         for (uint32_t i = 0; i < signals.size(); ++i) {
-                signals[i]->position = panner->signal_position (i);
+                signals[i]->position = panner_shell->panner()->signal_position (i);
         }
 
         if (w * last_width <= 0) {
@@ -258,7 +259,7 @@ Panner2d::handle_position_change ()
 
         last_width = w;
 
-        vector<Speaker>& the_speakers (panner->get_speakers()->speakers());
+        vector<Speaker>& the_speakers (panner_shell->panner()->get_speakers()->speakers());
 
        for (n = 0; n < speakers.size(); ++n) {
                speakers[n]->position = the_speakers[n].angles();
@@ -273,7 +274,7 @@ Panner2d::move_signal (int which, const AngularVector& a)
        if (which >= int (speakers.size())) {
                return;
        }
-       
+
        speakers[which]->position = a;
        queue_draw ();
 }
@@ -295,7 +296,7 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal)
         best_distance = sqrt ((c.x - x) * (c.x - x) +
                          (c.y - y) * (c.y - y));
         closest = &position;
-        
+
        for (Targets::const_iterator i = signals.begin(); i != signals.end(); ++i) {
                candidate = *i;
 
@@ -315,12 +316,12 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal)
 
         if (height > large_size_threshold) {
                 /* "big" */
-                if (best_distance > 30) { // arbitrary 
+                if (best_distance > 30) { // arbitrary
                         closest = 0;
                 }
         } else {
                 /* "small" */
-                if (best_distance > 10) { // arbitrary 
+                if (best_distance > 10) { // arbitrary
                         closest = 0;
                 }
         }
@@ -330,29 +331,29 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal)
         if (!closest) {
                 for (Targets::const_iterator i = speakers.begin(); i != speakers.end(); ++i) {
                         candidate = *i;
-                        
+
                         candidate->position.cartesian (c);
                         cart_to_gtk (c);
-                        
+
                         distance = sqrt ((c.x - x) * (c.x - x) +
                                          (c.y - y) * (c.y - y));
-                        
+
                         if (distance < best_distance) {
                                 closest = candidate;
                                 best_distance = distance;
                         }
                 }
-                
+
                 if (height > large_size_threshold) {
                         /* "big" */
-                        if (best_distance < 30) { // arbitrary 
+                        if (best_distance < 30) { // arbitrary
                                 is_signal = false;
                         } else {
                                 closest = 0;
                         }
                 } else {
                         /* "small" */
-                        if (best_distance < 10) { // arbitrary 
+                        if (best_distance < 10) { // arbitrary
                                 is_signal = false;
                         } else {
                                 closest = 0;
@@ -397,7 +398,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
         /* background */
 
        cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
-       if (!panner->bypassed()) {
+       if (!panner_shell->bypassed()) {
                cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 1.0);
        } else {
                cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.2);
@@ -419,7 +420,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
        cairo_stroke (cr);
 
        /* vertical line of "crosshairs" */
-       
+
        cairo_move_to (cr, radius, 0);
        cairo_line_to (cr, radius, diameter);
        cairo_stroke (cr);
@@ -446,8 +447,8 @@ Panner2d::on_expose_event (GdkEventExpose *event)
         if (signals.size() > 1) {
                 /* arc to show "diffusion" */
 
-                double width_angle = fabs (panner->pannable()->pan_width_control->get_value()) * 2 * M_PI;
-                double position_angle = (2 * M_PI) - panner->pannable()->pan_azimuth_control->get_value() * 2 * M_PI;
+                double width_angle = fabs (panner_shell->pannable()->pan_width_control->get_value()) * 2 * M_PI;
+                double position_angle = (2 * M_PI) - panner_shell->pannable()->pan_azimuth_control->get_value() * 2 * M_PI;
 
                 cairo_save (cr);
                 cairo_translate (cr, radius, radius);
@@ -455,7 +456,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                 cairo_move_to (cr, 0, 0);
                 cairo_arc_negative (cr, 0, 0, radius, width_angle, 0.0);
                 cairo_close_path (cr);
-                if (panner->pannable()->pan_width_control->get_value() >= 0.0) {
+                if (panner_shell->pannable()->pan_width_control->get_value() >= 0.0) {
                         /* normal width */
                         cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 0.45);
                 } else {
@@ -466,12 +467,12 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                 cairo_restore (cr);
         }
 
-       if (!panner->bypassed()) {
+       if (!panner_shell->bypassed()) {
 
                double arc_radius;
 
                cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
-                
+
                if (small) {
                        arc_radius = 4.0;
                } else {
@@ -484,19 +485,19 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                 if (signals.size() > 1) {
                         for (Targets::iterator i = signals.begin(); i != signals.end(); ++i) {
                                 Target* signal = *i;
-                                
+
                                 if (signal->visible) {
 
                                         signal->position.cartesian (c);
                                         cart_to_gtk (c);
-                                        
+
                                         cairo_new_path (cr);
                                         cairo_arc (cr, c.x, c.y, arc_radius, 0, 2.0 * M_PI);
                                         cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 0.85);
                                         cairo_fill_preserve (cr);
                                         cairo_set_source_rgba (cr, 0.517, 0.772, 0.882, 1.0);
                                         cairo_stroke (cr);
-                                        
+
                                         if (!small && !signal->text.empty()) {
                                                 cairo_set_source_rgb (cr, 0.517, 0.772, 0.882);
                                                 /* the +/- adjustments are a hack to try to center the text in the circle */
@@ -523,14 +524,14 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                        if (speaker->visible) {
 
                                CartesianVector c;
-                                
+
                                speaker->position.cartesian (c);
                                cart_to_gtk (c);
 
                                snprintf (buf, sizeof (buf), "%d", n);
 
                                 /* stroke out a speaker shape */
-                                
+
                                 cairo_move_to (cr, c.x, c.y);
                                 cairo_save (cr);
                                 cairo_rotate (cr, -(speaker->position.azi/360.0) * (2.0 * M_PI));
@@ -556,7 +557,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                                         cairo_set_font_size (cr, 16);
 
                                         /* move the text in just a bit */
-                                        
+
                                         AngularVector textpos (speaker->position.azi, speaker->position.ele, 0.85);
                                         textpos.cartesian (c);
                                         cart_to_gtk (c);
@@ -568,7 +569,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                }
 
                 /* draw position */
-                
+
                 position.position.cartesian (c);
                 cart_to_gtk (c);
 
@@ -604,17 +605,17 @@ Panner2d::on_button_press_event (GdkEventButton *ev)
        case 2:
                 x = ev->x - border;
                 y = ev->y - border;
-                        
+
                if ((drag_target = find_closest_object (x, y, is_signal)) != 0) {
                         if (!is_signal) {
-                                panner->set_position (drag_target->position.azi/360.0);
+                                panner_shell->panner()->set_position (drag_target->position.azi/360.0);
                                 drag_target = 0;
                         } else {
                                 drag_target->set_selected (true);
                         }
                }
 
-               drag_x = ev->x; 
+               drag_x = ev->x;
                drag_y = ev->y;
                state = (GdkModifierType) ev->state;
 
@@ -677,12 +678,12 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
        if ((state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK)) == 0) {
                return false;
        }
-        
+
 
        if (state & GDK_BUTTON1_MASK && !(state & GDK_BUTTON2_MASK)) {
                CartesianVector c;
                bool need_move = false;
-                
+
                drag_target->position.cartesian (c);
                cart_to_gtk (c);
 
@@ -702,13 +703,13 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
                        /* generate an angular representation of the current mouse position */
 
                        cp.angular (av);
-                        
+
                         if (drag_target == &position) {
                                 double degree_fract = av.azi / 360.0;
-                                panner->set_position (degree_fract);
+                                panner_shell->panner()->set_position (degree_fract);
                         }
                }
-       } 
+       }
 
        return true;
 }
@@ -719,12 +720,12 @@ Panner2d::on_scroll_event (GdkEventScroll* ev)
         switch (ev->direction) {
         case GDK_SCROLL_UP:
         case GDK_SCROLL_RIGHT:
-                panner->set_position (panner->pannable()->pan_azimuth_control->get_value() - 1.0/360.0);
+                panner_shell->panner()->set_position (panner_shell->pannable()->pan_azimuth_control->get_value() - 1.0/360.0);
                 break;
 
         case GDK_SCROLL_DOWN:
         case GDK_SCROLL_LEFT:
-                panner->set_position (panner->pannable()->pan_azimuth_control->get_value() + 1.0/360.0);
+                panner_shell->panner()->set_position (panner_shell->pannable()->pan_azimuth_control->get_value() + 1.0/360.0);
                 break;
         }
         return true;
@@ -773,10 +774,10 @@ Panner2d::clamp_to_circle (double& x, double& y)
 void
 Panner2d::toggle_bypass ()
 {
-       panner->set_bypassed (!panner->bypassed());
+       panner_shell->set_bypassed (!panner_shell->bypassed());
 }
 
-Panner2dWindow::Panner2dWindow (boost::shared_ptr<Panner> p, int32_t h, uint32_t inputs)
+Panner2dWindow::Panner2dWindow (boost::shared_ptr<PannerShell> p, int32_t h, uint32_t inputs)
        : ArdourDialog (_("Panner (2D)"))
         , widget (p, h)
        , bypass_button (_("Bypass"))
@@ -838,10 +839,10 @@ void
 Panner2dWindow::bypass_toggled ()
 {
         bool view = bypass_button.get_active ();
-        bool model = widget.get_panner()->bypassed ();
-        
+        bool model = widget.get_panner_shell()->bypassed ();
+
         if (model != view) {
-                widget.get_panner()->set_bypassed (view);
+                widget.get_panner_shell()->set_bypassed (view);
         }
 }