ElementBox: extract the caption and size handling logic into sub widget

as it turns out, this is a self-contained separate concern,
and thus this arrangement of two icons plus a caption shall
now manage itself as a custom widget.

And while touching this subject, I have also reconsidered
the purpose and arrangement of those icons and completed
the specification with some decisions...
- context menus will be left-click, selection right-click (Blender!)
- we will always show those two icons, just allocate different graphics
- when there is no expander, the 2nd icon will just serve to open the menu
- so the button is almost redundant in that case (except when dragging)
This commit is contained in:
Fischlurch 2022-09-30 18:55:22 +02:00
parent c05abb88ab
commit 53c614afc2
4 changed files with 296 additions and 40 deletions

View file

@ -95,8 +95,11 @@ namespace widget {
IDLabel::~IDLabel() { }
ElementBoxWidget::~ElementBoxWidget() { }
Literal
ElementBoxWidget::Config::getIconID() const
{
@ -104,6 +107,13 @@ namespace widget {
return "track_enabled"; //////////////////////////////////////////////TICKET #1219 : maybe at least a better generic placeholder icon...?
}
Literal
ElementBoxWidget::Config::getMenuSymb() const
{
///////////////////////////////////////////////////////////////////////////TICKET #1185 : implement logic to pick suitable icon...
return "gtk-go-down"; //////////////////////////////////////////////TICKET #1219 : maybe at least a better generic placeholder icon...?
}
Gtk::IconSize
ElementBoxWidget::Config::getIconSize() const
{
@ -124,25 +134,49 @@ namespace widget {
}
IDLabel::IDLabel (Literal iconID, Literal menuSymb, Gtk::IconSize siz)
: Gtk::Box{Gtk::ORIENTATION_HORIZONTAL}
, imgIcon_{Gtk::StockID{iconID}, siz} ///////////////////////////////TICKET #1030 : use of stockIDs is deprecated; care for a more modern icon naming scheme
, imgMenu_{Gtk::StockID{menuSymb}, siz} ////////////////////////
{
icon_.set_image(imgIcon_);
menu_.set_image(imgMenu_);
this->add(icon_);
this->add(menu_);
this->add(name_);
this->set_name(ID_caption);
this->get_style_context()->add_class(CLASS_background);
name_.set_hexpand(true);
}
cuString
IDLabel::getCaption() const
{
return name_.get_text();
}
void
IDLabel::setCaption(cuString& idCaption)
{
name_.set_text(idCaption);
}
ElementBoxWidget::ElementBoxWidget (Config config)
: Frame{}
, strategy_{config.buildLayoutStrategy(*this)}
, label_{Gtk::ORIENTATION_HORIZONTAL}
, icon_{Gtk::StockID{config.getIconID()} ///////////////////////////////TICKET #1030 : use of stockIDs is deprecated; care for a more modern icon naming scheme
, config.getIconSize()}
, label_{config.getIconID()
,config.getMenuSymb()
,config.getIconSize()}
{
set_name(ID_element);
get_style_context()->add_class(CLASS_background); // Style to ensure an opaque backdrop
set_label_align(0.0, 0.0);
set_label_widget(label_);
label_.add(icon_);
label_.add(name_);
label_.set_name(ID_caption);
label_.get_style_context()->add_class(CLASS_background);
name_.set_text(config.getName());
name_.set_hexpand(true);
label_.setCaption(config.getName());
this->show_all();
}
@ -238,15 +272,29 @@ namespace widget {
* in case the extension of ElementBoxWidget is explicitly constrained in size.
*/
void
ElementBoxWidget::imposeSizeConstraint(int widthC, int heightC)
ElementBoxWidget::imposeSizeConstraint (int widthC, int heightC)
{
ASSERT (name_.get_realized(), "ElementBoxWidget layout constraint imposed "
"on widget not yet realized by GTK");
bool hiddenCaption = not name_.get_visible();
if (not hiddenCaption)
ASSERT (label_.get_realized(), "ElementBoxWidget layout constraint imposed "
"on widget not yet realized by GTK");
label_.imposeSizeConstraint (widthC, heightC);
}
/**
* Ensure the IDLabel stays within a given size constraint.
* In case the standard rendering of with icon and name caption exceeds
* the given screen space, this simplified initial implementation just
* hides the name caption, assuming without further check that the two
* icons will fit into the constrained space.
* @todo as of 9/22, a planned full implementation will eventually
* shorten the caption text and possibly also combine both
* Icons into a single button when necessary... ///////////////////TICKET #1238 : adjust size of the ID caption
*/
void
IDLabel::imposeSizeConstraint (int widthC, int heightC)
{
if (name_.get_visible())
{ // detect if label box fits within given size constraint
queryNaturalSize (label_, labelFullSize_);
queryNaturalSize (*this, labelFullSize_);
if (labelFullSize_.width > widthC or labelFullSize_.height > heightC)
name_.hide();

View file

@ -93,12 +93,49 @@ namespace widget {
using SizeGetter = std::function<int()>;
/**
* Widget arrangement to represent an entity for manipulation.
* This uniform standard arrangement is comprised of
* - a leading Placement- or Type-Icon
* - a Menu button
* - a caption for identification
* The IDLabel widget offers standard hooks for wiring signals
* and controlling the layout; notably the widget extension
* can be confined to stay within given constraints.
*/
class IDLabel
: public Gtk::Box
{
Gtk::Image imgIcon_;
Gtk::Image imgMenu_;
Gtk::Button icon_;
Gtk::Button menu_;
Gtk::Label name_;
public:
~IDLabel();
IDLabel(Literal iconID, Literal menuSymb, Gtk::IconSize);
cuString getCaption() const;
void setCaption(cuString&);
void imposeSizeConstraint(int, int);
private:
Gtk::Requisition labelFullSize_{};
};
/*************************************************************************//**
* 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
* 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 be set to a fixed horizontal extension,
* to allow presentation on a time calibrated canvas. Pre-defined styling and
* bindings to expand the display and to invoke a menu are provided.
* @todo consider policy based design, //////////////////////////////////////////////////////////////////TICKET #1239 : re-evaluate Design, maybe use Policy Based Design
* but need more exposure and real world usage as of 9/22
*/
@ -117,10 +154,7 @@ namespace widget {
/** actual layout strategy binding for this widget */
Strategy strategy_;
Gtk::Box label_;
Gtk::Image icon_;
Gtk::Label name_;
IDLabel label_;
public:
class Config;
@ -142,7 +176,6 @@ namespace widget {
void on_size_allocate (Gtk::Allocation&) override;
void imposeSizeConstraint(int, int);
Gtk::Requisition labelFullSize_{};
};
@ -172,7 +205,8 @@ namespace widget {
/** decide upon the presentation strategy */
Strategy buildLayoutStrategy(ElementBoxWidget&);
Literal getIconID() const;
Literal getIconID() const;
Literal getMenuSymb() const;
Gtk::IconSize getIconSize() const;
cuString

View file

@ -3217,7 +3217,7 @@ In accordance with this structure, we introduce a central component, the {{{Pane
</pre>
</div>
<div title="GuiElementBoxWidget" creator="Ichthyostega" modifier="Ichthyostega" created="201811011919" modified="202209241501" tags="GuiPattern spec draft" changecount="13">
<div title="GuiElementBoxWidget" creator="Ichthyostega" modifier="Ichthyostega" created="201811011919" modified="202209301654" tags="GuiPattern spec draft" changecount="18">
<pre>//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)
@ -3237,7 +3237,7 @@ This characteristic cadence of elements gives us a horizontal box with distinct
!Properties
* the Icon shall be easily configurable (from the coding view point, of course this is all hard wired in the code or the theme)
** the default is to configure the ''Placement Icon''
** alternatively a ~Stock-ID can be given
** alternatively the icon shall indicate the type of the object (video, audio, events, meta,...)
* the horizontal extension is easy to control, through several options
** natural extension; don't give any ''size request'', let GTK figure out the extension rather
** set a fixed length-limit, causing the text label to be abridged eventually
@ -3247,9 +3247,10 @@ This characteristic cadence of elements gives us a horizontal box with distinct
We offer pre-arranged options for standard wiring of interaction response
* when the Icon is a Placement, it will launch the [[Placement-Pop-up|GuiPlacementDisplay]] -- which in turn can be de-modalised, thereby allocating a place in the [[Property grid pane|GuiPropertyPane]]. When such a placement control already is open and allocated, the click to the placement icon will lead there.
* in the most basic case, there is only one common binding, which is a signal, emitted when clicking on the icon or the menu button
* yet there can be two distinct bindings (signals) for the icon and the button
* 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
* yet there can be two distinct bindings (signals) for the icon and the button; when present, these //push aside (or shadow)// the generic signal
* 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; in this case, the menu changes to an up/down arrow and shadows the generic signal (which is typically a context menu)
* each of the bindings can be easily replaced by a [[pop-up menu|GuiPopupMenu]]
* the context menu opens on ''left click'' (selection will be ''right click'' in Lumiera!)
!!!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
@ -3277,8 +3278,23 @@ In addition to these mandatory arguments, a sequence of //qualifiers// can be su
*{{{constrained(λ, [λₙ])}}} : constrain widget extension, providing getter functors to retrieve desired size in canvas pixels
!!!presentation intent and layout
The indicated //intent of presentation// controls various aspects of the basic arrangement and wiring -- this custom widget has to cover two quite different usage situations, and aims at establishing an uniform handling scheme throughout the UI. For one, it will represent an //item,// either within a selection or within a control pane (e.g. track head). While the other usage scenario is to present //content.//
* presentation of items should be concise, and the visual clues serve to indicate the type of data or object
* while the presentation of content aims at manipulation and arrangement; in many cases there is also an interaction with the content itself
The common denominator however is, that ''each element is an object'' and thus can be ''placed'' (by a [[Placement]]), and it offers ''methods'' through a ''context menu''. Moreover, //mutations and manipulations// shall only be possible on ''selected elements'' (never accidentally by just clicking on something). Selection has to be //kept distinct from manipulation.// Just clicking on the placement icon (or the type icon for that) will activate a //property box,// enabling to tweak the //way of placement// together with some further generic marks and tags. Settings and tweaks on the content are rather accessed through the content display -- while there should be also a shortcut to move from the property box into tweaking of parameters (e.g. of effects)
!!!!To summarise...
* first icon &amp;rarr; placement property box
* second icon &amp;rarr;
** either expand / collapse
** or the regular object context menu
* click on the object also yields that context menu
* mutation methods are only accessible when the entity is selected
* the same holds true for manipulation through gestures (dragging, trim edits)
!!!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
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 scrolled content display, it creates the dominant movement when scrolling an extended timeline
''Technically'', this has to be build as a self-contained component, which can be unit-tested. The input and reference is a &quot;Window&quot; (in fact an interval) together with its start position //relative// to the element's own start position. The component has to derive from this input the actual relational configuration of the window's extension with respect to its own extension. For context, the //window// corresponds to the visible area, which can be larger, smaller disjoint, partially overlapping and fully contained. Please note that ''handling the relations of intervals is a notoriously challenging problem.''

View file

@ -18184,6 +18184,79 @@
<node CREATED="1625073209509" ID="ID_1647215892" MODIFIED="1625073216705" TEXT="Knopf mit Ein/Aus-Funktion"/>
<node CREATED="1625073252395" ID="ID_1887674930" MODIFIED="1625073270866" TEXT="Placement mit Placement-Properties"/>
<node CREATED="1625073397733" ID="ID_252893466" MODIFIED="1625073403209" TEXT="Typ-Icon"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664546626719" ID="ID_482244613" MODIFIED="1664548727113" TEXT="Varianten">
<linktarget COLOR="#5559e6" DESTINATION="ID_482244613" ENDARROW="Default" ENDINCLINATION="-920;179;" ID="Arrow_ID_1621895884" SOURCE="ID_303509395" STARTARROW="None" STARTINCLINATION="226;27;"/>
<icon BUILTIN="yes"/>
<node CREATED="1664546651860" ID="ID_54475262" MODIFIED="1664546667097" TEXT="das Grundmuster ist unver&#xe4;nderbar fixiert"/>
<node CREATED="1664546675817" ID="ID_1608209700" MODIFIED="1664546690747" TEXT="das erste Icon wird nach Presentation-Intent belegt">
<node CREATED="1664546694038" ID="ID_375518756" MODIFIED="1664546699722" TEXT="default: Placement"/>
<node CREATED="1664546700429" ID="ID_1871717245" MODIFIED="1664546714656" TEXT="Bin-Item: Typ-Icon"/>
</node>
<node CREATED="1664546716995" ID="ID_1893051713" MODIFIED="1664546729304" TEXT="das zweite Icon ist entweder ein Men&#xfc;, oder ein Expander">
<node CREATED="1664546774836" ID="ID_1104234333" MODIFIED="1664548057947" TEXT="Men&#xfc; == normales Kontext-Men&#xfc;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...das hei&#223;t, der Men&#252;-Button ist dann nur <i>pro forma </i>da, und bietet eine Fl&#228;che, auf der man zuverl&#228;ssig dieses Men&#252; trifft; letzteres ist relevant f&#252;r eine Anzeige in Listen und Bins, bei der ansonsten die Ausdehnung des Widgets stark reduziert ist. Ein Klick auf das Name-Label hat eine andere Funktion (n&#228;mlich Editieren des Namens). Ein Weiterer Aspekt ist die Drag-Geste: es ist denkbar, diese auf dem Men&#252;-Button <i>nicht</i>&#160;zu starten (wobei allerdings zu bedenken ist, das Ziehen auch noch an weitere Voraussetzungen zu kn&#252;pfen, z.B. einen Modifiere, oder den Umstand, da&#223; das Objekt auch selektiert ist)
</p>
</body>
</html></richcontent>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1664546786666" ID="ID_418065847" MODIFIED="1664546893122" TEXT="links-Klick">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Ja, wir wollen das alte Blender-Modell: Selektion mit rechts, Aktion mit links
</p>
</body>
</html></richcontent>
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="yes"/>
</node>
<node CREATED="1664546793973" ID="ID_79262414" MODIFIED="1664546802948" TEXT="auch auf dem freien Hintergrund"/>
</node>
<node CREATED="1664546805728" ID="ID_162637423" MODIFIED="1664547883294" TEXT="Expander typischerweise f&#xfc;r Timeline-Content">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
in diesem Fall ist das dann eine Art Toggle-Button, d.h. er wechselt auch seine Gestalt
</p>
</body>
</html></richcontent>
<node CREATED="1664546823853" ID="ID_1235252109" MODIFIED="1664546831232" TEXT="dann verdrahtet mit Tangible"/>
<node CREATED="1664546831980" ID="ID_1813900014" MODIFIED="1664547929394">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
das <i>verdr&#228;ngt lediglich </i>das Kontext-Men&#252;
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...denn das Kontext-Men&#252; soll auf dem ganzen Widget liegen (und konkurriert &#252;brigens mit der Drag-Geste)
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1625073420073" ID="ID_1610907627" MODIFIED="1625073651531" TEXT="Expander">
<icon BUILTIN="flag-yellow"/>
@ -18223,8 +18296,8 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1612620683850" ID="ID_1290975013" MODIFIED="1612620687427" TEXT="auszuarbeiten....">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1612620683850" ID="ID_1290975013" MODIFIED="1664548424931" TEXT="auszuarbeiten....">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1625075258497" ID="ID_1793264120" MODIFIED="1625075268568" TEXT="Steuerung des Darstellungs-Verhaltens">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1625075337795" ID="ID_873107891" MODIFIED="1625075355499" TEXT="Analyse">
@ -18260,7 +18333,7 @@
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1625075342643" ID="ID_1177317250" MODIFIED="1625075354429" TEXT="Design-Entscheidungen">
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1625075347837" ID="ID_1633859495" MODIFIED="1664029945723" TEXT="dynamic composition in ctor">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
@ -18587,6 +18660,43 @@
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#210f69" CREATED="1664548449268" ID="ID_303509395" MODIFIED="1664548735480" TEXT="Design-Prinzipien">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<ul>
<li>
festes Schema aus zwei Icons
</li>
<li>
nur die Art der Icons wird ausgewechselt
</li>
<li>
beide Icons sind Buttons und l&#246;sen f&#252;hren eine Steuer-Aktion aus (keine direkte Manipulation)
</li>
<li>
der erste Button f&#252;hrt immer in den Placement-Editor, der so etwas wie eine Property-Box darstellt (ggfs als Pop-Up, ggfs in einem Pannel-Grid)
</li>
<li>
der zweite Button &#246;ffnet entweder das normale Pop-up-Men&#252; (das auf <b>Linksklick</b>&#160;liegt), oder er bet&#228;tigt den Expander
</li>
</ul>
</body>
</html></richcontent>
<arrowlink COLOR="#5559e6" DESTINATION="ID_482244613" ENDARROW="Default" ENDINCLINATION="-920;179;" ID="Arrow_ID_1621895884" STARTARROW="None" STARTINCLINATION="226;27;"/>
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1664548762473" ID="ID_1889891499" MODIFIED="1664548771120" TEXT="Icons belegen">
<icon BUILTIN="hourglass"/>
<node COLOR="#338800" CREATED="1664548773656" ID="ID_1911341239" MODIFIED="1664553930837" TEXT="M&#xf6;glichkeit f&#xfc;r zwei Icon-Button vorsehen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1664548786932" ID="ID_1354120525" MODIFIED="1664553936475" TEXT="Konfigurierbarkeit gew&#xe4;hrleisten">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1662241779699" ID="ID_178231784" MODIFIED="1664036010955" TEXT="#1236 Placement-Icon">
<icon BUILTIN="flag-yellow"/>
</node>
@ -19139,17 +19249,61 @@
<linktarget COLOR="#fcf2bc" DESTINATION="ID_611179505" ENDARROW="Default" ENDINCLINATION="88;-31;" ID="Arrow_ID_96952850" SOURCE="ID_1660318028" STARTARROW="None" STARTINCLINATION="76;2;"/>
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664543738587" ID="ID_418832883" MODIFIED="1664543749125" TEXT="Experiment durchf&#xfc;hren">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664543750721" ID="ID_1515243070" MODIFIED="1664543842744">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<font face="Monospaced">setName(cuString&amp;)</font>&#160;implementieren
</p>
</body>
</html></richcontent>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664543863364" ID="ID_1704098172" MODIFIED="1664543873447" TEXT="Test-Manipulationsfunktion">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664543973587" ID="ID_1411171343" MODIFIED="1664544008919" TEXT="Verb &quot;manip&quot;">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664543988561" ID="ID_622195313" MODIFIED="1664544008920" TEXT="manipuliert die zuletzt erzeugte Box">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664543997192" ID="ID_332394972" MODIFIED="1664544008921" TEXT="setzt einen neuen Random-String">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664544020621" ID="ID_1995553965" MODIFIED="1664544039227" TEXT="Verhalten per Dump-msg beobachten">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1664033233729" ID="ID_73562728" MODIFIED="1664033252543" TEXT="ggfs &#xdc;bersetzungs-Faktor im Advice-System ablegen">
<icon BUILTIN="hourglass"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1664033337194" ID="ID_142928718" MODIFIED="1664033344674" TEXT="Label-Komponente anlegen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1664033348579" ID="ID_575467306" MODIFIED="1664033378313" TEXT="erst mal nur als eine Gruppierung mit HIlfsfunktionen">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1664033337194" ID="ID_142928718" MODIFIED="1664553871141" TEXT="Label-Komponente anlegen">
<arrowlink COLOR="#feebc1" DESTINATION="ID_1075411565" ENDARROW="Default" ENDINCLINATION="-16;-582;" ID="Arrow_ID_957764469" STARTARROW="None" STARTINCLINATION="-606;54;"/>
<icon BUILTIN="pencil"/>
<node COLOR="#435e98" CREATED="1664033348579" ID="ID_575467306" MODIFIED="1664553856140" TEXT="erst mal als gruppiertes Sub-Widget extrahieren">
<icon BUILTIN="yes"/>
<node COLOR="#338800" CREATED="1664544131446" ID="ID_448994253" MODIFIED="1664553853255" TEXT="der Box-Container">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1664033361175" ID="ID_314954032" MODIFIED="1664033374574" TEXT="k&#xf6;nnte sp&#xe4;ter mal selber ein Custom-Widget werden">
<node COLOR="#338800" CREATED="1664544138573" ID="ID_334656865" MODIFIED="1664553854357" TEXT="plus die Size-Handling-Logik">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1664553879483" ID="ID_923634948" MODIFIED="1664553900007" TEXT="Buttons sind zu gro&#xdf;">
<icon BUILTIN="broken-line"/>
</node>
<node COLOR="#338800" CREATED="1664544186535" ID="ID_272598573" MODIFIED="1664553847453" TEXT="Auslegung der Icons per Strategy steuerbar machen">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1664033361175" ID="ID_314954032" MODIFIED="1664544103011" TEXT="k&#xf6;nnte sp&#xe4;ter mal eigenst&#xe4;ndiges Custom-Widget werden">
<icon BUILTIN="hourglass"/>
</node>
</node>
@ -19350,6 +19504,10 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1664548844498" ID="ID_1075411565" MODIFIED="1664548893098" TEXT="Label-Komponente weiterentwickeln">
<linktarget COLOR="#feebc1" DESTINATION="ID_1075411565" ENDARROW="Default" ENDINCLINATION="-16;-582;" ID="Arrow_ID_957764469" SOURCE="ID_142928718" STARTARROW="None" STARTINCLINATION="-606;54;"/>
<icon BUILTIN="hourglass"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1661703437825" ID="ID_1401386216" MODIFIED="1661703453368" TEXT="proportional Head placement">
<icon BUILTIN="hourglass"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1661703477179" ID="ID_1739233114" MODIFIED="1661703485808" TEXT="#1186 proportional Head placement">
@ -58691,9 +58849,9 @@
</body>
</html></richcontent>
<arrowlink COLOR="#4c96df" DESTINATION="ID_619170334" ENDARROW="Default" ENDINCLINATION="22;-288;" ID="Arrow_ID_1241133759" STARTARROW="None" STARTINCLINATION="-30;150;"/>
<linktarget COLOR="#692b5b" DESTINATION="ID_563938836" ENDARROW="Default" ENDINCLINATION="621;-190;" ID="Arrow_ID_152388281" SOURCE="ID_1917960846" STARTARROW="None" STARTINCLINATION="-357;417;"/>
<linktarget COLOR="#692b5b" DESTINATION="ID_563938836" ENDARROW="Default" ENDINCLINATION="668;-205;" ID="Arrow_ID_378269338" SOURCE="ID_1435876974" STARTARROW="None" STARTINCLINATION="-279;578;"/>
<linktarget COLOR="#852376" DESTINATION="ID_563938836" ENDARROW="Default" ENDINCLINATION="18;-93;" ID="Arrow_ID_1194665328" SOURCE="ID_1959081786" STARTARROW="None" STARTINCLINATION="-211;17;"/>
<linktarget COLOR="#692b5b" DESTINATION="ID_563938836" ENDARROW="Default" ENDINCLINATION="668;-205;" ID="Arrow_ID_378269338" SOURCE="ID_1435876974" STARTARROW="None" STARTINCLINATION="-279;578;"/>
<linktarget COLOR="#692b5b" DESTINATION="ID_563938836" ENDARROW="Default" ENDINCLINATION="621;-190;" ID="Arrow_ID_152388281" SOURCE="ID_1917960846" STARTARROW="None" STARTINCLINATION="-357;417;"/>
<icon BUILTIN="idea"/>
<node CREATED="1663955121019" ID="ID_1249298775" MODIFIED="1663955138898" TEXT="wird direkt anscheinend nur von Init aus aktiviert"/>
<node CREATED="1663955139409" ID="ID_857432800" MODIFIED="1663955255321" TEXT="aber die Call-Graphen sind schwer durchschaubar">