Timeline: consider to turn RulerTrack into a part of the systematic UI model

...meaing
 - it can be diff mutated
 - it is attached to the UI-Bus
 - it has persistent presentation state
This commit is contained in:
Fischlurch 2018-12-15 06:00:16 +01:00
parent 1452f1f022
commit 1cf2e459c6
8 changed files with 84 additions and 47 deletions

View file

@ -35,6 +35,7 @@ namespace stage {
const Symbol TYPE_Fork{"Fork"};
const Symbol TYPE_Clip{"Clip"};
const Symbol TYPE_Ruler{"Ruler"};
const Symbol TYPE_Marker{"Marker"};
const Symbol TYPE_Channel{"Channel"};
const Symbol TYPE_Effect{"Effect"};

View file

@ -74,6 +74,7 @@ namespace stage {
extern const Symbol TYPE_Fork;
extern const Symbol TYPE_Clip;
extern const Symbol TYPE_Ruler;
extern const Symbol TYPE_Marker;
extern const Symbol TYPE_Channel;
extern const Symbol TYPE_Effect;

View file

@ -22,10 +22,10 @@
/** @file ruler-track.cpp
** Implementation details regarding custom drawing of timeline and
** frame count ticks at the top of the TimelineCanvas.
** Implementation details regarding custom drawing of track overview
** and time code ticks and markers onto the TimelineCanvas.
**
** @todo WIP-WIP-WIP as of 12/2016
** @todo WIP-WIP-WIP as of 12/2018
**
*/
@ -76,13 +76,6 @@ namespace timeline {
}
void
RulerTrack::setTrackName (cuString& trackName)
{
TODO ("is the track name of any relevance for the TrackBody widget?");
}
/**
* recursively calculate the height in pixels to display this track,
* including all nested sub-tracks
@ -90,10 +83,7 @@ namespace timeline {
uint
RulerTrack::calcHeight()
{
uint heightSum = overviewHeight_ + contentHeight_;
for (TrackBody* subTrack : subTracks_)
heightSum += subTrack->calcHeight();
return heightSum;
UNIMPLEMENTED ("calculate display height of the overview ruler in pixels");
}

View file

@ -22,22 +22,17 @@
/** @file ruler-track.hpp
** Timeline presentation helper to organise drawing of the time overview ruler.
** Timeline presentation helper to organise drawing of the overview rulers.
** The scrollable body part of the timeline display relies on custom drawing onto
** a ["widget canvas"](\ref TimelineCanvas) for the nested track content; above
** this area we build a horizontal ruler to show the timecode and frame count
** references plus any markers, ranges and locators. Since these need to be
** aligned precisely with the content, we employ custom drawing for this
** part as well. The TimelineRuler helper -- like any parts of the coordinated
** TimelineLayout, are referred to from and used by the BodyCanvasWidget for
** offloading specific parts of the drawing routines.
** Actually, this space is just a working area and created by custom
** drawing on the [timeline canvas](\ref timeline::BodyCanvasWidget);
** yet for coordination of a globally consistent timeline layout, each
** track display is coordinated by a TrackPresenter, which corresponds
** to a session::Fork and directly controls the respective display elements
** in the [header pane](\ref timeline::HeaderPaneWidget) and the display of the
** timeline body, which is actually a canvas for custom drawing.
** this track content area we build a horizontal ruler to show the timecode or
** frame count references plus any markers, ranges and locators. In case of
** group tracks or collapsed tracks, a synopsis of the content may be rendered
** into this overview bar. Since any of these display elements need to be aligned
** precisely with the content, we employ custom drawing for the rulers as well.
** The RulerTrack -- like any parts of the coordinated TimelineLayout, will be
** referred to from and used by the BodyCanvasWidget for offloading specific
** parts of the drawing routines.
**
** @todo WIP-WIP-WIP as of 12/2018
**
@ -66,17 +61,9 @@ namespace timeline {
/**
* Helper to organise and draw the time overview ruler at the top of the
* timeline BodyCanvasWidget. Support custom drawing onto the TimelineCanvas
* to show the timecode or frame count ticks plus any markers, ranges and locators...
* TrackBody units work together with the TimelineCanvas, which arranges all
* elements placed into the tracks and performs custom drawing to mark the
* working space available for placing those elements (Clips, Effects, Markers).
* A given TrackBody works with coordinates relative to its vertical starting point;
* coordinates on the TimelineCanvas operate from top downwards. The fundamental
* task of a TrackBody is to find out about its own overall height, including the
* overall height required by all its nested children. Moreover, the height of
* the content area needs to be negotiated with the actual content elements.
* Helper to organise and draw the time or content overview ruler at the top of the
* timeline track display. The purpose is to support custom drawing onto the TimelineCanvas
* to show rendered content, timecode or frame count ticks plus any markers, ranges and locators...
* @todo WIP-WIP as of 10/2018
*/
class RulerTrack

View file

@ -41,10 +41,11 @@
#define STAGE_TIMELINE_TRACK_BODY_H
#include "stage/gtk-base.hpp"
#include "stage/timeline/ruler-track.hpp"
//#include "lib/util.hpp"
//#include <memory>
#include <memory>
#include <vector>
@ -52,6 +53,8 @@
namespace stage {
namespace timeline {
class TrackPresenter;
/**
* Helper to organise and draw the space allocated for a fork of sub-tracks.
@ -70,8 +73,12 @@ namespace timeline {
uint overviewHeight_;
uint contentHeight_;
using PRuler = std::unique_ptr<RulerTrack>;
using Rulers = std::vector<PRuler>;
using SubTracks = std::vector<TrackBody*>;
Rulers rulers_;
SubTracks subTracks_;
public:
@ -82,8 +89,26 @@ namespace timeline {
uint calcHeight();
private:/* ===== Internals ===== */
/**
* Allow the TrackPresenter to manage the rulers
* The collection of rulers is part of the systematic UI model
* and thus formally a direct child of the TrackPresenter; however they
* are only relevant for the immediate display and interaction mechanics,
* thus we store them right here, close to usage site.
* @note Ruler entries can be added and removed by diff message, but since
* the UI is performed single threaded, these mutations never interfer
* with display evaluation passes.
*/
Rulers&
bindRulers()
{
return rulers_;
}
friend class TrackPresenter;
};

View file

@ -85,9 +85,29 @@ namespace timeline {
using PFork = unique_ptr<TrackPresenter>;
using PClip = unique_ptr<ClipPresenter>;
using PMarker = unique_ptr<MarkerWidget>;
using PRuler = unique_ptr<RulerTrack>;
buffer.create (
TreeMutator::build()
.attach (collection(display_.body.bindRulers())
.isApplicableIf ([&](GenNode const& spec) -> bool
{ // »Selector« : require object-like sub scope with type-field "Ruler"
return TYPE_Ruler == spec.data.recordType();
})
.matchElement ([&](GenNode const& spec, PRuler const& elm) -> bool
{
// return spec.idi == ID{*elm}; ////////////////////////////////////////////////////////////TICKET #1193 : shall RulerTrack be a Tangible?
})
.constructFrom ([&](GenNode const& spec) -> PRuler
{
// return make_unique<RulerTrack> (spec.idi, this->uiBus_); ///////////////////////////////TICKET #1193 : how to construct a RulerTrack?
})
.buildChildMutator ([&](PRuler& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
{ ///////////////////////////////TICKET #1193 : do we even want to "mutate" a ruler?
// if (ID{*target} != subID) return false;
// target->buildMutator (buff);
// return true;
}))
.attach (collection(markers_)
.isApplicableIf ([&](GenNode const& spec) -> bool
{ // »Selector« : require object-like sub scope with type-field "Marker"

View file

@ -124,8 +124,9 @@ namespace timeline {
~TrackPresenter();
/**
* @param identity used to refer to a corresponding session::Fork in the Session
* @param id identity used to refer to a corresponding session::Fork
* @param nexus a way to connect this Controller to the UI-Bus.
* @param anchorDisplay a one-way closure to attach into the display fabric
*/
template<class FUN>
TrackPresenter (ID id, ctrl::BusTerm& nexus, FUN anchorDisplay)

View file

@ -19415,8 +19415,15 @@
<node CREATED="1544839243971" ID="ID_1000231823" MODIFIED="1544839267628" TEXT="Ausf&#xfc;hrung obliegt der Session"/>
</node>
<node CREATED="1544839283413" ID="ID_960193981" MODIFIED="1544839285469" TEXT="Bauen">
<node CREATED="1544839288936" ID="ID_43593052" MODIFIED="1544839679363" TEXT="zwei Ruler-Konfigs in das systematische UI-Modell">
<arrowlink COLOR="#5f84b0" DESTINATION="ID_1083901292" ENDARROW="Default" ENDINCLINATION="-756;-315;" ID="Arrow_ID_1167484185" STARTARROW="None" STARTINCLINATION="-381;12;"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1544849233126" ID="ID_1576984939" MODIFIED="1544849240021" TEXT="#1193 represent time and overview rulers">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1544839288936" ID="ID_43593052" MODIFIED="1544846001893" TEXT="zwei Ruler-Konfigs in das systematische UI-Modell">
<arrowlink COLOR="#5f84b0" DESTINATION="ID_1083901292" ENDARROW="Default" ENDINCLINATION="-756;-82;" ID="Arrow_ID_1167484185" STARTARROW="None" STARTINCLINATION="-592;0;"/>
<node CREATED="1544849869166" ID="ID_1025477379" MODIFIED="1544849874738" TEXT="Frage: wo ansiedeln?">
<node CREATED="1544849875744" ID="ID_27673928" MODIFIED="1544849880145" TEXT="im TrackPresenter"/>
<node CREATED="1544849880757" ID="ID_1796042436" MODIFIED="1544849886920" TEXT="direkt im TimelineBody"/>
</node>
</node>
</node>
</node>
@ -21740,13 +21747,13 @@
<node CREATED="1538956945754" ID="ID_1216887436" MODIFIED="1538956953906" TEXT="&quot;name&quot;"/>
<node CREATED="1538956717369" ID="ID_21520084" MODIFIED="1538956955642" TEXT="&quot;fork&quot; = Track"/>
<node CREATED="1538956709026" ID="ID_326010297" MODIFIED="1538956792235" TEXT="Sequence{Marker}"/>
<node CREATED="1544839585279" ID="ID_1083901292" MODIFIED="1544840347800" TEXT="Sequence{Ruler}">
<linktarget COLOR="#5f84b0" DESTINATION="ID_1083901292" ENDARROW="Default" ENDINCLINATION="-756;-315;" ID="Arrow_ID_1167484185" SOURCE="ID_43593052" STARTARROW="None" STARTINCLINATION="-381;12;"/>
</node>
</node>
<node CREATED="1538956769298" ID="ID_1319425167" MODIFIED="1538956771477" TEXT="Track">
<node CREATED="1538956775249" ID="ID_1811758034" MODIFIED="1538956789843" TEXT="Sequence{Track}">
<node CREATED="1538957049292" ID="ID_1618683787" MODIFIED="1538957055215" TEXT="if typeID = &quot;Fork&quot;"/>
<node CREATED="1544846114433" ID="ID_1306886572" MODIFIED="1544846122141" TEXT="die Sub-Tracks">
<icon BUILTIN="info"/>
</node>
</node>
<node CREATED="1538956796214" ID="ID_337674261" MODIFIED="1538956801905" TEXT="Sequence{Clip}">
<node CREATED="1538957049292" ID="ID_100537539" MODIFIED="1538957063726" TEXT="if typeID = &quot;Clip&quot;"/>
@ -21754,6 +21761,11 @@
<node CREATED="1538956802701" ID="ID_840384156" MODIFIED="1538956809576" TEXT="Sequence{Marker}">
<node CREATED="1538957049292" ID="ID_1955645432" MODIFIED="1538957077700" TEXT="if typeID = &quot;Marker&quot;"/>
</node>
<node CREATED="1544839585279" ID="ID_1083901292" MODIFIED="1544846001893" TEXT="Sequence{Ruler}">
<linktarget COLOR="#5f84b0" DESTINATION="ID_1083901292" ENDARROW="Default" ENDINCLINATION="-756;-82;" ID="Arrow_ID_1167484185" SOURCE="ID_43593052" STARTARROW="None" STARTINCLINATION="-592;0;"/>
<node CREATED="1544846037083" ID="ID_667362504" MODIFIED="1544846061300" TEXT="if typeID = &quot;Ruler&quot;"/>
<node CREATED="1544846062288" ID="ID_855083299" MODIFIED="1544846101674" TEXT="storage direkt (nested) im TrackBody"/>
</node>
</node>
<node CREATED="1538956769298" ID="ID_721666986" MODIFIED="1538957197892" TEXT="Clip">
<node CREATED="1538956775249" ID="ID_1108737612" MODIFIED="1538957210090" TEXT="Sequence{Channel}">