Fix confusion about the 'done' variable in InterThreadInfo during import. 'done...
[ardour.git] / gtk2_ardour / panner2d.cc
index 7a081101f6979c50660f4b8c7dbd09ebc5a42a88..84c0e1f1bc2f90bfba6752d4380bd95b1f865d1e 100644 (file)
@@ -36,9 +36,9 @@
 
 using namespace std;
 using namespace Gtk;
-using namespace sigc;
 using namespace ARDOUR;
 using namespace PBD;
+using Gtkmm2ext::Keyboard;
 
 Panner2d::Target::Target (float xa, float ya, const char *txt)
        : x (xa, 0.0, 1.0, 0.01, 0.1)
@@ -50,7 +50,7 @@ Panner2d::Target::Target (float xa, float ya, const char *txt)
 }
 
 Panner2d::Target::~Target ()
-{ 
+{
        if (text) {
                free (text);
        }
@@ -65,16 +65,16 @@ Panner2d::Target::set_text (const char* txt)
        text = strdup (txt);
 }
 
-Panner2d::Panner2d (Panner& p, int32_t h)
+Panner2d::Panner2d (boost::shared_ptr<Panner> p, int32_t h)
        : panner (p), width (0), height (h)
 {
        allow_x = false;
        allow_y = false;
        allow_target = false;
 
-       panner.StateChanged.connect (mem_fun(*this, &Panner2d::handle_state_change));
-       panner.Changed.connect (mem_fun(*this, &Panner2d::handle_position_change));
-       
+       panner->StateChanged.connect (state_connection, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context());
+       panner->Changed.connect (change_connection, 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);
 }
@@ -82,7 +82,7 @@ Panner2d::Panner2d (Panner& p, int32_t h)
 Panner2d::~Panner2d()
 {
        for (Targets::iterator i = targets.begin(); i != targets.end(); ++i) {
-               delete i->second;
+               delete *i;
        }
 }
 
@@ -96,83 +96,77 @@ Panner2d::reset (uint32_t n_inputs)
        while (pucks.size() < n_inputs) {
                add_puck ("", 0.0, 0.0);
        }
-       
-       while (pucks.size() > n_inputs) {
-               pucks.erase (pucks.begin());
-       }
 
+       if (pucks.size() > n_inputs) {
+               for (uint32_t i = pucks.size(); i < n_inputs; ++i) {
+                       delete pucks[i];
+               }
+
+               pucks.resize (n_inputs);
+       }
+                                               
        for (Targets::iterator x = pucks.begin(); x != pucks.end(); ++x) {
-               (*x).second->visible = false;
+               (*x)->visible = false;
        }
 
        switch (n_inputs) {
        case 0:
                break;
-               
+
        case 1:
                pucks[0]->set_text ("");
-               pucks[0]->x.set_value (0.0);
-               pucks[0]->y.set_value (0.5);
-               pucks[0]->visible = true;
                break;
-               
+
        case 2:
                pucks[0]->set_text ("R");
-               if (existing_pucks < 0) {
-                       pucks[0]->x.set_value (0.5f);
-                       pucks[1]->y.set_value (0.25f);
-               }
-               pucks[0]->visible = true;
                pucks[1]->set_text ("L");
-               if (existing_pucks < 2) {
-                       pucks[1]->x.set_value (0.25f);
-                       pucks[1]->y.set_value (0.5f);
-               }
-               pucks[1]->visible = true;
                break;
-               
+
        default:
                for (uint32_t i = 0; i < n_inputs; ++i) {
                        char buf[64];
                        snprintf (buf, sizeof (buf), "%" PRIu32, i);
                        pucks[i]->set_text (buf);
-                       
-                       if (existing_pucks < i) {
-                               float x, y;
-                               panner.streampanner (i).get_position (x, y);
-                               pucks[i]->x.set_value (x);
-                               pucks[i]->y.set_value (y);
-                       }
-
-                       pucks[i]->visible = true;
                }
                break;
        }
-       
+
+       for (uint32_t i = existing_pucks; i < n_inputs; ++i) {
+               float x, y;
+               panner->streampanner (i).get_position (x, y);
+               pucks[i]->x.set_value (x);
+               pucks[i]->y.set_value (y);
+               pucks[i]->visible = true;
+       }
+
        /* add all outputs */
-       
-       while (targets.size() < panner.nouts()) {
+
+       while (targets.size() < panner->nouts()) {
                add_target (0.0, 0.0);
        }
-       
-       while (targets.size() > panner.nouts()) {
-               targets.erase (targets.begin());
+
+       if (targets.size() > panner->nouts()) {
+               for (uint32_t i = panner->nouts(); i < targets.size(); ++i) {
+                       delete targets[i];
+               }
+
+               targets.resize (panner->nouts ());
        }
 
        for (Targets::iterator x = targets.begin(); x != targets.end(); ++x) {
-               (*x).second->visible = false;
+               (*x)->visible = false;
        }
 
-       for (uint32_t n = 0; n < panner.nouts(); ++n) {
+       for (uint32_t n = 0; n < panner->nouts(); ++n) {
                char buf[16];
 
                snprintf (buf, sizeof (buf), "%d", n+1);
                targets[n]->set_text (buf);
-               targets[n]->x.set_value (panner.output(n).x);
-               targets[n]->y.set_value (panner.output(n).y);
+               targets[n]->x.set_value (panner->output(n).x);
+               targets[n]->y.set_value (panner->output(n).y);
                targets[n]->visible = true;
        }
-       
+
        allow_x_motion (true);
        allow_y_motion (true);
        allow_target_motion (true);
@@ -205,68 +199,27 @@ int
 Panner2d::add_puck (const char* text, float x, float y)
 {
        Target* puck = new Target (x, y, text);
-
-       pair<int,Target *> newpair;
-       newpair.first = pucks.size();
-       newpair.second = puck;
-
-       pucks.insert (newpair);
+       pucks.push_back (puck);
        puck->visible = true;
-       
+
        return 0;
 }
 
 int
 Panner2d::add_target (float x, float y)
 {
-       Target *target = new Target (x, y, "");
-
-       pair<int,Target *> newpair;
-       newpair.first = targets.size();
-       newpair.second = target;
-
-       targets.insert (newpair);
+       Target* target = new Target (x, y, "");
+       targets.push_back (target);
        target->visible = true;
        queue_draw ();
 
-       return newpair.first;
+       return targets.size() - 1;
 }
 
-void
-Panner2d::drop_targets ()
-{
-       for (Targets::iterator i = targets.begin(); i != targets.end(); ) {
-
-               Targets::iterator tmp;
-
-               tmp = i;
-               ++tmp;
-
-               delete i->second;
-               targets.erase (i);
-
-               i = tmp;
-       }
-
-       queue_draw ();
-}
-
-void
-Panner2d::remove_target (int which)
-{
-       Targets::iterator i = targets.find (which);
-
-       if (i != targets.end()) {
-               delete i->second;
-               targets.erase (i);
-               queue_draw ();
-       }
-}              
-
 void
 Panner2d::handle_state_change ()
 {
-       ENSURE_GUI_THREAD(mem_fun(*this, &Panner2d::handle_state_change));
+       ENSURE_GUI_THREAD (*this, &Panner2d::handle_state_change)
 
        queue_draw ();
 }
@@ -275,107 +228,33 @@ void
 Panner2d::handle_position_change ()
 {
        uint32_t n;
-       ENSURE_GUI_THREAD(mem_fun(*this, &Panner2d::handle_position_change));
+       ENSURE_GUI_THREAD (*this, &Panner2d::handle_position_change)
 
        for (n = 0; n < pucks.size(); ++n) {
                float x, y;
-               panner.streampanner(n).get_position (x, y);
+               panner->streampanner(n).get_position (x, y);
                pucks[n]->x.set_value (x);
                pucks[n]->y.set_value (y);
        }
 
        for (n = 0; n < targets.size(); ++n) {
-               targets[n]->x.set_value (panner.output(n).x);
-               targets[n]->y.set_value (panner.output(n).y);
+               targets[n]->x.set_value (panner->output(n).x);
+               targets[n]->y.set_value (panner->output(n).y);
        }
 
        queue_draw ();
 }
 
-void
-Panner2d::move_target (int which, float x, float y)
-{
-       Targets::iterator i = targets.find (which);
-       Target *target;
-
-       if (!allow_target) {
-               return;
-       }
-
-       if (i != targets.end()) {
-               target = i->second;
-               target->x.set_value (x);
-               target->y.set_value (y);
-               
-               queue_draw ();
-       }
-}              
-
 void
 Panner2d::move_puck (int which, float x, float y)
 {
-       Targets::iterator i = pucks.find (which);
-       Target *target;
-
-       if (i != pucks.end()) {
-               target = i->second;
-               target->x.set_value (x);
-               target->y.set_value (y);
-               
-               queue_draw ();
-       }
-}              
-
-void
-Panner2d::show_puck (int which)
-{
-       Targets::iterator i = pucks.find (which);
-
-       if (i != pucks.end()) {
-               Target* puck = i->second;
-               if (!puck->visible) {
-                       puck->visible = true;
-                       queue_draw ();
-               }
-       }
-}
-
-void
-Panner2d::hide_puck (int which)
-{
-       Targets::iterator i = pucks.find (which);
-
-       if (i != pucks.end()) {
-               Target* puck = i->second;
-               if (!puck->visible) {
-                       puck->visible = false;
-                       queue_draw ();
-               }
-       }
-}
-
-void
-Panner2d::show_target (int which)
-{
-       Targets::iterator i = targets.find (which);
-       if (i != targets.end()) {
-               if (!i->second->visible) {
-                       i->second->visible = true;
-                       queue_draw ();
-               }
-       }
-}
-
-void
-Panner2d::hide_target (int which)
-{
-       Targets::iterator i = targets.find (which);
-       if (i != targets.end()) {
-               if (i->second->visible) {
-                       i->second->visible = false;
-                       queue_draw ();
-               }
+       if (which >= int (targets.size())) {
+               return;
        }
+       
+       targets[which]->x.set_value (x);
+       targets[which]->y.set_value (y);
+       queue_draw ();
 }
 
 Panner2d::Target *
@@ -396,7 +275,7 @@ Panner2d::find_closest_object (gdouble x, gdouble y, int& which, bool& is_puck)
        is_puck = false;
 
        for (Targets::const_iterator i = targets.begin(); i != targets.end(); ++i, ++which) {
-               candidate = i->second;
+               candidate = *i;
 
                cx = candidate->x.get_value();
                cy = candidate->y.get_value();
@@ -411,7 +290,7 @@ Panner2d::find_closest_object (gdouble x, gdouble y, int& which, bool& is_puck)
        }
 
        for (Targets::const_iterator i = pucks.begin(); i != pucks.end(); ++i, ++pwhich) {
-               candidate = i->second;
+               candidate = *i;
 
                cx = candidate->x.get_value();
                cy = candidate->y.get_value();
@@ -426,9 +305,9 @@ Panner2d::find_closest_object (gdouble x, gdouble y, int& which, bool& is_puck)
                        which = pwhich;
                }
        }
-       
+
        return closest;
-}              
+}
 
 bool
 Panner2d::on_motion_notify_event (GdkEventMotion *ev)
@@ -458,7 +337,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
        cairo_set_line_width (cr, 1.0);
 
        cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
-       if (!panner.bypassed()) {
+       if (!panner->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);
@@ -482,7 +361,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
        cairo_arc (cr, height/2, height/2, height/2, 0, 2.0 * M_PI);
        cairo_stroke (cr);
 
-       if (!panner.bypassed()) {
+       if (!panner->bypassed()) {
                float arc_radius;
 
                cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
@@ -497,32 +376,32 @@ Panner2d::on_expose_event (GdkEventExpose *event)
 
                for (Targets::iterator i = pucks.begin(); i != pucks.end(); ++i) {
 
-                       Target* puck = i->second;
+                       Target* puck = *i;
 
                        if (puck->visible) {
                                /* redraw puck */
-                               
+
                                fx = min (puck->x.get_value(), 1.0);
                                fx = max (fx, -1.0f);
                                x = (gint) floor (width * fx - 4);
-                               
+
                                fy = min (puck->y.get_value(), 1.0);
                                fy = max (fy, -1.0f);
                                y = (gint) floor (height * fy - 4);
-                               
+
                                cairo_arc (cr, x, y, arc_radius, 0, 2.0 * M_PI);
                                cairo_set_source_rgb (cr, 0.8, 0.2, 0.1);
                                cairo_close_path (cr);
                                cairo_fill (cr);
 
                                /* arrow */
-                               
+
                                if (height > 100.0f) {
 
                                        float endx, endy;
                                        endx = x;
                                        endy = y;
-                                       
+
                                        cairo_save (cr);
                                        cairo_translate (cr, x, y);
                                        cairo_rotate (cr, puck->azimuth.get_value());
@@ -537,9 +416,9 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                                        cairo_move_to (cr, 0.0, 0.0);
                                        cairo_line_to (cr, endx, endy);
                                        cairo_stroke (cr);
-                                       
+
                                        /* arrow head */
-                                       
+
                                        cairo_move_to (cr, endx - 10.0, endy + 10.0);
                                        cairo_line_to (cr, endx, endy);
                                        cairo_line_to (cr, endx - 10.0, endy - 10.0);
@@ -555,20 +434,20 @@ Panner2d::on_expose_event (GdkEventExpose *event)
                }
 
                /* redraw any visible targets */
-               
+
                int n = 0;
 
                for (Targets::iterator i = targets.begin(); i != targets.end(); ++i) {
-                       Target *target = i->second;
+                       Target *target = *i;
                        char buf[256];
                        ++n;
 
                        if (target->visible) {
-                               
+
                                fx = min (target->x.get_value(), 1.0);
                                fx = max (fx, -1.0f);
                                x = (gint) floor (width  * fx);
-                       
+
                                fy = min (target->y.get_value(), 1.0);
                                fy = max (fy, -1.0f);
                                y = (gint) floor (height * fy);
@@ -612,7 +491,7 @@ Panner2d::on_button_press_event (GdkEventButton *ev)
        default:
                break;
        }
-       
+
        return FALSE;
 }
 
@@ -645,7 +524,7 @@ Panner2d::on_button_release_event (GdkEventButton *ev)
                } else {
                        ret = handle_motion (x, y, state);
                }
-               
+
                drag_target = 0;
                break;
 
@@ -660,7 +539,7 @@ Panner2d::on_button_release_event (GdkEventButton *ev)
                } else {
                        ret = handle_motion (x, y, state);
                }
-               
+
                drag_target = 0;
                break;
 
@@ -703,7 +582,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
                                need_move = true;
                        }
                }
-               
+
                if (allow_y || drag_is_puck) {
                        float new_y;
                        y = min (evy, height - 1);
@@ -714,21 +593,22 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
                                need_move = true;
                        }
                }
-               
+
                if (need_move) {
-                       
+
                        if (drag_is_puck) {
-                               
-                               panner.streampanner(drag_index).set_position (drag_target->x.get_value(), drag_target->y.get_value(), false);
-                               
+
+                               panner->streampanner(drag_index).set_position (
+                                               drag_target->x.get_value(), drag_target->y.get_value(), false);
+
                        } else {
-                               
+
                                TargetMoved (drag_index);
                        }
 
                        queue_draw ();
                }
-               
+
 
        } else if ((state & GDK_BUTTON2_MASK) && !(state & GDK_BUTTON1_MASK)) {
 
@@ -738,7 +618,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
 
                int xdelta = drag_x - evx;
                int ydelta = drag_x - evy;
-               
+
                drag_target->azimuth.set_value (drag_target->azimuth.get_value() + (2 * M_PI) * ((float)ydelta)/height * ((float) -xdelta)/height);
                queue_draw ();
        }
@@ -749,7 +629,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
 void
 Panner2d::toggle_bypass ()
 {
-       panner.set_bypassed (!panner.bypassed());
+       panner->set_bypassed (!panner->bypassed());
 }
 
 void
@@ -770,7 +650,7 @@ Panner2d::allow_y_motion (bool yn)
        allow_y = yn;
 }
 
-Panner2dWindow::Panner2dWindow (Panner&p, int32_t h, uint32_t inputs)
+Panner2dWindow::Panner2dWindow (boost::shared_ptr<Panner> p, int32_t h, uint32_t inputs)
        : widget (p, h)
        , reset_button (_("Reset"))
        , bypass_button (_("Bypass"))
@@ -780,7 +660,7 @@ Panner2dWindow::Panner2dWindow (Panner&p, int32_t h, uint32_t inputs)
 
        set_title (_("Panner"));
        widget.set_size_request (h, h);
-       
+
        button_box.set_spacing (6);
        button_box.pack_start (reset_button, false, false);
        button_box.pack_start (bypass_button, false, false);
@@ -804,7 +684,7 @@ Panner2dWindow::Panner2dWindow (Panner&p, int32_t h, uint32_t inputs)
        hpacker.pack_start (widget, false, false);
        hpacker.pack_start (left_side, false, false);
        hpacker.show ();
-       
+
        add (hpacker);
        reset (inputs);
        widget.show ();