Made drop targets more sensible

This commit is contained in:
Joel Holdsworth 2009-01-20 23:31:40 +00:00
parent d42bc4ea90
commit d209e0e2f2
2 changed files with 95 additions and 46 deletions

View file

@ -191,66 +191,108 @@ TimelineLayoutHelper::drag_to_point(const Gdk::Point &point)
continue; continue;
} }
// Get the rectangle and the next rectangle // Lookup the tracks
const shared_ptr<model::Track> model_track(*iterator); const shared_ptr<model::Track> model_track(*iterator);
REQUIRE(model_track); REQUIRE(model_track);
const weak_ptr<timeline::Track> timeline_track = const weak_ptr<timeline::Track> timeline_track =
lookup_timeline_track(model_track); lookup_timeline_track(model_track);
// Calculate coordinates
const Gdk::Rectangle &rect = headerBoxes[timeline_track]; const Gdk::Rectangle &rect = headerBoxes[timeline_track];
const int half_height = rect.get_height() / 2; const int half_height = rect.get_height() / 2;
const int y = rect.get_y(); const int y = rect.get_y();
const int y_mid = y + half_height; const int y_mid = y + half_height;
const int full_width = TimelineWidget::HeaderWidth; const int full_width = rect.get_x() + rect.get_width();
const int x_mid = rect.get_x() + rect.get_width() / 2; const int x_mid = rect.get_x() + rect.get_width() / 2;
// Is our track being dragged before this header? // Do hit test
if(pt_in_rect(dragPoint, if(attempt_drop_upper(iterator, dragPoint,
Gdk::Rectangle(0, y, full_width, half_height))) y, full_width, half_height))
{ break;
draggingTrackIter = layoutTree.move_before(
iterator, draggingTrackIter); if(attempt_drop_lower(iterator, dragPoint,
x_mid, full_width, y_mid, half_height))
break; break;
} }
if(model_track->can_host_children() && update_layout();
model_track->get_child_tracks().empty()) }
bool
TimelineLayoutHelper::attempt_drop_upper(
TrackTree::pre_order_iterator target, const Gdk::Point &point,
const int y, const int full_width, const int half_height)
{
if(pt_in_rect(point, Gdk::Rectangle(0, y, full_width, half_height)))
{
draggingTrackIter = layoutTree.move_before(
target, draggingTrackIter);
return true;
}
return false;
}
bool
TimelineLayoutHelper::attempt_drop_lower(
TrackTree::pre_order_iterator target, const Gdk::Point &point,
const int x_mid, const int full_width, const int y_mid,
const int half_height)
{
const shared_ptr<model::Track> model_track(*target);
REQUIRE(model_track);
if(!pt_in_rect(point, Gdk::Rectangle(0, y_mid,
full_width, half_height)))
return false;
if(model_track->can_host_children())
{
if(model_track->get_child_tracks().empty())
{ {
// Is our track being dragged after this header? // Is our track being dragged after this header?
if(pt_in_rect(dragPoint, if(dragPoint.get_x() < x_mid)
Gdk::Rectangle(0, y_mid, x_mid, half_height)))
{ {
draggingTrackIter = layoutTree.move_after( draggingTrackIter = layoutTree.move_after(
iterator, draggingTrackIter); target, draggingTrackIter);
break;
} }
else if(pt_in_rect(dragPoint, else
Gdk::Rectangle(x_mid, y_mid, {
full_width - x_mid, half_height))) if(draggingTrackIter.node->parent != target.node)
{ {
// Insert a place-holder in the tree // Insert a place-holder in the tree
const TrackTree::pre_order_iterator placeholder = const TrackTree::pre_order_iterator placeholder =
layoutTree.append_child( layoutTree.prepend_child(target);
iterator, shared_ptr<model::Track>());
// Replace it with the relocated branch // Replace it with the relocated branch
draggingTrackIter = layoutTree.move_ontop( draggingTrackIter = layoutTree.move_ontop(
placeholder, draggingTrackIter); placeholder, draggingTrackIter);
break; }
} }
} }
else else
{ {
if(pt_in_rect(dragPoint, if(draggingTrackIter.node->parent != target.node)
Gdk::Rectangle(0, y_mid, full_width, half_height)))
{ {
// Insert a place-holder in the tree
const TrackTree::pre_order_iterator placeholder =
layoutTree.append_child(target);
// Replace it with the relocated branch
draggingTrackIter = layoutTree.move_ontop(
placeholder, draggingTrackIter);
}
}
}
else
{
// When this track cannot be a parent, the dragging track is
// simply dropped after
draggingTrackIter = layoutTree.move_after( draggingTrackIter = layoutTree.move_after(
iterator, draggingTrackIter); target, draggingTrackIter);
break;
}
}
} }
update_layout(); return true;
} }
int int

View file

@ -220,6 +220,13 @@ protected:
**/ **/
bool on_animation_tick(); bool on_animation_tick();
bool
attempt_drop_upper(TrackTree::pre_order_iterator target, const Gdk::Point &point, const int y, const int full_width, const int half_height);
bool
attempt_drop_lower(TrackTree::pre_order_iterator target, const Gdk::Point &point, const int x_mid, const int full_width, const int y_mid, const int half_height);
protected: protected:
/** /**