WIP: Added preliminary track dragging support
This commit is contained in:
parent
27ffbd1875
commit
542af7cc80
4 changed files with 132 additions and 23 deletions
|
|
@ -149,12 +149,17 @@ bool TimelineHeaderContainer::on_button_press_event (
|
||||||
{
|
{
|
||||||
case 1: // Left Click
|
case 1: // Left Click
|
||||||
// Did the user press the button on an expander?
|
// Did the user press the button on an expander?
|
||||||
if(hoveringExpander != NULL)
|
if(hoveringExpander)
|
||||||
{
|
{
|
||||||
// Yes? The prime for a release event
|
// Yes? The prime for a release event
|
||||||
clickedExpander = hoveringExpander;
|
clickedExpander = hoveringExpander;
|
||||||
queue_draw();
|
queue_draw();
|
||||||
}
|
}
|
||||||
|
else if(hoveringTrack) // Is the user hovering on a track
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Right Click
|
case 3: // Right Click
|
||||||
|
|
@ -186,6 +191,8 @@ bool TimelineHeaderContainer::on_button_press_event (
|
||||||
bool TimelineHeaderContainer::on_button_release_event (
|
bool TimelineHeaderContainer::on_button_release_event (
|
||||||
GdkEventButton* event)
|
GdkEventButton* event)
|
||||||
{
|
{
|
||||||
|
TimelineLayoutHelper &layout = timelineWidget.layoutHelper;
|
||||||
|
|
||||||
// Did the user release the button on an expander?
|
// Did the user release the button on an expander?
|
||||||
if(clickedExpander != NULL)
|
if(clickedExpander != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -194,9 +201,13 @@ bool TimelineHeaderContainer::on_button_release_event (
|
||||||
clickedExpander->get_expanded() ? Track::Collapse : Track::Expand);
|
clickedExpander->get_expanded() ? Track::Collapse : Track::Expand);
|
||||||
clickedExpander.reset();
|
clickedExpander.reset();
|
||||||
|
|
||||||
timelineWidget.layoutHelper.update_layout();
|
layout.update_layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has the user been dragging?
|
||||||
|
if(layout.get_dragging_track())
|
||||||
|
layout.end_dragging_track();
|
||||||
|
|
||||||
return Container::on_button_release_event(event);
|
return Container::on_button_release_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,30 +216,49 @@ bool TimelineHeaderContainer::on_motion_notify_event (
|
||||||
{
|
{
|
||||||
REQUIRE(event != NULL);
|
REQUIRE(event != NULL);
|
||||||
|
|
||||||
|
const bool result = Container::on_motion_notify_event(event);
|
||||||
|
|
||||||
|
const Gdk::Point point(event->x, event->y);
|
||||||
|
TimelineLayoutHelper &layout = timelineWidget.layoutHelper;
|
||||||
|
|
||||||
|
// Are we beginning to drag a header?
|
||||||
|
if((event->state & GDK_BUTTON1_MASK) && hoveringTrack &&
|
||||||
|
!hoveringExpander && !layout.get_dragging_track())
|
||||||
|
{
|
||||||
|
layout.begin_dragging_track(hoveringTrack);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are we currently dragging?
|
||||||
|
if(layout.get_dragging_track())
|
||||||
|
{
|
||||||
|
layout.drag_to_point(point);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Hit test the rectangle
|
// Hit test the rectangle
|
||||||
shared_ptr<timeline::Track> header =
|
hoveringTrack = layout.header_from_point(point);
|
||||||
timelineWidget.layoutHelper.header_from_point(
|
|
||||||
Gdk::Point(event->x, event->y));
|
|
||||||
|
|
||||||
if(header)
|
if(hoveringTrack)
|
||||||
{
|
{
|
||||||
const optional<Gdk::Rectangle> rect =
|
const optional<Gdk::Rectangle> rect =
|
||||||
get_expander_button_rectangle(header);
|
get_expander_button_rectangle(hoveringTrack);
|
||||||
|
|
||||||
REQUIRE(rect);
|
REQUIRE(rect);
|
||||||
|
|
||||||
// Are we hovering on the expander?
|
// Are we hovering on the expander?
|
||||||
if(event->x >= rect->get_x() &&
|
if(event->x >= rect->get_x() &&
|
||||||
event->x < rect->get_x() + rect->get_width() &&
|
event->x < rect->get_x() + rect->get_width() &&
|
||||||
event->y >= rect->get_y() &&
|
event->y >= rect->get_y() &&
|
||||||
event->y < rect->get_y() + rect->get_height())
|
event->y < rect->get_y() + rect->get_height())
|
||||||
{
|
{
|
||||||
hoveringExpander = header;
|
hoveringExpander = hoveringTrack;
|
||||||
queue_draw();
|
queue_draw();
|
||||||
}
|
}
|
||||||
}
|
else hoveringExpander.reset();
|
||||||
|
}
|
||||||
|
|
||||||
return Container::on_motion_notify_event(event);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,8 @@ private:
|
||||||
Gtk::Menu contextMenu;
|
Gtk::Menu contextMenu;
|
||||||
|
|
||||||
//----- User Interaction State -----//
|
//----- User Interaction State -----//
|
||||||
|
boost::shared_ptr<timeline::Track> hoveringTrack;
|
||||||
|
|
||||||
boost::shared_ptr<timeline::Track> hoveringExpander;
|
boost::shared_ptr<timeline::Track> hoveringExpander;
|
||||||
|
|
||||||
boost::shared_ptr<timeline::Track> clickedExpander;
|
boost::shared_ptr<timeline::Track> clickedExpander;
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,71 @@ TimelineLayoutHelper::track_from_y(int y)
|
||||||
return shared_ptr<timeline::Track>();
|
return shared_ptr<timeline::Track>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineLayoutHelper::begin_dragging_track(
|
||||||
|
boost::shared_ptr<timeline::Track> track)
|
||||||
|
{
|
||||||
|
REQUIRE(track);
|
||||||
|
draggingTrack = track;
|
||||||
|
g_message("begin_dragging_track");
|
||||||
|
|
||||||
|
// Find the track in the tree
|
||||||
|
const shared_ptr<model::Track> model_track = track->get_model_track();
|
||||||
|
REQUIRE(model_track);
|
||||||
|
for(draggingTrackIter = layoutTree.begin();
|
||||||
|
draggingTrackIter != layoutTree.end();
|
||||||
|
draggingTrackIter++)
|
||||||
|
{
|
||||||
|
if(*draggingTrackIter == model_track)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineLayoutHelper::end_dragging_track()
|
||||||
|
{
|
||||||
|
draggingTrack.reset();
|
||||||
|
clone_tree_from_sequence();
|
||||||
|
update_layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<timeline::Track>
|
||||||
|
TimelineLayoutHelper::get_dragging_track() const
|
||||||
|
{
|
||||||
|
return draggingTrack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineLayoutHelper::drag_to_point(Gdk::Point point)
|
||||||
|
{
|
||||||
|
// Apply the scroll offset
|
||||||
|
point.set_y(point.get_y() + timelineWidget.get_y_scroll_offset());
|
||||||
|
|
||||||
|
// Search the headers
|
||||||
|
TrackTree::pre_order_iterator iterator;
|
||||||
|
for(iterator = ++layoutTree.begin(); // ++ so we miss out the root sequence
|
||||||
|
iterator != layoutTree.end();
|
||||||
|
iterator++)
|
||||||
|
{
|
||||||
|
// Hit test the rectangle
|
||||||
|
const weak_ptr<timeline::Track> track =
|
||||||
|
lookup_timeline_track(*iterator);
|
||||||
|
const Gdk::Rectangle &rect = headerBoxes[track];
|
||||||
|
|
||||||
|
if(point.get_x() >= rect.get_x() &&
|
||||||
|
point.get_x() < rect.get_x() + rect.get_width() &&
|
||||||
|
point.get_y() >= rect.get_y() &&
|
||||||
|
point.get_y() < rect.get_y() + rect.get_height())
|
||||||
|
{
|
||||||
|
// Relocate the header
|
||||||
|
draggingTrackIter = layoutTree.move_after(
|
||||||
|
iterator, draggingTrackIter);
|
||||||
|
update_layout();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
TimelineLayoutHelper::get_total_height() const
|
TimelineLayoutHelper::get_total_height() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,14 @@ public:
|
||||||
**/
|
**/
|
||||||
boost::shared_ptr<timeline::Track> track_from_y(int y);
|
boost::shared_ptr<timeline::Track> track_from_y(int y);
|
||||||
|
|
||||||
|
void begin_dragging_track(boost::shared_ptr<timeline::Track> track);
|
||||||
|
|
||||||
|
void end_dragging_track();
|
||||||
|
|
||||||
|
boost::shared_ptr<timeline::Track> get_dragging_track() const;
|
||||||
|
|
||||||
|
void drag_to_point(Gdk::Point point);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the total height in pixels of the layout tree.
|
* Returns the total height in pixels of the layout tree.
|
||||||
* @remarks This function is only on returns a valid value fter
|
* @remarks This function is only on returns a valid value fter
|
||||||
|
|
@ -228,6 +236,10 @@ protected:
|
||||||
**/
|
**/
|
||||||
int totalHeight;
|
int totalHeight;
|
||||||
|
|
||||||
|
TrackTree::pre_order_iterator draggingTrackIter;
|
||||||
|
|
||||||
|
boost::shared_ptr<timeline::Track> draggingTrack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The connection to the animation timer.
|
* The connection to the animation timer.
|
||||||
* @see begin_animation()
|
* @see begin_animation()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue