diff --git a/src/stage/timeline/clip-presenter.cpp b/src/stage/timeline/clip-presenter.cpp index 5770b3e2e..266eb4e3c 100644 --- a/src/stage/timeline/clip-presenter.cpp +++ b/src/stage/timeline/clip-presenter.cpp @@ -130,6 +130,16 @@ namespace timeline { ,getClipContentCanvas() ,std::nullopt); /////////////////////////TICKET #1213 : time → horizontal extension : how to represent "always" / "the whole track"?? })) + .change(ATTR_name, [&](string val) + { // »Attribute Setter« : receive a new value for the clip name field + REQUIRE (widget_); + widget_->setClipName (val); + }) + .change(ATTR_timing, [&](TimeSpan val) + { + REQUIRE (widget_); + widget_->changeTiming (val); + }) //-Diff-Change-Listener---------------- .onLocalChange ([this]() { @@ -154,7 +164,9 @@ namespace timeline { int ClipPresenter::determineRequiredVerticalExtension() const { - UNIMPLEMENTED ("any details regarding clip presentation"); + REQUIRE (widget_); + return widget_->calcRequiredHeight() + + widget_->getVerticalOffset(); } diff --git a/src/stage/timeline/clip-widget.cpp b/src/stage/timeline/clip-widget.cpp index 6592634ba..ef0dbc8a6 100644 --- a/src/stage/timeline/clip-widget.cpp +++ b/src/stage/timeline/clip-widget.cpp @@ -106,6 +106,7 @@ //using Gtk::Widget; //using sigc::mem_fun; //using sigc::ptr_fun; +using lib::time::TimeVar; using util::unConst; //using std::cout; //using std::endl; @@ -149,6 +150,9 @@ namespace timeline { , util::NonCopyable { WidgetHook& display_; + uString clipName_; + TimeVar start_; /////////////////////////////////////////////////////////////////TICKET #1038 : how to handle storage of timings?? + TimeVar len_; /* === Interface ClipDelegate === */ @@ -167,15 +171,51 @@ namespace timeline { cuString getClipName() const override { - return "lala LOLO"; ///////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store the clip name/ID + return clipName_; ///////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store the clip name/ID } + void + setClipName(cuString newName) override + { + clipName_ = newName; + } + + Time getStartTime() const override { - return Time::NEVER; ///////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store the clip start time + return start_; ////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store the clip start time } - + + Duration + getLen() const override + { + return Duration{this->len_}; + } + + void + changeTiming (TimeSpan changedTimings) override + { + this->start_ = changedTimings.start(); + this->len_ = changedTimings.duration(); + } + + /** + * This is a mere data record without actual presentation, + * and thus can not occupy any screen extension. + */ + uint + calcRequiredHeight() const override + { + return 0; + } + + uint + getVerticalOffset() const override + { + return 0; + } + WidgetHook& getCanvas() const override { @@ -187,12 +227,18 @@ namespace timeline { ClipData(WidgetHook& displayAnchor) : ClipDelegate{} , display_{displayAnchor} + , clipName_{"?name?"} + , start_{Time::NEVER} + , len_{Duration::NIL} { } /** state switch ctor */ ClipData(ClipDelegate& existing) : ClipDelegate{} , display_{existing.getCanvas()} + , clipName_{existing.getClipName()} + , start_{existing.getStartTime()} + , len_{existing.getLen()} { TODO("copy further clip presentation properties"); } @@ -203,6 +249,9 @@ namespace timeline { : public HookedWidget , public ClipDelegate { + TimeVar start_; /////////////////////////////////////////////////////////////////TICKET #1038 : how to handle storage of timings?? + TimeVar len_; + /* === Interface ClipDelegate === */ Appearance @@ -225,10 +274,41 @@ namespace timeline { return this->get_label(); } + void + setClipName(cuString newName) override + { + this->set_label (newName); + } + + void + changeTiming (TimeSpan changedTimings) override + { + this->start_ = changedTimings.start(); + this->len_ = changedTimings.duration(); + } + Time getStartTime() const override { - return Time::NEVER; ///////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store the clip start time + return this->start_; ///////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store the clip start time + } + + Duration + getLen() const override + { + return Duration{this->len_}; + } + + uint + getVerticalOffset() const override + { + return defaultOffsetY; ///////////////////////////////////////////////////////////////TICKET #1038 : data storage; here : store a per clip vertical offset + } + + uint + calcRequiredHeight() const override + { + return this->get_height(); //////////////////////////////////////////////////////////TICKET #1038 : for the first draft we just use a Button; TODO: actual calculation here } WidgetHook& @@ -239,17 +319,24 @@ namespace timeline { public: - ClipWidget(WidgetHook::Pos hookPoint, Duration dur, uString clipName) + ClipWidget(WidgetHook::Pos hookPoint, Duration dur, uString clipName) /////////////////////TICKET #1038 : it's probably wrong only to pass-in the duration, beacuse we also need to retain the start point in full precision : HookedWidget{hookPoint, clipName} , ClipDelegate{} - { } + , start_{Time::NEVER} + , len_{dur} + { + show_all(); + } /** state switch ctor */ ClipWidget(ClipDelegate& existing, WidgetHook* newView) : HookedWidget{existing.establishHookPoint(newView), existing.getClipName()} , ClipDelegate{} + , start_{existing.getStartTime()} + , len_{existing.getLen()} { TODO("copy further clip presentation properties"); + show_all(); } }; diff --git a/src/stage/timeline/clip-widget.hpp b/src/stage/timeline/clip-widget.hpp index 159d3e62c..04b0deb59 100644 --- a/src/stage/timeline/clip-widget.hpp +++ b/src/stage/timeline/clip-widget.hpp @@ -177,10 +177,17 @@ namespace timeline { /** human readable rendering of the clip's name or identity */ virtual cuString getClipName() const =0; + virtual void setClipName (cuString) =0; - virtual Time getStartTime() const =0; + virtual void changeTiming (TimeSpan) =0; + virtual Time getStartTime() const =0; + virtual Duration getLen() const =0; + + virtual uint getVerticalOffset() const =0; virtual WidgetHook& getCanvas() const =0; + + virtual uint calcRequiredHeight() const =0; /** (re)establish current canvas attachment coordinates, * thereby possibly switching to a new canvas implementation diff --git a/src/stage/timeline/display-evaluation.hpp b/src/stage/timeline/display-evaluation.hpp index 9d0fd1a14..78cdb7496 100644 --- a/src/stage/timeline/display-evaluation.hpp +++ b/src/stage/timeline/display-evaluation.hpp @@ -32,7 +32,7 @@ ** pass; typically additional space requirements are discovered and propagated _as message_ to GTK, ** and so the DisplayEvaluation can be expected to be re-triggered soon thereafter. ** - ** # Tasks to perform + ** # Specification ** ** The basic goal is to establish a coherent vertical space allocation for all tracks within the ** timeline (while, to the contrary, the horizontal extension is a fixed requirement and can be @@ -41,7 +41,7 @@ ** - buildup of a timeline::TrackProfile to accommodate those requirements and all decorations ** - adjustment of the TrackHeadWidget extensions to match the allocated track body space precisely. ** - ** # Evaluation structure + ** ## Evaluation structure ** ** This is an intricate collaboration of closely related elements; however, each of the aforementioned ** tasks is defined such as to operate in a self-confined way on some part of the timeline. All the @@ -49,9 +49,9 @@ ** to pass on the DisplayEvaluation itself by reference, recursively. To make the overall process work, ** moreover we establish a *Requirement* to pass on this invocation _strictly in layout order_ -- which ** implies a recursive depth-first invocation proceeding *top-down* and *from left to right*. It is - ** each LayoutElement's liability to recurse appropriately to make this happen. + ** each LayoutElement's liability to recurse appropriately in order to make this happen. ** - ** # Evaluation state and phases + ** ## Evaluation state and phases ** ** The DisplayEvaluation works by direct (side)effect within the invoked elements, eventually leading ** to some of the embedded GTK widgets being resized -- which typically will re-trigger our custom drawing diff --git a/src/stage/timeline/track-body.cpp b/src/stage/timeline/track-body.cpp index c4d030ebc..77dec56ff 100644 --- a/src/stage/timeline/track-body.cpp +++ b/src/stage/timeline/track-body.cpp @@ -121,6 +121,17 @@ namespace timeline { /* ==== Code for vertical track display layout ==== */ + + /** + * ensure content with the given extension can be accommodated + * within this track's content area + */ + void + TrackBody::accomodateHeight(uint contentExtension) + { + if (contentExtension > contentHeight_) + contentHeight_ = contentExtension; + } /** * recursively calculate the height in pixels to display this track, @@ -218,7 +229,7 @@ namespace timeline { // we render this prefix part on a separate drawing canvas, profile.markPrefixEnd(); // ...and now we switch to the second, scrollable canvas, - // which thus needs to use adjusted coordinates for widgets. + // which uses its own local coordinates, thus restart Y-pos. line = 0; } // mark offset of the actual content area relative to this track's top diff --git a/src/stage/timeline/track-body.hpp b/src/stage/timeline/track-body.hpp index 864f66d0a..41f6917ce 100644 --- a/src/stage/timeline/track-body.hpp +++ b/src/stage/timeline/track-body.hpp @@ -118,6 +118,7 @@ namespace timeline { uint establishTrackSpace (TrackProfile&); uint calcRulerHeight(); uint calcHeight(); + void accomodateHeight(uint contentExtension); uint getContentOffsetY() { return startLine_ + contentOffset_; } diff --git a/src/stage/timeline/track-presenter.hpp b/src/stage/timeline/track-presenter.hpp index dca598972..d419e18b2 100644 --- a/src/stage/timeline/track-presenter.hpp +++ b/src/stage/timeline/track-presenter.hpp @@ -330,6 +330,8 @@ namespace timeline { { return clip->determineRequiredVerticalExtension(); })); + this->body_.accomodateHeight(maxVSize); + //////////////////////////////////////////////////////////////////////////////////////////TICKET #1211 : actually implement a coordination of head / body sizes here int headSize = this->head_.get_height(); int bodySize = this->body_.calcHeight(); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index c886939d8..c3aec128a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -21300,7 +21300,7 @@ - + @@ -21755,9 +21755,21 @@ - + + + + + + + + + + + + + @@ -21771,6 +21783,9 @@ + + + @@ -27975,13 +27990,16 @@ - + + + + @@ -28589,6 +28607,7 @@ + @@ -28604,24 +28623,27 @@ - - - - - - -

- UNIMPLEMENTED: clip-presenter.cpp:157: worker_3: determineRequiredVerticalExtension: any details regarding clip presentation -

- -
- + + + + + +
+ + + + + + + + +