diff --git a/src/stage/widget/element-box-widget.cpp b/src/stage/widget/element-box-widget.cpp index 5a5f1ef3b..e4970c3f4 100644 --- a/src/stage/widget/element-box-widget.cpp +++ b/src/stage/widget/element-box-widget.cpp @@ -62,34 +62,34 @@ namespace widget { ElementBoxWidget::~ElementBoxWidget() { } - void - ElementBoxWidget::Strategy::configure() + ElementBoxWidget::Strategy + ElementBoxWidget::Config::buildLayoutStrategy() { - + return Strategy{"LoLoLo"}; } Literal - ElementBoxWidget::Strategy::getIconID() const + ElementBoxWidget::Config::getIconID() const { ///////////////////////////////////////////////////////////////////////////TICKET #1185 : implement logic to pick suitable icon... return "track_enabled"; //////////////////////////////////////////////TICKET #1219 : maybe at leas a better generic placeholder icon...? } Gtk::IconSize - ElementBoxWidget::Strategy::getIconSize() const + ElementBoxWidget::Config::getIconSize() const { ///////////////////////////////////////////////////////////////////////////TICKET #1185 : is Icon-Size flexible under some circumstances? return Gtk::ICON_SIZE_MENU; } - ElementBoxWidget::ElementBoxWidget (Strategy strategy) + ElementBoxWidget::ElementBoxWidget (Config config) : Frame{} + , strategy_{config.buildLayoutStrategy()} , label_{Gtk::ORIENTATION_HORIZONTAL} - , icon_{Gtk::StockID{strategy.getIconID()} ///////////////////////////////TICKET #1030 : use of stockIDs is deprecated; care for a more modern icon naming scheme - , strategy.getIconSize()} + , icon_{Gtk::StockID{config.getIconID()} ///////////////////////////////TICKET #1030 : use of stockIDs is deprecated; care for a more modern icon naming scheme + , config.getIconSize()} { - strategy.configure(); set_name(ID_element); get_style_context()->add_class(CLASS_background); // Style to ensure an opaque backdrop set_label_align(0.0, 0.0); @@ -99,7 +99,7 @@ namespace widget { label_.add(name_); label_.set_name(ID_caption); label_.get_style_context()->add_class(CLASS_background); - name_.set_text(strategy.getName()); + name_.set_text(config.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 252d7ccbc..c739e2128 100644 --- a/src/stage/widget/element-box-widget.hpp +++ b/src/stage/widget/element-box-widget.hpp @@ -93,17 +93,25 @@ namespace widget { class ElementBoxWidget : public Gtk::Frame { + struct Strategy + { + string lambdaLaLa; + }; + + /** actual layout strategy binding for this widget */ + Strategy strategy_; + Gtk::Box label_; Gtk::Image icon_; Gtk::Label name_; public: - class Strategy; + class Config; template ElementBoxWidget (Kind kind, Type type, QS ...qualifiers); - ElementBoxWidget (Strategy); + ElementBoxWidget (Config); ~ElementBoxWidget(); // default copy acceptable @@ -112,12 +120,12 @@ namespace widget { }; - class ElementBoxWidget::Strategy - : lib::BuilderQualifierSupport + class ElementBoxWidget::Config + : lib::BuilderQualifierSupport { Type type_; uString nameID_{"∅"}; - string logTODO_{nameID_}; + string logTODO_{nameID_}; //////////////////////////////////////////////////////////////////////////TICKET #1219 : Placeholder for detailed layout configuration friend Qualifier kind(Kind); friend Qualifier name(string id); @@ -125,14 +133,14 @@ namespace widget { public: template - Strategy(Type type, Qualifier qual, QS... qs) + Config(Type type, Qualifier qual, QS... qs) : type_{type} { qualify(*this, qual, qs...); } /** decide upon the presentation strategy */ - void configure(); + Strategy buildLayoutStrategy(); Literal getIconID() const; Gtk::IconSize getIconSize() const; @@ -145,33 +153,33 @@ namespace widget { }; - inline ElementBoxWidget::Strategy::Qualifier + inline ElementBoxWidget::Config::Qualifier kind(Kind kind) { - return ElementBoxWidget::Strategy::Qualifier{ - [=](ElementBoxWidget::Strategy& strategy) + return ElementBoxWidget::Config::Qualifier{ + [=](ElementBoxWidget::Config& config) { - strategy.logTODO_ += util::_Fmt{"+kind(%s)"} % kind; + config.logTODO_ += util::_Fmt{"+kind(%s)"} % kind; }}; } - inline ElementBoxWidget::Strategy::Qualifier + inline ElementBoxWidget::Config::Qualifier name(string id) { - return ElementBoxWidget::Strategy::Qualifier{ - [=](ElementBoxWidget::Strategy& strategy) + return ElementBoxWidget::Config::Qualifier{ + [=](ElementBoxWidget::Config& config) { - strategy.nameID_ = id; + config.nameID_ = id; }}; } - inline ElementBoxWidget::Strategy::Qualifier + inline ElementBoxWidget::Config::Qualifier expander(model::Expander& expander) { - return ElementBoxWidget::Strategy::Qualifier{ - [&](ElementBoxWidget::Strategy& strategy) + return ElementBoxWidget::Config::Qualifier{ + [&](ElementBoxWidget::Config& config) { - strategy.logTODO_ += util::_Fmt{"+expander(%s)"} % &expander; + config.logTODO_ += util::_Fmt{"+expander(%s)"} % &expander; }}; } @@ -183,7 +191,7 @@ namespace widget { */ template inline ElementBoxWidget::ElementBoxWidget (Kind widgetKind, Type type, QS ...qualifiers) - : ElementBoxWidget{Strategy(type, kind(widgetKind), qualifiers...)} + : ElementBoxWidget{Config(type, kind(widgetKind), qualifiers...)} { } diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 663908cb7..ccafa926f 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)
@@ -3274,6 +3274,7 @@ The class {{{widget::ElementBoxWidget}}} uses a flexible declarative constructor
 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)
+*{{{constrained(λ, [λₙ])}}} : constrain widget extension, providing getter functors to retrieve desired size in canvas pixels
 
 
 !!!proportional Head placement
@@ -3296,7 +3297,8 @@ Thus, if we intend to bring a custom widget into compliance with our contextual
 * the resulting desired ("natural") size allocation is then adjusted by widget decoration and finally passed to the widget for storage and use
 It turns out that the GTK layout management implementation always observes the widget's preferred extension, but possibly expands the allocation to fill additional space. And the standard implementation of {{{Gtk::Widget}}} in turn delegates those queries to the ''GTK CSS Gadget'' — which is a mapping of the hierarchical widget structure into CSS layout nodes.
 
-So the seemingly ''optimal leverage point'' is to ''return our pre established size constraint as result'' from these query functions — which can be overridden in the Gtkmm C++ implementation through the {{{Gtk::Widget::get_preferred_width_vfunc()}}} and {{{Gtk::Widget::get_preferred_height_for_width_vfunc()}}}. However, since GTK assumes these values to be sane and sufficient for a proper realisation of any embedded content, at this point we get the responsibility to control and reduce the embedded child widget's extension to bring them into compliance. Failing to do so will lead to garbled drawing on screen.
+So the seemingly ''optimal leverage point'' is to ''return our pre established size constraint as result'' from these query functions — which can be overridden in the Gtkmm C++ implementation through the {{{Gtk::Widget::get_preferred_width_vfunc()}}} and {{{Gtk::Widget::get_preferred_height_for_width_vfunc()}}}. However, since GTK assumes these values to be sane and sufficient for a proper realisation of any embedded content, at this point it becomes our responsibility to control and reduce the embedded child widget's extension to bring them into compliance. Failing to do so will lead to garbled drawing on screen.
+
 Our solution approach is to watch the results returned by the default implementation and possibly to hide content until the remaining content conforms to the size constraint; after that, we can return //exactly our calibrated size// and expect GTK to observe this request, passing it down to embedded widgets reduced by style decorations.
 
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 94e22c43d..1207c1faa 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -6312,7 +6312,7 @@ - + @@ -17932,6 +17932,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -18235,8 +18257,14 @@ - - + + + + + + + + @@ -18509,6 +18537,7 @@ + @@ -18554,7 +18583,7 @@ - + @@ -18597,6 +18626,436 @@ + + + + + + + + + + + + +

+ das ist eine Design/Architektur-Entscheidung; ein generisches Widget soll noch nicht mit dem speziellen Belang einer Eichung in Zeiteinheiten belastet werden; dies hat dann jeweils ins abgeleiteten Klassen zu erfolgen, so z.B im Clip-Widget +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...insofern dann die Beschränkung der Ausdehnung einzig dadurch aktiviert werden kann, daß man ein geeignetes Verb angibt, welches diese beiden Lambda als Argument nimmt +

+ +
+
+ + + + + + +

+ ...und ich muß die Frage, wann genau diese Info bezogen wird, überhaupt nicht klären +

+ +
+
+ + + + + + +

+ wobei letztlich nur ein queue_resize erfolgen muß; es könnte also sein, daß dafür der Aufruf einer bestehenden GTK-Funktion genügt +

+ +
+
+ + + + + + +

+ ...unter der Annahme, daß letzlich eine "invalidation" des Widgets genügt, ließe sich das elegant lösen, indem der Canvas-Container insgesamt "invalidated" wird. +

+ +
+
+
+
+ + + + + + +

+ In Summe viel eleganter. +

+
    +
  • + das Dokumentations-Problem wird durch die DSL gelöst +
  • +
  • + die "Invalidation" sollte sich aus dem Parent-Container ergeben +
  • +
  • + damit bleiben hier praktisch keine Probleme mehr übrig +
  • +
  • + Redundanz im DSL-API ist nicht wirklich ein Problem; Kind=CONTENT impliziert nicht notwendig auch ein geeichtes Display +
  • +
  • + ansonsten sollte dieser Ansatz komplett transparent funktionieren, und dürfte weniger fragil sein +
  • +
+ +
+ + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +

+ Bedingt durch das Aufrufschema können wir nicht zu Beginn steuernd eingreifen, sondern wir können nur erkennen, wenn das Sub-Widget (aus welchen Gründen auch immer) den extension-constraint verletzt. Und wir bekommen keine direkten Wirkfaktoren in die Hand (weil sich die Ausdehnung aus einem komplexen Zusammenspiel von Font, Pixelgröße und Styles ergibt) +

+ +
+ +
+ + + + + + + + + + + +

+ ...das heißt... +

+
    +
  • + der GTK-Lyout-Callback wird aufgerufen +
  • +
  • + er ruft die btr. Callbacks der Kinder auf, um deren natürliche Größe zu ermitteln +
  • +
  • + wenn die Kinder nicht in den vorhandenen Platz passen, werden sie manipuliert oder verborgen +
  • +
+ +
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +

+ Unterscheidung resize ⟺ rerender +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +

+ Analyse: welche beweglichen Teile gibt es überhaupt? +

+ +
+ +
+ + + + + + + + + + + + + +

+ ...die name-ID muß eindeutig sein (modulo Objekt-Typ), weil allein daraus eine EntryID zu konstruieren ist, vermöge deren die Kommunikation über den Bus gesteuert wird. Daher ist es denkbar, daß die User [optional] eine mnemonische Form definieren wollen, und diese steht dann im Label-Widget. Und noch etwas: der Label-Text wird ggfs. zur Anzeige gekürzt, also muß irgendwo der Basis-Text stehen (es sei denn, man holt sich den via Request über den Bus) +

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+ analog wie ein Player; während das Content-Rendering läuft muß der Clip eine Registrierung in einem zuständigen OutputManager aufrechterhalten, um die berechneten Pixmaps dann entgegenzunehmen +

+ +
+
+ + + + + + +

+ ...wir speichern ganz sicher nicht ein Mini-Bild für jeden Frame eines Video, sondern brauchen hier wohl eine Art lokales Caching; das heißt, die Pixmaps für einen aktiven Bereich plus eine gewisse Umgebung sind direkt greifbar im GUI. Dieses Caching ist aber nur ein 1st-Level, denn wir wollen den (als sehr elaboriert konzipierten) globalen Frame-Cache auch für diesen Zweck mitbenutzen; schließlich dürften diese Vorschaubilder die häufigsten laufenden Rendervorgänge sein... +

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18741,6 +19200,15 @@ + + + + + + + + + @@ -26803,7 +27271,7 @@ - + @@ -27959,7 +28427,7 @@ - + @@ -31563,14 +32031,14 @@ - + - + - + @@ -31787,7 +32255,7 @@ - + @@ -32001,7 +32469,7 @@ - + @@ -32009,7 +32477,7 @@ - + @@ -32227,6 +32695,7 @@ + @@ -33868,6 +34337,7 @@ + @@ -34917,10 +35387,11 @@ - + - + + @@ -52002,8 +52473,8 @@ - + @@ -57559,8 +58030,8 @@ - + @@ -57737,9 +58208,9 @@ - - + + @@ -60386,6 +60857,60 @@ + + + + + + + + + + + + + + + +

+ Das Thema »Layout-Steuerung in der Timeline« lief aus dem Ruder (wie erwartet — warum soll's mir besser gehen, als Joel Holdsworth?). Ich habe dahinter aber ein Architektur-Problem identifiziert, nämlich daß hier eine selbs-ähnliche rekursive Struktur notwendig ist, welche aber mehrere separate Kontexte überspannt. Dafür habe ich die Entität DisplayFrame  erfunden, und die Idee war, diesen als Kristallisationskern zu verwenden, um die gesamte Struktur um das Timeline-Layout zu reinigen. Leider konnte ich das aber (Stand 9/2022) nicht weiterführen, weil ich nun das GUI wieder verlassen muß, um an der RenderEngine weiterzuarbeiten... +

+ +
+ +
+ + + + + + +

+ ....dieses Thema sollte generisch gelöst werden, und dann weiter entwickelt in Richtung »Interaction Design« — also mit einem aktuellen Fokus verbunden, und mit jeweils eigener Historie pro Fokus, so daß man in die verschiedenen Fokus-Zonen über gut etablierte "Leitern" wieder einsteigen könnte. Leider muß ich (Stand 9/2022) das GUI nun wieder verlassen, und es ist ganz und gar ungeklärt, unter welchen Umständen dieses zentrale Thema wieder aufgenommen werden kann... +

+

+ WaitingDesign um den Display-Frame im Timeline-Layout  +

+ +
+ +
+ + + + + + +

+ ...beim Herauslösen aus dem Gnome-Application / GIO-Framework habe ich detailiert die Strukturen um die Main-Loop untersucht und verstanden. Leider stehen diese Infos bisher (Stand 9/2022) nur in meiner Mindmap; ich sollte eine eigene Kategorie in der Webseite/Dokumentation schaffen, in der solche Einsichten aufgezeichnet werden können... +

+ +
+ +
+
+ +