Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
track-body.cpp
Go to the documentation of this file.
1/*
2 TrackBody - track body area within the timeline display canvas
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
27#include "stage/gtk-base.hpp"
30
31#include "lib/util.hpp"
32
33using util::isnil;
34using util::min;
35
36
37namespace stage {
38namespace timeline {
39
44
45
46
47
49 : contentHeight_{DEFAULT_CONTENT_HEIGHT_px}
50 , contentOffset_{0}
51 , startLine_{0}
52 , subTracks_{}
53 , rulers_{}
54 { }
55
56
58 { // indicate change of the global track structure
60 }
61
62
65
66
67 void
69 {
70 TODO ("is the track name of any relevance for the TrackBody widget?");
71 }
72
73
74 /* ==== Interface: ViewHook ===== */
75
76 void
78 {
79 subTracks_.push_back (&subBody);
80
81 // notify presentation code of the changed structure
83 signalStructureChange_(); // this _is_ such a change
84 }
85
86 void
92
93 void
94 TrackBody::rehook (TrackBody& subBody) noexcept
95 {
96 util::removeall (subTracks_, &subBody);
97 subTracks_.push_back (&subBody);
98 signalStructureChange_();
99 }
100
101
102 /* ==== Code for vertical track display layout ==== */
103
108 void
110 {
111 if (contentExtension > contentHeight_)
112 contentHeight_ = contentExtension;
113 }
114
122 uint
124 {
125 return calcContentHeight()
127 }
128
133 uint
135 {
136 return calcRulerHeight()
138 + (isnil (subTracks_)? 0 // slope down to nested scope
139 : decoration.borders[0]);
140 }
141
146 uint
148 { // „insider trick“ to include prelude padding on root track...
149 uint overviewHeight{startLine_== 0? // parent adds offset to startLine_ of any sub-track
150 decoration.topMar : 0};
151 for (auto& ruler : rulers_)
152 {
153 overviewHeight += ruler->calcHeight()
154 + ruler->getGapHeight()
156 }
157 return overviewHeight;
158 }
159
160 uint
162 {
163 uint heightSum{isnil (subTracks_)? 0 // approximate slope up (possibly exaggerated)
164 : decoration.borders[0] };
165 for (TrackBody* subTrack : subTracks_)
166 heightSum += subTrack->calcHeight();
167 return heightSum;
168 }
169
170
171 namespace {
179 inline uint
181 {
182 if (depth==0) return 0;
183 depth = min (depth, TrackBody::decoration.borders.size() - 1);
184 return TrackBody::decoration.borders[depth];
185 }
186 }
187
188
203 uint
205 {
206 uint line=0;
207 bool topLevel = isnil (profile);
208 if (topLevel)
209 {
210 // global setup for the profile
211 line += decoration.topMar;
212 profile.append_prelude();
213 }
214 else
215 { // adjust if preceded by a combined up-slope
216 line += combinedSlopeHeight (profile.getPrecedingSlopeUp());
217 }
218
219 // reserve space for the overview rulers
220 for (auto& ruler : rulers_)
221 {
222 uint rulerHeight = ruler->calcHeight();
223 uint gapHeight = ruler->getGapHeight();
224 line += rulerHeight+gapHeight + decoration.ruler;
225 profile.append_ruler (rulerHeight);
226 if (gapHeight > 0)
227 profile.append_gap (gapHeight);
228 }
229 if (topLevel)
230 {
231 // The first Profile elements are always visible on top;
232 // we render this prefix part on a separate drawing canvas,
233 profile.markPrefixEnd();
234 // ...and now we switch to the second, scrollable canvas,
235 // which uses its own local coordinates, thus restart Y-pos.
236 line = 0;
237 }
238 // mark offset of the actual content area relative to this track's top
239 this->contentOffset_ = line + decoration.trackPad;
240
241 // allocate space for the track content
242 line += this->contentHeight_ + decoration.content;
243 profile.append_content (this->contentHeight_);
244
245 // account for the space required by nested sub-tracks
246 if (not isnil (subTracks_))
247 {
248 // account for a single slope one step down
249 line += decoration.borders[0]; // (downward slopes are never combined)
250 profile.addSlopeDown();
251
252 for (TrackBody* subTrack : subTracks_)
253 {
254 // (re)set the subTrack's start coordinates
255 // to reflect the allocation calculation done thus far
256 subTrack->startLine_ = this->startLine_ + line;
257 line += subTrack->establishTrackSpace (profile);
258 }
259
260 profile.addSlopeUp(); // note: up-slopes might be combined
261 } // thus we'll add their contribution
262 // at the calling function one level higher
263 if (topLevel)
264 {
265 // adjust when reaching top-level after a combined up-slope
266 line += combinedSlopeHeight (profile.getPrecedingSlopeUp());
267
268 line += decoration.botMar + TIMELINE_BOTTOM_PADDING_px;
269 profile.append_coda (TIMELINE_BOTTOM_PADDING_px);
270 }
271
272 return line;
273 }
274
275
276
277}}// namespace stage::timeline
Helper to organise and draw the space allocated for a fork of sub-tracks.
DisplayManager::SignalStructureChange signalStructureChange_
void rehook(TrackBody &) noexcept override
void accommodateContentHeight(uint contentExtension)
ensure content with the given extension can be accommodated within this track's content area
static Decoration decoration
storage for common style/padding settings
void setTrackName(cuString &)
uint establishTrackSpace(TrackProfile &)
recursively establish the screen space allocation for this structure of nested tracks.
uint calcHeight() const
recursively calculate the height in pixels to display this track, including all nested sub-tracks and...
uint calcRulerHeight() const
sum up the vertical extension required by all overview rulers.
void hook(TrackBody &) override
void remove(TrackBody &) override
Description of the structure and arrangement of tracks for display in the UI.
A set of basic GTK includes for the UI.
unsigned int uint
Definition integral.hpp:29
uint combinedSlopeHeight(uint depth)
helper to get the width of combined slope borders.
Borders borders
width of up to 6 levels of combined upward slope borders (defined in CSS)
Configure additional vertical padding for the decorations added through CSS.
Lumiera GTK UI implementation root.
Definition guifacade.cpp:37
const uString cuString
Definition gtk-base.hpp:93
auto min(IT &&elms)
SEQ::iterator removeall(SEQ &coll, typename SEQ::value_type const &val)
shortcut for removing all copies of an Element in any sequential collection
Definition util.hpp:306
bool isnil(lib::time::Duration const &dur)
This helper class serves to manage the layout and display of the horizontally extended space of a "tr...
Abstraction to build the layout for the track spaces within timeline display.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...