Timeline: handle notification of structural updates
This commit is contained in:
parent
83c462abc3
commit
77805a5c8c
12 changed files with 165 additions and 26 deletions
|
|
@ -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<bool,Booh&>;`
|
||||
- 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,
|
||||
|
|
|
|||
|
|
@ -248,6 +248,9 @@ namespace timeline {
|
|||
, rulerCanvas_{makeRenderer<Grounding, RULER>(layout_,profile_), makeRenderer<Overlay, RULER>(layout_,profile_)}
|
||||
, mainCanvas_ {makeRenderer<Grounding, BODY>(layout_,profile_), makeRenderer<Overlay, BODY>(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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ namespace timeline {
|
|||
|
||||
private:/* ===== Internals ===== */
|
||||
|
||||
void slotStructureChange() noexcept;
|
||||
TrackProfile& establishTrackProfile();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@
|
|||
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
//#include <memory>
|
||||
//#include <vector>
|
||||
|
||||
|
|
@ -107,6 +109,16 @@ namespace timeline {
|
|||
/** the overall horizontal pixel span to cover by this timeline */
|
||||
virtual PixSpan getPixSpan() =0;
|
||||
|
||||
using SignalStructureChange = sigc::signal<void>;
|
||||
|
||||
/**
|
||||
* 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 ===== */
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ===== */
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -97,6 +97,12 @@ namespace timeline {
|
|||
return elements.empty();
|
||||
}
|
||||
|
||||
void
|
||||
clear() noexcept
|
||||
{
|
||||
elements.clear();
|
||||
}
|
||||
|
||||
void
|
||||
performWith (ProfileInterpreter& interpreter)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -128,10 +128,12 @@ namespace widget {
|
|||
using Entry = std::pair<Mark,Mark>;
|
||||
using TextWidget = model::FlashDeco<Gtk::TextView>;
|
||||
|
||||
using SignalErrorChanged = sigc::signal<void, bool>;
|
||||
|
||||
vector<Entry> errorMarks_;
|
||||
TextWidget textLog_;
|
||||
|
||||
sigc::signal<void, bool> errorChangedSignal_;
|
||||
SignalErrorChanged errorChangedSignal_;
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -291,7 +293,7 @@ namespace widget {
|
|||
}
|
||||
|
||||
/** signal fired when error state changes */
|
||||
sigc::signal<void,bool>
|
||||
SignalErrorChanged
|
||||
signalErrorChanged()
|
||||
{
|
||||
return errorChangedSignal_;
|
||||
|
|
|
|||
|
|
@ -18447,7 +18447,10 @@
|
|||
<node CREATED="1480124145476" ID="ID_1268974326" MODIFIED="1557498707225" TEXT="für einen ganzen Scope"/>
|
||||
<node CREATED="1480124153979" ID="ID_887707794" MODIFIED="1557498707225" TEXT="stellt fest, was gezeigt werden muß"/>
|
||||
<node CREATED="1480124174144" ID="ID_1145067443" MODIFIED="1557498707225" TEXT="synthetisiert Anzeige-Parameter (z.B: Koordinaten, Z-Ordnung)"/>
|
||||
<node CREATED="1480124235128" ID="ID_162610711" MODIFIED="1557498707225" TEXT="muß inkrementell arbeiten und bestehende Widgets anpassen"/>
|
||||
<node CREATED="1480124235128" ID="ID_162610711" MODIFIED="1561047428001" TEXT="muß inkrementell arbeiten und bestehende Widgets anpassen">
|
||||
<arrowlink COLOR="#d6677c" DESTINATION="ID_1660005887" ENDARROW="Default" ENDINCLINATION="130;-668;" ID="Arrow_ID_1942101483" STARTARROW="None" STARTINCLINATION="613;0;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -19139,9 +19142,10 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1560698483596" ID="ID_368409585" MODIFIED="1560698492402" TEXT="Infrastruktur für Status-Änderungen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1560698506599" ID="ID_1679016153" MODIFIED="1560698513827" TEXT="notwendig">
|
||||
<node COLOR="#338800" CREATED="1560698483596" ID="ID_368409585" MODIFIED="1561048727700" TEXT="Infrastruktur für Status-Änderungen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1560698506599" ID="ID_1679016153" MODIFIED="1561048713811" TEXT="notwendig">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1560698514618" ID="ID_424874311" MODIFIED="1560698517787" TEXT="Benachrichtigung">
|
||||
<node CREATED="1560698522830" ID="ID_771595987" MODIFIED="1560698534464" TEXT="initial..."/>
|
||||
<node CREATED="1560698535135" ID="ID_499624854" MODIFIED="1560698542403" TEXT="bei neuen Elementen"/>
|
||||
|
|
@ -19150,8 +19154,9 @@
|
|||
</node>
|
||||
<node CREATED="1560698518159" ID="ID_625626693" MODIFIED="1560698521434" TEXT="Aktionen"/>
|
||||
</node>
|
||||
<node CREATED="1560698568536" ID="ID_1734037059" MODIFIED="1560698572183" TEXT="Mechanismen">
|
||||
<node CREATED="1560698573838" ID="ID_546774892" MODIFIED="1560698581946" TEXT="Call-chain bauen">
|
||||
<node COLOR="#435e98" CREATED="1560698568536" ID="ID_1734037059" MODIFIED="1561048706720" TEXT="Mechanismen">
|
||||
<node CREATED="1560698573838" ID="ID_546774892" MODIFIED="1561042610462" TEXT="Call-chain bauen">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1560698613458" ID="ID_1618171484" MODIFIED="1560698618101" TEXT="direkte Parent-Links">
|
||||
<node CREATED="1560698643705" ID="ID_1904845397" MODIFIED="1560698651645" TEXT="eine Menge Aufwand"/>
|
||||
<node CREATED="1560698652882" ID="ID_314410558" MODIFIED="1560698659496" TEXT="komplex instand zu halten"/>
|
||||
|
|
@ -19160,7 +19165,7 @@
|
|||
<node CREATED="1560698618689" ID="ID_231185798" MODIFIED="1560698625444" TEXT="notification-Callbacks">
|
||||
<node CREATED="1560698764250" ID="ID_926915515" MODIFIED="1560698770146" TEXT="Publisher-Subscriber"/>
|
||||
<node CREATED="1560698668089" ID="ID_1609727906" MODIFIED="1560698674278" TEXT="ebenso problematisch"/>
|
||||
<node CREATED="1560698675226" ID="ID_1528720357" MODIFIED="1560698750879" TEXT="Signale sind aber Callbacks....">
|
||||
<node CREATED="1560698675226" ID="ID_1528720357" MODIFIED="1561042754690" TEXT="Signale sind aber Callbacks....">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -19172,28 +19177,79 @@
|
|||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#fcc76b" DESTINATION="ID_64926941" ENDARROW="Default" ENDINCLINATION="15;-34;" ID="Arrow_ID_1800480673" STARTARROW="None" STARTINCLINATION="-57;0;"/>
|
||||
<arrowlink COLOR="#fcc76b" DESTINATION="ID_64926941" ENDARROW="Default" ENDINCLINATION="24;-35;" ID="Arrow_ID_1800480673" STARTARROW="None" STARTINCLINATION="-57;0;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1560698625944" ID="ID_64926941" MODIFIED="1560698753534" TEXT="ein spezielles Signal hierfür">
|
||||
<linktarget COLOR="#fcc76b" DESTINATION="ID_64926941" ENDARROW="Default" ENDINCLINATION="15;-34;" ID="Arrow_ID_1800480673" SOURCE="ID_1528720357" STARTARROW="None" STARTINCLINATION="-57;0;"/>
|
||||
<node CREATED="1560698805704" ID="ID_1490359824" MODIFIED="1560698813328" TEXT="wer trägt es?"/>
|
||||
<node CREATED="1560698814327" ID="ID_44788176" MODIFIED="1560698819234" TEXT="wie wird es zugänglich?"/>
|
||||
<node COLOR="#435e98" CREATED="1560698625944" ID="ID_64926941" MODIFIED="1561048698955" TEXT="ein spezielles Signal hierfür">
|
||||
<linktarget COLOR="#fcc76b" DESTINATION="ID_64926941" ENDARROW="Default" ENDINCLINATION="24;-35;" ID="Arrow_ID_1800480673" SOURCE="ID_1528720357" STARTARROW="None" STARTINCLINATION="-57;0;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1560698805704" ID="ID_1490359824" MODIFIED="1561042627539" TEXT="wer trägt es?">
|
||||
<arrowlink DESTINATION="ID_1799554074" ENDARROW="Default" ENDINCLINATION="93;0;" ID="Arrow_ID_576839005" STARTARROW="None" STARTINCLINATION="169;0;"/>
|
||||
</node>
|
||||
<node CREATED="1560698814327" ID="ID_44788176" MODIFIED="1561048694418" TEXT="wie wird es zugänglich?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
per direktem Zugriff via Interface DisplayManager
|
||||
</li>
|
||||
<li>
|
||||
per Zuweisung an die einzelnen TrackBody (signal == smart-ptr!)
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1561036803347" ID="ID_281948392" MODIFIED="1561036824656" TEXT="Sigc-Signal ist ein (ref-counting) smart-ptr">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1561036911418" ID="ID_1948376179" MODIFIED="1561036913846" TEXT="Struktur">
|
||||
<node CREATED="1561036914961" ID="ID_318008470" MODIFIED="1561036944385" TEXT="der DisplayManager trägt das "Anker"-Signal">
|
||||
<node CREATED="1561036987264" ID="ID_1799554074" MODIFIED="1561037495245" TEXT="signalStructureChange"/>
|
||||
<node COLOR="#338800" CREATED="1561036911418" ID="ID_1948376179" MODIFIED="1561048719567" TEXT="Struktur">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1561036914961" ID="ID_318008470" MODIFIED="1561042586692" TEXT="der DisplayManager trägt das "Anker"-Signal">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1561036987264" ID="ID_1799554074" MODIFIED="1561042627539" TEXT="signalStructureChange">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1799554074" ENDARROW="Default" ENDINCLINATION="93;0;" ID="Arrow_ID_576839005" SOURCE="ID_1490359824" STARTARROW="None" STARTINCLINATION="169;0;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1561036945238" ID="ID_932981139" MODIFIED="1561036956895" TEXT="Nutzer kopieren es sich hiervon"/>
|
||||
<node CREATED="1561037513769" ID="ID_1240081490" MODIFIED="1561037547694" TEXT="das BodyCanvasWidget hängt daran seinen Slot">
|
||||
<node CREATED="1561037555636" ID="ID_830580579" MODIFIED="1561037559431" TEXT="slotStructureChange"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1561036945238" ID="ID_932981139" MODIFIED="1561047017981" TEXT="Nutzer kopieren es sich hiervon">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1561037513769" ID="ID_1240081490" MODIFIED="1561042582058" TEXT="das BodyCanvasWidget hängt daran seinen Slot">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1561037555636" ID="ID_830580579" MODIFIED="1561042600545" TEXT="slotStructureChange">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1561047296781" ID="ID_1660005887" MODIFIED="1561047428001" TEXT="Neuberechnung / Reihenfolge">
|
||||
<linktarget COLOR="#d6677c" DESTINATION="ID_1660005887" ENDARROW="Default" ENDINCLINATION="130;-668;" ID="Arrow_ID_1942101483" SOURCE="ID_162610711" STARTARROW="None" STARTINCLINATION="613;0;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1561047320822" ID="ID_652813348" MODIFIED="1561047325927" TEXT="Grundsätzliches">
|
||||
<node CREATED="1561047326773" ID="ID_455856045" MODIFIED="1561047353557" TEXT="wie wird die Reihenfolge der Tracks festgelegt?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1561047338983" ID="ID_608382986" MODIFIED="1561047362267" TEXT="wie werden Änderungen dieser realisiert?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1561048744043" ID="ID_1401239177" MODIFIED="1561048756692" TEXT="Konzept klären">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1561048792468" ID="ID_638394722" MODIFIED="1561048797689" TEXT="#1199 handle Timeline layout changes">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1561047369284" ID="ID_488158262" MODIFIED="1561047377394" TEXT="Implementierung">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -20890,6 +20946,9 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1541814988759" ID="ID_327310802" MODIFIED="1557498707230" TEXT="muß der TrackBody seinen Namen kennen?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1561047126901" ID="ID_376833399" MODIFIED="1561047145040" TEXT="Ordnung und Entfernen von sub-Track Bodies!!">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1541861473496" ID="ID_457526663" MODIFIED="1557498707230" TEXT="draw">
|
||||
|
|
|
|||
Loading…
Reference in a new issue