From 77805a5c8cf23a2e9c19ffda7f94e2abe90b41b4 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 20 Jun 2019 18:40:36 +0200 Subject: [PATCH] Timeline: handle notification of structural updates --- doc/technical/stage/CodePolicy.txt | 24 ++++++ src/stage/timeline/body-canvas-widget.cpp | 11 +++ src/stage/timeline/body-canvas-widget.hpp | 1 + src/stage/timeline/display-manager.hpp | 12 +++ src/stage/timeline/timeline-layout.cpp | 5 ++ src/stage/timeline/track-body.cpp | 16 +++- src/stage/timeline/track-body.hpp | 6 +- src/stage/timeline/track-presenter.cpp | 5 +- src/stage/timeline/track-presenter.hpp | 4 +- src/stage/timeline/track-profile.hpp | 6 ++ src/stage/widget/error-log-display.hpp | 6 +- wiki/thinkPad.ichthyo.mm | 95 ++++++++++++++++++----- 12 files changed, 165 insertions(+), 26 deletions(-) diff --git a/doc/technical/stage/CodePolicy.txt b/doc/technical/stage/CodePolicy.txt index ec68e1e2c..1c0b664a2 100644 --- a/doc/technical/stage/CodePolicy.txt +++ b/doc/technical/stage/CodePolicy.txt @@ -67,6 +67,30 @@ in response to a (population) diff message. to be properly detached from signals. We want to ensure this happens as soon as the child is taken out of service. Do not use an ``can collect garbage later'' approach.] +Signals +~~~~~~~ +Basically, Signals are just typed callback functors. However, the *Sigc\++* library +helps to deal with the inherent danger of _dangling references,_ and it allows to +manage and disconnect signal attachments. Thus, whenever cross wiring beyond the +given model structure can be expected within the UI, usage of `sigc::signal<..>` +should be preferred. + +NOTE: by itself, `sigc::signal` is a lightweight ref-counting smart-pointer. + +.Conventions +- the names of signals are prefixed by the word `signal`. +- whenever a signal is used over several widgets and components, + there should be a _typedef_ for the signal type, + e.g. `using SignalBarf = sigc::signal;` +- it is perfectly fine for a signal to be just a public member of some component, + especially when the sole purpose of that signal is for someone else to connect + or invoke it. However, when a signal is meant to be an internal implementation + detail, then better make it private, optinally exposing it via accessor function. +- a function intended to be connected to a signal is termed as ``Slot'', and its + name should be prefixed by the word `slot`, e.g. `bool slotBarf (Booh& moo);` +- such a slot function should be `noexcept` + + Error handling ~~~~~~~~~~~~~~ Be aware that GTK is written in C. And while GTKmm has some safeguards in place, diff --git a/src/stage/timeline/body-canvas-widget.cpp b/src/stage/timeline/body-canvas-widget.cpp index 7a1f7632e..6f4171f11 100644 --- a/src/stage/timeline/body-canvas-widget.cpp +++ b/src/stage/timeline/body-canvas-widget.cpp @@ -248,6 +248,9 @@ namespace timeline { , rulerCanvas_{makeRenderer(layout_,profile_), makeRenderer(layout_,profile_)} , mainCanvas_ {makeRenderer(layout_,profile_), makeRenderer(layout_,profile_)} { + // respond to any structure changes of the timeline by recomputing the TrackProfile + layout_.signalStructureChange_.connect (sigc::mem_fun (*this, &BodyCanvasWidget::slotStructureChange)); + this->set_border_width (0); this->property_expand() = true; // dynamically grab any available additional space this->pack_start (rulerCanvas_); @@ -286,6 +289,14 @@ namespace timeline { } + /** force rebuilding of theTrackProfile whenever the global timeline structure changes */ + void + BodyCanvasWidget::slotStructureChange() noexcept + { + profile_.clear(); + } + + /** * */ diff --git a/src/stage/timeline/body-canvas-widget.hpp b/src/stage/timeline/body-canvas-widget.hpp index 74c995ef6..f60e52042 100644 --- a/src/stage/timeline/body-canvas-widget.hpp +++ b/src/stage/timeline/body-canvas-widget.hpp @@ -130,6 +130,7 @@ namespace timeline { private:/* ===== Internals ===== */ + void slotStructureChange() noexcept; TrackProfile& establishTrackProfile(); }; diff --git a/src/stage/timeline/display-manager.hpp b/src/stage/timeline/display-manager.hpp index 8dee060fd..b33c77d12 100644 --- a/src/stage/timeline/display-manager.hpp +++ b/src/stage/timeline/display-manager.hpp @@ -60,6 +60,8 @@ #include "lib/util.hpp" +#include + //#include //#include @@ -107,6 +109,16 @@ namespace timeline { /** the overall horizontal pixel span to cover by this timeline */ virtual PixSpan getPixSpan() =0; + using SignalStructureChange = sigc::signal; + + /** + * signal to be invoked whenever the virtual structure of the + * corresponding timeline changes, thus necessitating a new + * arrangement of the timeline layout. + */ + SignalStructureChange signalStructureChange_; + + private:/* ===== Internals ===== */ }; diff --git a/src/stage/timeline/timeline-layout.cpp b/src/stage/timeline/timeline-layout.cpp index 58313b288..0cd3669fb 100644 --- a/src/stage/timeline/timeline-layout.cpp +++ b/src/stage/timeline/timeline-layout.cpp @@ -32,6 +32,7 @@ #include "stage/gtk-base.hpp" #include "stage/timeline/timeline-layout.hpp" +#include "stage/timeline/track-body.hpp" //#include "stage/ui-bus.hpp" //#include "lib/format-string.hpp" @@ -84,6 +85,10 @@ namespace timeline { { headerPane_.installForkRoot (head); bodyCanvas_.installForkRoot (body); + + // detect changes of the track structure + body.signalStructureChange_ = signalStructureChange_; + signalStructureChange_(); // this _is_ such a change } diff --git a/src/stage/timeline/track-body.cpp b/src/stage/timeline/track-body.cpp index 0034c78d8..aefdead09 100644 --- a/src/stage/timeline/track-body.cpp +++ b/src/stage/timeline/track-body.cpp @@ -73,8 +73,8 @@ namespace timeline { TrackBody::~TrackBody() - { - TODO ("detach from parent; store a functor or backreference"); + { // indicate change of the global track structure + signalStructureChange_(); } @@ -85,6 +85,18 @@ namespace timeline { } + void + TrackBody::attachSubTrack (TrackBody* subBody) + { + REQUIRE (subBody); + subTracks_.push_back (subBody); /////////////////////////////////////////////////////TICKET #1199 : this can not possibly work; we need a way to retain the order of tracks, and we need to detach tracks... + + // detect changes of the track structure + subBody->signalStructureChange_ = signalStructureChange_; + signalStructureChange_(); // this _is_ such a change + } + + /** * recursively calculate the height in pixels to display this track, * including all nested sub-tracks diff --git a/src/stage/timeline/track-body.hpp b/src/stage/timeline/track-body.hpp index c503563f9..0345218c7 100644 --- a/src/stage/timeline/track-body.hpp +++ b/src/stage/timeline/track-body.hpp @@ -42,6 +42,7 @@ #include "stage/gtk-base.hpp" #include "stage/timeline/ruler-track.hpp" +#include "stage/timeline/timeline-layout.hpp" //#include "lib/util.hpp" @@ -86,10 +87,11 @@ namespace timeline { ~TrackBody(); void setTrackName (cuString&); - + void establishTrackSpace (TrackProfile&); + void attachSubTrack (TrackBody*); uint calcHeight(); - void establishTrackSpace (TrackProfile&); + DisplayManager::SignalStructureChange signalStructureChange_; private:/* ===== Internals ===== */ diff --git a/src/stage/timeline/track-presenter.cpp b/src/stage/timeline/track-presenter.cpp index 47c807fa6..5b6a4859f 100644 --- a/src/stage/timeline/track-presenter.cpp +++ b/src/stage/timeline/track-presenter.cpp @@ -70,7 +70,10 @@ namespace timeline { - TrackPresenter::~TrackPresenter() { } + TrackPresenter::~TrackPresenter() + { + TODO ("find a way how to detach from parent tracks"); ////////////////////////////////////////////TICKET #1199 : how to deal with re-ordering of tracks? + } diff --git a/src/stage/timeline/track-presenter.hpp b/src/stage/timeline/track-presenter.hpp index fa12b241c..1581fb470 100644 --- a/src/stage/timeline/track-presenter.hpp +++ b/src/stage/timeline/track-presenter.hpp @@ -92,6 +92,7 @@ namespace timeline { ~DisplayFrame() { + // Note: ~TrackBody triggers DisplayManager::signalStructureChange_() TODO ("cause the managed presentation elements to detach from their parents"); } ///////////////////////////////////TICKET #1198 -- clarify to what extent esp. the header widgets need to be actively removed from the display structure. Is it sufficient just to kill the TrackHeadWidget @@ -103,8 +104,9 @@ namespace timeline { } void - injectSubTrack (TrackHeadWidget& head, TrackBody& body) + injectSubTrack (TrackHeadWidget& subHead, TrackBody& subBody) { + body.attachSubTrack (&subBody); UNIMPLEMENTED ("inject the widgets to represent a nested sub-track within this timeline track display frame"); } }; diff --git a/src/stage/timeline/track-profile.hpp b/src/stage/timeline/track-profile.hpp index 17aa026d2..d44c2fb55 100644 --- a/src/stage/timeline/track-profile.hpp +++ b/src/stage/timeline/track-profile.hpp @@ -97,6 +97,12 @@ namespace timeline { return elements.empty(); } + void + clear() noexcept + { + elements.clear(); + } + void performWith (ProfileInterpreter& interpreter) { diff --git a/src/stage/widget/error-log-display.hpp b/src/stage/widget/error-log-display.hpp index e5af57edb..2e7f71115 100644 --- a/src/stage/widget/error-log-display.hpp +++ b/src/stage/widget/error-log-display.hpp @@ -128,10 +128,12 @@ namespace widget { using Entry = std::pair; using TextWidget = model::FlashDeco; + using SignalErrorChanged = sigc::signal; + vector errorMarks_; TextWidget textLog_; - sigc::signal errorChangedSignal_; + SignalErrorChanged errorChangedSignal_; public: @@ -291,7 +293,7 @@ namespace widget { } /** signal fired when error state changes */ - sigc::signal + SignalErrorChanged signalErrorChanged() { return errorChangedSignal_; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 2972e86db..c024d2bc1 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -18447,7 +18447,10 @@ - + + + + @@ -19139,9 +19142,10 @@ - - - + + + + @@ -19150,8 +19154,9 @@ - - + + + @@ -19160,7 +19165,7 @@ - + @@ -19172,28 +19177,79 @@ - + - - - - + + + + + + + + + + + + +
    +
  • + per direktem Zugriff via Interface DisplayManager +
  • +
  • + per Zuweisung an die einzelnen TrackBody (signal == smart-ptr!) +
  • +
+ + +
+
- - - + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -20890,6 +20946,9 @@ + + +