diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index b4cdcfb8dc..593e2cbf0a 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -326,10 +326,8 @@ AudioRegionView::fade_out_active_changed () void AudioRegionView::region_scale_amplitude_changed () { - double g = audio_region()->scale_amplitude (); - for (uint32_t n = 0; n < waves.size(); ++n) { - waves[n]->set_amplitude (g); + waves[n]->gain_changed (); } } @@ -729,10 +727,10 @@ AudioRegionView::set_samples_per_pixel (gdouble fpp) } void -AudioRegionView::set_amplitude_above_axis (gdouble spp) +AudioRegionView::set_amplitude_above_axis (gdouble a) { for (uint32_t n=0; n < waves.size(); ++n) { - waves[n]->property_amplitude_above_axis() = spp; + waves[n]->set_amplitude_above_axis (a); } } @@ -895,7 +893,6 @@ AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/) wave->set_y_position (yoff); wave->set_height (ht); wave->set_samples_per_pixel (samples_per_pixel); - wave->property_amplitude_above_axis() = _amplitude_above_axis; if (_recregion) { wave->set_outline_color (_region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->get_canvasvar_RecWaveForm(), MUTED_ALPHA) : ARDOUR_UI::config()->get_canvasvar_RecWaveForm()); @@ -1075,7 +1072,7 @@ AudioRegionView::add_ghost (TimeAxisView& tv) wave->set_channel (n); wave->set_x_position (0); wave->set_samples_per_pixel (samples_per_pixel); - wave->property_amplitude_above_axis() = _amplitude_above_axis; + wave->set_amplitude_above_axis (_amplitude_above_axis); wave->set_region_start (_region->start()); ghost->waves.push_back(wave); diff --git a/gtk2_ardour/editor_cursors.cc b/gtk2_ardour/editor_cursors.cc index a1e1726747..59b81b2b48 100644 --- a/gtk2_ardour/editor_cursors.cc +++ b/gtk2_ardour/editor_cursors.cc @@ -75,8 +75,7 @@ EditorCursor::set_position (framepos_t frame) } if (new_pos != _track_canvas_item.x0 ()) { - _track_canvas_item.set_x0 (new_pos); - _track_canvas_item.set_x1 (new_pos); + _track_canvas_item.set_x (new_pos, new_pos); } _current_frame = frame; diff --git a/gtk2_ardour/editor_cursors.h b/gtk2_ardour/editor_cursors.h index a58a46bd5d..93689c6e7b 100644 --- a/gtk2_ardour/editor_cursors.h +++ b/gtk2_ardour/editor_cursors.h @@ -45,6 +45,10 @@ class EditorCursor { return _track_canvas_item; } + ArdourCanvas::Arrow& time_bar_canvas_item () { + return _time_bars_canvas_item; + } + PBD::Signal1 PositionChanged; private: diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d626afcdc6..98d251f762 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -2335,9 +2335,10 @@ TempoMarkerDrag::aborted (bool moved) } } -CursorDrag::CursorDrag (Editor* e, ArdourCanvas::Item* i, bool s) - : Drag (e, i), - _stop (s) +CursorDrag::CursorDrag (Editor* e, EditorCursor& c, bool s) + : Drag (e, &c.time_bar_canvas_item()) + , _cursor (c) + , _stop (s) { DEBUG_TRACE (DEBUG::Drags, "New CursorDrag\n"); } @@ -2376,6 +2377,10 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c) Session* s = _editor->session (); + /* grab the track canvas item as well */ + + _cursor.track_canvas_item().grab(); + if (s) { if (_was_rolling && _stop) { s->request_stop (); @@ -2419,6 +2424,8 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred) { _editor->_dragging_playhead = false; + _cursor.track_canvas_item().ungrab(); + if (!movement_occurred && _stop) { return; } @@ -2436,6 +2443,8 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred) void CursorDrag::aborted (bool) { + _cursor.track_canvas_item().ungrab(); + if (_editor->_dragging_playhead) { _editor->session()->request_resume_timecode_transmission (); _editor->_dragging_playhead = false; diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 5c9f09d04e..7c9b3538e9 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -626,7 +626,7 @@ private: class CursorDrag : public Drag { public: - CursorDrag (Editor *, ArdourCanvas::Item *, bool); + CursorDrag (Editor *, EditorCursor&, bool); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); @@ -648,6 +648,7 @@ public: private: void fake_locate (framepos_t); + EditorCursor& _cursor; bool _stop; ///< true to stop the transport on starting the drag, otherwise false double _grab_zoom; ///< editor frames per unit when our grab started }; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index efb4c1d5ae..0e4b54c7a2 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -708,7 +708,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT switch (item_type) { case PlayheadCursorItem: - _drags->set (new CursorDrag (this, item, true), event); + _drags->set (new CursorDrag (this, *playhead_cursor, true), event); return true; case MarkerItem: @@ -766,7 +766,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case TempoBarItem: case MeterBarItem: if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { - _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event); + _drags->set (new CursorDrag (this, *playhead_cursor, false), event); } return true; break; @@ -774,7 +774,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case RangeMarkerBarItem: if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { - _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event); + _drags->set (new CursorDrag (this, *playhead_cursor, false), event); } else { _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker), event); } @@ -783,7 +783,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case CdMarkerBarItem: if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { - _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event); + _drags->set (new CursorDrag (this, *playhead_cursor, false), event); } else { _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker), event); } @@ -792,7 +792,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case TransportMarkerBarItem: if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { - _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event); + _drags->set (new CursorDrag (this, *playhead_cursor, false), event); } else { _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker), event); } diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index 5993bb4432..477dd23f69 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -251,7 +251,7 @@ Editor::ruler_button_press (GdkEventButton* ev) } /* playhead cursor */ - _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), reinterpret_cast (ev)); + _drags->set (new CursorDrag (this, *playhead_cursor, false), reinterpret_cast (ev)); _dragging_playhead = true; } diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 5afc59a8b4..03c6a67438 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -26,6 +26,7 @@ #include "canvas/polygon.h" #include "canvas/text.h" #include "canvas/canvas.h" +#include "canvas/debug.h" #include "ardour_ui.h" /* @@ -252,9 +253,8 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con /* adjust to properly locate the tip */ mark = new ArdourCanvas::Polygon (group); -#ifdef CANVAS_DEBUG - mark->name = string_compose ("Marker::mark for %1", annotation); -#endif + CANVAS_DEBUG_NAME (mark, string_compose ("Marker::mark for %1", annotation)); + mark->set (*points); set_color_rgba (rgba); @@ -270,12 +270,9 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con Gtkmm2ext::get_ink_pixel_size (layout, width, name_height); _name_item = new ArdourCanvas::Text (group); + CANVAS_DEBUG_NAME (_name_item, string_compose ("Marker::_name_item for %1", annotation)); _name_item->set_font_description (name_font); _name_item->set_color (RGBA_TO_UINT (0,0,0,255)); - -#ifdef CANVAS_DEBUG - _name_item->name = string_compose ("Marker::_name_item for %1", annotation); -#endif _name_item->set_position (ArdourCanvas::Duple (_label_offset, (13.0 / 2.0) - (name_height / 2.0))); set_name (annotation.c_str()); @@ -292,7 +289,6 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con if (handle_events) { group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_marker_event), group, this)); } - } Marker::~Marker () diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index ff624be8fb..3c3980890e 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -72,6 +72,18 @@ Canvas::render (Rect const & area, Cairo::RefPtr const & context context->save (); +#ifdef CANVAS_DEBUG + if (getenv ("ARDOUR_REDRAW_CANVAS")) { + /* light up the canvas to show redraws */ + context->set_source_rgba (random()%255 / 255.0, + random()%255 / 255.0, + random()%255 / 255.0, + 255); + context->rectangle (area.x0, area.y0, area.width(), area.height()); + context->stroke (); + } +#endif + /* clip to the requested area */ context->rectangle (area.x0, area.y0, area.width(), area.height()); context->clip (); diff --git a/libs/canvas/canvas/line.h b/libs/canvas/canvas/line.h index b84d831143..36c0f48379 100644 --- a/libs/canvas/canvas/line.h +++ b/libs/canvas/canvas/line.h @@ -39,6 +39,8 @@ public: void set_y0 (Coord); void set_x1 (Coord); void set_y1 (Coord); + void set_x (Coord, Coord); + Coord x0 () const { return _points[0].x; } diff --git a/libs/canvas/canvas/wave_view.h b/libs/canvas/canvas/wave_view.h index 4fd45cff5d..f88ca41ba4 100644 --- a/libs/canvas/canvas/wave_view.h +++ b/libs/canvas/canvas/wave_view.h @@ -65,17 +65,17 @@ public: void set_outline_color (Color); void region_resized (); + void gain_changed (); void set_show_zero_line (bool); bool show_zero_line() const { return _show_zero; } void set_zero_color (Color); void set_clip_color (Color); - void set_amplitude (double); void set_logscaled (bool); void set_gradient_depth (double); double gradient_depth() const { return _gradient_depth; } void set_shape (Shape); - double amplitude() const { return _amplitude; } + /* currently missing because we don't need them (yet): set_shape_independent(); @@ -90,6 +90,9 @@ public: static bool global_logscaled() { return _global_logscaled; } static Shape global_shape() { return _global_shape; } + void set_amplitude_above_axis (double v); + double amplitude_above_axis () const { return _amplitude_above_axis; } + #ifdef CANVAS_COMPATIBILITY void*& property_gain_src () { return _foo_void; @@ -97,15 +100,9 @@ public: void*& property_gain_function () { return _foo_void; } - double& property_amplitude_above_axis () { - return _foo_double; - } private: void* _foo_void; - bool _foo_bool; - int _foo_int; - Color _foo_uint; - double _foo_double; + #endif class CacheEntry @@ -157,10 +154,10 @@ private: bool _logscaled; Shape _shape; double _gradient_depth; - double _amplitude; bool _shape_independent; bool _logscaled_independent; bool _gradient_depth_independent; + double _amplitude_above_axis; /** The `start' value to use for the region; we can't use the region's * value as the crossfade editor needs to alter it. diff --git a/libs/canvas/line.cc b/libs/canvas/line.cc index 2894a80a89..c409f48c7d 100644 --- a/libs/canvas/line.cc +++ b/libs/canvas/line.cc @@ -75,6 +75,20 @@ Line::set (Duple a, Duple b) DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: line change\n"); } +void +Line::set_x (Coord x0, Coord x1) +{ + begin_change (); + + _points[0].x = x0; + _points[1].x = x1; + + _bounding_box_dirty = true; + end_change (); + + DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: line change\n"); +} + void Line::set_x0 (Coord x0) { diff --git a/libs/canvas/wave_view.cc b/libs/canvas/wave_view.cc index 6a2661262a..71f993a579 100644 --- a/libs/canvas/wave_view.cc +++ b/libs/canvas/wave_view.cc @@ -61,10 +61,10 @@ WaveView::WaveView (Group* parent, boost::shared_ptr region , _logscaled (_global_logscaled) , _shape (_global_shape) , _gradient_depth (_global_gradient_depth) - , _amplitude (1.0) , _shape_independent (false) , _logscaled_independent (false) , _gradient_depth_independent (false) + , _amplitude_above_axis (1.0) , _region_start (0) { VisualPropertiesChanged.connect_same_thread (invalidation_connection, boost::bind (&WaveView::handle_visual_property_change, this)); @@ -252,21 +252,26 @@ WaveView::set_channel (int channel) void WaveView::invalidate_whole_cache () { + begin_visual_change (); for (list::iterator i = _cache.begin(); i != _cache.end(); ++i) { delete *i; } _cache.clear (); - _canvas->item_visual_property_changed (this); + + end_visual_change (); } void WaveView::invalidate_image_cache () { + begin_visual_change (); + for (list::iterator i = _cache.begin(); i != _cache.end(); ++i) { (*i)->clear_image (); } - _canvas->item_visual_property_changed (this); + + end_visual_change (); } void @@ -285,12 +290,9 @@ WaveView::set_logscaled (bool yn) } void -WaveView::set_amplitude (double a) +WaveView::gain_changed () { - if (_amplitude != a) { - _amplitude = a; - invalidate_image_cache (); - } + invalidate_whole_cache (); } void @@ -329,6 +331,15 @@ WaveView::set_shape (Shape s) } } +void +WaveView::set_amplitude_above_axis (double a) +{ + if (_amplitude_above_axis != a) { + _amplitude_above_axis = a; + invalidate_image_cache (); + } +} + void WaveView::set_global_shape (Shape s) { @@ -410,7 +421,6 @@ WaveView::CacheEntry::image () context->begin_new_path(); - if (_wave_view->_shape == WaveView::Rectified) { /* top edge of waveform is based on max (fabs (peak_min, peak_max)) @@ -418,13 +428,12 @@ WaveView::CacheEntry::image () if (_wave_view->_logscaled) { for (int i = 0; i < _n_peaks; ++i) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * - alt_log_meter (fast_coefficient_to_dB ( + context->line_to (i + 0.5, position (alt_log_meter (fast_coefficient_to_dB ( max (fabs (_peaks[i].max), fabs (_peaks[i].min)))))); } } else { for (int i = 0; i < _n_peaks; ++i) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * max (fabs (_peaks[i].max), fabs (_peaks[i].min)))); + context->line_to (i + 0.5, position (max (fabs (_peaks[i].max), fabs (_peaks[i].min)))); } } @@ -433,16 +442,16 @@ WaveView::CacheEntry::image () for (int i = 0; i < _n_peaks; ++i) { Coord y = _peaks[i].max; if (y > 0.0) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * alt_log_meter (fast_coefficient_to_dB (y)))); + context->line_to (i + 0.5, position (alt_log_meter (fast_coefficient_to_dB (y)))); } else if (y < 0.0) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * -alt_log_meter (fast_coefficient_to_dB (-y)))); + context->line_to (i + 0.5, position (alt_log_meter (fast_coefficient_to_dB (-y)))); } else { context->line_to (i + 0.5, position (0.0)); } } } else { for (int i = 0; i < _n_peaks; ++i) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * _peaks[i].max)); + context->line_to (i + 0.5, position (_peaks[i].max)); } } } @@ -469,16 +478,16 @@ WaveView::CacheEntry::image () for (int i = _n_peaks-1; i >= 0; --i) { Coord y = _peaks[i].min; if (y > 0.0) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * alt_log_meter (fast_coefficient_to_dB (y)))); + context->line_to (i + 0.5, position (alt_log_meter (fast_coefficient_to_dB (y)))); } else if (y < 0.0) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * -alt_log_meter (fast_coefficient_to_dB (-y)))); + context->line_to (i + 0.5, position (-alt_log_meter (fast_coefficient_to_dB (-y)))); } else { context->line_to (i + 0.5, position (0.0)); } } } else { for (int i = _n_peaks-1; i >= 0; --i) { - context->line_to (i + 0.5, position (_wave_view->amplitude() * _peaks[i].min)); + context->line_to (i + 0.5, position (_peaks[i].min)); } }