Timeline: make TrackPresenter header-only
...there is no need for yet another indirection here, since TrackPresenter is not much of an interface and only included at into two other translation units. Moreover, header-only code simplifies the use of templated lambdas, which come in handy when dealing with the various nested sub-collections.
This commit is contained in:
parent
5ddf426add
commit
8d87029fd5
2 changed files with 171 additions and 215 deletions
|
|
@ -1,212 +0,0 @@
|
||||||
/*
|
|
||||||
TrackPresenter - presentation control element for a track within the timeline
|
|
||||||
|
|
||||||
Copyright (C) Lumiera.org
|
|
||||||
2016, Hermann Vosseler <Ichthyostega@web.de>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
* *****************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/** @file track-presenter.cpp
|
|
||||||
** Implementation details of track presentation management.
|
|
||||||
** Especially here we define the model binding of all sub-elements belonging
|
|
||||||
** to a given track. The TrackPresenter::buildMutator() implementation hooks up
|
|
||||||
** the necessary callbacks, to allow adding and removing of sub elements and properties
|
|
||||||
** of a track, by sending appropriate _mutation messages_ over the stage::UiBus.
|
|
||||||
**
|
|
||||||
** @todo WIP-WIP-WIP as of 12/2016
|
|
||||||
** @todo as of 10/2018 timeline display in the UI is rebuilt to match the architecture
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "stage/gtk-base.hpp"
|
|
||||||
#include "include/ui-protocol.hpp"
|
|
||||||
#include "stage/timeline/track-presenter.hpp"
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
|
||||||
#include "lib/format-cout.hpp"
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
|
||||||
|
|
||||||
//#include "stage/ui-bus.hpp"
|
|
||||||
//#include "lib/format-string.hpp"
|
|
||||||
//#include "lib/format-cout.hpp"
|
|
||||||
|
|
||||||
//#include "lib/util.hpp"
|
|
||||||
|
|
||||||
//#include <algorithm>
|
|
||||||
//#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//using util::_Fmt;
|
|
||||||
using lib::diff::TreeMutator;
|
|
||||||
using lib::diff::collection;
|
|
||||||
using std::make_unique;
|
|
||||||
//using util::contains;
|
|
||||||
//using Gtk::Widget;
|
|
||||||
//using sigc::mem_fun;
|
|
||||||
//using sigc::ptr_fun;
|
|
||||||
//using std::cout;
|
|
||||||
//using std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
namespace stage {
|
|
||||||
namespace timeline {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TrackPresenter::~TrackPresenter()
|
|
||||||
{
|
|
||||||
TODO ("find a way how to detach from parent tracks"); ////////////////////////////////////////////TICKET #1199 : how to deal with re-ordering of tracks?
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
|
||||||
void
|
|
||||||
TrackPresenter::injectDebugTrackLabels()
|
|
||||||
{
|
|
||||||
uint x = rand() % 50;
|
|
||||||
uint y = 0;
|
|
||||||
Gtk::Button* butt = Gtk::manage (new ViewHooked<Gtk::Button, Gtk::Widget>{display_.hookedAt(x,y), TODO_trackName_});
|
|
||||||
butt->signal_clicked().connect(
|
|
||||||
[butt]{ cout << "|=="<<butt->get_label()<<endl; });
|
|
||||||
butt->show();
|
|
||||||
|
|
||||||
for (auto& subTrack : subFork_)
|
|
||||||
subTrack->injectDebugTrackLabels();
|
|
||||||
}
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
|
||||||
/**
|
|
||||||
* @note we distinguish between the contents of our four nested child collections
|
|
||||||
* based on the symbolic type field sent in the Record type within the diff representation
|
|
||||||
* - "Marker" designates a Marker object
|
|
||||||
* - "Clip" designates a Clip placed on this track
|
|
||||||
* - "Fork" designates a nested sub-track
|
|
||||||
* - "Ruler" designates a nested ruler (timescale, overview,....) belonging to this track
|
|
||||||
* @see TimelineController::buildMutator() for a basic explanation of the data binding mechanism
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
TrackPresenter::buildMutator (TreeMutator::Handle buffer)
|
|
||||||
{
|
|
||||||
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_.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 == elm->getID();
|
|
||||||
})
|
|
||||||
.constructFrom ([&](GenNode const& spec) -> PRuler
|
|
||||||
{ // »Constructor« : how to attach a new ruler track
|
|
||||||
return make_unique<RulerTrack> (spec.idi, this->uiBus_, *this);
|
|
||||||
})
|
|
||||||
.buildChildMutator ([&](PRuler& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
|
||||||
{
|
|
||||||
if (subID != target->getID()) 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"
|
|
||||||
return TYPE_Marker == spec.data.recordType();
|
|
||||||
})
|
|
||||||
.matchElement ([&](GenNode const& spec, PMarker const& elm) -> bool
|
|
||||||
{
|
|
||||||
return spec.idi == elm->getID();
|
|
||||||
})
|
|
||||||
.constructFrom ([&](GenNode const& spec) -> PMarker
|
|
||||||
{
|
|
||||||
return make_unique<MarkerWidget> (spec.idi, this->uiBus_);
|
|
||||||
})
|
|
||||||
.buildChildMutator ([&](PMarker& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
|
||||||
{
|
|
||||||
if (subID != target->getID()) return false;
|
|
||||||
target->buildMutator (buff);
|
|
||||||
return true;
|
|
||||||
}))
|
|
||||||
.attach (collection(clips_)
|
|
||||||
.isApplicableIf ([&](GenNode const& spec) -> bool
|
|
||||||
{ // »Selector« : require object-like sub scope with type-field "Clip"
|
|
||||||
return TYPE_Clip == spec.data.recordType();
|
|
||||||
})
|
|
||||||
.matchElement ([&](GenNode const& spec, PClip const& elm) -> bool
|
|
||||||
{
|
|
||||||
return spec.idi == elm->getID();
|
|
||||||
})
|
|
||||||
.constructFrom ([&](GenNode const& spec) -> PClip
|
|
||||||
{
|
|
||||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_);
|
|
||||||
})
|
|
||||||
.buildChildMutator ([&](PClip& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
|
||||||
{
|
|
||||||
if (subID != target->getID()) return false;
|
|
||||||
target->buildMutator (buff);
|
|
||||||
return true;
|
|
||||||
}))
|
|
||||||
.attach (collection(subFork_)
|
|
||||||
.isApplicableIf ([&](GenNode const& spec) -> bool
|
|
||||||
{ // »Selector« : require object-like sub scope with type-field "Fork"
|
|
||||||
return TYPE_Fork == spec.data.recordType();
|
|
||||||
})
|
|
||||||
.matchElement ([&](GenNode const& spec, PFork const& elm) -> bool
|
|
||||||
{
|
|
||||||
return spec.idi == elm->getID();
|
|
||||||
})
|
|
||||||
.constructFrom ([&](GenNode const& spec) -> PFork
|
|
||||||
{
|
|
||||||
return make_unique<TrackPresenter> (spec.idi, uiBus_, this->display_);
|
|
||||||
})
|
|
||||||
.buildChildMutator ([&](PFork& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
|
||||||
{
|
|
||||||
if (subID != target->getID()) return false;
|
|
||||||
target->buildMutator (buff);
|
|
||||||
return true;
|
|
||||||
}))
|
|
||||||
.change(ATTR_name, [&](string val)
|
|
||||||
{ // »Attribute Setter« : receive a new value for the track name field
|
|
||||||
this->setTrackName (val);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** @todo 2/2020 */
|
|
||||||
void
|
|
||||||
TrackPresenter::establishLayout (DisplayEvaluation& displayEvaluation)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED ("respond to the DisplayEvaluation-Pass and pass on evaluation recursively");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}// namespace stage::timeline
|
|
||||||
|
|
@ -38,8 +38,43 @@
|
||||||
** represent potentially several thousand individual elements as GTK entities, while at any time
|
** represent potentially several thousand individual elements as GTK entities, while at any time
|
||||||
** only a small number of elements can be visible and active as far as user interaction is concerned.
|
** only a small number of elements can be visible and active as far as user interaction is concerned.
|
||||||
**
|
**
|
||||||
** @todo WIP-WIP-WIP as of 12/2016
|
** # Structure of the TrackPresenter
|
||||||
|
**
|
||||||
|
** Each TrackPresenter corresponds to a "sub-Fork" of timeline tracks. Since Lumiera always arranges
|
||||||
|
** tracks as nested scopes into a tree, there is one root fork, recursively holding several sub forks.
|
||||||
|
** - thus each TrackPresenter holds a collection #subFor_ -- possibly empty.
|
||||||
|
** - moreover, it holds a collection #clips_, which represent the actual content of this track itself,
|
||||||
|
** as opposed to content on some sub-track. These clips are to be arranged within the _content area_
|
||||||
|
** of the track display, in the track body area (at the right side of the timeline). Actually, this
|
||||||
|
** collection holds timeline::ClipPresenter objects, thus repeating the same design pattern.
|
||||||
|
** - in addition, there can be a collection of #markers_, to be translated into various kinds of
|
||||||
|
** region or point/location markup, typically shown in the (optional) _overview ruler,_ running
|
||||||
|
** along the top-side of this track's display area.
|
||||||
|
**
|
||||||
|
** Since TrackPresenter is a model::Tangible, a central concern is the ability to respond to
|
||||||
|
** _diff messages._ In fact, any actual content, including all the nested sub-structures, is
|
||||||
|
** _populated_ through such _mutation messages_ sent from the session up via the stage::UiBus.
|
||||||
|
** Thus, the TrackPresenter::buildMutator() implementation hooks up the necessary callbacks,
|
||||||
|
** to allow adding and removing of sub elements and properties of a track.
|
||||||
|
**
|
||||||
|
** Another concern handled here is the coordination of layout and display activities.
|
||||||
|
** A special twist arises here: The track header ("patchbay") display can be designed as a
|
||||||
|
** classical tree / grid control, while the actual timeline body contents require us to perform
|
||||||
|
** custom drawing activities. Which leads to the necessity to coordinate and connect two distinct
|
||||||
|
** presentation schemes to form a coherent layout. We solve this challenge by introducing a helper
|
||||||
|
** entity, the DisplayFrame. These act as a bridge to hook into both display hierarchies (the nested
|
||||||
|
** TrackHeaderWidget and the TrackBody record managed by the BodyCanvasWidget). Display frames are
|
||||||
|
** hooked down from their respective parent frame, thereby creating a properly interwoven fabric.
|
||||||
|
**
|
||||||
|
** After assembling the necessary GTK widgets, typically our custom drawing code will be invoked
|
||||||
|
** at some point, thereby triggering BodyCanvasWidget::maybeRebuildLayout(). At this point the
|
||||||
|
** timeline::TrackProfile needs to be established, so to reflect the succession and extension
|
||||||
|
** of actual track spaces running alongside the time axis. This is accomplished through a global
|
||||||
|
** timeline::DisplayEvaluation pass, recursively visiting all the involved parts to perform
|
||||||
|
** size adjustments, until the layout is globally balanced.
|
||||||
|
**
|
||||||
** @todo as of 10/2018 timeline display in the UI is rebuilt to match the architecture
|
** @todo as of 10/2018 timeline display in the UI is rebuilt to match the architecture
|
||||||
|
** @todo still WIP as of 3/2020 -- yet the basic structure is settled by now.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -48,12 +83,16 @@
|
||||||
#define STAGE_TIMELINE_TRACK_PRESENTER_H
|
#define STAGE_TIMELINE_TRACK_PRESENTER_H
|
||||||
|
|
||||||
#include "stage/gtk-base.hpp"
|
#include "stage/gtk-base.hpp"
|
||||||
|
#include "include/ui-protocol.hpp"
|
||||||
#include "stage/model/controller.hpp"
|
#include "stage/model/controller.hpp"
|
||||||
#include "stage/timeline/display-evaluation.hpp"
|
#include "stage/timeline/display-evaluation.hpp"
|
||||||
#include "stage/timeline/marker-widget.hpp"
|
#include "stage/timeline/marker-widget.hpp"
|
||||||
#include "stage/timeline/clip-presenter.hpp"
|
#include "stage/timeline/clip-presenter.hpp"
|
||||||
#include "stage/timeline/track-head-widget.hpp"
|
#include "stage/timeline/track-head-widget.hpp"
|
||||||
#include "stage/timeline/track-body.hpp"
|
#include "stage/timeline/track-body.hpp"
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
||||||
|
#include "lib/format-cout.hpp"
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
||||||
|
|
||||||
#include "lib/nocopy.hpp"
|
#include "lib/nocopy.hpp"
|
||||||
//#include "lib/util.hpp"
|
//#include "lib/util.hpp"
|
||||||
|
|
@ -70,6 +109,10 @@ namespace timeline {
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
|
|
||||||
|
using lib::diff::TreeMutator;
|
||||||
|
using lib::diff::collection;
|
||||||
|
using std::make_unique;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference frame to organise the presentation related to a specific Track in the Timeline-GUI.
|
* Reference frame to organise the presentation related to a specific Track in the Timeline-GUI.
|
||||||
|
|
@ -134,8 +177,6 @@ namespace timeline {
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~TrackPresenter();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id identity used to refer to a corresponding session::Fork
|
* @param id identity used to refer to a corresponding session::Fork
|
||||||
* @param nexus a way to connect this Controller to the UI-Bus.
|
* @param nexus a way to connect this Controller to the UI-Bus.
|
||||||
|
|
@ -179,5 +220,132 @@ namespace timeline {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
||||||
|
inline void
|
||||||
|
TrackPresenter::injectDebugTrackLabels()
|
||||||
|
{
|
||||||
|
uint x = rand() % 50;
|
||||||
|
uint y = 0;
|
||||||
|
Gtk::Button* butt = Gtk::manage (new ViewHooked<Gtk::Button, Gtk::Widget>{display_.hookedAt(x,y), TODO_trackName_});
|
||||||
|
butt->signal_clicked().connect(
|
||||||
|
[butt]{ cout << "|=="<<butt->get_label()<<endl; });
|
||||||
|
butt->show();
|
||||||
|
|
||||||
|
for (auto& subTrack : subFork_)
|
||||||
|
subTrack->injectDebugTrackLabels();
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this
|
||||||
|
/**
|
||||||
|
* @note we distinguish between the contents of our four nested child collections
|
||||||
|
* based on the symbolic type field sent in the Record type within the diff representation
|
||||||
|
* - "Marker" designates a Marker object
|
||||||
|
* - "Clip" designates a Clip placed on this track
|
||||||
|
* - "Fork" designates a nested sub-track
|
||||||
|
* - "Ruler" designates a nested ruler (timescale, overview,....) belonging to this track
|
||||||
|
* @see TimelineController::buildMutator() for a basic explanation of the data binding mechanism
|
||||||
|
*/
|
||||||
|
inline void
|
||||||
|
TrackPresenter::buildMutator (TreeMutator::Handle buffer)
|
||||||
|
{
|
||||||
|
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_.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 == elm->getID();
|
||||||
|
})
|
||||||
|
.constructFrom ([&](GenNode const& spec) -> PRuler
|
||||||
|
{ // »Constructor« : how to attach a new ruler track
|
||||||
|
return make_unique<RulerTrack> (spec.idi, this->uiBus_, *this);
|
||||||
|
})
|
||||||
|
.buildChildMutator ([&](PRuler& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||||
|
{
|
||||||
|
if (subID != target->getID()) 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"
|
||||||
|
return TYPE_Marker == spec.data.recordType();
|
||||||
|
})
|
||||||
|
.matchElement ([&](GenNode const& spec, PMarker const& elm) -> bool
|
||||||
|
{
|
||||||
|
return spec.idi == elm->getID();
|
||||||
|
})
|
||||||
|
.constructFrom ([&](GenNode const& spec) -> PMarker
|
||||||
|
{
|
||||||
|
return make_unique<MarkerWidget> (spec.idi, this->uiBus_);
|
||||||
|
})
|
||||||
|
.buildChildMutator ([&](PMarker& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||||
|
{
|
||||||
|
if (subID != target->getID()) return false;
|
||||||
|
target->buildMutator (buff);
|
||||||
|
return true;
|
||||||
|
}))
|
||||||
|
.attach (collection(clips_)
|
||||||
|
.isApplicableIf ([&](GenNode const& spec) -> bool
|
||||||
|
{ // »Selector« : require object-like sub scope with type-field "Clip"
|
||||||
|
return TYPE_Clip == spec.data.recordType();
|
||||||
|
})
|
||||||
|
.matchElement ([&](GenNode const& spec, PClip const& elm) -> bool
|
||||||
|
{
|
||||||
|
return spec.idi == elm->getID();
|
||||||
|
})
|
||||||
|
.constructFrom ([&](GenNode const& spec) -> PClip
|
||||||
|
{
|
||||||
|
return make_unique<ClipPresenter> (spec.idi, this->uiBus_);
|
||||||
|
})
|
||||||
|
.buildChildMutator ([&](PClip& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||||
|
{
|
||||||
|
if (subID != target->getID()) return false;
|
||||||
|
target->buildMutator (buff);
|
||||||
|
return true;
|
||||||
|
}))
|
||||||
|
.attach (collection(subFork_)
|
||||||
|
.isApplicableIf ([&](GenNode const& spec) -> bool
|
||||||
|
{ // »Selector« : require object-like sub scope with type-field "Fork"
|
||||||
|
return TYPE_Fork == spec.data.recordType();
|
||||||
|
})
|
||||||
|
.matchElement ([&](GenNode const& spec, PFork const& elm) -> bool
|
||||||
|
{
|
||||||
|
return spec.idi == elm->getID();
|
||||||
|
})
|
||||||
|
.constructFrom ([&](GenNode const& spec) -> PFork
|
||||||
|
{
|
||||||
|
return make_unique<TrackPresenter> (spec.idi, uiBus_, this->display_);
|
||||||
|
})
|
||||||
|
.buildChildMutator ([&](PFork& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||||
|
{
|
||||||
|
if (subID != target->getID()) return false;
|
||||||
|
target->buildMutator (buff);
|
||||||
|
return true;
|
||||||
|
}))
|
||||||
|
.change(ATTR_name, [&](string val)
|
||||||
|
{ // »Attribute Setter« : receive a new value for the track name field
|
||||||
|
this->setTrackName (val);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @todo 2/2020 */
|
||||||
|
inline void
|
||||||
|
TrackPresenter::establishLayout (DisplayEvaluation& displayEvaluation)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED ("respond to the DisplayEvaluation-Pass and pass on evaluation recursively");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}}// namespace stage::timeline
|
}}// namespace stage::timeline
|
||||||
#endif /*STAGE_TIMELINE_TRACK_PRESENTER_H*/
|
#endif /*STAGE_TIMELINE_TRACK_PRESENTER_H*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue