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
This commit is contained in:
Carl Hetherington 2009-06-08 19:28:51 +00:00
parent 472fa271fd
commit 0874426a5b
26 changed files with 658 additions and 424 deletions

View file

@ -66,7 +66,7 @@ using namespace ArdourCanvas;
static const int32_t sync_mark_width = 9; static const int32_t sync_mark_width = 9;
AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu, AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
Gdk::Color& basic_color) Gdk::Color const & basic_color)
: RegionView (parent, tv, r, spu, basic_color) : RegionView (parent, tv, r, spu, basic_color)
, sync_mark(0) , sync_mark(0)
, zero_line(0) , zero_line(0)
@ -83,7 +83,7 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu, AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> 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) : RegionView (parent, tv, r, spu, basic_color, recording, visibility)
, sync_mark(0) , sync_mark(0)
, zero_line(0) , zero_line(0)
@ -145,7 +145,7 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
} }
void 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 // FIXME: Some redundancy here with RegionView::init. Need to figure out
// where order is important and where it isn't... // where order is important and where it isn't...
@ -731,9 +731,9 @@ AudioRegionView::set_amplitude_above_axis (gdouble spp)
} }
void 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; uint32_t r, g, b, a;

View file

@ -53,13 +53,13 @@ class AudioRegionView : public RegionView
RouteTimeAxisView&, RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>,
double initial_samples_per_unit, double initial_samples_per_unit,
Gdk::Color& basic_color); Gdk::Color const & basic_color);
AudioRegionView (ArdourCanvas::Group *, AudioRegionView (ArdourCanvas::Group *,
RouteTimeAxisView&, RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>,
double samples_per_unit, double samples_per_unit,
Gdk::Color& basic_color, Gdk::Color const & basic_color,
bool recording, bool recording,
TimeAxisViewItem::Visibility); TimeAxisViewItem::Visibility);
@ -68,7 +68,7 @@ class AudioRegionView : public RegionView
~AudioRegionView (); ~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<ARDOUR::AudioRegion> audio_region() const; boost::shared_ptr<ARDOUR::AudioRegion> audio_region() const;
@ -162,7 +162,7 @@ class AudioRegionView : public RegionView
void store_flags (); void store_flags ();
void set_colors (); void set_colors ();
void compute_colors (Gdk::Color&); void compute_colors (Gdk::Color const &);
void reset_width_dependent_items (double pixel_width); void reset_width_dependent_items (double pixel_width);
void set_waveview_data_src(); void set_waveview_data_src();
void set_frame_color (); void set_frame_color ();

View file

@ -104,36 +104,15 @@ AudioStreamView::set_amplitude_above_axis (gdouble app)
} }
RegionView* RegionView*
AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording) AudioStreamView::create_region_view (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
{ {
AudioRegionView *region_view = 0; AudioRegionView *region_view = 0;
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r); boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
if (region == 0) { if (region == 0) {
return NULL; return 0;
} }
// if(!recording){
// for (list<RegionView *>::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<AudioRegionView*>(*i);
// if (arv) {
// arv->set_waveform_scale (_waveform_scale);
// arv->set_waveform_shape (_waveform_shape);
// }
// return NULL;
// }
// }
// }
switch (_trackview.audio_track()->mode()) { switch (_trackview.audio_track()->mode()) {
case NonLayered: case NonLayered:
@ -160,7 +139,6 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
region_view->init (region_color, wait_for_waves); region_view->init (region_color, wait_for_waves);
region_view->set_amplitude_above_axis(_amplitude_above_axis); region_view->set_amplitude_above_axis(_amplitude_above_axis);
region_view->set_height (child_height ()); 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 /* if its the special single-sample length that we use for rec-regions, make it
insensitive to events insensitive to events
@ -195,8 +173,42 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
/* follow global waveform setting */ /* follow global waveform setting */
region_view->set_waveform_visible(_trackview.editor().show_waveforms()); region_view->set_waveform_visible(_trackview.editor().show_waveforms());
return region_view;
}
RegionView*
AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> 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<RegionView *>::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<AudioRegionView*>(*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 */ /* catch regionview going away */
region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r))); r->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r)));
RegionViewAdded (region_view); RegionViewAdded (region_view);
@ -400,7 +412,7 @@ AudioStreamView::redisplay_diskstream ()
if (_trackview.is_audio_track()) { if (_trackview.is_audio_track()) {
_trackview.get_diskstream()->playlist()->foreach_region( _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<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>( boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(

View file

@ -80,6 +80,8 @@ class AudioStreamView : public StreamView
void hide_xfades_involving (AudioRegionView&); void hide_xfades_involving (AudioRegionView&);
void reveal_xfades_involving (AudioRegionView&); void reveal_xfades_involving (AudioRegionView&);
RegionView* create_region_view (boost::shared_ptr<ARDOUR::Region>, bool, bool);
private: private:
void setup_rec_box (); void setup_rec_box ();
void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<ARDOUR::Source> src); void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<ARDOUR::Source> src);

View file

@ -33,7 +33,7 @@ AutomationRegionView::AutomationRegionView(ArdourCanvas::Group*
const Evoral::Parameter& param, const Evoral::Parameter& param,
boost::shared_ptr<ARDOUR::AutomationList> list, boost::shared_ptr<ARDOUR::AutomationList> list,
double spu, double spu,
Gdk::Color& basic_color) Gdk::Color const & basic_color)
: RegionView(parent, time_axis, region, spu, basic_color) : RegionView(parent, time_axis, region, spu, basic_color)
, _parameter(param) , _parameter(param)
{ {
@ -46,7 +46,7 @@ AutomationRegionView::AutomationRegionView(ArdourCanvas::Group*
} }
void void
AutomationRegionView::init (Gdk::Color& basic_color, bool wfd) AutomationRegionView::init (Gdk::Color const & basic_color, bool wfd)
{ {
_enable_display = false; _enable_display = false;

View file

@ -45,11 +45,11 @@ public:
const Evoral::Parameter& parameter, const Evoral::Parameter& parameter,
boost::shared_ptr<ARDOUR::AutomationList>, boost::shared_ptr<ARDOUR::AutomationList>,
double initial_samples_per_unit, double initial_samples_per_unit,
Gdk::Color& basic_color); Gdk::Color const & basic_color);
~AutomationRegionView() {} ~AutomationRegionView() {}
void init (Gdk::Color& basic_color, bool wfd); void init (Gdk::Color const & basic_color, bool wfd);
inline AutomationTimeAxisView* automation_view() const inline AutomationTimeAxisView* automation_view() const
{ return dynamic_cast<AutomationTimeAxisView*>(&trackview); } { return dynamic_cast<AutomationTimeAxisView*>(&trackview); }

View file

@ -167,7 +167,7 @@ AutomationStreamView::redisplay_diskstream ()
// Add and display region views, and flag them as valid // Add and display region views, and flag them as valid
if (_trackview.is_track()) { if (_trackview.is_track()) {
_trackview.get_diskstream()->playlist()->foreach_region ( _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))
); );
} }

View file

@ -1495,6 +1495,7 @@ public:
Gtk::Allocation canvas_allocation; Gtk::Allocation canvas_allocation;
void track_canvas_allocate (Gtk::Allocation alloc); void track_canvas_allocate (Gtk::Allocation alloc);
bool track_canvas_size_allocated (); bool track_canvas_size_allocated ();
bool track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const &, int, int, guint);
void set_playhead_cursor (); void set_playhead_cursor ();
@ -2014,7 +2015,7 @@ public:
void duplicate_dialog (bool with_dialog); 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 /* returns false if mouse pointer is not in track or marker canvas
*/ */
@ -2244,6 +2245,8 @@ public:
friend class RangeMarkerBarDrag; friend class RangeMarkerBarDrag;
friend class MouseZoomDrag; friend class MouseZoomDrag;
friend class RegionCreateDrag; friend class RegionCreateDrag;
friend class RegionMotionDrag;
friend class RegionInsertDrag;
}; };
#endif /* __ardour_editor_h__ */ #endif /* __ardour_editor_h__ */

View file

@ -22,7 +22,6 @@
#include <jack/types.h> #include <jack/types.h>
#include <gtkmm2ext/utils.h> #include <gtkmm2ext/utils.h>
#include "ardour/audioregion.h"
#include "ardour/profile.h" #include "ardour/profile.h"
#include "ardour_ui.h" #include "ardour_ui.h"
@ -39,9 +38,9 @@
#include "editing.h" #include "editing.h"
#include "rgb_macros.h" #include "rgb_macros.h"
#include "utils.h" #include "utils.h"
#include "time_axis_view.h"
#include "audio_time_axis.h" #include "audio_time_axis.h"
#include "editor_drag.h" #include "editor_drag.h"
#include "region_view.h"
#include "i18n.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_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_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_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->set_name ("EditorMainCanvas");
track_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK); track_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK);
@ -532,20 +532,10 @@ Editor::drop_regions (const RefPtr<Gdk::DragContext>& context,
const SelectionData& data, const SelectionData& data,
guint info, guint time) guint info, guint time)
{ {
std::list<boost::shared_ptr<Region> > regions; assert (_drag);
Gtk::TreeView* source; _drag->end_grab (0);
region_list_display.get_object_drag_data (regions, &source); delete _drag;
_drag = 0;
for (list<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r) {
boost::shared_ptr<AudioRegion> ar;
if ((ar = boost::dynamic_pointer_cast<AudioRegion>(*r)) != 0) {
insert_region_list_drag (ar, x, y);
}
}
context->drag_finish (true, false, time);
} }
void void

View file

@ -26,6 +26,9 @@
#include "ardour/audio_diskstream.h" #include "ardour/audio_diskstream.h"
#include "ardour/audioplaylist.h" #include "ardour/audioplaylist.h"
#include "ardour/midi_region.h"
#include "ardour/audioregion.h"
#include "ardour/region_factory.h"
#include "editor.h" #include "editor.h"
#include "keyboard.h" #include "keyboard.h"
@ -43,6 +46,7 @@
#include "simplerect.h" #include "simplerect.h"
#include "interactive-item.h" #include "interactive-item.h"
#include "editor_drag.h" #include "editor_drag.h"
#include "midi_time_axis.h"
#include "i18n.h" #include "i18n.h"
@ -896,3 +900,63 @@ Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
return typed_event (item, event, NoItem); return typed_event (item, event, NoItem);
} }
bool
Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> 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<TimeAxisView*, int> const tv = trackview_by_y_position (py);
if (tv.first == 0) {
return true;
}
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
if (rtav == 0 || !rtav->is_track ()) {
return true;
}
list<boost::shared_ptr<Region> > regions;
TreeView* source;
region_list_display.get_object_drag_data (regions, &source);
assert (regions.size() == 1);
boost::shared_ptr<Region> region = regions.front ();
boost::shared_ptr<Region> region_copy = RegionFactory::create (region);
if (boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
dynamic_cast<AudioTimeAxisView*> (tv.first) == 0) {
/* audio -> non-audio */
return true;
}
if (boost::dynamic_pointer_cast<MidiRegion> (region_copy) == 0 &&
dynamic_cast<MidiTimeAxisView*> (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;
}

View file

@ -33,6 +33,8 @@
#include "utils.h" #include "utils.h"
#include "region_gain_line.h" #include "region_gain_line.h"
#include "editor_drag.h" #include "editor_drag.h"
#include "audio_time_axis.h"
#include "midi_time_axis.h"
using namespace std; using namespace std;
using namespace ARDOUR; using namespace ARDOUR;
@ -50,7 +52,6 @@ Drag::Drag (Editor* e, ArdourCanvas::Item* i) :
_grab_frame (0), _grab_frame (0),
_last_pointer_frame (0), _last_pointer_frame (0),
_current_pointer_frame (0), _current_pointer_frame (0),
_copy (false),
_had_movement (false), _had_movement (false),
_move_threshold_passed (false) _move_threshold_passed (false)
{ {
@ -138,11 +139,9 @@ Drag::end_grab (GdkEvent* event)
_item->ungrab (event ? event->button.time : 0); _item->ungrab (event ? event->button.time : 0);
if (event) {
_last_pointer_x = _current_pointer_x; _last_pointer_x = _current_pointer_x;
_last_pointer_y = _current_pointer_y; _last_pointer_y = _current_pointer_y;
finished (event, _had_movement); finished (event, _had_movement);
}
_editor->hide_verbose_canvas_cursor(); _editor->hide_verbose_canvas_cursor();
@ -256,50 +255,242 @@ RegionDrag::update_selection ()
_editor->selection->set (s); _editor->selection->set (s);
} }
RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b, bool c) RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
: RegionDrag (e, i, p, v), : RegionDrag (e, i, p, v),
_dest_trackview (0),
_dest_layer (0),
_brushing (b) _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<RouteTimeAxisView*> (tv);
if (rtv && rtv->is_track()) {
speed = rtv->get_diskstream()->speed ();
}
_last_frame_position = static_cast<nframes64_t> (_primary->region()->position() / speed);
} }
void void
RegionMoveDrag::start_grab (GdkEvent* event, Gdk::Cursor *) RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{ {
Drag::start_grab (event); Drag::start_grab (event);
_pointer_frame_offset = _grab_frame - _last_frame_position;
_editor->show_verbose_time_cursor (_last_frame_position, 10); _editor->show_verbose_time_cursor (_last_frame_position, 10);
} }
void RegionMotionDrag::TimeAxisViewSummary
RegionMoveDrag::motion (GdkEvent* event, bool first_move) RegionMotionDrag::get_time_axis_view_summary ()
{ {
double x_delta = 0; int32_t children = 0;
double y_delta = 0; TimeAxisViewSummary sum;
nframes64_t pending_region_position = 0;
int32_t pointer_order_span = 0, canvas_pointer_order_span = 0; _editor->visible_order_range (&sum.visible_y_low, &sum.visible_y_high);
int32_t pointer_layer_span = 0;
/* get a bitmask representing the visible tracks */
for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*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++;
}
}
}
}
return sum;
}
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) {
*pointer_order_span = 0;
*pointer_layer_span = 0;
return true;
}
bool clamp_y_axis = false; bool clamp_y_axis = false;
vector<int32_t>::iterator j;
if (_copy && first_move) { /* the change in track order between this callback and the last */
copy_regions (event); *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) {
/* 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;
if (last_pointer_view->order() >= current_pointer_view->order()) {
for (int32_t y = current_pointer_view->order(); y < last_pointer_view->order(); y++) {
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 (tavs.height_list[y] == 0) {
*canvas_pointer_order_span++;
}
}
}
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
RegionView* rv = (*i);
if (rv->region()->locked()) {
continue;
}
double ix1, ix2, iy1, iy2;
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1);
iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize;
/* get the new trackview for this particular region */
pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (iy1);
assert (tvp.first);
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
/* 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_view->order(), *canvas_pointer_order_span, tavs
);
if (clamp_y_axis) {
break;
}
}
} else if (_dest_trackview == current_pointer_view) {
if (current_pointer_layer == last_pointer_layer) {
/* No movement; clamp */
clamp_y_axis = true;
}
}
if (!clamp_y_axis) {
_dest_trackview = current_pointer_view;
_dest_layer = current_pointer_layer;
}
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.
*/
if (_current_pointer_frame >= _pointer_frame_offset) {
nframes64_t sync_frame;
nframes64_t sync_offset;
int32_t sync_dir;
*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);
/* we snap if the snap modifier is not enabled.
*/
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
_editor->snap_to (sync_frame);
}
*pending_region_position = _primary->region()->adjust_to_sync (sync_frame);
} else {
*pending_region_position = _last_frame_position;
}
}
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 ()) {
/* now compute the canvas unit distance we need to move the regionview
to make it appear at the new location.
*/
x_delta = (static_cast<double> (*pending_region_position) - _last_frame_position) / _editor->frames_per_unit;
if (*pending_region_position <= _last_frame_position) {
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
RegionView* rv = (*i);
// If any regionview is at zero, we need to know so we can stop further leftward motion.
double ix1, ix2, iy1, iy2;
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1);
if (-x_delta > ix1 + _editor->horizontal_adjustment.get_value()) {
x_delta = 0;
*pending_region_position = _last_frame_position;
break;
}
}
}
_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<int32_t>::iterator j;
/* *pointer* variables reflect things about the pointer; as we may be moving /* *pointer* variables reflect things about the pointer; as we may be moving
multiple regions, much detail must be computed per-region */ multiple regions, much detail must be computed per-region */
@ -319,225 +510,19 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
/* the layer that we were pointing at last time we entered this method */ /* the layer that we were pointing at last time we entered this method */
layer_t const last_pointer_layer = _dest_layer; layer_t const last_pointer_layer = _dest_layer;
/************************************************************ int32_t pointer_order_span;
Y DELTA COMPUTATION int32_t pointer_layer_span;
************************************************************/ int32_t canvas_pointer_order_span;
/* Height of TimeAxisViews, indexed by order */ bool const clamp_y_axis = compute_y_delta (
/* XXX: hard-coded limit of TimeAxisViews */ last_pointer_view, current_pointer_view,
vector<int32_t> height_list (512); last_pointer_layer, current_pointer_layer, tavs,
&pointer_order_span, &pointer_layer_span,
if (_brushing) { &canvas_pointer_order_span
clamp_y_axis = true;
pointer_order_span = 0;
goto y_axis_done;
}
/* the change in track order between this callback and the last */
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 */
for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*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 ((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;
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--;
}
}
} else {
for (int32_t y = last_pointer_view->order(); y <= current_pointer_view->order(); y++) {
if (height_list[y] == 0) {
canvas_pointer_order_span++;
}
}
}
for (list<RegionView*>::const_iterator i = _editor->selection->regions.by_layer().begin(); i != _editor->selection->regions.by_layer().end(); ++i) {
RegionView* rv = (*i);
if (rv->region()->locked()) {
continue;
}
double ix1, ix2, iy1, iy2;
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1);
iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize;
/* get the new trackview for this particular region */
pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (iy1);
assert (tvp.first);
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (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
); );
if (clamp_y_axis) { nframes64_t pending_region_position;
break; double const x_delta = compute_x_delta (event, &pending_region_position);
}
}
} else if (_dest_trackview == current_pointer_view) {
if (current_pointer_layer == last_pointer_layer) {
/* No movement; clamp */
clamp_y_axis = true;
}
}
y_axis_done:
if (!clamp_y_axis) {
_dest_trackview = current_pointer_view;
_dest_layer = current_pointer_layer;
}
/************************************************************
X DELTA COMPUTATION
************************************************************/
/* compute the amount of pointer motion in frames, and where
the region would be if we moved it by that much.
*/
if (_current_pointer_frame >= _pointer_frame_offset) {
nframes64_t sync_frame;
nframes64_t sync_offset;
int32_t sync_dir;
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);
/* we snap if the snap modifier is not enabled.
*/
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
_editor->snap_to (sync_frame);
}
pending_region_position = _primary->region()->adjust_to_sync (sync_frame);
} else {
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 != _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.
*/
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);
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
RegionView* rv = (*i);
// If any regionview is at zero, we need to know so we can stop further leftward motion.
double ix1, ix2, iy1, iy2;
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1);
if (-x_delta > ix1 + _editor->horizontal_adjustment.get_value()) {
x_delta = 0;
pending_region_position = _last_frame_position;
break;
}
}
}
_last_frame_position = pending_region_position;
} else {
x_delta = 0;
}
/************************************************************* /*************************************************************
PREPARE TO MOVE PREPARE TO MOVE
@ -614,9 +599,9 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
/* INTER-TRACK MOVEMENT */ /* INTER-TRACK MOVEMENT */
/* move through the height list to the track that the region is currently on */ /* move through the height list to the track that the region is currently on */
vector<int32_t>::iterator j = height_list.begin (); vector<int32_t>::iterator j = tavs.height_list.begin ();
int32_t x = 0; int32_t x = 0;
while (j != height_list.end () && x != rtv->order ()) { while (j != tavs.height_list.end () && x != rtv->order ()) {
++x; ++x;
++j; ++j;
} }
@ -624,7 +609,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
y_delta = 0; y_delta = 0;
int32_t temp_pointer_order_span = canvas_pointer_order_span; 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 /* Account for layers in the original and
destination tracks. If we're moving around in layers we assume 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, /* we're moving up canvas-wise,
so we need to find the next track height so we need to find the next track height
*/ */
if (j != height_list.begin()) { if (j != tavs.height_list.begin()) {
j--; j--;
} }
@ -678,7 +663,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
} }
} }
if (j != height_list.end()) { if (j != tavs.height_list.end()) {
j++; j++;
} }
@ -726,6 +711,16 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
} }
} }
void
RegionMoveDrag::motion (GdkEvent* event, bool first_move)
{
if (_copy && first_move) {
copy_regions (event);
}
RegionMotionDrag::motion (event, first_move);
}
void void
RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred) RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
{ {
@ -769,8 +764,6 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
goto out; goto out;
} }
char* op_string;
/* reverse this here so that we have the correct logic to finalize /* reverse this here so that we have the correct logic to finalize
the drag. the drag.
*/ */
@ -781,19 +774,18 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
if (_copy) { if (_copy) {
if (_x_constrained) { if (_x_constrained) {
op_string = _("fixed time region copy"); _editor->begin_reversible_command (_("fixed time region copy"));
} else { } else {
op_string = _("region copy"); _editor->begin_reversible_command (_("region copy"));
} }
} else { } else {
if (_x_constrained) { if (_x_constrained) {
op_string = _("fixed time region drag"); _editor->begin_reversible_command (_("fixed time region drag"));
} else { } 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())); changed_position = (_last_frame_position != (nframes64_t) (_primary->region()->position()));
tvp = _editor->trackview_by_y_position (_current_pointer_y); tvp = _editor->trackview_by_y_position (_current_pointer_y);
changed_tracks = (tvp.first != &_primary->get_time_axis_view()); 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 (); _editor->track_canvas->update_now ();
/* make a list of where each region ended up */ /* make a list of where each region ended up */
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) { final = find_time_axis_views ();
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<TimeAxisView*, int> tv = _editor->trackview_by_y_position (iy1);
final[*i] = dynamic_cast<RouteTimeAxisView*> (tv.first);
}
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ) { for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ) {
@ -1001,8 +984,33 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
} }
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 void
RegionMoveDrag::copy_regions (GdkEvent* event) RegionMotionDrag::copy_regions (GdkEvent* event)
{ {
/* duplicate the regionview(s) and region(s) */ /* duplicate the regionview(s) and region(s) */
@ -1043,7 +1051,8 @@ RegionMoveDrag::copy_regions (GdkEvent* event)
_primary = new_regionviews.front(); _primary = new_regionviews.front();
_views = new_regionviews; _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 sync the canvas to what we think is its current state
without it, the canvas seems to without it, the canvas seems to
@ -1055,7 +1064,7 @@ RegionMoveDrag::copy_regions (GdkEvent* event)
} }
bool bool
RegionMoveDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer) RegionMotionDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer)
{ {
/* Which trackview is this ? */ /* Which trackview is this ? */
@ -1081,16 +1090,10 @@ RegionMoveDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer)
/** @param new_order New track order. /** @param new_order New track order.
* @param old_order Old track order. * @param old_order Old track order.
* @param visible_y_low Lowest visible 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. * @return true if y movement should not happen, otherwise false.
*/ */
bool bool
RegionMoveDrag::y_movement_disallowed ( RegionMotionDrag::y_movement_disallowed (int new_order, int old_order, int y_span, TimeAxisViewSummary const & tavs) const
int new_order, int old_order, int y_span, int visible_y_low, int visible_y_high,
bitset<512> const & tracks, vector<int32_t> const & height_list
) const
{ {
if (new_order != old_order) { if (new_order != old_order) {
@ -1099,7 +1102,7 @@ RegionMoveDrag::y_movement_disallowed (
if (y_span > 0) { if (y_span > 0) {
/* moving up the canvas */ /* 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; int32_t n = 0;
@ -1107,13 +1110,13 @@ RegionMoveDrag::y_movement_disallowed (
int32_t visible_tracks = 0; int32_t visible_tracks = 0;
while (visible_tracks < y_span ) { while (visible_tracks < y_span ) {
visible_tracks++; 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 */ /* passing through a hidden track */
n--; n--;
} }
} }
if (tracks[new_order - (y_span - n)] != 0x00) { if (tavs.tracks[new_order - (y_span - n)] != 0x00) {
/* moving to a non-track; disallow */ /* moving to a non-track; disallow */
return true; return true;
} }
@ -1127,20 +1130,20 @@ RegionMoveDrag::y_movement_disallowed (
} else if (y_span < 0) { } else if (y_span < 0) {
/* moving down the canvas */ /* 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 visible_tracks = 0;
int32_t n = 0; int32_t n = 0;
while (visible_tracks > y_span ) { while (visible_tracks > y_span ) {
visible_tracks--; 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 */ /* passing through a hidden track */
n++; n++;
} }
} }
if (tracks[new_order - (y_span - n)] != 0x00) { if (tavs.tracks[new_order - (y_span - n)] != 0x00) {
/* moving to a non-track; disallow */ /* moving to a non-track; disallow */
return true; return true;
} }
@ -1157,10 +1160,10 @@ RegionMoveDrag::y_movement_disallowed (
/* this is the pointer's track */ /* 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 */ /* we will overflow */
return true; return true;
} else if ((new_order - y_span) < visible_y_low) { } else if ((new_order - y_span) < tavs.visible_y_low) {
/* we will overflow */ /* we will overflow */
return true; return true;
} }
@ -1169,6 +1172,97 @@ RegionMoveDrag::y_movement_disallowed (
return false; return false;
} }
RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> 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<RouteTimeAxisView*> (tv);
if (rtv && rtv->is_track()) {
speed = rtv->get_diskstream()->speed ();
}
_last_frame_position = static_cast<nframes64_t> (_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<Region> r, RouteTimeAxisView* v, nframes64_t pos)
: RegionMotionDrag (e, 0, 0, list<RegionView*> (), false)
{
assert ((boost::dynamic_pointer_cast<AudioRegion> (r) && dynamic_cast<AudioTimeAxisView*> (v)) ||
(boost::dynamic_pointer_cast<MidiRegion> (r) && dynamic_cast<MidiTimeAxisView*> (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<RegionView*, RouteTimeAxisView*>
RegionMotionDrag::find_time_axis_views ()
{
map<RegionView*, RouteTimeAxisView*> tav;
for (list<RegionView*>::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<TimeAxisView*, int> tv = _editor->trackview_by_y_position (iy1);
tav[*i] = dynamic_cast<RouteTimeAxisView*> (tv.first);
}
return tav;
}
void
RegionInsertDrag::finished (GdkEvent* event, bool movement_occurred)
{
_editor->track_canvas->update_now ();
map<RegionView*, RouteTimeAxisView*> 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> 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> (*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<RegionView*> const & v) RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionMoveDrag (e, i, p, v, false, false) : 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) MeterMarkerDrag::MeterMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
: Drag (e, i) : Drag (e, i),
_copy (c)
{ {
_copy = c;
_marker = reinterpret_cast<MeterMarker*> (_item->get_data ("marker")); _marker = reinterpret_cast<MeterMarker*> (_item->get_data ("marker"));
assert (_marker); assert (_marker);
} }
@ -1645,10 +1738,9 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
} }
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c) TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
: Drag (e, i) : Drag (e, i),
_copy (c)
{ {
_copy = c;
TempoMarker* _marker = reinterpret_cast<TempoMarker*> (_item->get_data ("marker")); TempoMarker* _marker = reinterpret_cast<TempoMarker*> (_item->get_data ("marker"));
assert (_marker); assert (_marker);
} }
@ -2731,7 +2823,8 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred)
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o) SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i), : 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) RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i), : 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 = new ArdourCanvas::SimpleRect (*_editor->time_line_group, 0.0, 0.0, 0.0, _editor->physical_screen_height);
_drag_rect->hide (); _drag_rect->hide ();

View file

@ -134,7 +134,6 @@ protected:
double _last_pointer_y; ///< item y of the pointer last time a motion occurred 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 _x_constrained; ///< true if x motion is constrained, otherwise false
bool _y_constrained; ///< true if y 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 bool _was_rolling; ///< true if the session was rolling before the drag started, otherwise false
private: private:
@ -164,33 +163,80 @@ private:
}; };
/** Drags to move regions */ /** Drags involving region motion from somewhere */
class RegionMoveDrag : public RegionDrag class RegionMotionDrag : public RegionDrag
{
public:
RegionMotionDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> 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<int32_t> 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<RegionView*, RouteTimeAxisView*> 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: public:
RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool); RegionMoveDrag (Editor *, ArdourCanvas::Item *, RegionView *, std::list<RegionView*> const &, bool, bool);
virtual ~RegionMoveDrag () {} virtual ~RegionMoveDrag () {}
virtual void start_grab (GdkEvent *, Gdk::Cursor *); virtual void start_grab (GdkEvent *, Gdk::Cursor *);
virtual void motion (GdkEvent *, bool); void motion (GdkEvent *, bool);
virtual void finished (GdkEvent *, bool); void finished (GdkEvent *, bool);
bool apply_move_threshold () const { bool apply_move_threshold () const {
return true; return true;
} }
protected: private:
bool x_move_allowed () const;
bool check_possible (RouteTimeAxisView **, ARDOUR::layer_t *); bool _copy;
};
TimeAxisView* _dest_trackview; /** Drag to insert a region from somewhere */
ARDOUR::layer_t _dest_layer; class RegionInsertDrag : public RegionMotionDrag
{
public:
RegionInsertDrag (Editor *, boost::shared_ptr<ARDOUR::Region>, RouteTimeAxisView*, nframes64_t);
void finished (GdkEvent *, bool);
private: private:
bool x_move_allowed () const;
void copy_regions (GdkEvent *);
bool y_movement_disallowed (int, int, int, int, int, std::bitset<512> const &, std::vector<int32_t> const &) const;
bool _brushing;
}; };
/** Region drag in splice mode */ /** Region drag in splice mode */
@ -264,6 +310,7 @@ public:
private: private:
MeterMarker* _marker; MeterMarker* _marker;
bool _copy;
}; };
/** Tempo marker drag */ /** Tempo marker drag */
@ -278,6 +325,7 @@ public:
private: private:
TempoMarker* _marker; TempoMarker* _marker;
bool _copy;
}; };
@ -416,6 +464,7 @@ public:
private: private:
Operation _operation; Operation _operation;
bool _copy;
}; };
/** Range marker drag */ /** Range marker drag */
@ -439,6 +488,7 @@ private:
Operation _operation; Operation _operation;
ArdourCanvas::SimpleRect* _drag_rect; ArdourCanvas::SimpleRect* _drag_rect;
bool _copy;
}; };
/* Drag of rectangle to set zoom */ /* Drag of rectangle to set zoom */

View file

@ -112,7 +112,7 @@ Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const
} }
nframes64_t 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; double cx, cy;

View file

@ -66,7 +66,7 @@ using namespace Editing;
using namespace ArdourCanvas; using namespace ArdourCanvas;
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color) boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color const & basic_color)
: RegionView (parent, tv, r, spu, basic_color) : RegionView (parent, tv, r, spu, basic_color)
, _force_channel(-1) , _force_channel(-1)
, _last_channel_selection(0xFFFF) , _last_channel_selection(0xFFFF)
@ -150,7 +150,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
} }
void void
MidiRegionView::init (Gdk::Color& basic_color, bool wfd) MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
{ {
if (wfd) { if (wfd) {
midi_region()->midi_source(0)->load_model(); midi_region()->midi_source(0)->load_model();

View file

@ -66,14 +66,14 @@ class MidiRegionView : public RegionView
RouteTimeAxisView&, RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::MidiRegion>, boost::shared_ptr<ARDOUR::MidiRegion>,
double initial_samples_per_unit, double initial_samples_per_unit,
Gdk::Color& basic_color); Gdk::Color const & basic_color);
MidiRegionView (const MidiRegionView& other); MidiRegionView (const MidiRegionView& other);
MidiRegionView (const MidiRegionView& other, boost::shared_ptr<ARDOUR::MidiRegion>); MidiRegionView (const MidiRegionView& other, boost::shared_ptr<ARDOUR::MidiRegion>);
~MidiRegionView (); ~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<ARDOUR::MidiRegion> midi_region() const inline const boost::shared_ptr<ARDOUR::MidiRegion> midi_region() const
{ return boost::dynamic_pointer_cast<ARDOUR::MidiRegion>(_region); } { return boost::dynamic_pointer_cast<ARDOUR::MidiRegion>(_region); }

View file

@ -129,19 +129,33 @@ veto_note_range(uint8_t& min, uint8_t& max)
assert(min <= 127); assert(min <= 127);
} }
RegionView*
MidiStreamView::create_region_view (boost::shared_ptr<Region> r, bool wfd, bool)
{
boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r);
if (region == 0) {
return 0;
}
RegionView* region_view = new MidiRegionView (canvas_group, _trackview, region,
_samples_per_unit, region_color);
region_view->init (region_color, false);
return region_view;
}
RegionView* RegionView*
MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd, bool recording) MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd, bool recording)
{ {
boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r); boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r);
if (region == 0) { if (region == 0) {
return NULL; return 0;
} }
MidiRegionView *region_view; for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
list<RegionView *>::iterator i;
for (i = region_views.begin(); i != region_views.end(); ++i) {
if ((*i)->region() == r) { if ((*i)->region() == r) {
/* great. we already have a MidiRegionView for this Region. use it again. */ /* great. we already have a MidiRegionView for this Region. use it again. */
@ -150,18 +164,19 @@ MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd,
display_region(dynamic_cast<MidiRegionView*>(*i), wfd); display_region(dynamic_cast<MidiRegionView*>(*i), wfd);
return NULL; return 0;
} }
} }
region_view = new MidiRegionView (canvas_group, _trackview, region, MidiRegionView* region_view = dynamic_cast<MidiRegionView*> (create_region_view (r, wfd, recording));
_samples_per_unit, region_color); if (region_view == 0) {
return 0;
}
region_view->init (region_color, false);
region_views.push_front (region_view); region_views.push_front (region_view);
/* display events and find note range */ /* display events and find note range */
display_region(region_view, wfd); display_region (region_view, wfd);
/* catch regionview going away */ /* catch regionview going away */
region->GoingAway.connect (bind (mem_fun (*this, &MidiStreamView::remove_region_view), region)); 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 // Add and display region views, and flag them as valid
_trackview.get_diskstream()->playlist()->foreach_region( _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 // Stack regions by layer, and remove invalid regions

View file

@ -98,6 +98,8 @@ class MidiStreamView : public StreamView
sigc::signal<void> NoteRangeChanged; sigc::signal<void> NoteRangeChanged;
RegionView* create_region_view (boost::shared_ptr<ARDOUR::Region>, bool, bool);
private: private:
void setup_rec_box (); void setup_rec_box ();

View file

@ -64,7 +64,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent,
TimeAxisView& tv, TimeAxisView& tv,
boost::shared_ptr<ARDOUR::Region> r, boost::shared_ptr<ARDOUR::Region> r,
double spu, 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 (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), false,
TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText| TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText|
TimeAxisViewItem::ShowNameHighlight| TimeAxisViewItem::ShowFrame)) TimeAxisViewItem::ShowNameHighlight| TimeAxisViewItem::ShowFrame))
@ -118,7 +118,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent,
TimeAxisView& tv, TimeAxisView& tv,
boost::shared_ptr<ARDOUR::Region> r, boost::shared_ptr<ARDOUR::Region> r,
double spu, double spu,
Gdk::Color& basic_color, Gdk::Color const & basic_color,
bool recording, bool recording,
TimeAxisViewItem::Visibility visibility) TimeAxisViewItem::Visibility visibility)
: TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), recording, 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 void
RegionView::init (Gdk::Color& basic_color, bool wfd) RegionView::init (Gdk::Color const & basic_color, bool wfd)
{ {
editor = 0; editor = 0;
valid = true; valid = true;
@ -350,12 +350,6 @@ RegionView::set_duration (nframes_t frames, void *src)
return true; return true;
} }
void
RegionView::compute_colors (Gdk::Color& basic_color)
{
TimeAxisViewItem::compute_colors (basic_color);
}
void void
RegionView::set_colors () RegionView::set_colors ()
{ {

View file

@ -45,14 +45,14 @@ class RegionView : public TimeAxisViewItem
TimeAxisView& time_view, TimeAxisView& time_view,
boost::shared_ptr<ARDOUR::Region> region, boost::shared_ptr<ARDOUR::Region> region,
double samples_per_unit, double samples_per_unit,
Gdk::Color& basic_color); Gdk::Color const & basic_color);
RegionView (const RegionView& other); RegionView (const RegionView& other);
RegionView (const RegionView& other, boost::shared_ptr<ARDOUR::Region> other_region); RegionView (const RegionView& other, boost::shared_ptr<ARDOUR::Region> other_region);
~RegionView (); ~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<ARDOUR::Region> region() const { return _region; } boost::shared_ptr<ARDOUR::Region> region() const { return _region; }
@ -100,7 +100,7 @@ class RegionView : public TimeAxisViewItem
TimeAxisView&, TimeAxisView&,
boost::shared_ptr<ARDOUR::Region>, boost::shared_ptr<ARDOUR::Region>,
double samples_per_unit, double samples_per_unit,
Gdk::Color& basic_color, Gdk::Color const & basic_color,
bool recording, bool recording,
TimeAxisViewItem::Visibility); TimeAxisViewItem::Visibility);
@ -117,7 +117,6 @@ class RegionView : public TimeAxisViewItem
void lock_toggle (); void lock_toggle ();
virtual void set_colors (); virtual void set_colors ();
virtual void compute_colors (Gdk::Color&);
virtual void set_frame_color (); virtual void set_frame_color ();
virtual void reset_width_dependent_items (double pixel_width); virtual void reset_width_dependent_items (double pixel_width);

View file

@ -178,12 +178,14 @@ StreamView::add_region_view_weak (boost::weak_ptr<Region> r)
} }
} }
void void
StreamView::add_region_view (boost::shared_ptr<Region> r) StreamView::add_region_view (boost::shared_ptr<Region> r)
{ {
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r)); ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r));
add_region_view_internal (r, true); add_region_view_internal (r, true);
if (_layer_display == Stacked) { if (_layer_display == Stacked) {
update_contents_height (); update_contents_height ();
} }

View file

@ -104,6 +104,10 @@ public:
double child_height () const; double child_height () const;
ARDOUR::layer_t layers () const { return _layers; } ARDOUR::layer_t layers () const { return _layers; }
virtual RegionView* create_region_view (boost::shared_ptr<ARDOUR::Region>, bool, bool) {
return 0;
}
sigc::signal<void,RegionView*> RegionViewAdded; sigc::signal<void,RegionView*> RegionViewAdded;
protected: protected:

View file

@ -52,7 +52,7 @@ const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility
TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
boost::shared_ptr<AudioRegion> r, boost::shared_ptr<AudioRegion> r,
double spu, double spu,
Gdk::Color& basic_color) Gdk::Color const & basic_color)
: AudioRegionView (parent, tv, r, spu, basic_color, false, : AudioRegionView (parent, tv, r, spu, basic_color, false,
TimeAxisViewItem::Visibility ((r->position() != 0) ? default_tape_visibility : TimeAxisViewItem::Visibility ((r->position() != 0) ? default_tape_visibility :
@ -61,7 +61,7 @@ TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTime
} }
void 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 /* never wait for data: always just create the waves, connect once and then
we'll update whenever we need to. we'll update whenever we need to.

View file

@ -31,11 +31,11 @@ class TapeAudioRegionView : public AudioRegionView
RouteTimeAxisView&, RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>,
double initial_samples_per_unit, double initial_samples_per_unit,
Gdk::Color& base_color); Gdk::Color const & base_color);
~TapeAudioRegionView (); ~TapeAudioRegionView ();
protected: 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 set_frame_color ();
void update (uint32_t n); void update (uint32_t n);

View file

@ -68,7 +68,7 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
* @param start the start point of this item * @param start the start point of this item
* @param duration the duration 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, nframes_t start, nframes_t duration, bool recording,
Visibility vis) Visibility vis)
: trackview (tv), _recregion(recording) : trackview (tv), _recregion(recording)
@ -124,7 +124,7 @@ TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
} }
void 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 ; item_name = it_name ;
samples_per_unit = spu ; samples_per_unit = spu ;
@ -614,7 +614,7 @@ TimeAxisViewItem::set_height (double height)
* *
*/ */
void void
TimeAxisViewItem::set_color(Gdk::Color& base_color) TimeAxisViewItem::set_color (Gdk::Color const & base_color)
{ {
compute_colors (base_color); compute_colors (base_color);
set_colors (); set_colors ();
@ -662,7 +662,7 @@ TimeAxisViewItem::get_name_pixbuf()
* @param color the base color of the item * @param color the base color of the item
*/ */
void void
TimeAxisViewItem::compute_colors(Gdk::Color& base_color) TimeAxisViewItem::compute_colors (Gdk::Color const & base_color)
{ {
unsigned char radius ; unsigned char radius ;
char minor_shift ; char minor_shift ;

View file

@ -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 start the start point of this item
* @param duration the duration 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)); nframes_t start, nframes_t duration, bool recording = false, Visibility v = Visibility (0));
TimeAxisViewItem (const TimeAxisViewItem& other); 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 * Calculates some contrasting color for displaying various parts of this item, based upon the base color
* *
* @param color the base color of the item * @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 * convenience method to set the various canvas item colors

View file

@ -46,6 +46,11 @@ class DnDTreeViewBase : public Gtk::TreeView
void add_drop_targets (std::list<Gtk::TargetEntry>&); void add_drop_targets (std::list<Gtk::TargetEntry>&);
void add_object_drag (int column, std::string type_name); void add_object_drag (int column, std::string type_name);
void on_drag_begin (Glib::RefPtr<Gdk::DragContext> const & context) {
Gtk::TreeView::on_drag_begin (context);
start_object_drag ();
}
void on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& context, guint time) { void on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& context, guint time) {
suggested_action = context->get_suggested_action(); suggested_action = context->get_suggested_action();
TreeView::on_drag_leave (context, time); TreeView::on_drag_leave (context, time);
@ -95,8 +100,6 @@ class DnDTreeView : public DnDTreeViewBase
} else if (selection_data.get_target() == object_type) { } else if (selection_data.get_target() == object_type) {
start_object_drag ();
/* we don't care about the data passed around by DnD, but /* we don't care about the data passed around by DnD, but
we have to provide something otherwise it will stop. we have to provide something otherwise it will stop.
*/ */