From 38b6228fac1b2e2eb57aaf1f7faa8c35ac7fe1d7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 1 Sep 2022 19:34:38 +0200 Subject: [PATCH] ElementBox: working draft of ElementBoxWidget, establishing ctor framework The flexible custom styling yet needs to be definied. Just adding a stock icon and a standard sized label field for now. Widget can be constructed and successfully attached to a track. --- src/stage/dialog/test-control.hpp | 2 +- src/stage/timeline/marker-widget.cpp | 3 +- src/stage/timeline/timeline-controller.cpp | 5 + src/stage/timeline/track-presenter.hpp | 13 +++ src/stage/widget/element-box-widget.cpp | 27 ++++- src/stage/widget/element-box-widget.hpp | 119 ++++++++++++++++++++- wiki/renderengine.html | 27 ++++- wiki/thinkPad.ichthyo.mm | 103 ++++++++++++++++-- 8 files changed, 281 insertions(+), 18 deletions(-) diff --git a/src/stage/dialog/test-control.hpp b/src/stage/dialog/test-control.hpp index f8e95795e..34a8fdf91 100644 --- a/src/stage/dialog/test-control.hpp +++ b/src/stage/dialog/test-control.hpp @@ -152,7 +152,7 @@ namespace dialog { * A complex, tabbed-notebook-style non-modal dialog window, * dedicated to development, diagnostics and experimentation. * The TestControl can be launched from Lumiera's "Help" menu, - * offers an (passive, up-link) [UI-Bus connection](\ref ui-bus.hpp) + * offers a (passive, up-link) [UI-Bus connection](\ref ui-bus.hpp) * and simplifies adding pages for occasional experiments and diagnostics. */ class TestControl diff --git a/src/stage/timeline/marker-widget.cpp b/src/stage/timeline/marker-widget.cpp index d9b6b8a14..65670f1b0 100644 --- a/src/stage/timeline/marker-widget.cpp +++ b/src/stage/timeline/marker-widget.cpp @@ -63,7 +63,8 @@ namespace timeline { MarkerWidget::MarkerWidget (ID identity, ctrl::BusTerm& nexus) - : Widget{identity, nexus} + : model::Widget{identity, nexus} + , ElementBoxWidget(widget::MARK, widget::Type::LABEL) , kind_{MARK} , name_{identity.getSym()} // ID symbol as name fallback { diff --git a/src/stage/timeline/timeline-controller.cpp b/src/stage/timeline/timeline-controller.cpp index 40dc234f6..9ef76888a 100644 --- a/src/stage/timeline/timeline-controller.cpp +++ b/src/stage/timeline/timeline-controller.cpp @@ -105,6 +105,11 @@ namespace timeline { { this->fork_->injectDebugTrackLabels(); } + else + if (mark.idi.getSym() == "box" && this->fork_) + { + this->fork_->attachElementBox(); + } else // forward to default handler model::Controller::doMark (mark); } diff --git a/src/stage/timeline/track-presenter.hpp b/src/stage/timeline/track-presenter.hpp index 1d7a66592..c7984b900 100644 --- a/src/stage/timeline/track-presenter.hpp +++ b/src/stage/timeline/track-presenter.hpp @@ -216,6 +216,7 @@ namespace timeline { virtual void buildMutator (lib::diff::TreeMutator::Handle) override; /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this void injectDebugTrackLabels(); + void attachElementBox(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this uString TODO_trackName_; @@ -257,6 +258,18 @@ namespace timeline { for (auto& subTrack : subFork_) subTrack->injectDebugTrackLabels(); } + inline void + TrackPresenter::attachElementBox() + { + uint x = rand() % 200; + uint y = 0; + widget::ElementBoxWidget* box = Gtk::manage ( + new model::CanvasHooked{display_.hookedAt(x,y) + , widget::Kind::MARK + , widget::Type::LABEL + , widget::name("Ω") + }); + } /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1201 : test/code... remove this /** * @note we distinguish between the contents of our four nested child collections diff --git a/src/stage/widget/element-box-widget.cpp b/src/stage/widget/element-box-widget.cpp index 881e9d7a9..60de7706b 100644 --- a/src/stage/widget/element-box-widget.cpp +++ b/src/stage/widget/element-box-widget.cpp @@ -59,15 +59,32 @@ namespace widget { - ElementBoxWidget::ElementBoxWidget () - { - } - - ElementBoxWidget::~ElementBoxWidget() { } + void + ElementBoxWidget::Strategy::configure() + { + + } + + ElementBoxWidget::ElementBoxWidget (Strategy strategy) + : Frame{} + , label_{Gtk::ORIENTATION_HORIZONTAL} + , icon_{Gtk::StockID{"track_enabled"}, Gtk::ICON_SIZE_MENU} ////////////////TODO: use of stockIDs is deprecated; care for a more modern icon naming scheme + { + strategy.configure(); + set_label_widget(label_); + label_.add(icon_); + label_.add(name_); + name_.set_text(strategy.getName()); + name_.set_hexpand(true); + + this->show_all(); + } + + diff --git a/src/stage/widget/element-box-widget.hpp b/src/stage/widget/element-box-widget.hpp index 92f5c622c..308d8454b 100644 --- a/src/stage/widget/element-box-widget.hpp +++ b/src/stage/widget/element-box-widget.hpp @@ -33,6 +33,7 @@ ** notion of _"type"._ ** ** @todo WIP-WIP-WIP as of 11/2018 ///////////////////////////////////////////////////////////////////////TICKET #1185 + ** @todo WIP-WIP-WIP as of 9/2022 ///////////////////////////////////////////////////////////////////////TICKET #1219 ** */ @@ -41,31 +42,145 @@ #define STAGE_WIDGET_ELEMENT_BOX_WIDGET_H #include "stage/gtk-base.hpp" +#include "stage/model/expander-revealer.hpp" +#include "lib/builder-qualifier-support.hpp" //#include "lib/util.hpp" +#include "lib/format-string.hpp" //#include //#include +#include //////TODO debugging namespace stage { namespace widget { + using std::string; /////TODO + using util::_Fmt; /////TODO debugging? + + /** the presentation intent for the ElementBoxWidget */ + enum Kind { MARK ///< Widget is a pin or marks a position + , SPAN ///< Widget spans a time range + , ITEM ///< Widget represents an entity within a collection (Bin) + , CONTENT ///< Widget serves to represent a piece of content (Clip) + }; + + /** the type of content object to derive suitable styling */ + enum Type { VIDEO ///< represents moving (or still) image data + , AUDIO ///< represents sound data + , TEXT ///< represents text content + , AUTO ///< represents automation + , EVENT ///< represents event streams or live connections + , EFFECT ///< represents a processor or transformer + , LABEL ///< represents a label or descriptor + , RULER ///< represents an overview ruler or TOC + , GROUP ///< represents a container to group other entities + , META ///< represents some meta entity + }; + /** - * @todo WIP-WIP as of 12/2016 + * A basic building block of the Lumiera UI. + * Representation of an entity, with a marker icon, a menu, descriptive label and + * possibly a content renderer (e.g. for a video clip). Depending on the presentation intent, + * the widget can extend to a defined time range horizontally. Pre-defined styling and bindings + * to expand the display and to invoke a menu are provided */ class ElementBoxWidget + : public Gtk::Frame { + Gtk::Box label_; + Gtk::Image icon_; + Gtk::Label name_; + public: - ElementBoxWidget (); + class Strategy; + + template + ElementBoxWidget (Kind kind, Type type, QS ...qualifiers); + + ElementBoxWidget (Strategy); ~ElementBoxWidget(); + + // default copy acceptable private:/* ===== Internals ===== */ }; + class ElementBoxWidget::Strategy + : lib::BuilderQualifierSupport + { + Type type_; + uString nameID_{"∅"}; + string logTODO_{nameID_}; + + friend Qualifier kind(Kind); + friend Qualifier name(string id); + friend Qualifier expander(model::Expander&); + + public: + template + Strategy(Type type, Qualifier qual, QS... qs) + : type_{type} + { + qualify(*this, qual, qs...); + } + + /** decide upon the presentation strategy */ + void configure(); + + cuString + getName() const + { + return nameID_; + } + }; + + + inline ElementBoxWidget::Strategy::Qualifier + kind(Kind kind) + { + return ElementBoxWidget::Strategy::Qualifier{ + [=](ElementBoxWidget::Strategy& strategy) + { + strategy.logTODO_ += util::_Fmt{"+kind(%s)"} % kind; + }}; + } + + inline ElementBoxWidget::Strategy::Qualifier + name(string id) + { + return ElementBoxWidget::Strategy::Qualifier{ + [=](ElementBoxWidget::Strategy& strategy) + { + strategy.nameID_ = id; + }}; + } + + inline ElementBoxWidget::Strategy::Qualifier + expander(model::Expander& expander) + { + return ElementBoxWidget::Strategy::Qualifier{ + [&](ElementBoxWidget::Strategy& strategy) + { + strategy.logTODO_ += util::_Fmt{"+expander(%s)"} % &expander; + }}; + } + + + /** setup an ElementBoxWidget with suitable presentation style. + * @param widgetKind the basic presentation intent + * @param type qualify the type of data represented by this object + * @param qualifiers pass further qualifiers to fine-tune the presentation + */ + template + inline ElementBoxWidget::ElementBoxWidget (Kind widgetKind, Type type, QS ...qualifiers) + : ElementBoxWidget{Strategy(type, kind(widgetKind), qualifiers...)} + { } + }}// namespace stage::widget #endif /*STAGE_WIDGET_ELEMENT_BOX_WIDGET_H*/ diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 283981cbf..f37367e05 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -3217,7 +3217,7 @@ In accordance with this structure, we introduce a central component, the {{{Pane -
+
//A building block used pervasively throughout the Lumiera UI  to represent a named entity.//
 This widget presents a horizontally extended body, which holds a characteristic ''Head-Triplet'' of visual Elements:
 * an //Icon// to create the visual anchor point. In many cases, this will be ''the Placment Icon'' (a hallmark of Lumiera's UI)
@@ -3251,6 +3251,31 @@ We offer pre-arranged options for standard wiring of interaction response
 * the ''Expander'' (which is part of the UI-Element protocol) is pre-wired with the arrow on the menu button, to yield a visible clue for the expand/collapse state
 * each of the bindings can be easily replaced by a [[pop-up menu|GuiPopupMenu]]
 
+!!!usage and setup
+The class {{{widget::ElementBoxWidget}}} uses a flexible declarative constructor style, defining the //intended use// while delegating the details of styling to CSS classes. On construction, it is mandatory to define
+;presentation intent
+:what we want to achieve with this widget instance
+:*{{{MARK}}} : Widget is a pin or marks a position 
+:*{{{SPAN}}} : Widget spans a time range
+:*{{{ITEM}}} : Widget represents an entity within a collection (Bin)
+:*{{{CONTENT}}} : Widget serves to represent a piece of content (Clip)
+;object type
+:the type of data to be represented by this widget
+:*{{{VIDEO}}} : represents moving (or still) image data
+:*{{{AUDIO}}} : represents sound data
+:*{{{TEXT}}} : represents text content, e.g. Subtitles, Credits
+:*{{{AUTO}}} : represents automation
+:*{{{EVENT}}} : represents event streams or live connections, like e.g. MIDI data
+:*{{{EFFECT}}} : represents a processor or transformer
+:*{{{LABEL}}} : represents a label or descriptor
+:*{{{RULER}}} : represents an overview ruler or TOC
+:*{{{GROUP}}} : represents a [[Fork]], Bin or similar container to group other entities
+:*{{{META}}} : represents some meta entity
+In addition to these mandatory arguments, a sequence of //qualifiers// can be supplied to tweak the details of the presentation
+*{{{name(string)}}} : define the name or ID to be shown in the label field
+*{{{expander(ref)}}} : use a expand/collapse button, wired with the given »expander« functor (part of the standard UI-Element protocol)
+
+
 !!!proportional Head placement
 This behaviour pattern (see [[#1186|https://issues.lumiera.org/ticket/1186]]) is a distinguishing trait of the Lumiera timeline display. It indicates elements with a temporal extension surpassing the current display window. Such elements are typically represented by an {{{ElementBoxWidget}}} with an large horizontal extension. Yet when scrolling, the head-triplet shall always remain within the visible area, but it will slowly glide from one side to the other, thereby indicating the our relative position. This pattern of behaviour matters, since, together with the scolled content display, it creates the dominant movement when scrolling an extended timeline
 
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 345956bd1..e01070285 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -5261,7 +5261,25 @@
 
 
 
-
+
+
+
+
+  
+    
+  
+  
+    

+ Stock-IDs sind @deprecated +

+ +
+ +
+ + + +
@@ -6338,6 +6356,10 @@
+ + + + @@ -18163,6 +18185,7 @@ + @@ -18339,7 +18362,7 @@ - + @@ -18351,9 +18374,18 @@

...was hab ich bei den Kind-Elementen vom Track gemacht?

+

+ ⟹ die heißen auch »Marker« +

+ + + + + +
@@ -18427,17 +18459,44 @@ - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18589,8 +18648,19 @@ - - + + + + + + + + + + + + + @@ -56363,6 +56433,23 @@ + + + + + + + +

+ @deprecated früher gab es die Stock-IDs +

+ +
+
+ + + +