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:
Fischlurch 2020-03-15 23:44:01 +01:00
parent dd016667ad
commit 030fbd74c4
6 changed files with 169 additions and 37 deletions

View file

@ -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
{

View file

@ -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();
};

View file

@ -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

View file

@ -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 ===== */
};

View file

@ -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
{

View file

@ -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&#xfc;gen uns Struktur-&#xc4;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&#xfc;gen uns Struktur-&#xc4;nderungen (onSeqChange)?">
<icon BUILTIN="help"/>
<icon BUILTIN="hourglass"/>
</node>
<node CREATED="1584307718907" ID="ID_211654301" MODIFIED="1584307729382" TEXT="im Moment ja, aber vermutlich l&#xe4;ngerfristig nicht">
<node COLOR="#435e98" CREATED="1584307718907" ID="ID_211654301" MODIFIED="1584318632228" TEXT="im Moment ja, aber vermutlich l&#xe4;ngerfristig nicht">
<icon BUILTIN="yes"/>
<node COLOR="#338800" CREATED="1584309711112" ID="ID_161551669" MODIFIED="1584309897727" TEXT="Diff-Listener um assignElm() erg&#xe4;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&#xe4;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&#xf6;tige Doppel-Allokation pro Clip vermeiden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
wenn man das naiv coden w&#252;rde, dann w&#252;rden wir f&#252;r jeden Clip erst mal einen ClipData-Placeholder erzeugen, nur um dann, nach dem Empfangen des vollst&#228;ndigen Diff, diesen wieder zu deallozieren und daf&#252;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&#xe4;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 &#xfc;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&#xfc;ckmelden">
<icon BUILTIN="flag-yellow"/>