WIP: Applying new layout system
This commit is contained in:
parent
ac28251915
commit
afb5b7298f
9 changed files with 190 additions and 234 deletions
|
|
@ -32,6 +32,7 @@
|
|||
#include <nobug.h>
|
||||
#include <vector>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include "lib/util.hpp"
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ TimelineWidget::TimelineWidget(
|
|||
playbackPeriodStart(0),
|
||||
playbackPeriodEnd(0),
|
||||
playbackPoint(GAVL_TIME_UNDEFINED),
|
||||
totalHeight(0),
|
||||
horizontalAdjustment(0, 0, 0),
|
||||
verticalAdjustment(0, 0, 0),
|
||||
horizontalScroll(horizontalAdjustment),
|
||||
verticalScroll(verticalAdjustment)
|
||||
{
|
||||
g_message("TimelineWidget::TimelineWidget");
|
||||
REQUIRE(sequence);
|
||||
|
||||
body = new TimelineBody(this);
|
||||
|
|
@ -64,6 +64,8 @@ TimelineWidget::TimelineWidget(
|
|||
ENSURE(headerContainer != NULL);
|
||||
ruler = new TimelineRuler(this);
|
||||
ENSURE(ruler != NULL);
|
||||
|
||||
g_message("Widgets Constructed");
|
||||
|
||||
horizontalAdjustment.signal_value_changed().connect( sigc::mem_fun(
|
||||
this, &TimelineWidget::on_scroll) );
|
||||
|
|
@ -77,6 +79,7 @@ TimelineWidget::TimelineWidget(
|
|||
viewWindow.set_time_scale(GAVL_TIME_SCALE / 200);
|
||||
set_selection(2000000, 4000000);
|
||||
|
||||
g_message("update_tracks");
|
||||
update_tracks();
|
||||
|
||||
attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND);
|
||||
|
|
@ -90,6 +93,7 @@ TimelineWidget::TimelineWidget(
|
|||
// Receive notifications of changes to the tracks
|
||||
sequence->get_child_track_list().signal_changed().connect(
|
||||
sigc::mem_fun( this, &TimelineWidget::on_track_list_changed ) );
|
||||
g_message("Constructor }");
|
||||
}
|
||||
|
||||
TimelineWidget::~TimelineWidget()
|
||||
|
|
@ -296,6 +300,10 @@ TimelineWidget::update_tracks()
|
|||
// Create timeline tracks from all the model tracks
|
||||
create_timeline_tracks();
|
||||
|
||||
// Update the layout helper
|
||||
layoutHelper.clone_tree_from_sequence();
|
||||
layoutHelper.update_layout();
|
||||
|
||||
// Update the header container
|
||||
REQUIRE(headerContainer != NULL);
|
||||
headerContainer->show_all_children();
|
||||
|
|
@ -303,15 +311,6 @@ TimelineWidget::update_tracks()
|
|||
|
||||
// Update the body
|
||||
body->queue_draw();
|
||||
|
||||
// Recalculate the total height of the timeline scrolled area
|
||||
totalHeight = 0;
|
||||
BOOST_FOREACH(shared_ptr<model::Track> track,
|
||||
sequence->get_child_tracks())
|
||||
{
|
||||
REQUIRE(track);
|
||||
totalHeight += measure_branch_height(track);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -339,9 +338,6 @@ TimelineWidget::create_timeline_tracks_from_branch(
|
|||
// We will need to create one
|
||||
trackMap[model_track] =
|
||||
create_timeline_track_from_model_track(model_track);
|
||||
|
||||
// Hook up
|
||||
|
||||
}
|
||||
|
||||
// Recurse to child tracks
|
||||
|
|
@ -419,6 +415,9 @@ TimelineWidget::lookup_timeline_track(
|
|||
shared_ptr<model::Track> model_track) const
|
||||
{
|
||||
REQUIRE(sequence);
|
||||
REQUIRE(model_track);
|
||||
REQUIRE(model_track != sequence); // The sequence isn't really a track
|
||||
|
||||
std::map<shared_ptr<model::Track>, shared_ptr<timeline::Track> >::
|
||||
const_iterator iterator = trackMap.find(model_track);
|
||||
if(iterator == trackMap.end())
|
||||
|
|
@ -434,31 +433,6 @@ TimelineWidget::lookup_timeline_track(
|
|||
return iterator->second;
|
||||
}
|
||||
|
||||
boost::shared_ptr<model::Track>
|
||||
TimelineWidget::lookup_model_track(
|
||||
const timeline::Track *timeline_track) const
|
||||
{
|
||||
REQUIRE(sequence);
|
||||
|
||||
std::pair<shared_ptr<model::Track>, shared_ptr<timeline::Track> >
|
||||
pair;
|
||||
BOOST_FOREACH( pair, trackMap )
|
||||
{
|
||||
if(pair.second.get() == timeline_track)
|
||||
{
|
||||
ENSURE(pair.first);
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
// The track is not present in the map
|
||||
// We are in an error condition if the timeline track is not found
|
||||
// - the timeline tracks must always be synchronous with the model
|
||||
// tracks.
|
||||
ENSURE(0);
|
||||
return shared_ptr<model::Track>();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineWidget::update_scroll()
|
||||
{
|
||||
|
|
@ -479,7 +453,8 @@ TimelineWidget::update_scroll()
|
|||
|
||||
// Calculate the vertical length that can be scrolled:
|
||||
// the total height of all the tracks minus one screenful
|
||||
int y_scroll_length = totalHeight - body_allocation.get_height();
|
||||
int y_scroll_length = layoutHelper.get_total_height() -
|
||||
body_allocation.get_height();
|
||||
if(y_scroll_length < 0) y_scroll_length = 0;
|
||||
|
||||
// If by resizing we're now over-scrolled, scroll back to
|
||||
|
|
@ -501,29 +476,6 @@ TimelineWidget::update_scroll()
|
|||
|
||||
}
|
||||
|
||||
int
|
||||
TimelineWidget::measure_branch_height(
|
||||
shared_ptr<model::Track> model_track)
|
||||
{
|
||||
REQUIRE(model_track);
|
||||
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
ENSURE(timeline_track);
|
||||
|
||||
int height = timeline_track->get_height() + TrackPadding;
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
{
|
||||
REQUIRE(child);
|
||||
height += measure_branch_height(child);
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
int
|
||||
TimelineWidget::get_y_scroll_offset() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -217,25 +217,11 @@ private:
|
|||
**/
|
||||
boost::shared_ptr<timeline::Track> lookup_timeline_track(
|
||||
boost::shared_ptr<model::Track> model_track) const;
|
||||
|
||||
/**
|
||||
* Looks up a model track in trackMap that corresponds to a
|
||||
* given timeline track.
|
||||
* @param timeline_track The timeline UI track to look up.
|
||||
* @returns The model track found, or an empty shared_ptr if
|
||||
* timeline_track has no corresponding timeline UI track (this is an
|
||||
* error condition).
|
||||
**/
|
||||
boost::shared_ptr<model::Track> lookup_model_track(
|
||||
const timeline::Track *timeline_track) const;
|
||||
|
||||
// ----- Layout Functions ----- //
|
||||
|
||||
void update_scroll();
|
||||
|
||||
int measure_branch_height(
|
||||
boost::shared_ptr<model::Track> model_track);
|
||||
|
||||
int get_y_scroll_offset() const;
|
||||
|
||||
// ----- Event Handlers -----//
|
||||
|
|
@ -293,8 +279,6 @@ protected:
|
|||
|
||||
boost::shared_ptr<timeline::Track> hoveringTrack;
|
||||
|
||||
int totalHeight;
|
||||
|
||||
// Child Widgets
|
||||
timeline::TimelineHeaderContainer *headerContainer;
|
||||
timeline::TimelineBody *body;
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ TimelineHeaderContainer::on_unrealize()
|
|||
bool TimelineHeaderContainer::on_button_press_event (
|
||||
GdkEventButton* event)
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
REQUIRE(event != NULL);
|
||||
|
||||
switch(event->button)
|
||||
|
|
@ -152,8 +153,9 @@ bool TimelineHeaderContainer::on_button_press_event (
|
|||
case 3: // Right Click
|
||||
{
|
||||
// Popup the context menu
|
||||
shared_ptr<Track> header = header_from_point(
|
||||
Gdk::Point(event->x, event->y));
|
||||
shared_ptr<Track> header(
|
||||
timelineWidget->layoutHelper.header_from_point(
|
||||
Gdk::Point(event->x, event->y)));
|
||||
|
||||
// Are we hovering on a header?
|
||||
if(header)
|
||||
|
|
@ -183,6 +185,8 @@ bool TimelineHeaderContainer::on_button_release_event (
|
|||
// Yes? The toggle the expanding
|
||||
clickedExpander->set_expanded(!clickedExpander->get_expanded());
|
||||
clickedExpander.reset();
|
||||
|
||||
timelineWidget->layoutHelper.update_layout();
|
||||
layout_headers();
|
||||
}
|
||||
|
||||
|
|
@ -304,88 +308,58 @@ TimelineHeaderContainer::on_hovering_track_changed(
|
|||
|
||||
void
|
||||
TimelineHeaderContainer::layout_headers()
|
||||
{
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
// We can't layout before the widget has been set up
|
||||
if(!gdkWindow)
|
||||
return;
|
||||
|
||||
// Make sure the style are loaded
|
||||
read_styles();
|
||||
|
||||
// Clear previously cached layout
|
||||
headerBoxes.clear();
|
||||
|
||||
// Start at minus-the-scroll offset
|
||||
int offset = -timelineWidget->get_y_scroll_offset();
|
||||
|
||||
const Allocation container_allocation = get_allocation();
|
||||
const int header_width = container_allocation.get_width();
|
||||
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track, get_tracks() )
|
||||
layout_headers_recursive(
|
||||
model_track, offset, header_width, 0, true);
|
||||
TimelineLayoutHelper &layoutHelper =
|
||||
timelineWidget->layoutHelper;
|
||||
const TimelineLayoutHelper::TrackTree &layoutTree =
|
||||
layoutHelper.get_layout_tree();
|
||||
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layoutTree.begin(); // ++ so that we skip the sequence root
|
||||
iterator != layoutTree.end();
|
||||
iterator++)
|
||||
{
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(*iterator);
|
||||
|
||||
Widget &widget = timeline_track->get_header_widget();
|
||||
|
||||
optional<Gdk::Rectangle> header_rect =
|
||||
layoutHelper.get_track_header_rect(timeline_track);
|
||||
|
||||
if(header_rect)
|
||||
{
|
||||
REQUIRE(header_rect->get_width() >= 0);
|
||||
REQUIRE(header_rect->get_height() >= 0);
|
||||
|
||||
// Calculate the allocation of the header widget
|
||||
Allocation header_allocation(
|
||||
header_rect->get_x() + margin + expand_button_size, // x
|
||||
header_rect->get_y() + margin, // y
|
||||
max( header_rect->get_width() - expand_button_size -
|
||||
margin * 2, 0 ), // width
|
||||
header_rect->get_height() - margin * 2); // height
|
||||
|
||||
// Apply the allocation to the header
|
||||
widget.size_allocate (header_allocation);
|
||||
if(!widget.is_visible())
|
||||
widget.show();
|
||||
}
|
||||
else // No header rect, so the track must be hidden
|
||||
if(widget.is_visible())
|
||||
widget.hide();
|
||||
}
|
||||
|
||||
// Repaint the background of our parenting
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::layout_headers_recursive(
|
||||
shared_ptr<model::Track> model_track, int &offset,
|
||||
const int header_width, const int depth, bool parent_expanded)
|
||||
{
|
||||
REQUIRE(depth >= 0);
|
||||
REQUIRE(model_track != NULL);
|
||||
|
||||
shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
const int indent = depth * 10;
|
||||
Widget &widget = timeline_track->get_header_widget();
|
||||
|
||||
if(parent_expanded)
|
||||
{
|
||||
const int track_height = timeline_track->get_height();
|
||||
|
||||
// Calculate the box of the header
|
||||
Gdk::Rectangle header_box(
|
||||
indent, // x
|
||||
offset, // y
|
||||
max( header_width - indent, 0 ), // width
|
||||
track_height); // height
|
||||
REQUIRE(header_box.get_height() >= 0);
|
||||
|
||||
// Cache the bounding box
|
||||
headerBoxes[timeline_track] = header_box;
|
||||
|
||||
// Calculate the allocation of the header widget
|
||||
Allocation header_allocation(
|
||||
header_box.get_x() + margin + expand_button_size, // x
|
||||
header_box.get_y() + margin, // y
|
||||
max( header_box.get_width() - expand_button_size -
|
||||
margin * 2, 0 ), // width
|
||||
header_box.get_height() - margin * 2); // height
|
||||
|
||||
// Apply the allocation to the header
|
||||
widget.size_allocate (header_allocation);
|
||||
if(!widget.is_visible())
|
||||
widget.show();
|
||||
|
||||
// Offset for the next header
|
||||
offset += track_height + TimelineWidget::TrackPadding;
|
||||
}
|
||||
else
|
||||
if(widget.is_visible())
|
||||
widget.hide();
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( boost::shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
layout_headers_recursive(
|
||||
child, offset, header_width, depth + 1,
|
||||
timeline_track->get_expanded() && parent_expanded);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::set_parent_recursive(
|
||||
boost::shared_ptr<model::Track> model_track)
|
||||
|
|
@ -442,6 +416,7 @@ TimelineHeaderContainer::draw_header_decoration(
|
|||
shared_ptr<model::Track> model_track,
|
||||
const Gdk::Rectangle &clip_rect)
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
REQUIRE(model_track != NULL);
|
||||
REQUIRE(clip_rect.get_width() > 0);
|
||||
REQUIRE(clip_rect.get_height() > 0);
|
||||
|
|
@ -452,10 +427,11 @@ TimelineHeaderContainer::draw_header_decoration(
|
|||
shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
// Get the cached header box
|
||||
weak_ptr<timeline::Track> ptr(timeline_track);
|
||||
REQUIRE(contains(headerBoxes, ptr));
|
||||
const Gdk::Rectangle &box = headerBoxes[timeline_track];
|
||||
// Get the header box
|
||||
const optional<Gdk::Rectangle> &optional_box =
|
||||
timelineWidget->layoutHelper.get_track_header_rect(timeline_track);
|
||||
REQUIRE(optional_box);
|
||||
const Gdk::Rectangle box = *optional_box;
|
||||
|
||||
// Paint the box, if it will be visible
|
||||
if(box.get_x() < clip_rect.get_width() &&
|
||||
|
|
@ -498,58 +474,55 @@ TimelineHeaderContainer::draw_header_decoration(
|
|||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<timeline::Track>
|
||||
TimelineHeaderContainer::header_from_point(const Gdk::Point &point)
|
||||
{
|
||||
std::pair<shared_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle &rect = pair.second;
|
||||
|
||||
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())
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
return shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
TimelineHeaderContainer::expander_button_from_point(
|
||||
const Gdk::Point &point)
|
||||
{
|
||||
std::pair<shared_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
const TimelineLayoutHelper::TrackTree &layoutTree =
|
||||
timelineWidget->layoutHelper.get_layout_tree();
|
||||
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layoutTree.begin(); // ++ so we skip the sequence root
|
||||
iterator != layoutTree.end();
|
||||
iterator++)
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle rect =
|
||||
get_expander_button_rectangle(pair.first);
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(*iterator);
|
||||
|
||||
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())
|
||||
return pair.first;
|
||||
// Hit test the rectangle
|
||||
const optional<Gdk::Rectangle> rect =
|
||||
get_expander_button_rectangle(timeline_track);
|
||||
|
||||
if(rect)
|
||||
{
|
||||
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())
|
||||
return timeline_track;
|
||||
}
|
||||
}
|
||||
|
||||
return shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
const Gdk::Rectangle
|
||||
const optional<Gdk::Rectangle>
|
||||
TimelineHeaderContainer::get_expander_button_rectangle(
|
||||
shared_ptr<Track> track)
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
REQUIRE(track != NULL);
|
||||
weak_ptr<timeline::Track> ptr(track);
|
||||
REQUIRE(contains(headerBoxes, ptr));
|
||||
|
||||
const Gdk::Rectangle &box = headerBoxes[track];
|
||||
return Gdk::Rectangle(
|
||||
margin + box.get_x(), margin + box.get_y(),
|
||||
expand_button_size, box.get_height() - margin * 2);
|
||||
optional<Gdk::Rectangle> box =
|
||||
timelineWidget->layoutHelper.get_track_header_rect(track);
|
||||
if(box)
|
||||
{
|
||||
return optional<Gdk::Rectangle>(Gdk::Rectangle(
|
||||
margin + box->get_x(), margin + box->get_y(),
|
||||
expand_button_size, box->get_height() - margin * 2));
|
||||
}
|
||||
|
||||
return optional<Gdk::Rectangle>();
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
|
|
|
|||
|
|
@ -149,19 +149,7 @@ private:
|
|||
* stacking etc.
|
||||
*/
|
||||
void layout_headers();
|
||||
|
||||
/**
|
||||
* Recursively lays out all the controls in the header widget.
|
||||
* @param track The parent track object which will be recursed into.
|
||||
* @param offset A shared value used to accumulate the y-offset of
|
||||
* header widgets.
|
||||
* @param header_width The width of this widget in pixels.
|
||||
* @param depth The depth within the tree of track.
|
||||
**/
|
||||
void layout_headers_recursive(boost::shared_ptr<model::Track> track,
|
||||
int &offset, const int header_width, const int depth,
|
||||
bool parent_expanded);
|
||||
|
||||
|
||||
/**
|
||||
* Recursively sets all the track header widgets to be child widgets
|
||||
* of this widget.
|
||||
|
|
@ -199,9 +187,6 @@ private:
|
|||
void draw_header_decoration(
|
||||
boost::shared_ptr<model::Track> model_track,
|
||||
const Gdk::Rectangle &clip_rect);
|
||||
|
||||
boost::shared_ptr<timeline::Track> header_from_point(
|
||||
const Gdk::Point &point);
|
||||
|
||||
/**
|
||||
* Given a point, expander_button_from_point finds the track of the
|
||||
|
|
@ -219,7 +204,7 @@ private:
|
|||
* @param track The track to get the expander button rectangle of.
|
||||
* @return Returns the rectangle of the expander button of track.
|
||||
**/
|
||||
const Gdk::Rectangle get_expander_button_rectangle(
|
||||
const boost::optional<Gdk::Rectangle> get_expander_button_rectangle(
|
||||
boost::shared_ptr<timeline::Track> track);
|
||||
|
||||
/**
|
||||
|
|
@ -278,16 +263,7 @@ private:
|
|||
* click is not processed by track headers.
|
||||
**/
|
||||
Gtk::Menu contextMenu;
|
||||
|
||||
/**
|
||||
* A map of tracks to the rectangles of their headers.
|
||||
* @remarks This map is used as a cache, so that the rectangles don't
|
||||
* need to be perpetually recalculated. This cache is regenerated by
|
||||
* the layout_headers method.
|
||||
**/
|
||||
std::map<boost::weak_ptr<timeline::Track>, Gdk::Rectangle>
|
||||
headerBoxes;
|
||||
|
||||
|
||||
//----- User Interaction State -----//
|
||||
boost::shared_ptr<timeline::Track> hoveringExpander;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,13 +31,15 @@ using namespace Gtk;
|
|||
using namespace std;
|
||||
using namespace boost;
|
||||
using namespace lumiera;
|
||||
using namespace util;
|
||||
|
||||
namespace gui {
|
||||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
TimelineLayoutHelper::TimelineLayoutHelper(TimelineWidget &owner)
|
||||
: timelineWidget(owner)
|
||||
TimelineLayoutHelper::TimelineLayoutHelper(TimelineWidget &owner) :
|
||||
timelineWidget(owner),
|
||||
totalHeight(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -48,12 +50,16 @@ TimelineLayoutHelper::clone_tree_from_sequence()
|
|||
REQUIRE(sequence);
|
||||
|
||||
layoutTree.clear();
|
||||
TrackTree::iterator_base iterator =
|
||||
layoutTree.set_head(sequence);
|
||||
|
||||
TrackTree::iterator_base iterator = layoutTree.set_head(sequence);
|
||||
add_branch(iterator, sequence);
|
||||
}
|
||||
|
||||
TimelineLayoutHelper::TrackTree&
|
||||
TimelineLayoutHelper::get_layout_tree()
|
||||
{
|
||||
return layoutTree;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayoutHelper::add_branch(
|
||||
TrackTree::iterator_base parent_iterator,
|
||||
|
|
@ -68,6 +74,45 @@ TimelineLayoutHelper::add_branch(
|
|||
}
|
||||
}
|
||||
|
||||
optional<Gdk::Rectangle>
|
||||
TimelineLayoutHelper::get_track_header_rect(
|
||||
boost::weak_ptr<timeline::Track> track)
|
||||
{
|
||||
if(contains(headerBoxes, track))
|
||||
{
|
||||
Gdk::Rectangle rect(headerBoxes[track]);
|
||||
rect.set_y(rect.get_y() - timelineWidget.get_y_scroll_offset());
|
||||
return optional<Gdk::Rectangle>(rect);
|
||||
}
|
||||
return optional<Gdk::Rectangle>();
|
||||
}
|
||||
|
||||
weak_ptr<timeline::Track>
|
||||
TimelineLayoutHelper::header_from_point(const Gdk::Point &point)
|
||||
{
|
||||
std::pair<weak_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle &rect = pair.second;
|
||||
|
||||
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())
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
return shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
int
|
||||
TimelineLayoutHelper::get_total_height() const
|
||||
{
|
||||
ENSURE(totalHeight >= 0);
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayoutHelper::update_layout()
|
||||
{
|
||||
|
|
@ -81,11 +126,13 @@ TimelineLayoutHelper::update_layout()
|
|||
int offset = 0;//-timelineWidget->get_y_scroll_offset();
|
||||
|
||||
//const Allocation container_allocation = get_allocation();
|
||||
const int header_width = 100;//container_allocation.get_width();
|
||||
const int header_width = 150;//container_allocation.get_width();
|
||||
const int indent_width = 10;
|
||||
|
||||
|
||||
layout_headers_recursive(layoutTree.begin(),
|
||||
offset, header_width, indent_width, 0, true);
|
||||
|
||||
totalHeight = offset;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -56,17 +56,30 @@ public:
|
|||
|
||||
public:
|
||||
TimelineLayoutHelper(TimelineWidget &owner);
|
||||
protected:
|
||||
|
||||
|
||||
void clone_tree_from_sequence();
|
||||
|
||||
TrackTree& get_layout_tree();
|
||||
|
||||
/**
|
||||
* Recalculates the track layout from layoutTree.
|
||||
**/
|
||||
void update_layout();
|
||||
|
||||
boost::optional<Gdk::Rectangle> get_track_header_rect(
|
||||
boost::weak_ptr<timeline::Track> track);
|
||||
|
||||
boost::weak_ptr<timeline::Track> header_from_point(
|
||||
const Gdk::Point &point);
|
||||
|
||||
int get_total_height() const;
|
||||
|
||||
protected:
|
||||
|
||||
void add_branch(TrackTree::iterator_base parent_iterator,
|
||||
boost::shared_ptr<model::Track> parent);
|
||||
|
||||
/**
|
||||
* Recaculates the track layout from layoutTree.
|
||||
**/
|
||||
void update_layout();
|
||||
|
||||
|
||||
/**
|
||||
* Recursively lays out all the controls in the header widget.
|
||||
|
|
@ -113,6 +126,8 @@ protected:
|
|||
**/
|
||||
std::map<boost::weak_ptr<timeline::Track>, Gdk::Rectangle>
|
||||
headerBoxes;
|
||||
|
||||
int totalHeight;
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -90,6 +90,12 @@ Track::get_header_widget()
|
|||
return headerWidget;
|
||||
}
|
||||
|
||||
shared_ptr<model::Track>
|
||||
Track::get_model_track() const
|
||||
{
|
||||
return model_track;
|
||||
}
|
||||
|
||||
int
|
||||
Track::get_height() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ public:
|
|||
|
||||
Gtk::Widget& get_header_widget();
|
||||
|
||||
boost::shared_ptr<model::Track> get_model_track() const;
|
||||
|
||||
int get_height() const;
|
||||
|
||||
bool get_expanded() const;
|
||||
|
|
|
|||
Loading…
Reference in a new issue