Clip: next step to establish a Delegate and appearance style
while the actual selection logic for the appearance style still remains to be coded, this changeset basically settles the tricky initialisation sequence
This commit is contained in:
parent
dd016667ad
commit
030fbd74c4
6 changed files with 169 additions and 37 deletions
|
|
@ -64,15 +64,20 @@ namespace timeline {
|
|||
|
||||
|
||||
|
||||
|
||||
ClipPresenter::ClipPresenter (ID identity, ctrl::BusTerm& nexus, optional<int> offsetX)
|
||||
/**
|
||||
* @param identity referring to the corresponding session::Clip in Steam-Layer.
|
||||
* @param nexus a way to connect this Controller to the UI-Bus.
|
||||
* @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)
|
||||
: Controller{identity, nexus}
|
||||
, channels_{}
|
||||
, effects_{}
|
||||
, markers_{}
|
||||
, widget_{}
|
||||
{
|
||||
UNIMPLEMENTED ("decide upon the appearance style, based on the presence of the offset. Instantiate the appropriate delegate");
|
||||
ClipDelegate::buildDelegate (widget_, view, offsetX);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -122,7 +127,9 @@ namespace timeline {
|
|||
})
|
||||
.constructFrom ([&](GenNode const& spec) -> PEffect
|
||||
{
|
||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_, std::nullopt); ///////////TICKET #1213 : is it really such a good idea to pass that here??
|
||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_
|
||||
,getClipContentCanvas()
|
||||
,std::nullopt); /////////////////////////TICKET #1213 : is it really such a good idea to pass that here?? Note: nullopt effectively disables any display
|
||||
})
|
||||
.buildChildMutator ([&](PEffect& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||
{
|
||||
|
|
@ -141,17 +148,36 @@ namespace timeline {
|
|||
})
|
||||
.constructFrom ([&](GenNode const& spec) -> PChannel
|
||||
{
|
||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_, std::nullopt); ///////////TICKET #1213 : is it really such a good idea to pass that here??
|
||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_
|
||||
,getClipContentCanvas()
|
||||
,std::nullopt); /////////////////////////TICKET #1213 : how to represent "always" / "the whole track"??
|
||||
})
|
||||
.buildChildMutator ([&](PChannel& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||
{
|
||||
if (subID != target->getID()) return false;
|
||||
target->buildMutator (buff);
|
||||
return true;
|
||||
})));
|
||||
}))
|
||||
.onLocalChange ([this]()
|
||||
{
|
||||
this->resetAppearanceStyle();
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipPresenter::resetAppearanceStyle()
|
||||
{
|
||||
ClipDelegate::switchAppearance (this->widget_, defaultAppearance);
|
||||
}
|
||||
|
||||
WidgetViewHook&
|
||||
ClipPresenter::getClipContentCanvas()
|
||||
{
|
||||
UNIMPLEMENTED ("how to create and wire an embedded canvas for the clip contents/effects");
|
||||
}
|
||||
|
||||
int
|
||||
ClipPresenter::determineRequiredVerticalExtension() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,12 +86,15 @@ namespace timeline {
|
|||
|
||||
unique_ptr<ClipDelegate> widget_;
|
||||
|
||||
/** default level of detail presentation desired for each clip.
|
||||
* @note the actual appearance style is chosen based on this setting
|
||||
* yet limited by the additional information necessary to establish
|
||||
* a given level; e.g. name or content renderer must be available
|
||||
* to allow for a detailed rendering of the clip in the timeline. */
|
||||
static const ClipDelegate::Appearance defaultAppearance = ClipDelegate::COMPACT;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param identity used to refer to a corresponding session::Fork in the Session
|
||||
* @param nexus a way to connect this Controller to the UI-Bus.
|
||||
*/
|
||||
ClipPresenter (ID identity, ctrl::BusTerm& nexus, optional<int> offsetX);
|
||||
ClipPresenter (ID, ctrl::BusTerm&, WidgetViewHook&, optional<int> offsetX);
|
||||
|
||||
~ClipPresenter();
|
||||
|
||||
|
|
@ -106,6 +109,19 @@ namespace timeline {
|
|||
int determineRequiredVerticalExtension() const;
|
||||
|
||||
private:/* ===== Internals ===== */
|
||||
|
||||
/** reevaluate desired presentation mode and available data,
|
||||
* possibly leading to a changed appearance style of the clip.
|
||||
* @remark a typical example would be, when a clip's temporal position,
|
||||
* previously unspecified, now becomes defined through a diff message.
|
||||
* With this data, it becomes feasible _actually to show the clip_ in
|
||||
* the timeline. Thus the [Appearance style](\ref ClipDelegate::Appearance)
|
||||
* of the presentation widget (delegate) can be switched up from `PENDING`
|
||||
* to `ABRIDGED`.
|
||||
*/
|
||||
void resetAppearanceStyle();
|
||||
|
||||
WidgetViewHook& getClipContentCanvas();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,36 +55,55 @@
|
|||
//using sigc::ptr_fun;
|
||||
//using std::cout;
|
||||
//using std::endl;
|
||||
using std::optional;
|
||||
using std::nullopt;
|
||||
|
||||
|
||||
namespace stage {
|
||||
namespace timeline {
|
||||
|
||||
|
||||
|
||||
const int ClipDelegate::defaultOffsetY{0};
|
||||
const string ClipDelegate::defaultName{_("clip")};
|
||||
|
||||
|
||||
ClipDelegate::~ClipDelegate() { }
|
||||
|
||||
|
||||
ClipDelegate::ClipDelegate(WidgetViewHook& displayAnchor)
|
||||
: display_{&displayAnchor}
|
||||
ClipDelegate::ClipDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
namespace {// details of concrete clip appearance styles...
|
||||
|
||||
class ClipData
|
||||
: public ClipDelegate
|
||||
, util::NonCopyable
|
||||
{
|
||||
WidgetViewHook& display_;
|
||||
|
||||
/* === Interface ClipDelegate === */
|
||||
|
||||
public:
|
||||
ClipData(WidgetViewHook& 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 Gtk::Button //////////////////////////////////////////////////////////////////TICKET #1211 : need preliminary placeholder clip widget for timeline layout
|
||||
: public ViewHookedWidget
|
||||
, public ClipDelegate
|
||||
, util::MoveOnly
|
||||
, util::NonCopyable
|
||||
{
|
||||
/* === Interface ClipDelegate === */
|
||||
|
||||
public:
|
||||
ClipWidget(WidgetViewHook& displayAnchor)
|
||||
: ClipDelegate{displayAnchor}
|
||||
ClipWidget(WidgetViewHook& displayAnchor, int x, int y, uString clipName)
|
||||
: ViewHookedWidget{displayAnchor.hookedAt(x,y), clipName}
|
||||
, ClipDelegate{}
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
@ -100,6 +119,15 @@ namespace timeline {
|
|||
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!!!
|
||||
{
|
||||
if (startOffsetX)
|
||||
manager.reset (new ClipWidget{view, *startOffsetX, defaultOffsetY, defaultName});
|
||||
else
|
||||
manager.reset (new ClipData{view});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}// namespace stage::timeline
|
||||
|
|
|
|||
|
|
@ -106,7 +106,9 @@
|
|||
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
//#include <vector>
|
||||
|
||||
|
||||
|
|
@ -114,6 +116,8 @@
|
|||
namespace stage {
|
||||
namespace timeline {
|
||||
|
||||
using std::string;
|
||||
|
||||
using WidgetViewHook = model::ViewHook<Gtk::Widget>;
|
||||
|
||||
class ClipDelegate;
|
||||
|
|
@ -125,16 +129,20 @@ namespace timeline {
|
|||
*/
|
||||
class ClipDelegate
|
||||
{
|
||||
WidgetViewHook* display_;
|
||||
|
||||
public:
|
||||
virtual ~ClipDelegate(); ///< this is an interface
|
||||
ClipDelegate();
|
||||
|
||||
|
||||
enum Appearance {PENDING, SYMBOLIC, ABRIDGED, COMPACT, EXPANDED, DEGRADED};
|
||||
|
||||
|
||||
ClipDelegate(WidgetViewHook& displayAnchor);
|
||||
/** vertical offset below the track start */
|
||||
static const int defaultOffsetY;
|
||||
|
||||
/** placeholder name -- typically overridden from the model */
|
||||
static const string defaultName;
|
||||
|
||||
|
||||
/** request to change the clip delegate's appearance style, if possible.
|
||||
* @param manager entity to hold and maintain this specific appearance state.
|
||||
|
|
@ -161,6 +169,12 @@ namespace timeline {
|
|||
Appearance desired =PENDING,
|
||||
WidgetViewHook* 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,
|
||||
std::optional<int> startOffsetX); ///////////////////////TICKET #1213 : translation time->offset should be built into the ViewHook!!!
|
||||
|
||||
private:/* ===== Internals ===== */
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -146,17 +146,16 @@ namespace timeline {
|
|||
ViewHooked<TrackHeadWidget> head_;
|
||||
ViewHooked<TrackBody> body_;
|
||||
|
||||
/* ==== Interface: DisplayViewHooks===== */
|
||||
|
||||
model::ViewHook<TrackHeadWidget>& getHeadHook() override { return head_; };
|
||||
model::ViewHook<TrackBody>& getBodyHook() override { return body_; };
|
||||
model::ViewHook<Gtk::Widget>& getClipHook() override { return *this; };
|
||||
|
||||
/* === extended Interface for relative view hook === */
|
||||
|
||||
int hookAdjX (int xPos) override { return xPos; };
|
||||
int hookAdjY (int yPos) override { return yPos + body_.getContentOffsetY(); };
|
||||
|
||||
public: /* ==== Interface: DisplayViewHooks===== */
|
||||
|
||||
model::ViewHook<TrackHeadWidget>& getHeadHook() override { return head_; };
|
||||
model::ViewHook<TrackBody>& getBodyHook() override { return body_; };
|
||||
model::ViewHook<Gtk::Widget>& getClipHook() override { return *this; };
|
||||
|
||||
public:
|
||||
DisplayFrame (DisplayViewHooks& displayAnchor)
|
||||
|
|
@ -333,7 +332,7 @@ namespace timeline {
|
|||
.constructFrom ([&](GenNode const& spec) -> PClip
|
||||
{
|
||||
std::optional<int> startOffsetX{extractStartOffset (spec)}; //////////////////////////TICKET #1213 : should pass the start time instead!!
|
||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_, startOffsetX);
|
||||
return make_unique<ClipPresenter> (spec.idi, this->uiBus_, display_.getClipHook(), startOffsetX);
|
||||
})
|
||||
.buildChildMutator ([&](PClip& target, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27808,18 +27808,21 @@
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1584289349339" ID="ID_1202416542" MODIFIED="1584289360503" TEXT="also eben doch nicht gleich beim ctor-Aufruf"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584289361215" ID="ID_1687516658" MODIFIED="1584289369023" TEXT="brauche stattdessen einen Diff-Listener">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584307692087" ID="ID_1525336492" MODIFIED="1584307714957" TEXT="genügen uns Struktur-Änderungen (onSeqChange)?">
|
||||
<node COLOR="#338800" CREATED="1584289361215" ID="ID_1687516658" MODIFIED="1584319384536" TEXT="brauche stattdessen einen Diff-Listener">
|
||||
<linktarget COLOR="#38abc2" DESTINATION="ID_1687516658" ENDARROW="Default" ENDINCLINATION="30;37;" ID="Arrow_ID_901736037" SOURCE="ID_560620961" STARTARROW="None" STARTINCLINATION="129;9;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1584307692087" ID="ID_1525336492" MODIFIED="1584318646372" TEXT="genügen uns Struktur-Änderungen (onSeqChange)?">
|
||||
<icon BUILTIN="help"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
<node CREATED="1584307718907" ID="ID_211654301" MODIFIED="1584307729382" TEXT="im Moment ja, aber vermutlich längerfristig nicht">
|
||||
<node COLOR="#435e98" CREATED="1584307718907" ID="ID_211654301" MODIFIED="1584318632228" TEXT="im Moment ja, aber vermutlich längerfristig nicht">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#338800" CREATED="1584309711112" ID="ID_161551669" MODIFIED="1584309897727" TEXT="Diff-Listener um assignElm() ergänzen">
|
||||
<arrowlink COLOR="#427176" DESTINATION="ID_274485695" ENDARROW="Default" ENDINCLINATION="-1913;0;" ID="Arrow_ID_1484023114" STARTARROW="None" STARTINCLINATION="926;63;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584309903737" ID="ID_1025527544" MODIFIED="1584309912017" TEXT="onLocalChange()-Listener installieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1584309903737" ID="ID_1025527544" MODIFIED="1584318627678" TEXT="onLocalChange()-Listener installieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1584307731586" ID="ID_1716161483" MODIFIED="1584307998380">
|
||||
|
|
@ -27839,7 +27842,10 @@
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1584201751260" ID="ID_1492285349" MODIFIED="1584201760641" TEXT="Problem: initiale Koordinaten">
|
||||
<node CREATED="1584201782842" ID="ID_560620961" MODIFIED="1584201793508" TEXT="sind nicht (zwingend) im Populations-Diff"/>
|
||||
<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"/>
|
||||
</node>
|
||||
<node CREATED="1584202974665" ID="ID_920397941" MODIFIED="1584203052619" TEXT="eigentlich ehr vom Anzeigestil abhängig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -27864,6 +27870,20 @@
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1584319394162" ID="ID_1919037634" MODIFIED="1584319465811" TEXT="wir wollen aber eine unnötige Doppel-Allokation pro Clip vermeiden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
wenn man das naiv coden würde, dann würden wir für jeden Clip erst mal einen ClipData-Placeholder erzeugen, nur um dann, nach dem Empfangen des vollständigen Diff, diesen wieder zu deallozieren und dafür ein ClipWidget zu erzeugen...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1584201841529" ID="ID_1310327519" MODIFIED="1584202923362" TEXT="Nebengedanke: Eigenheiten des Populations-Diff">
|
||||
<arrowlink COLOR="#2e3f60" DESTINATION="ID_1634323626" ENDARROW="Default" ENDINCLINATION="-1672;80;" ID="Arrow_ID_1671674197" STARTARROW="None" STARTINCLINATION="-1515;90;"/>
|
||||
</node>
|
||||
|
|
@ -28026,7 +28046,33 @@
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1584229452911" ID="ID_1237351867" MODIFIED="1584229457411" TEXT="Clip auf Track"/>
|
||||
<node CREATED="1584229458191" ID="ID_911164271" MODIFIED="1584229464666" TEXT="Effekt / Medienspur im clip"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584229458191" ID="ID_911164271" MODIFIED="1584318715606" TEXT="Effekt / Medienspur im clip">
|
||||
<icon BUILTIN="flag"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1584318674620" ID="ID_789719668" MODIFIED="1584318732864" TEXT="noch TOTAL ungeklärt">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584318680419" ID="ID_1709596760" MODIFIED="1584318690915" TEXT="TODO: brauche nested Canvas-ViewHook">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584319635024" ID="ID_1833569495" MODIFIED="1584319648254" TEXT="Logik im Detail ausimplementieren">
|
||||
<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">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1584319543957" ID="ID_615255607" MODIFIED="1584319606901" TEXT="erst den alten ClipDelegate vom smart-Ptr abkoppeln">
|
||||
<icon BUILTIN="full-1"/>
|
||||
</node>
|
||||
<node CREATED="1584319564342" ID="ID_1748945736" MODIFIED="1584319609077" TEXT="denn den neuen per Copy-Initialisierung erzeugen">
|
||||
<icon BUILTIN="full-2"/>
|
||||
</node>
|
||||
<node CREATED="1584319578712" ID="ID_1036218022" MODIFIED="1584319612171" TEXT="dann den alten ClipDelegate verwerfen">
|
||||
<icon BUILTIN="full-3"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1584319587975" ID="ID_609955363" MODIFIED="1584319603776" TEXT="und das alles am Besten per smart-Ptr abgesichert">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -28067,6 +28113,9 @@
|
|||
<icon BUILTIN="forward"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1583678075045" ID="ID_1071916226" MODIFIED="1583678101462" TEXT="erst mal überhaupt einen Block belegen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1584318751425" ID="ID_1908104469" MODIFIED="1584318760838" TEXT="nehme mal einen Gtk::Button...">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1583678122516" ID="ID_73602256" MODIFIED="1583678142379" TEXT="...und dessen vertikale Ausdehnung ermitteln und zurückmelden">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue