From ac28251915c7aa01cead836caf0ad824cee09a76 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 1 Jan 2009 13:31:34 +0000 Subject: [PATCH] Added layout code from TimelineHeaderContainer --- .../timeline/timeline-layout-helper.cpp | 81 +++++++++++++++++-- .../timeline/timeline-layout-helper.hpp | 55 ++++++++++++- 2 files changed, 127 insertions(+), 9 deletions(-) diff --git a/src/gui/widgets/timeline/timeline-layout-helper.cpp b/src/gui/widgets/timeline/timeline-layout-helper.cpp index 148132c16..11d97d7ce 100644 --- a/src/gui/widgets/timeline/timeline-layout-helper.cpp +++ b/src/gui/widgets/timeline/timeline-layout-helper.cpp @@ -48,7 +48,7 @@ TimelineLayoutHelper::clone_tree_from_sequence() REQUIRE(sequence); layoutTree.clear(); - tree< shared_ptr >::iterator_base iterator = + TrackTree::iterator_base iterator = layoutTree.set_head(sequence); add_branch(iterator, sequence); @@ -56,20 +56,91 @@ TimelineLayoutHelper::clone_tree_from_sequence() void TimelineLayoutHelper::add_branch( - lumiera::tree< shared_ptr >::iterator_base - parent_iterator, + TrackTree::iterator_base parent_iterator, shared_ptr parent) { BOOST_FOREACH(shared_ptr child, parent->get_child_tracks()) { - tree< shared_ptr >::iterator_base - child_iterator = + TrackTree::iterator_base child_iterator = layoutTree.append_child(parent_iterator, child); add_branch(child_iterator, child); } } +void +TimelineLayoutHelper::update_layout() +{ + // Make sure the style are loaded + //read_styles(); + + // Clear previously cached layout + headerBoxes.clear(); + + // Start at minus-the-scroll offset + 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 indent_width = 10; + + layout_headers_recursive(layoutTree.begin(), + offset, header_width, indent_width, 0, true); +} + +void +TimelineLayoutHelper::layout_headers_recursive( + TrackTree::iterator_base parent_iterator, + int &offset, const int header_width, const int indent_width, + const int depth, bool parent_expanded) +{ + REQUIRE(depth >= 0); + + TrackTree::sibling_iterator iterator; + for(iterator = layoutTree.begin(parent_iterator); + iterator != layoutTree.end(parent_iterator); + iterator++) + { + const shared_ptr &model_track = *iterator; + REQUIRE(model_track); + + shared_ptr timeline_track = + lookup_timeline_track(model_track); + + if(parent_expanded) + { + // Calculate and store the box of the header + const int track_height = timeline_track->get_height(); + const int indent = depth * indent_width; + + headerBoxes[timeline_track] = Gdk::Rectangle( + indent, // x + offset, // y + max( header_width - indent, 0 ), // width + track_height); // height + + // Offset for the next header + offset += track_height + TimelineWidget::TrackPadding; + } + + layout_headers_recursive(iterator, offset, header_width, + indent_width, depth + 1, + timeline_track->get_expanded() && parent_expanded); + } +} + +shared_ptr +TimelineLayoutHelper::lookup_timeline_track( + shared_ptr model_track) +{ + REQUIRE(model_track != NULL); + shared_ptr timeline_track = + timelineWidget.lookup_timeline_track(model_track); + ENSURE(timeline_track); + + return timeline_track; +} + } // namespace timeline } // namespace widgets } // namespace gui diff --git a/src/gui/widgets/timeline/timeline-layout-helper.hpp b/src/gui/widgets/timeline/timeline-layout-helper.hpp index b5c077ce3..d9446d707 100644 --- a/src/gui/widgets/timeline/timeline-layout-helper.hpp +++ b/src/gui/widgets/timeline/timeline-layout-helper.hpp @@ -51,21 +51,68 @@ class Track; */ class TimelineLayoutHelper : public boost::noncopyable { +public: + typedef lumiera::tree< boost::shared_ptr > TrackTree; + public: TimelineLayoutHelper(TimelineWidget &owner); protected: void clone_tree_from_sequence(); - void add_branch( - lumiera::tree< boost::shared_ptr >::iterator_base - parent_iterator, + void add_branch(TrackTree::iterator_base parent_iterator, boost::shared_ptr parent); + /** + * Recaculates the track layout from layoutTree. + **/ + void update_layout(); + + /** + * 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. + * !!!!!!!!!!! indent_width + * @param depth The depth within the tree of track. + **/ + void layout_headers_recursive( + TrackTree::iterator_base parent_iterator, + int &offset, const int header_width, const int indent_width, + const int depth, bool parent_expanded); + + /** + * A helper function which calls lookup_timeline_track within the + * parent timeline widget, but also applies lots of data consistency + * checks in the process. + * @param model_track The model track to look up in the parent widget. + * @return Returns the track found, or returns NULL if no matching + * track was found. + * @remarks If the return value is going to be NULL, an ENSURE will + * fail. + **/ + boost::shared_ptr lookup_timeline_track( + boost::shared_ptr model_track); + protected: + TimelineWidget &timelineWidget; - lumiera::tree< boost::shared_ptr > layoutTree; + TrackTree layoutTree; + + /** + * 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, Gdk::Rectangle> + headerBoxes; }; } // namespace timeline