From fa4a9014a19bdb7bb44e02b73e3ca69cdc5655d5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 29 Aug 2019 23:02:44 +0200 Subject: [PATCH] Timeline: nail the problem with calculating overall vertical space In the end, I used the profile building pass to also calculate and sum up the vertical offsets. Seems to be the only sane approach to get really precise values, since adjacent upwards slopes can be combined at various places (and I do not want to use the actual drawing code for this calculation) --- src/stage/lumiera-light-theme-complement.css | 5 +- src/stage/timeline/body-canvas-widget.cpp | 7 +- src/stage/timeline/track-body.cpp | 72 +++++++++++-- src/stage/timeline/track-body.hpp | 6 +- src/stage/timeline/track-profile.hpp | 8 ++ wiki/thinkPad.ichthyo.mm | 103 +++++++++++++------ 6 files changed, 150 insertions(+), 51 deletions(-) diff --git a/src/stage/lumiera-light-theme-complement.css b/src/stage/lumiera-light-theme-complement.css index b8d93fb76..e4f72f7a0 100644 --- a/src/stage/lumiera-light-theme-complement.css +++ b/src/stage/lumiera-light-theme-complement.css @@ -40,13 +40,14 @@ * background is used within the track scopes */ .timeline__page > .timeline__body fork.timeline__fork { - margin: 2ex 0; + margin: 2ex; + padding: 10px; border-style: inset; border-color: IndianRed; background-color: Lime; } fork.timeline__fork frame.timeline__ruler { - margin: 3ex 0; + margin: 1ex; border: 3px outset GoldenRod; background-color: DarkCyan; } diff --git a/src/stage/timeline/body-canvas-widget.cpp b/src/stage/timeline/body-canvas-widget.cpp index a709bef7a..7bf163c88 100644 --- a/src/stage/timeline/body-canvas-widget.cpp +++ b/src/stage/timeline/body-canvas-widget.cpp @@ -472,10 +472,9 @@ namespace timeline { { setupAdditionalTrackPadding_fromCSS(); layout_.triggerDisplayEvaluation(); - rootBody_->establishTrackSpace (profile_); - adjustCanvasHeight(layout_.getPixSpan().delta(), - rootBody_->calcHeight(), - rootBody_->calcRulerHeight()); + uint overallHeight = rootBody_->establishTrackSpace (profile_); + uint rulerHeight = rootBody_->calcRulerHeight() + TrackBody::decoration.topMar; + adjustCanvasHeight(layout_.getPixSpan().delta(), overallHeight, rulerHeight); } } diff --git a/src/stage/timeline/track-body.cpp b/src/stage/timeline/track-body.cpp index a269648b4..3700e83b5 100644 --- a/src/stage/timeline/track-body.cpp +++ b/src/stage/timeline/track-body.cpp @@ -46,6 +46,7 @@ //using util::_Fmt; using util::isnil; +using util::min; //using util::contains; //using Gtk::Widget; //using sigc::mem_fun; @@ -134,47 +135,98 @@ namespace timeline { } + namespace { + /** helper to get the width of combined slope borders. + * Upwards slopes are combined up to a certain level; + * however, the actual width of such a combined border + * is defined through a class in the CSS stylesheet. + * The TrackBody::decoration.borders array holds the + * actual values read from the CSS. + */ + inline uint + combinedSlopeHeight (uint depth) + { + if (depth==0) return 0; + depth = min (depth, TrackBody::decoration.borders.size() - 1); + return TrackBody::decoration.borders[depth]; + } + } + + /** * recursively establish the screen space allocation for this structure of nested tracks. - * The TrackProfile is an abstracted description of the sequence of track elements, - * which constitute a vertical cross section through the track bodies + * For one, we'll have to find out about the total vertical space for each track, so to + * establish the vertical starting position, which is required to place clips onto the canvas. + * + * Moreover we have to build the TrackProfile, which is an abstracted description of the sequence + * of track elements, akin to a vertical cross section through the track bodies. This profile is + * repeatedly "played back" to paint the background and overlays corresponding to each track. + * + * This function recursively processes the tree of track bodies... * - pre: the given profile is built and complete up to the (upper side) start of the current track. * - post: the profile is elaborated for this track and its children, down to the lower end. - * @todo 6/19 this very much looks like the "display evaluation pass" envisioned for the timeline::DisplayManager. - * Need to find out if we'll need a dedicated evaluation pass and how to interconnect both. + * @return total vertical extension required for this track with all its nested sub tracks. */ - void + uint TrackBody::establishTrackSpace (TrackProfile& profile) { + uint line=0; bool topLevel = isnil (profile); if (topLevel) { // global setup for the profile + line += decoration.topMar; profile.append_prelude(); // The first Profile elements are always visible on top: // Top-level rules and one additionally for the prelude profile.pinnedPrefixCnt = 1 + rulers_.size(); } + // adjust if preceded by a combined up-slope + line += combinedSlopeHeight (profile.getPrecedingSlopeUp()); + // reserve space for the overview rulers for (auto& ruler : rulers_) { - profile.append_ruler (ruler->calcHeight()); + uint rulerHeight = ruler->calcHeight(); uint gapHeight = ruler->getGapHeight(); + line += rulerHeight+gapHeight + decoration.ruler; + profile.append_ruler (rulerHeight); if (gapHeight > 0) profile.append_gap (gapHeight); } + ////////TODO: store the current line as start-offset of the content area + + // allocate space for the track content + line += this->contentHeight_ + decoration.content; profile.append_content (this->contentHeight_); + + // account for the space required by nested sub-tracks if (not isnil (subTracks_)) { + // account for a single slope one step down + line += decoration.borders[0]; // (downward slopes are never combined) profile.addSlopeDown(); + for (TrackBody* subTrack : subTracks_) - subTrack->establishTrackSpace (profile); - profile.addSlopeUp(); - } + { + ////////TODO: store the current line as start-offset for this track + line += subTrack->establishTrackSpace (profile); + } + + profile.addSlopeUp(); // note: up-slopes might be combined + } // thus we'll add them one level higher if (topLevel) - profile.append_coda (TIMELINE_BOTTOM_PADDING_px); + { + // adjust when reaching top-level after a combined up-slope + line += combinedSlopeHeight (profile.getPrecedingSlopeUp()); + + line += decoration.botMar + TIMELINE_BOTTOM_PADDING_px; + profile.append_coda (TIMELINE_BOTTOM_PADDING_px); + } + + return line; } diff --git a/src/stage/timeline/track-body.hpp b/src/stage/timeline/track-body.hpp index 23cfc3134..39eb02cc0 100644 --- a/src/stage/timeline/track-body.hpp +++ b/src/stage/timeline/track-body.hpp @@ -74,8 +74,8 @@ namespace timeline { uint topMar = 0; uint botMar = 0; - using Borders = std::array; - Borders borders{0,0,0,0,0}; + using Borders = std::array; + Borders borders{0,0,0,0,0,0}; }; @@ -110,7 +110,7 @@ namespace timeline { ~TrackBody(); void setTrackName (cuString&); - void establishTrackSpace (TrackProfile&); + uint establishTrackSpace (TrackProfile&); void attachSubTrack (TrackBody*); uint calcRulerHeight(); uint calcHeight(); diff --git a/src/stage/timeline/track-profile.hpp b/src/stage/timeline/track-profile.hpp index a88f983cc..b290941a3 100644 --- a/src/stage/timeline/track-profile.hpp +++ b/src/stage/timeline/track-profile.hpp @@ -159,6 +159,14 @@ namespace timeline { append_close (1); } + uint + getPrecedingSlopeUp() + { + if (lastEntryIs("close")) + return elements.back().accessArg(); + return 0; + } + private: bool lastEntryIs (Literal expectedToken) diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a74840427..fdccb8715 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -22866,11 +22866,11 @@ - + - - + + @@ -22880,6 +22880,10 @@ + + + + @@ -22887,8 +22891,7 @@ - - + @@ -22962,6 +22965,14 @@ + + + + + + + + @@ -23889,9 +23900,9 @@ - + - + @@ -23931,13 +23942,13 @@ - - + + - + - + @@ -23954,10 +23965,7 @@ - - - - + @@ -23974,8 +23982,13 @@ - - + + + + + + + @@ -23990,9 +24003,11 @@ - + + + - + @@ -24012,15 +24027,16 @@ - + - - - + + + + @@ -24029,20 +24045,43 @@ - - - - + + + + - - + + - + + + + + + + + + + +
    +
  • + bisher verwende ich den nur im Prolog/Coda. +
  • +
  • + könnte sinnvoll sein, um direkt benachbarte Spuren leicht voneinander abzusetzen +
  • +
  • + muß allerdings wirklich außerhalb der (inset) slopes eingebaut werden +
  • +
+ + +
-
- + +