Lumiera  0.pre.03
»edit your freedom«
timeline-layout.cpp
Go to the documentation of this file.
1 /*
2  TimelineLayout - global timeline layout management and display control
3 
4  Copyright (C)
5  2016, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
14 
24 #include "stage/gtk-base.hpp"
27 
28 #include "common/advice.hpp"
29 #include "lib/time/timevalue.hpp"
30 
31 using lib::time::Time;
32 using lib::time::FSecs;
34 
35 
36 namespace stage {
37 namespace timeline {
38 
39 
40 
41 
42 
43  TimelineLayout::~TimelineLayout() { }
44 
45  TimelineLayout::TimelineLayout (Gtk::Paned& topLevelContainer)
46  : paneSplitPosition_{topLevelContainer.property_position()}
47  , bodyCanvas_{*this} // inject (as interface DisplayManager)
48  , headerPane_{bodyCanvas_.get_vadjustment()} // wire the patchbay (Gtk::Viewport) to follow the body vertical scroll movement
49  , displayEvaluation_{}
50  {
51  topLevelContainer.add1 (headerPane_);
52  topLevelContainer.add2 (bodyCanvas_);
54  zoomWindow_.attachChangeNotification (signalStructureChange_);
55  // make the ZoomWindow react on changes to the horizontal scrollbar pos
56  bodyCanvas_.get_hadjustment()->property_value().signal_changed().connect(
57  sigc::bind(sigc::mem_fun(*this, &TimelineLayout::syncZoomWindow)
58  ,bodyCanvas_.get_hadjustment()));
59  // make the ZoomWindow react on changes to the window geometry
60  bodyCanvas_.signal_size_allocate().connect(
61  sigc::mem_fun(*this, &TimelineLayout::sizeZoomWindow));
62  }
63 
64 
73  void
75  {
76  headerPane_.installForkRoot (head);
77  bodyCanvas_.installForkRoot (body);
78 
79  // detect changes of the track structure
80  body.signalStructureChange_ = signalStructureChange_;
81  signalStructureChange_(); // this _is_ such a change
82  }
83 
88  void
90  {
91  displayEvaluation_.attach (*this);
92  displayEvaluation_.attach (forkRoot);
93  displayEvaluation_.attach (bodyCanvas_);
94  }
95 
96  Gtk::WidgetPath
97  TimelineLayout::getBodyWidgetPath() const
98  {
99  return bodyCanvas_.get_path();
100  }
101 
102 
103 
104 
110  void
112  {
113  displayEvaluation_.perform();
114  }
115 
120  void
122  {
123  Time windowStart = zoomWindow_.visible().start();
124  int pxOffset = translateTimeToPixels (windowStart);
125  bodyCanvas_.get_hadjustment()->set_value(pxOffset);
126  }
127 
128  void
129  TimelineLayout::completeLayout (DisplayEvaluation&)
130  {
131  /* nothing to do for the collect-phase */
132  }
133 
143  void
145  {
146  double pos = hadj->get_value();
147  TimeValue windowStart = applyScreenDelta(zoomWindow_.overallSpan().start(), pos);
148  zoomWindow_.setVisibleStart (windowStart);
149  }
150 
156  void
157  TimelineLayout::sizeZoomWindow (Gtk::Allocation& alloc)
158  {
159  int contentWidthPx = alloc.get_width();
160  if (abs(contentWidthPx) != zoomWindow_.pxWidth())
161  zoomWindow_.calibrateExtension (contentWidthPx);
162  }
163 
164 
165 
166  /* ==== Interface: ViewHook ===== */
167 
168  void
169  TimelineLayout::hook (TrackHeadWidget& head)
170  {
171  headerPane_.installForkRoot (head);
172  }
173 
174  void
175  TimelineLayout::hook (TrackBody& body)
176  {
177  bodyCanvas_.installForkRoot (body);
178 
179  // detect changes of the track structure
180  body.signalStructureChange_ = signalStructureChange_;
181  signalStructureChange_(); // this _is_ such a change
182  }
183 
184 
185  void
186  TimelineLayout::remove (TrackHeadWidget&)
187  {
188  headerPane_.disable();
189  }
190 
191  void
192  TimelineLayout::remove (TrackBody&)
193  {
194  bodyCanvas_.disable();
195  }
196 
197 
198  void
199  TimelineLayout::rehook (TrackHeadWidget&) noexcept
200  {
201  NOTREACHED ("TimelineLayout: top-Level must not be re-ordered");
202  }
203 
204  void
205  TimelineLayout::rehook (TrackBody&) noexcept
206  {
207  NOTREACHED ("TimelineLayout: top-Level must not be re-ordered");
208  }
209 
210 
211 
212 }}// namespace stage::timeline
Header pane control area corresponding to a Track with nested child Tracks.
void establishLayout(DisplayEvaluation &) override
TimelineLayout also participates itself in the DisplayEvaluation, notably to set up the basic paramet...
void setupStructure(LayoutElement &)
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
void triggerDisplayEvaluation() override
Perform a complete recursive pass over all elements relevant for layout, reestablish size allocation ...
void sizeZoomWindow(Gtk::Allocation &)
Signal receiver (slot) to react on changes of the window screen space allocation. ...
A core service of the timeline UI to ensure consistent display and layout of all components within th...
Visitor and state holder for a collaborative layout adjustment pass.
Expecting Advice and giving Advice: a cross-cutting collaboration of loosely coupled participants...
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
void syncZoomWindow(PAdjustment)
Signal receiver (slot) to react on scrollbar changes.
void installRootTrack(TrackHeadWidget &, TrackBody &)
This function is invoked once for each new TimelineWidget, in order to build the starting point for t...
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Definition: timevalue.hpp:220
Helper to organise and draw the space allocated for a fork of sub-tracks.
Definition: track-body.hpp:86
This helper class serves to manage the layout and display of the horizontally extended space of a "tr...
A time interval anchored at a specific point in time.
Definition: timevalue.hpp:573
a family of time value like entities and their relationships.
basic constant internal time value.
Definition: timevalue.hpp:133
A set of basic GTK includes for the UI.