43 #ifndef STAGE_TIMELINE_CLIP_PRESENTER_H 44 #define STAGE_TIMELINE_CLIP_PRESENTER_H 70 using std::unique_ptr;
71 using std::make_unique;
91 vector<unique_ptr<ClipPresenter>> channels_;
92 vector<unique_ptr<ClipPresenter>> effects_;
93 vector<unique_ptr<MarkerWidget>> markers_;
95 unique_ptr<ClipDelegate> widget_;
115 : Controller{identity, nexus}
132 using PChannel = unique_ptr<ClipPresenter>;
133 using PEffect = unique_ptr<ClipPresenter>;
134 using PMarker = unique_ptr<MarkerWidget>;
139 .isApplicableIf ([&](
GenNode const& spec) ->
bool 143 .constructFrom ([&](
GenNode const& spec) -> PMarker
145 return make_unique<MarkerWidget> (spec.idi, this->uiBus_);
148 .isApplicableIf ([&](
GenNode const& spec) ->
bool 152 .constructFrom ([&](
GenNode const& spec) -> PEffect
155 return make_unique<ClipPresenter> (spec.idi, this->uiBus_
156 ,getClipContentCanvas()
160 .isApplicableIf ([&](
GenNode const& spec) ->
bool 162 return TYPE_Channel == spec.data.
recordType();
164 .constructFrom ([&](
GenNode const& spec) -> PChannel
166 return make_unique<ClipPresenter> (spec.idi, this->uiBus_
167 ,getClipContentCanvas()
170 .change(ATTR_name, [&](
string val)
173 widget_->setClipName (val);
175 .change(ATTR_timing, [&](
TimeSpan val)
178 widget_->accessStartTime() = val.start();
179 widget_->accessDuration() = val.duration();
182 .onLocalChange ([
this]()
197 return widget_->calcRequiredHeight()
198 + widget_->getVerticalOffset();
212 widget_->updatePosition();
228 updateOffset (
double deltaX,
double deltaY)
override 231 subject_.widget_->updatePosition();
232 std::cerr <<
_Fmt{
"Gesture(%s) → Δ ≔ (%3.1f,%3.1f) ⟹ %s ↷ %s"}
237 % subject_.widget_->accessStartTime()
242 markGestureCompleted()
override 244 std::cerr <<
_Fmt{
"!!BANG!! Gesture-Cmd '%s' Time ↷ %s"}
253 , subject_{clipPresenter}
254 , metric_ {subject_.widget_->getCanvas().getMetric()}
255 , newTime_{subject_.widget_->accessStartTime()}
288 optional<TimeSpan>
const& timing =nullopt)
290 void* prevDelegate = widget_.get();
293 if (prevDelegate != widget_.get()
294 and newAppearance > ClipDelegate::DEGRADED)
304 getClipContentCanvas()
306 UNIMPLEMENTED (
"how to create and wire an embedded canvas for the clip contents/effects");
static Appearance selectAppearance(PDelegate &existing, Appearance desired=PENDING, WidgetHook *newView=nullptr, optional< TimeSpan > const &timing=nullopt)
request to change the clip delegate's appearance style, if possible.
a mutable time value, behaving like a plain number, allowing copy and re-accessing ...
void establishAppearance(WidgetHook *newView=nullptr, optional< TimeSpan > const &timing=nullopt)
reevaluate desired presentation mode and available data, possibly leading to a changed appearance sty...
A View-Model entity to represent a clip within the timeline-UI.
Hard wired key constants and basic definitions for communication with the GUI.
CmdContext && linkSubject(Subject &subj)
Builder operation: define the subject to use for the following interaction bindings.
connection point at the UI-Bus.
void buildGestureObserver(Symbol cmdID, Buffer buffer) override
prompt the Subject to build an Observer for the gesture in formation
Mix-in interface to allow for concrete CanvasHooked widgets to adapt themselves to the metric current...
ClipPresenter(ID identity, ctrl::BusTerm &nexus, WidgetHook &view, optional< TimeSpan > const &timing)
Appearance
desired appearance style for the clip
SUB & create(ARGS &&...args)
Abbreviation for placement new of a subclass SUB into the opaque buffer.
Common ID definitions for Steam-Layer commands.
A front-end for using printf-style formatting.
Lumiera's internal time value datatype.
Gtk::Widget & exposeWidget() override
the exposed widget can be used for wiring signal handlers
void setupRelocateDrag()
Terminal builder operation: establish the infrastructure for the already defined participants to be i...
void relink()
update and re-attach the presentation widget into its presentation context.
static Builder< TreeMutator > build()
DSL: start building a custom adapted tree mutator, where the operations are tied by closures or wrapp...
SUB & emplace(SUB &&implementation)
move-construct an instance of a subclass into the opaque buffer
Token or Atom with distinct identity.
A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBu...
static CmdContext of(Symbol cmdID, Symbol ctxID)
global static service accessor function.
static const ClipDelegate::Appearance defaultAppearance
default maximum level of detail presentation desired for each clip.
Lumiera GTK UI implementation root.
virtual TimeValue applyScreenDelta(Time anchor, double deltaPx) const =0
translate an offset in pixel coordinates into a temporal position
std::optional< X > retrieveAttribute(string key) const
mismatch tolerant convenience shortcut to peek into the attributes of a nested Record ...
string recordType() const
peek into the type field of a nested Record<GenNode>
virtual void buildMutator(TreeMutator::Handle buffer) override
set up a binding to respond to mutation messages via UiBus
uint determineRequiredVerticalExtension() const
find out the number of pixels necessary to render this clip properly, assuming its current presentati...
static Gtk::Widget & expect_and_expose_Widget(PDelegate &manager)
Wrapper to safely expose the actual clip implementation widget.
A time interval anchored at a specific point in time.
auto collection(COLL &coll)
Entry point to a nested DSL for setup and configuration of a collection binding.
a family of time value like entities and their relationships.
Collaboration interface for tracking the formation of a gesture.
Common Abstraction of all sub-controller, coordinated by the UI-Bus.
A set of basic GTK includes for the UI.
generic data element node within a tree
Abstraction: support for binding command invocation into an UI context.
Role-Interface: the Subject of Interaction.
Customisable intermediary to abstract mutating operations on arbitrary, hierarchical object-like data...