52 #ifndef STAGE_TIMELINE_CLIP_PRESENTER_H 53 #define STAGE_TIMELINE_CLIP_PRESENTER_H 79 using std::unique_ptr;
80 using std::make_unique;
100 vector<unique_ptr<ClipPresenter>> channels_;
101 vector<unique_ptr<ClipPresenter>> effects_;
102 vector<unique_ptr<MarkerWidget>> markers_;
104 unique_ptr<ClipDelegate> widget_;
124 : Controller{identity, nexus}
141 using PChannel = unique_ptr<ClipPresenter>;
142 using PEffect = unique_ptr<ClipPresenter>;
143 using PMarker = unique_ptr<MarkerWidget>;
148 .isApplicableIf ([&](
GenNode const& spec) ->
bool 152 .constructFrom ([&](
GenNode const& spec) -> PMarker
154 return make_unique<MarkerWidget> (spec.idi, this->uiBus_);
157 .isApplicableIf ([&](
GenNode const& spec) ->
bool 161 .constructFrom ([&](
GenNode const& spec) -> PEffect
164 return make_unique<ClipPresenter> (spec.idi, this->uiBus_
165 ,getClipContentCanvas()
169 .isApplicableIf ([&](
GenNode const& spec) ->
bool 171 return TYPE_Channel == spec.data.
recordType();
173 .constructFrom ([&](
GenNode const& spec) -> PChannel
175 return make_unique<ClipPresenter> (spec.idi, this->uiBus_
176 ,getClipContentCanvas()
179 .change(ATTR_name, [&](
string val)
182 widget_->setClipName (val);
184 .change(ATTR_timing, [&](
TimeSpan val)
187 widget_->accessStartTime() = val.start();
188 widget_->accessDuration() = val.duration();
191 .onLocalChange ([
this]()
206 return widget_->calcRequiredHeight()
207 + widget_->getVerticalOffset();
221 widget_->updatePosition();
237 updateOffset (
double deltaX,
double deltaY)
override 240 subject_.widget_->updatePosition();
241 std::cerr <<
_Fmt{
"Gesture(%s) → Δ ≔ (%3.1f,%3.1f) ⟹ %s ↷ %s"}
246 % subject_.widget_->accessStartTime()
251 markGestureCompleted()
override 253 std::cerr <<
_Fmt{
"!!BANG!! Gesture-Cmd '%s' Time ↷ %s"}
262 , subject_{clipPresenter}
263 , metric_ {subject_.widget_->getCanvas().getMetric()}
264 , newTime_{subject_.widget_->accessStartTime()}
297 optional<TimeSpan>
const& timing =nullopt)
299 void* prevDelegate = widget_.get();
302 if (prevDelegate != widget_.get()
303 and newAppearance > ClipDelegate::DEGRADED)
313 getClipContentCanvas()
315 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...