From 0874426a5b6777559a12f87070b2aadb230ec50d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 8 Jun 2009 19:28:51 +0000 Subject: Further refactoring of drag code. Changes so that drags from the region list display a region view during the drag. git-svn-id: svn://localhost/ardour2/branches/3.0@5127 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/audio_region_view.cc | 10 +- gtk2_ardour/audio_region_view.h | 16 +- gtk2_ardour/audio_streamview.cc | 64 +++-- gtk2_ardour/audio_streamview.h | 2 + gtk2_ardour/automation_region_view.cc | 4 +- gtk2_ardour/automation_region_view.h | 4 +- gtk2_ardour/automation_streamview.cc | 2 +- gtk2_ardour/editor.h | 5 +- gtk2_ardour/editor_canvas.cc | 22 +- gtk2_ardour/editor_canvas_events.cc | 64 +++++ gtk2_ardour/editor_drag.cc | 494 ++++++++++++++++++++-------------- gtk2_ardour/editor_drag.h | 78 +++++- gtk2_ardour/editor_mouse.cc | 2 +- gtk2_ardour/midi_region_view.cc | 4 +- gtk2_ardour/midi_region_view.h | 4 +- gtk2_ardour/midi_streamview.cc | 39 ++- gtk2_ardour/midi_streamview.h | 2 + gtk2_ardour/region_view.cc | 16 +- gtk2_ardour/region_view.h | 9 +- gtk2_ardour/streamview.cc | 4 +- gtk2_ardour/streamview.h | 4 + gtk2_ardour/tape_region_view.cc | 4 +- gtk2_ardour/tape_region_view.h | 4 +- gtk2_ardour/time_axis_view_item.cc | 8 +- gtk2_ardour/time_axis_view_item.h | 8 +- 25 files changed, 552 insertions(+), 321 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index ca8090dcc4..30f97ba523 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -66,7 +66,7 @@ using namespace ArdourCanvas; static const int32_t sync_mark_width = 9; AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color) + Gdk::Color const & basic_color) : RegionView (parent, tv, r, spu, basic_color) , sync_mark(0) , zero_line(0) @@ -83,7 +83,7 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color, bool recording, TimeAxisViewItem::Visibility visibility) + Gdk::Color const & basic_color, bool recording, TimeAxisViewItem::Visibility visibility) : RegionView (parent, tv, r, spu, basic_color, recording, visibility) , sync_mark(0) , zero_line(0) @@ -145,7 +145,7 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt } void -AudioRegionView::init (Gdk::Color& basic_color, bool wfd) +AudioRegionView::init (Gdk::Color const & basic_color, bool wfd) { // FIXME: Some redundancy here with RegionView::init. Need to figure out // where order is important and where it isn't... @@ -731,9 +731,9 @@ AudioRegionView::set_amplitude_above_axis (gdouble spp) } void -AudioRegionView::compute_colors (Gdk::Color& basic_color) +AudioRegionView::compute_colors (Gdk::Color const & basic_color) { - RegionView::compute_colors(basic_color); + RegionView::compute_colors (basic_color); uint32_t r, g, b, a; diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h index 35e93b985f..6d74b7a1ed 100644 --- a/gtk2_ardour/audio_region_view.h +++ b/gtk2_ardour/audio_region_view.h @@ -53,22 +53,22 @@ class AudioRegionView : public RegionView RouteTimeAxisView&, boost::shared_ptr, double initial_samples_per_unit, - Gdk::Color& basic_color); + Gdk::Color const & basic_color); AudioRegionView (ArdourCanvas::Group *, - RouteTimeAxisView&, - boost::shared_ptr, - double samples_per_unit, - Gdk::Color& basic_color, + RouteTimeAxisView&, + boost::shared_ptr, + double samples_per_unit, + Gdk::Color const & basic_color, bool recording, - TimeAxisViewItem::Visibility); + TimeAxisViewItem::Visibility); AudioRegionView (const AudioRegionView& other); AudioRegionView (const AudioRegionView& other, boost::shared_ptr); ~AudioRegionView (); - virtual void init (Gdk::Color& base_color, bool wait_for_data); + virtual void init (Gdk::Color const & base_color, bool wait_for_data); boost::shared_ptr audio_region() const; @@ -162,7 +162,7 @@ class AudioRegionView : public RegionView void store_flags (); void set_colors (); - void compute_colors (Gdk::Color&); + void compute_colors (Gdk::Color const &); void reset_width_dependent_items (double pixel_width); void set_waveview_data_src(); void set_frame_color (); diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index 03f3d3d8bd..e2aa080b64 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -104,36 +104,15 @@ AudioStreamView::set_amplitude_above_axis (gdouble app) } RegionView* -AudioStreamView::add_region_view_internal (boost::shared_ptr r, bool wait_for_waves, bool recording) +AudioStreamView::create_region_view (boost::shared_ptr r, bool wait_for_waves, bool recording) { AudioRegionView *region_view = 0; boost::shared_ptr region = boost::dynamic_pointer_cast (r); if (region == 0) { - return NULL; + return 0; } -// if(!recording){ -// for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) { -// if ((*i)->region() == r) { -// cerr << "audio_streamview in add_region_view_internal region found" << endl; - /* great. we already have a AudioRegionView for this Region. use it again. */ - -// (*i)->set_valid (true); - - // this might not be necessary -// AudioRegionView* const arv = dynamic_cast(*i); - -// if (arv) { -// arv->set_waveform_scale (_waveform_scale); -// arv->set_waveform_shape (_waveform_shape); -// } - -// return NULL; -// } -// } -// } - switch (_trackview.audio_track()->mode()) { case NonLayered: @@ -160,7 +139,6 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr r, bool wai region_view->init (region_color, wait_for_waves); region_view->set_amplitude_above_axis(_amplitude_above_axis); region_view->set_height (child_height ()); - region_views.push_front (region_view); /* if its the special single-sample length that we use for rec-regions, make it insensitive to events @@ -195,8 +173,42 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr r, bool wai /* follow global waveform setting */ region_view->set_waveform_visible(_trackview.editor().show_waveforms()); + return region_view; +} + +RegionView* +AudioStreamView::add_region_view_internal (boost::shared_ptr r, bool wait_for_waves, bool recording) +{ + RegionView *region_view = create_region_view (r, wait_for_waves, recording); + if (region_view == 0) { + return 0; + } + +// if(!recording){ +// for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) { +// if ((*i)->region() == r) { +// cerr << "audio_streamview in add_region_view_internal region found" << endl; + /* great. we already have a AudioRegionView for this Region. use it again. */ + +// (*i)->set_valid (true); + + // this might not be necessary +// AudioRegionView* const arv = dynamic_cast(*i); + +// if (arv) { +// arv->set_waveform_scale (_waveform_scale); +// arv->set_waveform_shape (_waveform_shape); +// } + +// return NULL; +// } +// } +// } + + region_views.push_front (region_view); + /* catch regionview going away */ - region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr (r))); + r->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr (r))); RegionViewAdded (region_view); @@ -400,7 +412,7 @@ AudioStreamView::redisplay_diskstream () if (_trackview.is_audio_track()) { _trackview.get_diskstream()->playlist()->foreach_region( - sigc::mem_fun (*this, &StreamView::add_region_view) + sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view)) ); boost::shared_ptr apl = boost::dynamic_pointer_cast( diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h index 9c1335042b..728e9b39f2 100644 --- a/gtk2_ardour/audio_streamview.h +++ b/gtk2_ardour/audio_streamview.h @@ -80,6 +80,8 @@ class AudioStreamView : public StreamView void hide_xfades_involving (AudioRegionView&); void reveal_xfades_involving (AudioRegionView&); + RegionView* create_region_view (boost::shared_ptr, bool, bool); + private: void setup_rec_box (); void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr src); diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc index dc0a5b07cd..80dbd669ca 100644 --- a/gtk2_ardour/automation_region_view.cc +++ b/gtk2_ardour/automation_region_view.cc @@ -33,7 +33,7 @@ AutomationRegionView::AutomationRegionView(ArdourCanvas::Group* const Evoral::Parameter& param, boost::shared_ptr list, double spu, - Gdk::Color& basic_color) + Gdk::Color const & basic_color) : RegionView(parent, time_axis, region, spu, basic_color) , _parameter(param) { @@ -46,7 +46,7 @@ AutomationRegionView::AutomationRegionView(ArdourCanvas::Group* } void -AutomationRegionView::init (Gdk::Color& basic_color, bool wfd) +AutomationRegionView::init (Gdk::Color const & basic_color, bool wfd) { _enable_display = false; diff --git a/gtk2_ardour/automation_region_view.h b/gtk2_ardour/automation_region_view.h index 99a344d681..e6531821d3 100644 --- a/gtk2_ardour/automation_region_view.h +++ b/gtk2_ardour/automation_region_view.h @@ -45,11 +45,11 @@ public: const Evoral::Parameter& parameter, boost::shared_ptr, double initial_samples_per_unit, - Gdk::Color& basic_color); + Gdk::Color const & basic_color); ~AutomationRegionView() {} - void init (Gdk::Color& basic_color, bool wfd); + void init (Gdk::Color const & basic_color, bool wfd); inline AutomationTimeAxisView* automation_view() const { return dynamic_cast(&trackview); } diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc index 0ba49fd2d9..1654e7e5a9 100644 --- a/gtk2_ardour/automation_streamview.cc +++ b/gtk2_ardour/automation_streamview.cc @@ -167,7 +167,7 @@ AutomationStreamView::redisplay_diskstream () // Add and display region views, and flag them as valid if (_trackview.is_track()) { _trackview.get_diskstream()->playlist()->foreach_region ( - sigc::mem_fun (*this, &StreamView::add_region_view) + sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view)) ); } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index c8fc118efa..2a28d0fe1b 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1495,6 +1495,7 @@ public: Gtk::Allocation canvas_allocation; void track_canvas_allocate (Gtk::Allocation alloc); bool track_canvas_size_allocated (); + bool track_canvas_drag_motion (Glib::RefPtr const &, int, int, guint); void set_playhead_cursor (); @@ -2014,7 +2015,7 @@ public: void duplicate_dialog (bool with_dialog); - nframes64_t event_frame (GdkEvent*, double* px = 0, double* py = 0) const; + nframes64_t event_frame (GdkEvent const *, double* px = 0, double* py = 0) const; /* returns false if mouse pointer is not in track or marker canvas */ @@ -2244,6 +2245,8 @@ public: friend class RangeMarkerBarDrag; friend class MouseZoomDrag; friend class RegionCreateDrag; + friend class RegionMotionDrag; + friend class RegionInsertDrag; }; #endif /* __ardour_editor_h__ */ diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 10878ce712..0c10ebf8c3 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -22,7 +22,6 @@ #include #include -#include "ardour/audioregion.h" #include "ardour/profile.h" #include "ardour_ui.h" @@ -39,9 +38,9 @@ #include "editing.h" #include "rgb_macros.h" #include "utils.h" -#include "time_axis_view.h" #include "audio_time_axis.h" #include "editor_drag.h" +#include "region_view.h" #include "i18n.h" @@ -283,6 +282,7 @@ Editor::initialize_canvas () track_canvas->signal_motion_notify_event().connect (mem_fun (*this, &Editor::track_canvas_motion_notify_event)); track_canvas->signal_button_press_event().connect (mem_fun (*this, &Editor::track_canvas_button_press_event)); track_canvas->signal_button_release_event().connect (mem_fun (*this, &Editor::track_canvas_button_release_event)); + track_canvas->signal_drag_motion().connect (mem_fun (*this, &Editor::track_canvas_drag_motion)); track_canvas->set_name ("EditorMainCanvas"); track_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK); @@ -532,20 +532,10 @@ Editor::drop_regions (const RefPtr& context, const SelectionData& data, guint info, guint time) { - std::list > regions; - Gtk::TreeView* source; - region_list_display.get_object_drag_data (regions, &source); - - for (list >::iterator r = regions.begin(); r != regions.end(); ++r) { - - boost::shared_ptr ar; - - if ((ar = boost::dynamic_pointer_cast(*r)) != 0) { - insert_region_list_drag (ar, x, y); - } - } - - context->drag_finish (true, false, time); + assert (_drag); + _drag->end_grab (0); + delete _drag; + _drag = 0; } void diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 73c02d75d6..99868367f0 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -26,6 +26,9 @@ #include "ardour/audio_diskstream.h" #include "ardour/audioplaylist.h" +#include "ardour/midi_region.h" +#include "ardour/audioregion.h" +#include "ardour/region_factory.h" #include "editor.h" #include "keyboard.h" @@ -43,6 +46,7 @@ #include "simplerect.h" #include "interactive-item.h" #include "editor_drag.h" +#include "midi_time_axis.h" #include "i18n.h" @@ -896,3 +900,63 @@ Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item) return typed_event (item, event, NoItem); } +bool +Editor::track_canvas_drag_motion (Glib::RefPtr const & c, int x, int y, guint time) +{ + double wx; + double wy; + track_canvas->window_to_world (x, y, wx, wy); + + GdkEvent event; + event.type = GDK_MOTION_NOTIFY; + event.button.x = wx; + event.button.y = wy; + /* assume we're dragging with button 1 */ + event.motion.state = Gdk::BUTTON1_MASK; + + if (_drag == 0) { + + double px; + double py; + nframes64_t const pos = event_frame (&event, &px, &py); + + std::pair const tv = trackview_by_y_position (py); + if (tv.first == 0) { + return true; + } + + RouteTimeAxisView* rtav = dynamic_cast (tv.first); + if (rtav == 0 || !rtav->is_track ()) { + return true; + } + + list > regions; + TreeView* source; + region_list_display.get_object_drag_data (regions, &source); + assert (regions.size() == 1); + boost::shared_ptr region = regions.front (); + + boost::shared_ptr region_copy = RegionFactory::create (region); + + if (boost::dynamic_pointer_cast (region_copy) != 0 && + dynamic_cast (tv.first) == 0) { + + /* audio -> non-audio */ + return true; + } + + if (boost::dynamic_pointer_cast (region_copy) == 0 && + dynamic_cast (tv.first) != 0) { + + /* MIDI -> non-MIDI */ + return true; + } + + _drag = new RegionInsertDrag (this, region_copy, rtav, pos); + _drag->start_grab (&event); + } + + _drag->motion_handler (&event, false); + + return true; +} diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index dd4c8c1b32..d41a91aadd 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -33,6 +33,8 @@ #include "utils.h" #include "region_gain_line.h" #include "editor_drag.h" +#include "audio_time_axis.h" +#include "midi_time_axis.h" using namespace std; using namespace ARDOUR; @@ -50,7 +52,6 @@ Drag::Drag (Editor* e, ArdourCanvas::Item* i) : _grab_frame (0), _last_pointer_frame (0), _current_pointer_frame (0), - _copy (false), _had_movement (false), _move_threshold_passed (false) { @@ -138,11 +139,9 @@ Drag::end_grab (GdkEvent* event) _item->ungrab (event ? event->button.time : 0); - if (event) { - _last_pointer_x = _current_pointer_x; - _last_pointer_y = _current_pointer_y; - finished (event, _had_movement); - } + _last_pointer_x = _current_pointer_x; + _last_pointer_y = _current_pointer_y; + finished (event, _had_movement); _editor->hide_verbose_canvas_cursor(); @@ -256,147 +255,108 @@ RegionDrag::update_selection () _editor->selection->set (s); } -RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool b, bool c) +RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool b) : RegionDrag (e, i, p, v), + _dest_trackview (0), + _dest_layer (0), _brushing (b) { - _copy = c; - TimeAxisView* const tv = &_primary->get_time_axis_view (); - - _dest_trackview = tv; - _dest_layer = _primary->region()->layer (); - - double speed = 1; - RouteTimeAxisView* rtv = dynamic_cast (tv); - if (rtv && rtv->is_track()) { - speed = rtv->get_diskstream()->speed (); - } - - _last_frame_position = static_cast (_primary->region()->position() / speed); } + void -RegionMoveDrag::start_grab (GdkEvent* event, Gdk::Cursor *) +RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor *) { Drag::start_grab (event); - _pointer_frame_offset = _grab_frame - _last_frame_position; _editor->show_verbose_time_cursor (_last_frame_position, 10); } -void -RegionMoveDrag::motion (GdkEvent* event, bool first_move) +RegionMotionDrag::TimeAxisViewSummary +RegionMotionDrag::get_time_axis_view_summary () { - double x_delta = 0; - double y_delta = 0; - nframes64_t pending_region_position = 0; - int32_t pointer_order_span = 0, canvas_pointer_order_span = 0; - int32_t pointer_layer_span = 0; - - bool clamp_y_axis = false; - vector::iterator j; + int32_t children = 0; + TimeAxisViewSummary sum; - if (_copy && first_move) { - copy_regions (event); - } - - /* *pointer* variables reflect things about the pointer; as we may be moving - multiple regions, much detail must be computed per-region */ + _editor->visible_order_range (&sum.visible_y_low, &sum.visible_y_high); + + /* get a bitmask representing the visible tracks */ - /* current_pointer_view will become the TimeAxisView that we're currently pointing at, and - current_pointer_layer the current layer on that TimeAxisView */ - RouteTimeAxisView* current_pointer_view; - layer_t current_pointer_layer; - if (!check_possible (¤t_pointer_view, ¤t_pointer_layer)) { - return; + for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) { + RouteTimeAxisView* rtv = dynamic_cast (*i); + TimeAxisView::Children children_list; + + /* zeroes are audio/MIDI tracks. ones are other types. */ + + if (!rtv->hidden()) { + + if (!rtv->is_track()) { + /* not an audio nor MIDI track */ + sum.tracks = sum.tracks |= (0x01 << rtv->order()); + } + + sum.height_list[rtv->order()] = (*i)->current_height(); + children = 1; + + if ((children_list = rtv->get_child_list()).size() > 0) { + for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { + sum.tracks = sum.tracks |= (0x01 << (rtv->order() + children)); + sum.height_list[rtv->order() + children] = (*j)->current_height(); + children++; + } + } + } } - /* TimeAxisView that we were pointing at last time we entered this method */ - TimeAxisView const * const last_pointer_view = _dest_trackview; - /* the order of the track that we were pointing at last time we entered this method */ - int32_t const last_pointer_order = last_pointer_view->order (); - /* the layer that we were pointing at last time we entered this method */ - layer_t const last_pointer_layer = _dest_layer; - - /************************************************************ - Y DELTA COMPUTATION - ************************************************************/ + return sum; +} - /* Height of TimeAxisViews, indexed by order */ - /* XXX: hard-coded limit of TimeAxisViews */ - vector height_list (512); - +bool +RegionMotionDrag::compute_y_delta ( + TimeAxisView const * last_pointer_view, TimeAxisView* current_pointer_view, + int32_t last_pointer_layer, int32_t current_pointer_layer, + TimeAxisViewSummary const & tavs, + int32_t* pointer_order_span, int32_t* pointer_layer_span, + int32_t* canvas_pointer_order_span + ) +{ if (_brushing) { - clamp_y_axis = true; - pointer_order_span = 0; - goto y_axis_done; + *pointer_order_span = 0; + *pointer_layer_span = 0; + return true; } + bool clamp_y_axis = false; + /* the change in track order between this callback and the last */ - pointer_order_span = last_pointer_view->order() - current_pointer_view->order(); + *pointer_order_span = last_pointer_view->order() - current_pointer_view->order(); /* the change in layer between this callback and the last; only meaningful if pointer_order_span == 0 (ie we've not moved tracks) */ - pointer_layer_span = last_pointer_layer - current_pointer_layer; - - if (pointer_order_span != 0) { - - int32_t children = 0; - /* XXX: hard-coded limit of tracks */ - bitset <512> tracks (0x00); - - int visible_y_high; - int visible_y_low; - _editor->visible_order_range (&visible_y_low, &visible_y_high); - - /* get a bitmask representing the visible tracks */ + *pointer_layer_span = last_pointer_layer - current_pointer_layer; - for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) { - RouteTimeAxisView* rtv = dynamic_cast (*i); - TimeAxisView::Children children_list; - - /* zeroes are audio/MIDI tracks. ones are other types. */ - - if (!rtv->hidden()) { - - if (!rtv->is_track()) { - /* not an audio nor MIDI track */ - tracks = tracks |= (0x01 << rtv->order()); - } - - height_list[rtv->order()] = (*i)->current_height(); - children = 1; + if (*pointer_order_span != 0) { - if ((children_list = rtv->get_child_list()).size() > 0) { - for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { - tracks = tracks |= (0x01 << (rtv->order() + children)); - height_list[rtv->order() + children] = (*j)->current_height(); - children++; - } - } - } - } - /* find the actual pointer span, in terms of the number of visible tracks; to do this, we reduce |pointer_order_span| by the number of hidden tracks over the span */ - canvas_pointer_order_span = pointer_order_span; + *canvas_pointer_order_span = *pointer_order_span; if (last_pointer_view->order() >= current_pointer_view->order()) { for (int32_t y = current_pointer_view->order(); y < last_pointer_view->order(); y++) { - if (height_list[y] == 0) { - canvas_pointer_order_span--; + if (tavs.height_list[y] == 0) { + *canvas_pointer_order_span--; } } } else { for (int32_t y = last_pointer_view->order(); y <= current_pointer_view->order(); y++) { - if (height_list[y] == 0) { - canvas_pointer_order_span++; + if (tavs.height_list[y] == 0) { + *canvas_pointer_order_span++; } } } - for (list::const_iterator i = _editor->selection->regions.by_layer().begin(); i != _editor->selection->regions.by_layer().end(); ++i) { + for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = (*i); @@ -414,18 +374,11 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) assert (tvp.first); RouteTimeAxisView* rtv = dynamic_cast (tvp.first); - /* I know this method has a slightly excessive argument list, but I think - it's nice to separate the code out all the same, since it has such a - simple result, and it makes it clear that there are no other - side-effects. - */ - /* XXX: not sure that we should be passing canvas_pointer_order_span in here, as surely this is a per-region thing... */ clamp_y_axis = y_movement_disallowed ( - rtv->order(), last_pointer_order, canvas_pointer_order_span, visible_y_low, visible_y_high, - tracks, height_list + rtv->order(), last_pointer_view->order(), *canvas_pointer_order_span, tavs ); if (clamp_y_axis) { @@ -441,16 +394,20 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) } } - y_axis_done: if (!clamp_y_axis) { _dest_trackview = current_pointer_view; _dest_layer = current_pointer_layer; } - - /************************************************************ - X DELTA COMPUTATION - ************************************************************/ + return clamp_y_axis; +} + + +double +RegionMotionDrag::compute_x_delta (GdkEvent const * event, nframes64_t* pending_region_position) +{ + *pending_region_position = 0; + /* compute the amount of pointer motion in frames, and where the region would be if we moved it by that much. */ @@ -460,14 +417,15 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) nframes64_t sync_offset; int32_t sync_dir; - pending_region_position = _current_pointer_frame - _pointer_frame_offset; + *pending_region_position = _current_pointer_frame - _pointer_frame_offset; sync_offset = _primary->region()->sync_offset (sync_dir); /* we don't handle a sync point that lies before zero. */ - if (sync_dir >= 0 || (sync_dir < 0 && pending_region_position >= sync_offset)) { - sync_frame = pending_region_position + (sync_dir*sync_offset); + if (sync_dir >= 0 || (sync_dir < 0 && *pending_region_position >= sync_offset)) { + + sync_frame = *pending_region_position + (sync_dir*sync_offset); /* we snap if the snap modifier is not enabled. */ @@ -476,43 +434,30 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) _editor->snap_to (sync_frame); } - pending_region_position = _primary->region()->adjust_to_sync (sync_frame); + *pending_region_position = _primary->region()->adjust_to_sync (sync_frame); } else { - pending_region_position = _last_frame_position; + *pending_region_position = _last_frame_position; } - } else { - pending_region_position = 0; - } - - if (pending_region_position > max_frames - _primary->region()->length()) { - pending_region_position = _last_frame_position; } - bool x_move_allowed; - - if (Config->get_edit_mode() == Lock) { - if (_copy) { - x_move_allowed = !_x_constrained; - } else { - /* in locked edit mode, reverse the usual meaning of _x_constrained */ - x_move_allowed = _x_constrained; - } - } else { - x_move_allowed = !_x_constrained; + if (*pending_region_position > max_frames - _primary->region()->length()) { + *pending_region_position = _last_frame_position; } + + double x_delta = 0; - if (( pending_region_position != _last_frame_position) && x_move_allowed ) { + if ((*pending_region_position != _last_frame_position) && x_move_allowed ()) { /* now compute the canvas unit distance we need to move the regionview to make it appear at the new location. */ + + x_delta = (static_cast (*pending_region_position) - _last_frame_position) / _editor->frames_per_unit; - if (pending_region_position > _last_frame_position) { - x_delta = ((double) (pending_region_position - _last_frame_position) / _editor->frames_per_unit); - } else { - x_delta = -((double) (_last_frame_position - pending_region_position) / _editor->frames_per_unit); + if (*pending_region_position <= _last_frame_position) { + for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { RegionView* rv = (*i); @@ -525,20 +470,60 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) if (-x_delta > ix1 + _editor->horizontal_adjustment.get_value()) { x_delta = 0; - pending_region_position = _last_frame_position; + *pending_region_position = _last_frame_position; break; } } } - _last_frame_position = pending_region_position; - - } else { - x_delta = 0; + _last_frame_position = *pending_region_position; } + return x_delta; +} + +void +RegionMotionDrag::motion (GdkEvent* event, bool first_move) +{ + double y_delta = 0; + + TimeAxisViewSummary tavs = get_time_axis_view_summary (); + + vector::iterator j; + + /* *pointer* variables reflect things about the pointer; as we may be moving + multiple regions, much detail must be computed per-region */ + + /* current_pointer_view will become the TimeAxisView that we're currently pointing at, and + current_pointer_layer the current layer on that TimeAxisView */ + RouteTimeAxisView* current_pointer_view; + layer_t current_pointer_layer; + if (!check_possible (¤t_pointer_view, ¤t_pointer_layer)) { + return; + } + + /* TimeAxisView that we were pointing at last time we entered this method */ + TimeAxisView const * const last_pointer_view = _dest_trackview; + /* the order of the track that we were pointing at last time we entered this method */ + int32_t const last_pointer_order = last_pointer_view->order (); + /* the layer that we were pointing at last time we entered this method */ + layer_t const last_pointer_layer = _dest_layer; + + int32_t pointer_order_span; + int32_t pointer_layer_span; + int32_t canvas_pointer_order_span; + bool const clamp_y_axis = compute_y_delta ( + last_pointer_view, current_pointer_view, + last_pointer_layer, current_pointer_layer, tavs, + &pointer_order_span, &pointer_layer_span, + &canvas_pointer_order_span + ); + + nframes64_t pending_region_position; + double const x_delta = compute_x_delta (event, &pending_region_position); + /************************************************************* PREPARE TO MOVE ************************************************************/ @@ -614,9 +599,9 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) /* INTER-TRACK MOVEMENT */ /* move through the height list to the track that the region is currently on */ - vector::iterator j = height_list.begin (); + vector::iterator j = tavs.height_list.begin (); int32_t x = 0; - while (j != height_list.end () && x != rtv->order ()) { + while (j != tavs.height_list.end () && x != rtv->order ()) { ++x; ++j; } @@ -624,7 +609,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) y_delta = 0; int32_t temp_pointer_order_span = canvas_pointer_order_span; - if (j != height_list.end ()) { + if (j != tavs.height_list.end ()) { /* Account for layers in the original and destination tracks. If we're moving around in layers we assume @@ -654,7 +639,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) /* we're moving up canvas-wise, so we need to find the next track height */ - if (j != height_list.begin()) { + if (j != tavs.height_list.begin()) { j--; } @@ -678,7 +663,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) } } - if (j != height_list.end()) { + if (j != tavs.height_list.end()) { j++; } @@ -724,7 +709,17 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) if (x_delta != 0 && !_brushing) { _editor->show_verbose_time_cursor (_last_frame_position, 10); } -} +} + +void +RegionMoveDrag::motion (GdkEvent* event, bool first_move) +{ + if (_copy && first_move) { + copy_regions (event); + } + + RegionMotionDrag::motion (event, first_move); +} void RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred) @@ -769,8 +764,6 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred) goto out; } - char* op_string; - /* reverse this here so that we have the correct logic to finalize the drag. */ @@ -781,19 +774,18 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred) if (_copy) { if (_x_constrained) { - op_string = _("fixed time region copy"); + _editor->begin_reversible_command (_("fixed time region copy")); } else { - op_string = _("region copy"); + _editor->begin_reversible_command (_("region copy")); } } else { if (_x_constrained) { - op_string = _("fixed time region drag"); + _editor->begin_reversible_command (_("fixed time region drag")); } else { - op_string = _("region drag"); + _editor->begin_reversible_command (_("region drag")); } } - _editor->begin_reversible_command (op_string); changed_position = (_last_frame_position != (nframes64_t) (_primary->region()->position())); tvp = _editor->trackview_by_y_position (_current_pointer_y); changed_tracks = (tvp.first != &_primary->get_time_axis_view()); @@ -803,16 +795,7 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred) _editor->track_canvas->update_now (); /* make a list of where each region ended up */ - for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { - - double ix1, ix2, iy1, iy2; - (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); - (*i)->get_canvas_frame()->i2w (ix1, iy1); - iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize; - - pair tv = _editor->trackview_by_y_position (iy1); - final[*i] = dynamic_cast (tv.first); - } + final = find_time_axis_views (); for (list::const_iterator i = _views.begin(); i != _views.end(); ) { @@ -999,10 +982,35 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred) delete *x; } } + + +bool +RegionMoveDrag::x_move_allowed () const +{ + if (Config->get_edit_mode() == Lock) { + if (_copy) { + return !_x_constrained; + } else { + /* in locked edit mode, reverse the usual meaning of _x_constrained */ + return _x_constrained; + } + } + return !_x_constrained; +} + +bool +RegionInsertDrag::x_move_allowed () const +{ + if (Config->get_edit_mode() == Lock) { + return _x_constrained; + } + + return !_x_constrained; +} void -RegionMoveDrag::copy_regions (GdkEvent* event) +RegionMotionDrag::copy_regions (GdkEvent* event) { /* duplicate the regionview(s) and region(s) */ @@ -1043,7 +1051,8 @@ RegionMoveDrag::copy_regions (GdkEvent* event) _primary = new_regionviews.front(); _views = new_regionviews; - swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time); + swap_grab (new_regionviews.front()->get_canvas_group (), 0, event ? event->motion.time : 0); + /* sync the canvas to what we think is its current state without it, the canvas seems to @@ -1055,7 +1064,7 @@ RegionMoveDrag::copy_regions (GdkEvent* event) } bool -RegionMoveDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer) +RegionMotionDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer) { /* Which trackview is this ? */ @@ -1081,16 +1090,10 @@ RegionMoveDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer) /** @param new_order New track order. * @param old_order Old track order. * @param visible_y_low Lowest visible order. - * @param visible_y_high Highest visible order. - * @param tracks Bitset of tracks indexed by order; 0 means a audio/MIDI track, 1 means something else. - * @param heigh_list Heights of tracks indexed by order. * @return true if y movement should not happen, otherwise false. */ bool -RegionMoveDrag::y_movement_disallowed ( - int new_order, int old_order, int y_span, int visible_y_low, int visible_y_high, - bitset<512> const & tracks, vector const & height_list - ) const +RegionMotionDrag::y_movement_disallowed (int new_order, int old_order, int y_span, TimeAxisViewSummary const & tavs) const { if (new_order != old_order) { @@ -1099,7 +1102,7 @@ RegionMoveDrag::y_movement_disallowed ( if (y_span > 0) { /* moving up the canvas */ - if ( (new_order - y_span) >= visible_y_low) { + if ( (new_order - y_span) >= tavs.visible_y_low) { int32_t n = 0; @@ -1107,13 +1110,13 @@ RegionMoveDrag::y_movement_disallowed ( int32_t visible_tracks = 0; while (visible_tracks < y_span ) { visible_tracks++; - while (height_list[new_order - (visible_tracks - n)] == 0) { + while (tavs.height_list[new_order - (visible_tracks - n)] == 0) { /* passing through a hidden track */ n--; } } - if (tracks[new_order - (y_span - n)] != 0x00) { + if (tavs.tracks[new_order - (y_span - n)] != 0x00) { /* moving to a non-track; disallow */ return true; } @@ -1127,20 +1130,20 @@ RegionMoveDrag::y_movement_disallowed ( } else if (y_span < 0) { /* moving down the canvas */ - if ((new_order - y_span) <= visible_y_high) { + if ((new_order - y_span) <= tavs.visible_y_high) { int32_t visible_tracks = 0; int32_t n = 0; while (visible_tracks > y_span ) { visible_tracks--; - while (height_list[new_order - (visible_tracks - n)] == 0) { + while (tavs.height_list[new_order - (visible_tracks - n)] == 0) { /* passing through a hidden track */ n++; } } - if (tracks[new_order - (y_span - n)] != 0x00) { + if (tavs.tracks[new_order - (y_span - n)] != 0x00) { /* moving to a non-track; disallow */ return true; } @@ -1157,10 +1160,10 @@ RegionMoveDrag::y_movement_disallowed ( /* this is the pointer's track */ - if ((new_order - y_span) > visible_y_high) { + if ((new_order - y_span) > tavs.visible_y_high) { /* we will overflow */ return true; - } else if ((new_order - y_span) < visible_y_low) { + } else if ((new_order - y_span) < tavs.visible_y_low) { /* we will overflow */ return true; } @@ -1169,6 +1172,97 @@ RegionMoveDrag::y_movement_disallowed ( return false; } + +RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v, bool b, bool c) + : RegionMotionDrag (e, i, p, v, b), + _copy (c) +{ + TimeAxisView* const tv = &_primary->get_time_axis_view (); + + _dest_trackview = tv; + _dest_layer = _primary->region()->layer (); + + double speed = 1; + RouteTimeAxisView* rtv = dynamic_cast (tv); + if (rtv && rtv->is_track()) { + speed = rtv->get_diskstream()->speed (); + } + + _last_frame_position = static_cast (_primary->region()->position() / speed); +} + +void +RegionMoveDrag::start_grab (GdkEvent* event, Gdk::Cursor* c) +{ + RegionMotionDrag::start_grab (event, c); + + _pointer_frame_offset = _grab_frame - _last_frame_position; +} + +RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr r, RouteTimeAxisView* v, nframes64_t pos) + : RegionMotionDrag (e, 0, 0, list (), false) +{ + assert ((boost::dynamic_pointer_cast (r) && dynamic_cast (v)) || + (boost::dynamic_pointer_cast (r) && dynamic_cast (v))); + + _primary = v->view()->create_region_view (r, false, false); + + _primary->get_canvas_group()->show (); + _primary->set_position (pos, 0); + _views.push_back (_primary); + + _last_frame_position = pos; + + _item = _primary->get_canvas_group (); + _dest_trackview = v; + _dest_layer = _primary->region()->layer (); +} + +map +RegionMotionDrag::find_time_axis_views () +{ + map tav; + + for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { + + double ix1, ix2, iy1, iy2; + (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); + (*i)->get_canvas_frame()->i2w (ix1, iy1); + iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize; + + pair tv = _editor->trackview_by_y_position (iy1); + tav[*i] = dynamic_cast (tv.first); + } + + return tav; +} + + +void +RegionInsertDrag::finished (GdkEvent* event, bool movement_occurred) +{ + _editor->track_canvas->update_now (); + + map final = find_time_axis_views (); + + RouteTimeAxisView* dest_rtv = final[_primary]; + + _primary->get_canvas_group()->reparent (*dest_rtv->view()->canvas_item()); + _primary->get_canvas_group()->property_y() = 0; + + boost::shared_ptr playlist = dest_rtv->playlist(); + + _editor->begin_reversible_command (_("insert region")); + XMLNode& before = playlist->get_state (); + playlist->add_region (_primary->region (), _last_frame_position); + _editor->session->add_command (new MementoCommand (*playlist, &before, &playlist->get_state())); + _editor->commit_reversible_command (); + + delete _primary; + _primary = 0; + _views.clear (); +} + RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list const & v) : RegionMoveDrag (e, i, p, v, false, false) { @@ -1550,10 +1644,9 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) } MeterMarkerDrag::MeterMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c) - : Drag (e, i) + : Drag (e, i), + _copy (c) { - _copy = c; - _marker = reinterpret_cast (_item->get_data ("marker")); assert (_marker); } @@ -1645,10 +1738,9 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred) } TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c) - : Drag (e, i) + : Drag (e, i), + _copy (c) { - _copy = c; - TempoMarker* _marker = reinterpret_cast (_item->get_data ("marker")); assert (_marker); } @@ -2731,7 +2823,8 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred) SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o) : Drag (e, i), - _operation (o) + _operation (o), + _copy (false) { } @@ -2944,7 +3037,8 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred) RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o) : Drag (e, i), - _operation (o) + _operation (o), + _copy (false) { _drag_rect = new ArdourCanvas::SimpleRect (*_editor->time_line_group, 0.0, 0.0, 0.0, _editor->physical_screen_height); _drag_rect->hide (); diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 79e0115471..370cc56643 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -134,7 +134,6 @@ protected: double _last_pointer_y; ///< item y of the pointer last time a motion occurred bool _x_constrained; ///< true if x motion is constrained, otherwise false bool _y_constrained; ///< true if y motion is constrained, otherwise false - bool _copy; ///< true if we're copying the things that we're dragging bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false private: @@ -164,33 +163,80 @@ private: }; -/** Drags to move regions */ -class RegionMoveDrag : public RegionDrag +/** Drags involving region motion from somewhere */ +class RegionMotionDrag : public RegionDrag +{ +public: + + RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool); + virtual ~RegionMotionDrag () {} + + virtual void start_grab (GdkEvent *, Gdk::Cursor *); + virtual void motion (GdkEvent *, bool); + virtual void finished (GdkEvent *, bool) = 0; + +protected: + struct TimeAxisViewSummary { + TimeAxisViewSummary () : height_list(512) {} + + std::bitset<512> tracks; + std::vector height_list; + int visible_y_low; + int visible_y_high; + }; + + void copy_regions (GdkEvent *); + bool y_movement_disallowed (int, int, int, TimeAxisViewSummary const &) const; + std::map find_time_axis_views (); + double compute_x_delta (GdkEvent const *, nframes64_t *); + bool compute_y_delta ( + TimeAxisView const *, TimeAxisView*, int32_t, int32_t, TimeAxisViewSummary const &, + int32_t *, int32_t *, int32_t * + ); + + TimeAxisViewSummary get_time_axis_view_summary (); + virtual bool x_move_allowed () const = 0; + + TimeAxisView* _dest_trackview; + ARDOUR::layer_t _dest_layer; + bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *); + bool _brushing; +}; + + +/** Drags to move (or copy) regions that are already shown in the GUI to + * somewhere different. + */ +class RegionMoveDrag : public RegionMotionDrag { public: RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list const &, bool, bool); virtual ~RegionMoveDrag () {} virtual void start_grab (GdkEvent *, Gdk::Cursor *); - virtual void motion (GdkEvent *, bool); - virtual void finished (GdkEvent *, bool); + void motion (GdkEvent *, bool); + void finished (GdkEvent *, bool); + bool apply_move_threshold () const { return true; } -protected: +private: + bool x_move_allowed () const; - bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *); + bool _copy; +}; - TimeAxisView* _dest_trackview; - ARDOUR::layer_t _dest_layer; +/** Drag to insert a region from somewhere */ +class RegionInsertDrag : public RegionMotionDrag +{ +public: + RegionInsertDrag (Editor *, boost::shared_ptr, RouteTimeAxisView*, nframes64_t); + void finished (GdkEvent *, bool); + private: - - void copy_regions (GdkEvent *); - bool y_movement_disallowed (int, int, int, int, int, std::bitset<512> const &, std::vector const &) const; - - bool _brushing; + bool x_move_allowed () const; }; /** Region drag in splice mode */ @@ -264,6 +310,7 @@ public: private: MeterMarker* _marker; + bool _copy; }; /** Tempo marker drag */ @@ -278,6 +325,7 @@ public: private: TempoMarker* _marker; + bool _copy; }; @@ -416,6 +464,7 @@ public: private: Operation _operation; + bool _copy; }; /** Range marker drag */ @@ -439,6 +488,7 @@ private: Operation _operation; ArdourCanvas::SimpleRect* _drag_rect; + bool _copy; }; /* Drag of rectangle to set zoom */ diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 32f01872fe..c67ca5942d 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -112,7 +112,7 @@ Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const } nframes64_t -Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) const +Editor::event_frame (GdkEvent const * event, double* pcx, double* pcy) const { double cx, cy; diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 4e0b58da95..4ec2698e67 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -66,7 +66,7 @@ using namespace Editing; using namespace ArdourCanvas; MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, - boost::shared_ptr r, double spu, Gdk::Color& basic_color) + boost::shared_ptr r, double spu, Gdk::Color const & basic_color) : RegionView (parent, tv, r, spu, basic_color) , _force_channel(-1) , _last_channel_selection(0xFFFF) @@ -150,7 +150,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptrmidi_source(0)->load_model(); diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index b26edb5a47..3df4001ab4 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -66,14 +66,14 @@ class MidiRegionView : public RegionView RouteTimeAxisView&, boost::shared_ptr, double initial_samples_per_unit, - Gdk::Color& basic_color); + Gdk::Color const & basic_color); MidiRegionView (const MidiRegionView& other); MidiRegionView (const MidiRegionView& other, boost::shared_ptr); ~MidiRegionView (); - virtual void init (Gdk::Color& basic_color, bool wfd); + virtual void init (Gdk::Color const & basic_color, bool wfd); inline const boost::shared_ptr midi_region() const { return boost::dynamic_pointer_cast(_region); } diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index b7fa88404e..ebc6b0d642 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -130,18 +130,32 @@ veto_note_range(uint8_t& min, uint8_t& max) } RegionView* -MidiStreamView::add_region_view_internal (boost::shared_ptr r, bool wfd, bool recording) +MidiStreamView::create_region_view (boost::shared_ptr r, bool wfd, bool) { boost::shared_ptr region = boost::dynamic_pointer_cast (r); if (region == 0) { - return NULL; + return 0; } - MidiRegionView *region_view; - list::iterator i; + RegionView* region_view = new MidiRegionView (canvas_group, _trackview, region, + _samples_per_unit, region_color); + + region_view->init (region_color, false); + + return region_view; +} - for (i = region_views.begin(); i != region_views.end(); ++i) { +RegionView* +MidiStreamView::add_region_view_internal (boost::shared_ptr r, bool wfd, bool recording) +{ + boost::shared_ptr region = boost::dynamic_pointer_cast (r); + + if (region == 0) { + return 0; + } + + for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) { if ((*i)->region() == r) { /* great. we already have a MidiRegionView for this Region. use it again. */ @@ -150,18 +164,19 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr r, bool wfd, display_region(dynamic_cast(*i), wfd); - return NULL; + return 0; } } + + MidiRegionView* region_view = dynamic_cast (create_region_view (r, wfd, recording)); + if (region_view == 0) { + return 0; + } - region_view = new MidiRegionView (canvas_group, _trackview, region, - _samples_per_unit, region_color); - - region_view->init (region_color, false); region_views.push_front (region_view); /* display events and find note range */ - display_region(region_view, wfd); + display_region (region_view, wfd); /* catch regionview going away */ region->GoingAway.connect (bind (mem_fun (*this, &MidiStreamView::remove_region_view), region)); @@ -266,7 +281,7 @@ MidiStreamView::redisplay_diskstream () // Add and display region views, and flag them as valid _trackview.get_diskstream()->playlist()->foreach_region( - sigc::mem_fun (*this, &StreamView::add_region_view) + sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view)) ); // Stack regions by layer, and remove invalid regions diff --git a/gtk2_ardour/midi_streamview.h b/gtk2_ardour/midi_streamview.h index a844d8d505..2b7a7b02fa 100644 --- a/gtk2_ardour/midi_streamview.h +++ b/gtk2_ardour/midi_streamview.h @@ -98,6 +98,8 @@ class MidiStreamView : public StreamView sigc::signal NoteRangeChanged; + RegionView* create_region_view (boost::shared_ptr, bool, bool); + private: void setup_rec_box (); diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 3d59c0a0d5..85d59a93b1 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -64,10 +64,10 @@ RegionView::RegionView (ArdourCanvas::Group* parent, TimeAxisView& tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color) + Gdk::Color const & basic_color) : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), false, - TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText| - TimeAxisViewItem::ShowNameHighlight| TimeAxisViewItem::ShowFrame)) + TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText| + TimeAxisViewItem::ShowNameHighlight| TimeAxisViewItem::ShowFrame)) , _region (r) , sync_mark(0) , sync_line(0) @@ -118,7 +118,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent, TimeAxisView& tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color, + Gdk::Color const & basic_color, bool recording, TimeAxisViewItem::Visibility visibility) : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), recording, visibility) @@ -137,7 +137,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent, } void -RegionView::init (Gdk::Color& basic_color, bool wfd) +RegionView::init (Gdk::Color const & basic_color, bool wfd) { editor = 0; valid = true; @@ -350,12 +350,6 @@ RegionView::set_duration (nframes_t frames, void *src) return true; } -void -RegionView::compute_colors (Gdk::Color& basic_color) -{ - TimeAxisViewItem::compute_colors (basic_color); -} - void RegionView::set_colors () { diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 25c4eb8714..98329ee77b 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -45,14 +45,14 @@ class RegionView : public TimeAxisViewItem TimeAxisView& time_view, boost::shared_ptr region, double samples_per_unit, - Gdk::Color& basic_color); + Gdk::Color const & basic_color); RegionView (const RegionView& other); RegionView (const RegionView& other, boost::shared_ptr other_region); ~RegionView (); - virtual void init (Gdk::Color& base_color, bool wait_for_data); + virtual void init (Gdk::Color const & base_color, bool wait_for_data); boost::shared_ptr region() const { return _region; } @@ -99,8 +99,8 @@ class RegionView : public TimeAxisViewItem RegionView (ArdourCanvas::Group *, TimeAxisView&, boost::shared_ptr, - double samples_per_unit, - Gdk::Color& basic_color, + double samples_per_unit, + Gdk::Color const & basic_color, bool recording, TimeAxisViewItem::Visibility); @@ -117,7 +117,6 @@ class RegionView : public TimeAxisViewItem void lock_toggle (); virtual void set_colors (); - virtual void compute_colors (Gdk::Color&); virtual void set_frame_color (); virtual void reset_width_dependent_items (double pixel_width); diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index 2127d1354c..4e55720ac6 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -178,12 +178,14 @@ StreamView::add_region_view_weak (boost::weak_ptr r) } } + void StreamView::add_region_view (boost::shared_ptr r) { ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r)); - + add_region_view_internal (r, true); + if (_layer_display == Stacked) { update_contents_height (); } diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h index bb6047df23..557f605f59 100644 --- a/gtk2_ardour/streamview.h +++ b/gtk2_ardour/streamview.h @@ -103,6 +103,10 @@ public: virtual void redisplay_diskstream () = 0; double child_height () const; ARDOUR::layer_t layers () const { return _layers; } + + virtual RegionView* create_region_view (boost::shared_ptr, bool, bool) { + return 0; + } sigc::signal RegionViewAdded; diff --git a/gtk2_ardour/tape_region_view.cc b/gtk2_ardour/tape_region_view.cc index c28d6c2f7f..a10541ffc6 100644 --- a/gtk2_ardour/tape_region_view.cc +++ b/gtk2_ardour/tape_region_view.cc @@ -52,7 +52,7 @@ const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color) + Gdk::Color const & basic_color) : AudioRegionView (parent, tv, r, spu, basic_color, false, TimeAxisViewItem::Visibility ((r->position() != 0) ? default_tape_visibility : @@ -61,7 +61,7 @@ TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTime } void -TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw) +TapeAudioRegionView::init (Gdk::Color const & basic_color, bool wfw) { /* never wait for data: always just create the waves, connect once and then we'll update whenever we need to. diff --git a/gtk2_ardour/tape_region_view.h b/gtk2_ardour/tape_region_view.h index 048c9bcc5b..8887281393 100644 --- a/gtk2_ardour/tape_region_view.h +++ b/gtk2_ardour/tape_region_view.h @@ -31,11 +31,11 @@ class TapeAudioRegionView : public AudioRegionView RouteTimeAxisView&, boost::shared_ptr, double initial_samples_per_unit, - Gdk::Color& base_color); + Gdk::Color const & base_color); ~TapeAudioRegionView (); protected: - void init (Gdk::Color& base_color, bool wait_for_waves); + void init (Gdk::Color const & base_color, bool wait_for_waves); void set_frame_color (); void update (uint32_t n); diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index 47790c7172..ed31104376 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -68,7 +68,7 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH; * @param start the start point of this item * @param duration the duration of this item */ -TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color, +TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color, nframes_t start, nframes_t duration, bool recording, Visibility vis) : trackview (tv), _recregion(recording) @@ -124,7 +124,7 @@ TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other) } void -TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, Visibility vis) +TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color const & base_color, nframes_t start, nframes_t duration, Visibility vis) { item_name = it_name ; samples_per_unit = spu ; @@ -614,7 +614,7 @@ TimeAxisViewItem::set_height (double height) * */ void -TimeAxisViewItem::set_color(Gdk::Color& base_color) +TimeAxisViewItem::set_color (Gdk::Color const & base_color) { compute_colors (base_color); set_colors (); @@ -662,7 +662,7 @@ TimeAxisViewItem::get_name_pixbuf() * @param color the base color of the item */ void -TimeAxisViewItem::compute_colors(Gdk::Color& base_color) +TimeAxisViewItem::compute_colors (Gdk::Color const & base_color) { unsigned char radius ; char minor_shift ; diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index 7cd1699caa..97e7a73745 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -213,7 +213,7 @@ class TimeAxisViewItem : public Selectable /** * */ - void set_color(Gdk::Color& color) ; + void set_color (Gdk::Color const &); /** * @@ -341,19 +341,19 @@ class TimeAxisViewItem : public Selectable * @param start the start point of this item * @param duration the duration of this item */ - TimeAxisViewItem(const std::string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color, + TimeAxisViewItem(const std::string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color, nframes_t start, nframes_t duration, bool recording = false, Visibility v = Visibility (0)); TimeAxisViewItem (const TimeAxisViewItem& other); - void init (const std::string& it_name, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, Visibility vis); + void init (const std::string& it_name, double spu, Gdk::Color const & base_color, nframes_t start, nframes_t duration, Visibility vis); /** * Calculates some contrasting color for displaying various parts of this item, based upon the base color * * @param color the base color of the item */ - virtual void compute_colors(Gdk::Color& color) ; + virtual void compute_colors (Gdk::Color const & color); /** * convenience method to set the various canvas item colors -- cgit v1.2.3