Relative-Hook: complete refactoring down to tracks and clips (see #1213)
...and the result was very much worth the effort, leading to more focused and cleaner code. - all the concerns of moving widgets and translating coordinates are now confined to the second abstraction layer (CanvasHook) - while the ViewHook now deals exclusively with attachment, detachment and reordering of attachment sequence
This commit is contained in:
parent
f956f27ff4
commit
e33eae729b
19 changed files with 157 additions and 280 deletions
|
|
@ -85,6 +85,13 @@ namespace model {
|
|||
virtual void hook (WID& widget, int xPos, int yPos) =0;
|
||||
virtual void move (WID& widget, int xPos, int yPos) =0;
|
||||
|
||||
/** Anchor point to build chains of related View Hooks */
|
||||
virtual CanvasHook<WID>&
|
||||
getAnchorHook() noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct Pos
|
||||
{
|
||||
CanvasHook& view;
|
||||
|
|
|
|||
|
|
@ -92,13 +92,6 @@ namespace model {
|
|||
|
||||
template<class IT>
|
||||
void reOrder (IT newOrder);
|
||||
|
||||
/** Anchor point to build chains of related View Hooks */
|
||||
virtual ViewHook<WID>&
|
||||
getAnchorHook() noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -176,7 +169,7 @@ namespace model {
|
|||
void
|
||||
ViewHook<WID>::reOrder (IT newOrder)
|
||||
{
|
||||
for (ViewHooked<WID>& existingHook : newOrder)
|
||||
for (WID& existingHook : newOrder)
|
||||
this->rehook (existingHook);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ namespace timeline {
|
|||
using CairoC = PCairoContext const&;
|
||||
using StyleC = PStyleContext const&;
|
||||
|
||||
namespace { /////////////////////////////////////////////////////TICKET #1213 : use proper zoom handling instead of dummy constants!!
|
||||
const int TODO_px_per_second = 25;
|
||||
const int TODO_px_per_microtick = TODO_px_per_second / Time::SCALE;
|
||||
} /////////////////////////////////////////////////////TICKET #1213 : (END) get rid of these dummy constants!!
|
||||
|
||||
namespace { // details of track background painting
|
||||
|
||||
const int INITIAL_TIMERULER_HEIGHT_px = 30;
|
||||
|
|
@ -569,6 +574,12 @@ namespace timeline {
|
|||
getCanvas(yPos).move (widget, xPos, yPos);
|
||||
}
|
||||
|
||||
int
|
||||
BodyCanvasWidget::translateTimeToPixels (Time startTimePoint) const
|
||||
{
|
||||
return TODO_px_per_microtick * _raw(startTimePoint); //////////TICKET #1213 : delegate zoom handling to the display manager (field #layout_) !!
|
||||
}
|
||||
|
||||
/** respond to the DisplayEvaluation pass.
|
||||
* @remark assuming that each track has already established it own vertical space requirement,
|
||||
* thereby placing the extension values into TrackBody::contentHeight_
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/timeline/track-profile.hpp"
|
||||
#include "stage/timeline/display-evaluation.hpp"
|
||||
#include "stage/model/view-hook.hpp"
|
||||
#include "stage/model/canvas-hook.hpp"
|
||||
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -90,6 +90,8 @@
|
|||
namespace stage {
|
||||
namespace timeline {
|
||||
|
||||
using lib::time::Time;
|
||||
|
||||
using CairoC = Cairo::RefPtr<Cairo::Context> const&;
|
||||
|
||||
class DisplayManager;
|
||||
|
|
@ -142,7 +144,7 @@ namespace timeline {
|
|||
*/
|
||||
class BodyCanvasWidget
|
||||
: public Gtk::Box
|
||||
, public model::ViewHook<Gtk::Widget>
|
||||
, public model::CanvasHook<Gtk::Widget>
|
||||
, public LayoutElement
|
||||
{
|
||||
DisplayManager& layout_;
|
||||
|
|
@ -168,13 +170,15 @@ namespace timeline {
|
|||
return contentArea_.get_vadjustment();
|
||||
}
|
||||
|
||||
protected: /* ==== Interface: ViewHook ===== */
|
||||
protected: /* ==== Interface: CanvasHook ===== */
|
||||
|
||||
void hook (Gtk::Widget&, int xPos=0, int yPos=0) override;
|
||||
void move (Gtk::Widget&, int xPos, int yPos) override;
|
||||
void remove (Gtk::Widget&) override;
|
||||
void rehook (Gtk::Widget&) noexcept override;
|
||||
|
||||
int translateTimeToPixels (Time) const override;
|
||||
|
||||
protected: /* ==== Interface: LayoutElement ===== */
|
||||
|
||||
void establishLayout (DisplayEvaluation&) override;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ namespace timeline {
|
|||
* @param view (abstracted) canvas or display framework to attach this clip to
|
||||
* @param offsetX offset relative to the start of the track ///////////////////////////////TICKET #1213 : translation time->offset should be built into the ViewHook!!!
|
||||
*/
|
||||
ClipPresenter::ClipPresenter (ID identity, ctrl::BusTerm& nexus, WidgetViewHook& view, optional<int> offsetX)
|
||||
ClipPresenter::ClipPresenter (ID identity, ctrl::BusTerm& nexus, WidgetHook& view, optional<int> offsetX)
|
||||
: Controller{identity, nexus}
|
||||
, channels_{}
|
||||
, effects_{}
|
||||
|
|
@ -172,7 +172,7 @@ namespace timeline {
|
|||
ClipDelegate::switchAppearance (this->widget_, defaultAppearance);
|
||||
}
|
||||
|
||||
WidgetViewHook&
|
||||
WidgetHook&
|
||||
ClipPresenter::getClipContentCanvas()
|
||||
{
|
||||
UNIMPLEMENTED ("how to create and wire an embedded canvas for the clip contents/effects");
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace timeline {
|
|||
static const ClipDelegate::Appearance defaultAppearance = ClipDelegate::COMPACT;
|
||||
|
||||
public:
|
||||
ClipPresenter (ID, ctrl::BusTerm&, WidgetViewHook&, optional<int> offsetX);
|
||||
ClipPresenter (ID, ctrl::BusTerm&, WidgetHook&, optional<int> offsetX);
|
||||
|
||||
~ClipPresenter();
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ namespace timeline {
|
|||
*/
|
||||
void resetAppearanceStyle();
|
||||
|
||||
WidgetViewHook& getClipContentCanvas();
|
||||
WidgetHook& getClipContentCanvas();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -75,34 +75,36 @@ namespace timeline {
|
|||
|
||||
|
||||
namespace {// details of concrete clip appearance styles...
|
||||
|
||||
|
||||
using WidgetHook = model::CanvasHook<Gtk::Widget>;
|
||||
using HookedWidget = model::CanvasHooked<Gtk::Button, Gtk::Widget>; ///////////////////////////////////////////TICKET #1211 : need preliminary placeholder clip widget for timeline layout
|
||||
|
||||
class ClipData
|
||||
: public ClipDelegate
|
||||
, util::NonCopyable
|
||||
{
|
||||
WidgetViewHook& display_;
|
||||
WidgetHook& display_;
|
||||
|
||||
/* === Interface ClipDelegate === */
|
||||
|
||||
public:
|
||||
ClipData(WidgetViewHook& displayAnchor)
|
||||
ClipData(WidgetHook& displayAnchor)
|
||||
: ClipDelegate{}
|
||||
, display_{displayAnchor}
|
||||
{ }
|
||||
};
|
||||
|
||||
using ViewHookedWidget = model::ViewHooked<Gtk::Button, Gtk::Widget>; ///////////////////////////////////////////TICKET #1211 : need preliminary placeholder clip widget for timeline layout
|
||||
|
||||
class ClipWidget
|
||||
: public ViewHookedWidget
|
||||
: public HookedWidget
|
||||
, public ClipDelegate
|
||||
, util::NonCopyable
|
||||
{
|
||||
/* === Interface ClipDelegate === */
|
||||
|
||||
public:
|
||||
ClipWidget(WidgetViewHook& displayAnchor, int x, int y, uString clipName)
|
||||
: ViewHookedWidget{displayAnchor.hookedAt(x,y), clipName}
|
||||
ClipWidget(WidgetHook::Pos hookPoint, uString clipName)
|
||||
: HookedWidget{hookPoint, clipName}
|
||||
, ClipDelegate{}
|
||||
{ }
|
||||
};
|
||||
|
|
@ -114,16 +116,16 @@ namespace timeline {
|
|||
/* === Appearance Style state transitions === */
|
||||
|
||||
ClipDelegate::Appearance
|
||||
ClipDelegate::switchAppearance (PDelegate& manager, Appearance desired, WidgetViewHook* newView)
|
||||
ClipDelegate::switchAppearance (PDelegate& manager, Appearance desired, WidgetHook* newView)
|
||||
{
|
||||
UNIMPLEMENTED ("clip appearance style state management");
|
||||
}
|
||||
|
||||
ClipDelegate::Appearance
|
||||
ClipDelegate::buildDelegate (PDelegate& manager, WidgetViewHook& view, optional<int> startOffsetX) ////////////////TICKET #1213 : translation time->offset should be built into the ViewHook!!!
|
||||
ClipDelegate::buildDelegate (PDelegate& manager, WidgetHook& view, optional<int> startOffsetX) ////////////////TICKET #1213 : translation time->offset should be built into the ViewHook!!!
|
||||
{
|
||||
if (startOffsetX)
|
||||
manager.reset (new ClipWidget{view, *startOffsetX, defaultOffsetY, defaultName});
|
||||
manager.reset (new ClipWidget{view.hookedAt(*startOffsetX, defaultOffsetY), defaultName});
|
||||
else
|
||||
manager.reset (new ClipData{view});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@
|
|||
#define STAGE_TIMELINE_CLIP_WIDGET_H
|
||||
|
||||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/model/view-hook.hpp"
|
||||
#include "stage/model/canvas-hook.hpp"
|
||||
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ namespace timeline {
|
|||
|
||||
using std::string;
|
||||
|
||||
using WidgetViewHook = model::ViewHook<Gtk::Widget>;
|
||||
using WidgetHook = model::CanvasHook<Gtk::Widget>;
|
||||
|
||||
class ClipDelegate;
|
||||
using PDelegate = std::unique_ptr<ClipDelegate>;
|
||||
|
|
@ -167,12 +167,12 @@ namespace timeline {
|
|||
*/
|
||||
static Appearance switchAppearance (PDelegate& manager,
|
||||
Appearance desired =PENDING,
|
||||
WidgetViewHook* newView =nullptr);
|
||||
WidgetHook* newView =nullptr);
|
||||
|
||||
/** build the initial presentation widget on construction, using a minimally
|
||||
* viable appearance style. This is the first incantation of #switchAppearance.
|
||||
*/
|
||||
static Appearance buildDelegate (PDelegate& manager, WidgetViewHook& view,
|
||||
static Appearance buildDelegate (PDelegate& manager, WidgetHook& view,
|
||||
std::optional<int> startOffsetX); ///////////////////////TICKET #1213 : translation time->offset should be built into the ViewHook!!!
|
||||
|
||||
private:/* ===== Internals ===== */
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace timeline {
|
|||
|
||||
using util::max;
|
||||
|
||||
using model::ViewHooked;
|
||||
using lib::time::Time;
|
||||
class TrackHeadWidget;
|
||||
class TrackBody;
|
||||
|
||||
|
|
@ -75,10 +75,10 @@ namespace timeline {
|
|||
* when attaching or moving Widgets on the shared canvas.
|
||||
*/
|
||||
template<class WID>
|
||||
class ViewRefHook
|
||||
: public model::ViewHook<WID>
|
||||
class RelativeCanvasHook
|
||||
: public model::CanvasHook<WID>
|
||||
{
|
||||
model::ViewHook<WID>& refHook_;
|
||||
model::CanvasHook<WID>& refHook_;
|
||||
|
||||
|
||||
/* ==== Interface: ViewHook ===== */
|
||||
|
|
@ -108,7 +108,7 @@ namespace timeline {
|
|||
}
|
||||
|
||||
/** allow to build a derived ViewRefHook with different offset */
|
||||
model::ViewHook<WID>&
|
||||
model::CanvasHook<WID>&
|
||||
getAnchorHook() noexcept override
|
||||
{
|
||||
return this->refHook_;
|
||||
|
|
@ -118,8 +118,15 @@ namespace timeline {
|
|||
virtual int hookAdjX (int xPos) =0;
|
||||
virtual int hookAdjY (int yPos) =0;
|
||||
|
||||
/** delegating default implementation for timeline zoom */
|
||||
int
|
||||
translateTimeToPixels (Time startTimePoint) const override
|
||||
{
|
||||
return refHook_.hookedAt(startTimePoint).x;
|
||||
}
|
||||
|
||||
public:
|
||||
ViewRefHook(model::ViewHook<WID>& baseHook)
|
||||
RelativeCanvasHook(model::CanvasHook<WID>& baseHook)
|
||||
: refHook_{baseHook.getAnchorHook()}
|
||||
{ }
|
||||
};
|
||||
|
|
@ -144,7 +151,7 @@ namespace timeline {
|
|||
|
||||
virtual model::ViewHook<TrackHeadWidget>& getHeadHook() =0;
|
||||
virtual model::ViewHook<TrackBody>& getBodyHook() =0;
|
||||
virtual model::ViewHook<Gtk::Widget>& getClipHook() =0;
|
||||
virtual model::CanvasHook<Gtk::Widget>& getClipHook() =0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -135,16 +135,14 @@ namespace timeline {
|
|||
/* ==== Interface: ViewHook ===== */
|
||||
|
||||
void
|
||||
TimelineLayout::hook (TrackHeadWidget& head, int xPos, int yPos)
|
||||
TimelineLayout::hook (TrackHeadWidget& head)
|
||||
{
|
||||
REQUIRE (xPos==0 && yPos==0, "arbitrary positioning of sub-Tracks contradicts the concept of track-profile."); ///TODO remove that API
|
||||
headerPane_.installForkRoot (head);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayout::hook (TrackBody& body, int xPos, int yPos)
|
||||
TimelineLayout::hook (TrackBody& body)
|
||||
{
|
||||
REQUIRE (xPos==0 && yPos==0, "arbitrary positioning of sub-Tracks contradicts the concept of track-profile."); ///TODO remove that API
|
||||
bodyCanvas_.installForkRoot (body);
|
||||
|
||||
// detect changes of the track structure
|
||||
|
|
@ -179,18 +177,5 @@ namespace timeline {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TimelineLayout::move (TrackHeadWidget& head, int xPos, int yPos)
|
||||
{
|
||||
NOTREACHED ("ViewHooked: not supported -- refactor?");
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayout::move (TrackBody& body, int xPos, int yPos)
|
||||
{
|
||||
NOTREACHED ("ViewHooked: not supported -- refactor?");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}// namespace stage::timeline
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
#include "stage/timeline/display-evaluation.hpp"
|
||||
#include "stage/timeline/header-pane-widget.hpp"
|
||||
#include "stage/timeline/body-canvas-widget.hpp"
|
||||
#include "stage/model/view-hook.hpp"
|
||||
#include "stage/model/canvas-hook.hpp"
|
||||
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -143,19 +143,17 @@ namespace timeline {
|
|||
|
||||
model::ViewHook<TrackHeadWidget>& getHeadHook() override { return *this; };
|
||||
model::ViewHook<TrackBody>& getBodyHook() override { return *this; };
|
||||
model::ViewHook<Gtk::Widget>& getClipHook() override { return bodyCanvas_; };
|
||||
model::CanvasHook<Gtk::Widget>& getClipHook() override { return bodyCanvas_; };
|
||||
|
||||
protected: /* ==== Interface: ViewHook ===== */
|
||||
|
||||
void hook (TrackHeadWidget&, int xPos=0, int yPos=0) override;
|
||||
void move (TrackHeadWidget&, int xPos, int yPos) override;
|
||||
void remove (TrackHeadWidget&) override;
|
||||
void rehook (TrackHeadWidget&) noexcept override;
|
||||
void hook (TrackHeadWidget&) override;
|
||||
void remove (TrackHeadWidget&) override;
|
||||
void rehook (TrackHeadWidget&) noexcept override;
|
||||
|
||||
void hook (TrackBody&, int xPos=0, int yPos=0) override;
|
||||
void move (TrackBody&, int xPos, int yPos) override;
|
||||
void remove (TrackBody&) override;
|
||||
void rehook (TrackBody&) noexcept override;
|
||||
void hook (TrackBody&) override;
|
||||
void remove (TrackBody&) override;
|
||||
void rehook (TrackBody&) noexcept override;
|
||||
|
||||
private:/* ===== Internals ===== */
|
||||
|
||||
|
|
|
|||
|
|
@ -95,21 +95,14 @@ namespace timeline {
|
|||
/* ==== Interface: ViewHook ===== */
|
||||
|
||||
void
|
||||
TrackBody::hook (TrackBody& subBody, int xPos, int yPos)
|
||||
TrackBody::hook (TrackBody& subBody)
|
||||
{
|
||||
REQUIRE (xPos==0 && yPos==0, "arbitrary positioning of TrackBody contradicts the concept of track-profile."); ///TODO remove that API
|
||||
subTracks_.push_back (&subBody);
|
||||
|
||||
// notify presentation code of the changed structure
|
||||
subBody.signalStructureChange_ = signalStructureChange_;
|
||||
signalStructureChange_(); // this _is_ such a change
|
||||
}
|
||||
|
||||
void
|
||||
TrackBody::move (TrackBody& subBody, int xPos, int yPos)
|
||||
{
|
||||
NOTREACHED ("woot?? can we even move a sub-TrackBody????");
|
||||
}
|
||||
|
||||
void
|
||||
TrackBody::remove (TrackBody& subBody)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#define STAGE_TIMELINE_TRACK_BODY_H
|
||||
|
||||
#include "stage/gtk-base.hpp"
|
||||
#include "stage/model/view-hook.hpp"
|
||||
#include "stage/timeline/ruler-track.hpp"
|
||||
#include "stage/timeline/display-manager.hpp"
|
||||
|
||||
|
|
@ -125,10 +126,9 @@ namespace timeline {
|
|||
|
||||
/* ==== Interface: ViewHook ===== */
|
||||
|
||||
void hook (TrackBody&, int xPos=0, int yPos=0) override;
|
||||
void move (TrackBody&, int xPos, int yPos) override;
|
||||
void remove (TrackBody&) override;
|
||||
void rehook (TrackBody&) noexcept override;
|
||||
void hook (TrackBody&) override;
|
||||
void remove (TrackBody&) override;
|
||||
void rehook (TrackBody&) noexcept override;
|
||||
|
||||
/* ===== Internals ===== */
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -131,17 +131,10 @@ namespace timeline {
|
|||
/* ==== Interface: ViewHook ===== */
|
||||
|
||||
void
|
||||
TrackHeadWidget::hook (TrackHeadWidget& subHead, int xPos, int yPos)
|
||||
TrackHeadWidget::hook (TrackHeadWidget& subHead)
|
||||
{
|
||||
REQUIRE (xPos==0 && yPos==0, "selection of arbitrary row not yet implemented");
|
||||
attachSubFork (subHead);
|
||||
}
|
||||
|
||||
void
|
||||
TrackHeadWidget::move (TrackHeadWidget& subHead, int xPos, int yPos)
|
||||
{
|
||||
NOTREACHED ("woot?? can we even move a sub-TrackHead????");
|
||||
}
|
||||
|
||||
void
|
||||
TrackHeadWidget::remove (TrackHeadWidget& subHead)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ namespace stage {
|
|||
namespace timeline {
|
||||
|
||||
using ID = ctrl::BusTerm::ID;
|
||||
using model::ViewHooked;
|
||||
|
||||
/**
|
||||
* Header pane control area corresponding to a Track with nested child Tracks.
|
||||
|
|
@ -81,10 +80,9 @@ namespace timeline {
|
|||
|
||||
/* ==== Interface: ViewHook ===== */
|
||||
|
||||
void hook (TrackHeadWidget&, int xPos=0, int yPos=0) override;
|
||||
void move (TrackHeadWidget&, int xPos, int yPos) override;
|
||||
void remove (TrackHeadWidget&) override;
|
||||
void rehook (TrackHeadWidget&) noexcept override;
|
||||
void hook (TrackHeadWidget&) override;
|
||||
void remove (TrackHeadWidget&) override;
|
||||
void rehook (TrackHeadWidget&) noexcept override;
|
||||
|
||||
public:
|
||||
TrackHeadWidget();
|
||||
|
|
|
|||
|
|
@ -141,10 +141,10 @@ namespace timeline {
|
|||
class DisplayFrame
|
||||
: util::NonCopyable
|
||||
, public DisplayViewHooks
|
||||
, public ViewRefHook<Gtk::Widget>
|
||||
, public RelativeCanvasHook<Gtk::Widget>
|
||||
{
|
||||
ViewHooked<TrackHeadWidget> head_;
|
||||
ViewHooked<TrackBody> body_;
|
||||
model::ViewHooked<TrackHeadWidget> head_;
|
||||
model::ViewHooked<TrackBody> body_;
|
||||
|
||||
/* === extended Interface for relative view hook === */
|
||||
|
||||
|
|
@ -155,11 +155,11 @@ namespace timeline {
|
|||
|
||||
model::ViewHook<TrackHeadWidget>& getHeadHook() override { return head_; };
|
||||
model::ViewHook<TrackBody>& getBodyHook() override { return body_; };
|
||||
model::ViewHook<Gtk::Widget>& getClipHook() override { return *this; };
|
||||
model::CanvasHook<Gtk::Widget>& getClipHook() override { return *this; };
|
||||
|
||||
public:
|
||||
DisplayFrame (DisplayViewHooks& displayAnchor)
|
||||
: ViewRefHook{displayAnchor.getClipHook()}
|
||||
: RelativeCanvasHook{displayAnchor.getClipHook()}
|
||||
, head_{displayAnchor.getHeadHook()}
|
||||
, body_{displayAnchor.getBodyHook()}
|
||||
{ }
|
||||
|
|
@ -259,7 +259,7 @@ namespace timeline {
|
|||
{
|
||||
uint x = rand() % 50;
|
||||
uint y = 0;
|
||||
Gtk::Button* butt = Gtk::manage (new ViewHooked<Gtk::Button, Gtk::Widget>{display_.hookedAt(x,y), TODO_trackName_});
|
||||
Gtk::Button* butt = Gtk::manage (new model::CanvasHooked<Gtk::Button, Gtk::Widget>{display_.hookedAt(x,y), TODO_trackName_});
|
||||
butt->signal_clicked().connect(
|
||||
[butt]{ cout << "|=="<<butt->get_label()<<endl; });
|
||||
butt->show();
|
||||
|
|
|
|||
|
|
@ -123,24 +123,8 @@ namespace test {
|
|||
and pos->posY == y_expected;
|
||||
}
|
||||
|
||||
/** verify our internal sequence matches the given one */
|
||||
template<class IT>
|
||||
bool
|
||||
testContainsSequence (IT refSeq)
|
||||
{
|
||||
// NOTE the implementation twist of using a std::forward_list,
|
||||
// which causes reversed order of our internal elements
|
||||
lib::IterStack<int> ids;
|
||||
for (auto& entry : widgets_)
|
||||
ids.push (entry.widget.i);
|
||||
for ( ; refSeq and ids; ++refSeq, ++ids)
|
||||
if (refSeq->i != *ids) break;
|
||||
return isnil(refSeq)
|
||||
and isnil(ids);
|
||||
}
|
||||
|
||||
|
||||
/* === Interface ViewHook === */
|
||||
/* === Interface CanvasHook === */
|
||||
|
||||
void
|
||||
hook (DummyWidget& elm, int xPos, int yPos) override
|
||||
|
|
@ -208,39 +192,22 @@ namespace test {
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
verify_standardUsage();
|
||||
verify_multiplicity();
|
||||
attach2canvas();
|
||||
relocateWidget();
|
||||
reOrderHooked();
|
||||
}
|
||||
|
||||
|
||||
/** @test the standard use case is to hook up a widget to a canvas for display.
|
||||
/** @test attach several widgets with distinct coordinates
|
||||
* and verify automated detaching on destruction.
|
||||
*/
|
||||
void
|
||||
verify_standardUsage()
|
||||
{
|
||||
FakeCanvas canvas;
|
||||
CHECK (canvas.empty());
|
||||
{
|
||||
HookedWidget widget{canvas.hookedAt(0,0) };
|
||||
CHECK (canvas.testContains (widget.i));
|
||||
CHECK (not canvas.empty());
|
||||
}// hook goes out of scope...
|
||||
CHECK (canvas.empty());
|
||||
}
|
||||
|
||||
|
||||
/** @test each hooking has a distinct identity and is managed on its own.
|
||||
*/
|
||||
void
|
||||
verify_multiplicity()
|
||||
attach2canvas()
|
||||
{
|
||||
FakeCanvas canvas;
|
||||
CHECK (canvas.empty());
|
||||
|
||||
HookedWidget widget{canvas.hookedAt(1,1)};
|
||||
CHECK (canvas.testContains (widget.i));
|
||||
CHECK (canvas.testVerifyPos (widget, 1,1));
|
||||
CHECK (not canvas.empty());
|
||||
|
||||
int someID;
|
||||
|
|
@ -249,6 +216,8 @@ namespace test {
|
|||
someID = otherWidget.i;
|
||||
CHECK (canvas.testContains (someID));
|
||||
CHECK (canvas.testContains (widget.i));
|
||||
CHECK (canvas.testVerifyPos (widget, 1,1));
|
||||
CHECK (canvas.testVerifyPos (otherWidget, 2,2));
|
||||
}// hook goes out of scope...
|
||||
CHECK (not canvas.testContains (someID));
|
||||
CHECK (canvas.testContains (widget.i));
|
||||
|
|
@ -292,46 +261,6 @@ namespace test {
|
|||
CHECK (canvas.testVerifyPos (w1, x1,y1));
|
||||
CHECK (canvas.testVerifyPos (w3, x3,y3));
|
||||
}
|
||||
|
||||
|
||||
/** @test a mechanism to re-attach elements in changed order.
|
||||
* @remarks this test looks somewhat convoluted, because `ViewHooked<W>` is defined
|
||||
* to be non-copyable (for good reason, since we can assume that the canvas
|
||||
* somehow maintains a pointer to each widget added, so we can not allow the
|
||||
* attached widgets to move in memory). However, in practice the "order sequence"
|
||||
* is typically defined as a delegating iterator over some sequence of model elements,
|
||||
* which themselves are managed as a STL container of `std::unique_ptr`; thus it is
|
||||
* very much possible to alter the sequence of the model elements, without actually
|
||||
* touching the memory location of the slave widgets used for presentation.
|
||||
*/
|
||||
void
|
||||
reOrderHooked()
|
||||
{
|
||||
using Widgets = lib::ScopedCollection<HookedWidget>;
|
||||
using OrderIdx = vector<HookedWidget*>;
|
||||
|
||||
FakeCanvas canvas; // WARNING: Canvas must outlive the widgets!
|
||||
|
||||
// create 20 (random) widgets and hook them onto the canvas
|
||||
Widgets widgets{20};
|
||||
OrderIdx orderIdx;
|
||||
for (uint i=0; i<20; ++i)
|
||||
orderIdx.push_back (& widgets.emplace<HookedWidget>(canvas.hookedAt(0,1)));
|
||||
|
||||
// helper: use the orderIdx to generate sequence of widget refs (not pointers)
|
||||
auto orderSequence = [&] { return lib::ptrDeref(eachElm(orderIdx)); };
|
||||
|
||||
CHECK (canvas.testContainsSequence (eachElm(widgets)));
|
||||
CHECK (canvas.testContainsSequence (orderSequence()));
|
||||
|
||||
// now lets assume the relevant order of the widgets has been altered
|
||||
shuffle (orderIdx.begin(),orderIdx.end(), std::random_device());
|
||||
CHECK (not canvas.testContainsSequence (orderSequence()));
|
||||
|
||||
// so we need to re-construct the canvas attachments in the new order
|
||||
canvas.reOrder (orderSequence());
|
||||
CHECK (canvas.testContainsSequence (orderSequence()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@
|
|||
#include "lib/iter-adapter-stl.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <forward_list>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
|
||||
|
|
@ -43,9 +43,8 @@ using util::isnil;
|
|||
using util::contains;
|
||||
using util::isSameObject;
|
||||
using lib::iter_stl::eachElm;
|
||||
using std::vector;
|
||||
using std::forward_list;
|
||||
using std::shuffle;
|
||||
using std::vector;
|
||||
|
||||
|
||||
namespace stage{
|
||||
|
|
@ -73,21 +72,15 @@ namespace test {
|
|||
class FakeCanvas
|
||||
: public ViewHook<DummyWidget>
|
||||
{
|
||||
struct Attachment
|
||||
{
|
||||
DummyWidget& widget;
|
||||
int posX, posY;
|
||||
};
|
||||
forward_list<Attachment> widgets_;
|
||||
|
||||
std::list<DummyWidget> widgets_;
|
||||
|
||||
auto
|
||||
allWidgetIDs() const
|
||||
{
|
||||
return lib::treeExplore(widgets_)
|
||||
.transform([](Attachment const& entry)
|
||||
.transform([](DummyWidget const& entry)
|
||||
{
|
||||
return entry.widget.i;
|
||||
return entry.i;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +89,7 @@ namespace test {
|
|||
{
|
||||
return std::find_if (widgets_.begin()
|
||||
,widgets_.end()
|
||||
, [&](Attachment const& a) { return a.widget == someWidget; });
|
||||
, [&](DummyWidget const& widget) { return widget == someWidget; });
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -113,26 +106,12 @@ namespace test {
|
|||
return util::linearSearch (allWidgetIDs(), someWidgetID);
|
||||
}
|
||||
|
||||
bool
|
||||
testVerifyPos (DummyWidget const& someWidget, int x_expected, int y_expected)
|
||||
{
|
||||
auto end = widgets_.end();
|
||||
auto pos = findEntry (someWidget);
|
||||
return pos != end
|
||||
and pos->posX == x_expected
|
||||
and pos->posY == y_expected;
|
||||
}
|
||||
|
||||
/** verify our internal sequence matches the given one */
|
||||
template<class IT>
|
||||
bool
|
||||
testContainsSequence (IT refSeq)
|
||||
{
|
||||
// NOTE the implementation twist of using a std::forward_list,
|
||||
// which causes reversed order of our internal elements
|
||||
lib::IterStack<int> ids;
|
||||
for (auto& entry : widgets_)
|
||||
ids.push (entry.widget.i);
|
||||
auto ids = allWidgetIDs();
|
||||
for ( ; refSeq and ids; ++refSeq, ++ids)
|
||||
if (refSeq->i != *ids) break;
|
||||
return isnil(refSeq)
|
||||
|
|
@ -143,27 +122,15 @@ namespace test {
|
|||
/* === Interface ViewHook === */
|
||||
|
||||
void
|
||||
hook (DummyWidget& elm, int xPos, int yPos) override
|
||||
hook (DummyWidget& elm) override
|
||||
{
|
||||
widgets_.push_front (Attachment{elm, xPos,yPos});
|
||||
}
|
||||
|
||||
void
|
||||
move (DummyWidget& elm, int xPos, int yPos) override
|
||||
{
|
||||
auto end = widgets_.end();
|
||||
auto pos = findEntry (elm);
|
||||
if (pos != end)
|
||||
{
|
||||
pos->posX = xPos;
|
||||
pos->posY = yPos;
|
||||
}
|
||||
widgets_.push_back (elm);
|
||||
}
|
||||
|
||||
void
|
||||
remove (DummyWidget& elm) override
|
||||
{
|
||||
widgets_.remove_if ([&](Attachment const& a) { return a.widget == elm; });
|
||||
widgets_.remove_if ([&](auto const& widget) { return widget == elm; });
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -172,9 +139,9 @@ namespace test {
|
|||
{
|
||||
auto pos = findEntry (existingHook);
|
||||
REQUIRE (pos != widgets_.end(), "the given iterator must yield previously hooked-up elements");
|
||||
Attachment existing{*pos};
|
||||
this->remove (existing.widget);
|
||||
this->hook (existing.widget, existing.posX,existing.posY);
|
||||
DummyWidget& widget{*pos};
|
||||
this->remove (widget);
|
||||
this->hook (widget);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -202,7 +169,6 @@ namespace test {
|
|||
{
|
||||
verify_standardUsage();
|
||||
verify_multiplicity();
|
||||
relocateWidget();
|
||||
reOrderHooked();
|
||||
}
|
||||
|
||||
|
|
@ -248,44 +214,6 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/** @test hook a widget at a specific position and then later
|
||||
* relocate it on the canvas through the ViewHook front-end.
|
||||
*/
|
||||
void
|
||||
relocateWidget()
|
||||
{
|
||||
int x1 = rand() % 100;
|
||||
int y1 = rand() % 100;
|
||||
int x2 = rand() % 100;
|
||||
int y2 = rand() % 100;
|
||||
int x3 = rand() % 100;
|
||||
int y3 = rand() % 100;
|
||||
|
||||
FakeCanvas canvas;
|
||||
HookedWidget w1{canvas.hookedAt(x1,y1)};
|
||||
HookedWidget w3{canvas.hookedAt(x3,y3)};
|
||||
|
||||
int id2;
|
||||
{
|
||||
HookedWidget w2{canvas.hookedAt(x2,y2)};
|
||||
id2 = w2.i;
|
||||
CHECK (canvas.testContains (id2));
|
||||
CHECK (canvas.testVerifyPos (w2, x2,y2));
|
||||
|
||||
int newX = ++x2;
|
||||
int newY = --y2;
|
||||
w2.moveTo (newX,newY);
|
||||
|
||||
CHECK (canvas.testVerifyPos (w2, newX,newY));
|
||||
CHECK (canvas.testVerifyPos (w1, x1,y1));
|
||||
CHECK (canvas.testVerifyPos (w3, x3,y3));
|
||||
}
|
||||
CHECK (not canvas.testContains (id2));
|
||||
CHECK (canvas.testVerifyPos (w1, x1,y1));
|
||||
CHECK (canvas.testVerifyPos (w3, x3,y3));
|
||||
}
|
||||
|
||||
|
||||
/** @test a mechanism to re-attach elements in changed order.
|
||||
* @remarks this test looks somewhat convoluted, because `ViewHooked<W>` is defined
|
||||
* to be non-copyable (for good reason, since we can assume that the canvas
|
||||
|
|
|
|||
|
|
@ -791,6 +791,13 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node COLOR="#435e98" CREATED="1584932162467" ID="ID_813910229" MODIFIED="1584932190012" TEXT="inzwischen wohl geklärt">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584932093080" ID="ID_1234616959" MODIFIED="1584932222621" TEXT="es gibt aber noch einen ähnlichen Fehler....">
|
||||
<arrowlink COLOR="#b183a2" DESTINATION="ID_535289114" ENDARROW="Default" ENDINCLINATION="-2880;0;" ID="Arrow_ID_1219325605" STARTARROW="None" STARTINCLINATION="595;36;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1484800480472" ID="ID_1441013524" MODIFIED="1576282358158" TEXT="Sanity-Check in CoreService anpassen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -19174,10 +19181,10 @@
|
|||
<node CREATED="1575581015219" ID="ID_1015965713" MODIFIED="1575581026974" TEXT="für den Widget -> Canvas - Fall"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1576757730509" ID="ID_1949130658" MODIFIED="1584894698264" TEXT="»Widget-Position« heraus-abstrahieren">
|
||||
<node COLOR="#338800" CREATED="1576757730509" FOLDED="true" ID="ID_1949130658" MODIFIED="1584932567087" TEXT="»Widget-Position« heraus-abstrahieren">
|
||||
<linktarget COLOR="#605bb8" DESTINATION="ID_1949130658" ENDARROW="Default" ENDINCLINATION="204;611;" ID="Arrow_ID_993970158" SOURCE="ID_1816490333" STARTARROW="None" STARTINCLINATION="299;12;"/>
|
||||
<linktarget COLOR="#cd478c" DESTINATION="ID_1949130658" ENDARROW="Default" ENDINCLINATION="-1150;77;" ID="Arrow_ID_662295339" SOURCE="ID_730955223" STARTARROW="None" STARTINCLINATION="872;48;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<linktarget COLOR="#47cdcd" DESTINATION="ID_1949130658" ENDARROW="Default" ENDINCLINATION="-1150;77;" ID="Arrow_ID_662295339" SOURCE="ID_730955223" STARTARROW="None" STARTINCLINATION="877;53;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1576757867075" ID="ID_1947629675" MODIFIED="1576757891150" TEXT="der Themenkomplex "move()" steht isoliert da">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1576757893399" ID="ID_309464876" MODIFIED="1576757905274" TEXT="eigentlich ein orthogonaler Belang"/>
|
||||
|
|
@ -19213,8 +19220,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584894608428" ID="ID_1214957016" MODIFIED="1584894628941" TEXT="Sub-Interface CanvasHooked herauslösen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1584894608428" ID="ID_1214957016" MODIFIED="1584932472009" TEXT="Sub-Interface CanvasHooked herauslösen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1584894703681" ID="ID_101352353" MODIFIED="1584894725463" TEXT="ViewHook / CanvasHook">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1584894715892" ID="ID_70510619" MODIFIED="1584894722576" TEXT="oh Ja... viel schöner">
|
||||
|
|
@ -19224,19 +19231,23 @@
|
|||
<node COLOR="#338800" CREATED="1584894728286" ID="ID_414399172" MODIFIED="1584894738145" TEXT="Test umschreiben auf CanvasHook">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584894739041" ID="ID_1191395338" MODIFIED="1584894750232" TEXT="separaten Test für den Basis-Fall">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1584894739041" ID="ID_1191395338" MODIFIED="1584932467447" TEXT="separaten Test für den Basis-Fall">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584894751623" ID="ID_674921950" MODIFIED="1584894785196" TEXT="Interfaces in DisplayManager differenzieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1584894751623" ID="ID_674921950" MODIFIED="1584932474570" TEXT="Interfaces in DisplayManager differenzieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584894766013" ID="ID_1003825239" MODIFIED="1584894784715" TEXT="Interfaces im TrackPresenter differenzieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1584894766013" ID="ID_1003825239" MODIFIED="1584932476358" TEXT="Interfaces im TrackPresenter differenzieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584894775935" ID="ID_241955108" MODIFIED="1584894783892" TEXT="Interfaces im ClipPresenter differenzieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1584894775935" ID="ID_241955108" MODIFIED="1584932477944" TEXT="Interfaces im ClipPresenter differenzieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1584932523675" ID="ID_715711411" MODIFIED="1584932535644" TEXT="hat auf allen Ebenen den Code verbessert">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1575057172259" ID="ID_1193961919" MODIFIED="1575670553256" TEXT="Umordnen">
|
||||
<linktarget COLOR="#507b9b" DESTINATION="ID_1193961919" ENDARROW="Default" ENDINCLINATION="-877;88;" ID="Arrow_ID_1469804818" SOURCE="ID_876124745" STARTARROW="None" STARTINCLINATION="576;33;"/>
|
||||
|
|
@ -22097,8 +22108,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584888309716" ID="ID_236695014" MODIFIED="1584888323264" TEXT="explizit modelliert (CanvasHook)">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584888309716" ID="ID_236695014" MODIFIED="1584932638731" TEXT="explizit modelliert (CanvasHook)">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1584888472583" ID="ID_1663593154" MODIFIED="1584888561167" TEXT="Idee: smart-Handle">
|
||||
<linktarget COLOR="#775ae8" DESTINATION="ID_1663593154" ENDARROW="Default" ENDINCLINATION="84;-81;" ID="Arrow_ID_348205317" SOURCE="ID_384525360" STARTARROW="None" STARTINCLINATION="-297;47;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -22106,11 +22117,14 @@
|
|||
<node COLOR="#338800" CREATED="1584888672307" ID="ID_213768440" MODIFIED="1584888703767" TEXT="brauche zusätzlich lokalen Offset">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584888686257" ID="ID_380050520" MODIFIED="1584888921383" TEXT="brauche zusätzlich Übersetzung Time -> pixel">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584888686257" ID="ID_380050520" MODIFIED="1584932631032" TEXT="brauche zusätzlich Übersetzung Time -> pixel">
|
||||
<linktarget COLOR="#354ce1" DESTINATION="ID_380050520" ENDARROW="Default" ENDINCLINATION="-2737;0;" ID="Arrow_ID_459309015" SOURCE="ID_1764561185" STARTARROW="None" STARTINCLINATION="-885;49;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584889060615" ID="ID_730955223" MODIFIED="1584889187770" TEXT="muß Design des ViewHook ausdifferenzieren">
|
||||
<arrowlink COLOR="#cd478c" DESTINATION="ID_1949130658" ENDARROW="Default" ENDINCLINATION="-1150;77;" ID="Arrow_ID_662295339" STARTARROW="None" STARTINCLINATION="872;48;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1584889060615" ID="ID_730955223" MODIFIED="1584932567086" TEXT="muß Design des ViewHook ausdifferenzieren">
|
||||
<arrowlink COLOR="#47cdcd" DESTINATION="ID_1949130658" ENDARROW="Default" ENDINCLINATION="-1150;77;" ID="Arrow_ID_662295339" STARTARROW="None" STARTINCLINATION="877;53;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584932570334" ID="ID_626245969" MODIFIED="1584932585348" TEXT="TODO: Aufruf an den DisplayManager weiterleiten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27943,7 +27957,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1584201751260" ID="ID_1492285349" MODIFIED="1584201760641" TEXT="Problem: initiale Koordinaten">
|
||||
<node CREATED="1584201751260" ID="ID_1492285349" MODIFIED="1584932876269" TEXT="Problem: initiale Koordinaten">
|
||||
<linktarget COLOR="#6fa9d7" DESTINATION="ID_1492285349" ENDARROW="Default" ENDINCLINATION="-156;14;" ID="Arrow_ID_819317359" SOURCE="ID_726635217" STARTARROW="None" STARTINCLINATION="170;10;"/>
|
||||
<node COLOR="#338800" CREATED="1584201782842" ID="ID_560620961" MODIFIED="1584319384536" TEXT="sind nicht (zwingend) im Populations-Diff">
|
||||
<arrowlink COLOR="#38abc2" DESTINATION="ID_1687516658" ENDARROW="Default" ENDINCLINATION="30;37;" ID="Arrow_ID_901736037" STARTARROW="None" STARTINCLINATION="129;9;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -27991,6 +28006,13 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584932756457" HGAP="142" ID="ID_726635217" MODIFIED="1584932886403" TEXT="Einhängen, wenn möglich" VSHIFT="-7">
|
||||
<arrowlink COLOR="#6fa9d7" DESTINATION="ID_1492285349" ENDARROW="Default" ENDINCLINATION="-156;14;" ID="Arrow_ID_819317359" STARTARROW="None" STARTINCLINATION="170;10;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1584932910051" HGAP="63" ID="ID_1737560927" MODIFIED="1584932955050" TEXT="Zustands-Wechsel-Logik" VSHIFT="16">
|
||||
<arrowlink COLOR="#4768d0" DESTINATION="ID_1833569495" ENDARROW="Default" ENDINCLINATION="943;-75;" ID="Arrow_ID_416244548" STARTARROW="None" STARTINCLINATION="207;23;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584229199851" HGAP="47" ID="ID_1146096669" MODIFIED="1584229499004" TEXT="Vorsicht: Darstellung von Spuren und Effekten im Clip" VSHIFT="2">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -28159,7 +28181,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584319635024" ID="ID_1833569495" MODIFIED="1584319648254" TEXT="Logik im Detail ausimplementieren">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584319635024" ID="ID_1833569495" MODIFIED="1584932955050" TEXT="Logik im Detail ausimplementieren">
|
||||
<linktarget COLOR="#4768d0" DESTINATION="ID_1833569495" ENDARROW="Default" ENDINCLINATION="943;-75;" ID="Arrow_ID_416244548" SOURCE="ID_1737560927" STARTARROW="None" STARTINCLINATION="207;23;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1584319522106" ID="ID_600779996" MODIFIED="1584319541312" TEXT="Vorsicht Falle: Kopieren beim Wechsel des Anzeigestils">
|
||||
|
|
@ -28259,7 +28282,7 @@
|
|||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1540640109628" ID="ID_147809215" MODIFIED="1557498707231" TEXT="TODO: TimelineGui (proxy) muß kaskadieren">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1544135984042" ID="ID_429363053" MODIFIED="1576282358038" TEXT="Grund für den Fehler im Nexus?">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1544135984042" ID="ID_429363053" MODIFIED="1584932261288" TEXT="Grund für den Fehler im Nexus?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -28270,12 +28293,18 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#d23194" DESTINATION="ID_535289114" ENDARROW="Default" ENDINCLINATION="90;0;" ID="Arrow_ID_186398670" STARTARROW="None" STARTINCLINATION="110;9;"/>
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1540640144175" ID="ID_158939327" MODIFIED="1557498707231" TEXT="Zugang via TimelinePanel">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584932054082" ID="ID_535289114" MODIFIED="1584932261288" TEXT="#1216 Some UI components are still connected to the backbone at shutdown">
|
||||
<linktarget COLOR="#d23194" DESTINATION="ID_535289114" ENDARROW="Default" ENDINCLINATION="90;0;" ID="Arrow_ID_186398670" SOURCE="ID_429363053" STARTARROW="None" STARTINCLINATION="110;9;"/>
|
||||
<linktarget COLOR="#b183a2" DESTINATION="ID_535289114" ENDARROW="Default" ENDINCLINATION="-2880;0;" ID="Arrow_ID_1219325605" SOURCE="ID_1234616959" STARTARROW="None" STARTINCLINATION="595;36;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1540639255700" ID="ID_1855001421" MODIFIED="1557498707231" TEXT="Anzeige..">
|
||||
|
|
|
|||
Loading…
Reference in a new issue