X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=gtk2_ardour%2Fpanner2d.cc;h=35f573bcf11db0e877b9c3981673bea86e7c6cb8;hb=0796ccfb652dd31ea1d94526e0e6d92863a972b0;hp=826b86fc89bcc0bcbead13c5598b6357ea306a62;hpb=c46e74012e5727bd46b7bcf813970f60f1179af4;p=ardour.git diff --git a/gtk2_ardour/panner2d.cc b/gtk2_ardour/panner2d.cc index 826b86fc89..35f573bcf1 100644 --- a/gtk2_ardour/panner2d.cc +++ b/gtk2_ardour/panner2d.cc @@ -75,10 +75,11 @@ Panner2d::Panner2d (boost::shared_ptr p, int32_t h) , height (h) , last_width (0) , have_elevation (false) + , _send_mode (false) { - panner_shell->Changed.connect (connections, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context()); + panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context()); - panner_shell->panner()->SignalPositionChanged.connect (panconnect, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context()); + panner_shell->panner()->SignalPositionChanged.connect (panner_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); @@ -166,6 +167,7 @@ Panner2d::on_size_allocate (Gtk::Allocation& alloc) radius = min (width, height); radius -= border; radius /= 2; + radius = rint(radius) + .5; hoffset = max ((double) (width - height), border); voffset = max ((double) (height - width), border); @@ -200,12 +202,12 @@ Panner2d::add_speaker (const AngularVector& a) void Panner2d::handle_state_change () { - panconnect.drop_connections(); + panner_connections.drop_connections(); if (!panner_shell->panner()) { return; } - panner_shell->panner()->SignalPositionChanged.connect (panconnect, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context()); + panner_shell->panner()->SignalPositionChanged.connect (panner_connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context()); set params = panner_shell->panner()->what_can_be_automated(); set::iterator p = params.find(PanElevationAutomation); @@ -251,12 +253,8 @@ Panner2d::handle_position_change () uint32_t n; double w = panner_shell->pannable()->pan_width_control->get_value(); - if (have_elevation) { - position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0, - panner_shell->pannable()->pan_elevation_control->get_value() * 90.0); - } else { - position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0, 0); - } + position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0, + panner_shell->pannable()->pan_elevation_control->get_value() * 90.0); for (uint32_t i = 0; i < signals.size(); ++i) { signals[i]->position = panner_shell->panner()->signal_position (i); @@ -300,7 +298,11 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal) /* start with the position itself */ - position.position.cartesian (c); + PBD::AngularVector dp = position.position; + if (!have_elevation) dp.ele = 0; + dp.azi = 270 - dp.azi; + dp.cartesian (c); + cart_to_gtk (c); best_distance = sqrt ((c.x - x) * (c.x - x) + (c.y - y) * (c.y - y)); @@ -342,9 +344,11 @@ 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); + PBD::AngularVector sp = candidate->position; + sp.azi = 270 -sp.azi; + CartesianVector c; + sp.cartesian (c); + cart_to_gtk (c); distance = sqrt ((c.x - x) * (c.x - x) + (c.y - y) * (c.y - y)); @@ -375,6 +379,15 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal) return closest; } +void +Panner2d::set_send_drawing_mode (bool onoff) +{ + if (_send_mode != onoff) { + _send_mode = onoff; + queue_draw (); + } +} + bool Panner2d::on_motion_notify_event (GdkEventMotion *ev) { @@ -409,10 +422,16 @@ Panner2d::on_expose_event (GdkEventExpose *event) /* background */ cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); + + float r, g, b; + r = g = b = 0.1; + if (_send_mode) { + rgba_p_from_style("SendStripBase", &r, &g, &b, "fg"); + } if (!panner_shell->bypassed()) { - cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 1.0); + cairo_set_source_rgba (cr, r, g, b, 1.0); } else { - cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.2); + cairo_set_source_rgba (cr, r, g, b , 0.2); } cairo_fill_preserve (cr); cairo_clip (cr); @@ -426,14 +445,14 @@ Panner2d::on_expose_event (GdkEventExpose *event) /* horizontal line of "crosshairs" */ cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 1.0); - cairo_move_to (cr, 0.0, rint(radius) + .5); - cairo_line_to (cr, diameter, rint(radius) + .5); + cairo_move_to (cr, 0.0, radius); + cairo_line_to (cr, diameter, radius); cairo_stroke (cr); /* vertical line of "crosshairs" */ - cairo_move_to (cr, rint(radius) + .5, 0); - cairo_line_to (cr, rint(radius) + .5, diameter); + cairo_move_to (cr, radius, 0); + cairo_line_to (cr, radius, diameter); cairo_stroke (cr); /* the circle on which signals live */ @@ -456,15 +475,17 @@ Panner2d::on_expose_event (GdkEventExpose *event) } if (!panner_shell->bypassed()) { + /* convention top == front ^= azimuth == .5 (same as stereo/mono panners) */ if (signals.size() > 1) { /* arc to show "diffusion" */ 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; + double position_angle = panner_shell->pannable()->pan_azimuth_control->get_value() * 2 * M_PI; cairo_save (cr); cairo_translate (cr, radius, radius); + cairo_rotate (cr, M_PI / 2.0); cairo_rotate (cr, position_angle - (width_angle/2.0)); cairo_move_to (cr, 0, 0); cairo_arc_negative (cr, 0, 0, radius, width_angle, 0.0); @@ -493,7 +514,10 @@ Panner2d::on_expose_event (GdkEventExpose *event) /* draw position */ - position.position.cartesian (c); + PBD::AngularVector dp = position.position; + if (!have_elevation) dp.ele = 0; + dp.azi = 270 - dp.azi; + dp.cartesian (c); cart_to_gtk (c); cairo_new_path (cr); @@ -505,7 +529,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) /* signals */ - if (signals.size() > 1) { + if (signals.size() > 0) { for (Targets::iterator i = signals.begin(); i != signals.end(); ++i) { Target* signal = *i; @@ -516,6 +540,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) */ PBD::AngularVector sp = signal->position; if (!have_elevation) sp.ele = 0; + sp.azi += 270.0; sp.cartesian (c); cart_to_gtk (c); @@ -553,9 +578,10 @@ Panner2d::on_expose_event (GdkEventExpose *event) if (speaker->visible) { + PBD::AngularVector sp = speaker->position; + sp.azi += 270.0; CartesianVector c; - - speaker->position.cartesian (c); + sp.cartesian (c); cart_to_gtk (c); snprintf (buf, sizeof (buf), "%d", n); @@ -564,7 +590,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) cairo_move_to (cr, c.x, c.y); cairo_save (cr); - cairo_rotate (cr, -(speaker->position.azi/360.0) * (2.0 * M_PI)); + cairo_rotate (cr, -(sp.azi/360.0) * (2.0 * M_PI)); if (small) { cairo_scale (cr, 0.8, 0.8); } else { @@ -588,7 +614,8 @@ Panner2d::on_expose_event (GdkEventExpose *event) /* move the text in just a bit */ - AngularVector textpos (speaker->position.azi, speaker->position.ele, 0.85); + AngularVector textpos (speaker->position.azi + 270.0, speaker->position.ele, 0.85); + textpos.cartesian (c); cart_to_gtk (c); cairo_move_to (cr, c.x, c.y); @@ -716,6 +743,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state) if (!have_elevation) { clamp_to_circle (cp.x, cp.y); cp.angular (av); + av.azi = fmod(270 - av.azi, 360); if (drag_target == &position) { double degree_fract = av.azi / 360.0; panner_shell->panner()->set_position (degree_fract); @@ -727,6 +755,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state) double r2d = 180.0 / M_PI; av.azi = r2d * atan2(cp.y, cp.x); av.ele = r2d * asin(cp.z); + av.azi = fmod(270 - av.azi, 360); if (drag_target == &position) { double azi_fract = av.azi / 360.0; @@ -833,8 +862,11 @@ Panner2dWindow::Panner2dWindow (boost::shared_ptr p, int32_t h, uin bypass_button.signal_toggled().connect (sigc::mem_fun (*this, &Panner2dWindow::bypass_toggled)); width_spinner.signal_changed().connect (sigc::mem_fun (*this, &Panner2dWindow::width_changed)); - p->pannable()->pan_width_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2dWindow::set_width, this), gui_context()); - p->Changed.connect (connections, invalidator (*this), boost::bind (&Panner2dWindow::set_bypassed, this), gui_context()); + p->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&Panner2dWindow::set_bypassed, this), gui_context()); + /* needed for the width-spinbox in the main window */ + p->PannableChanged.connect (panshell_connections, invalidator (*this), boost::bind (&Panner2dWindow::pannable_handler, this), gui_context()); + p->pannable()->pan_width_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&Panner2dWindow::set_width, this), gui_context()); + button_box.set_spacing (6); button_box.pack_start (bypass_button, false, false); @@ -896,6 +928,14 @@ Panner2dWindow::width_changed () } } +void +Panner2dWindow::pannable_handler () +{ + panvalue_connections.drop_connections(); + widget.get_panner_shell()->pannable()->pan_width_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&Panner2dWindow::set_width, this), gui_context()); + set_width(); +} + void Panner2dWindow::set_bypassed () {