Structure-Change: implement a simplistic implementation of re-ordering

...verified by the rather conceptual unit test
This commit is contained in:
Fischlurch 2019-12-06 23:19:09 +01:00
parent 305ff8e6cc
commit ffcac2ea1e
3 changed files with 96 additions and 33 deletions

View file

@ -57,6 +57,17 @@ namespace model {
template<class ELM>
class ViewHook;
/**
* Interface to represent _"some presentation layout entity",_
* with the ability to _attach_ widgets managed elsewhere, to
* relocate those widgets to another position, and to re-establish
* a different sequence of the widgets (whatever this means).
* @remark some typical examples for the kind of facility modelled here:
* - a _canvas widget,_ (e.g. `Gtk::Layout`), allowing to attach
* child widgets at specific positions, together with custom drawing.
* - a tree or grid control, allowing to populate some lines a given widget.
*/
template<class ELM>
class ViewHookable
{
@ -66,6 +77,7 @@ namespace model {
virtual ViewHook<ELM> hook (ELM& elm, int xPos, int yPos) =0;
virtual void move (ELM& elm, int xPos, int yPos) =0;
virtual void remove (ELM& elm) noexcept =0;
virtual void rehook (ViewHook<ELM>& hook) noexcept =0;
template<class IT>
void reOrder (IT newOrder);
@ -140,12 +152,26 @@ namespace model {
/**
* re-attach elements in a given, new order.
* @param newOrder a Lumiera Forward Iterator to yield a reference to
* all attached elements, and in the new order to be established.
* @remark this operation becomes relevant, when "attaching an element" also
* constitutes some kind of arrangement in the visual presentation, like
* e.g. a stacking order, or by populating some table cells in sequence.
* The expected semantics is for this operation to detach each given element,
* and then immediately re-attach it _at the "beginning"_ (whatever this means).
* The element as such, and all associated presentation entities are not destroyed,
* but continue to exist with the same identity (and possibly all signal wirings).
* Just they now appear as if attached with the new ordering.
*/
template<class ELM>
template<class IT>
void
ViewHookable<ELM>::reOrder (IT newOrder)
{
UNIMPLEMENTED ("generic mechanism for re-attachment in given order");
for (ViewHook<ELM>& existingHook : newOrder)
this->rehook (existingHook);
}

View file

@ -32,8 +32,6 @@
#include "lib/iter-adapter-stl.hpp"
#include "lib/util.hpp"
//#include <utility>
//#include <memory>
#include <vector>
#include <forward_list>
#include <algorithm>
@ -43,9 +41,6 @@
using util::contains;
using util::isSameObject;
using lib::iter_stl::eachElm;
//using util::isnil;
//using std::make_unique;
//using std::move;
using std::vector;
using std::forward_list;
using std::shuffle;
@ -98,7 +93,7 @@ namespace test {
.transform([](Attachment const& entry)
{
return entry.widget;
});
});
}
auto
@ -133,11 +128,21 @@ namespace test {
and pos->posY == y_expected;
}
/** verify our internal sequence matches the given one */
template<class CON>
bool
testContainsSequence (CON const& refSeq)
{
UNIMPLEMENTED("compare our internal sequence with the given one");
// NOTE the implementation twist of using a std::forward_list,
// which causes reversed order of our internal elements
auto iRef = refSeq.crbegin();
auto eRef = refSeq.crend();
auto iInt = widgets_.cbegin();
auto eInt = widgets_.cend();
for ( ; iRef != eRef and iInt != eInt; ++iRef, ++iInt)
if (not (iInt->widget == **iRef)) return false;
return iRef == eRef
and iInt == eInt;
}
@ -167,6 +172,17 @@ namespace test {
{
widgets_.remove_if ([&](Attachment const& a) { return a.widget == elm; });
}
void
rehook (WidgetViewHook& existingHook) noexcept override
{
auto pos = findEntry (*existingHook);
REQUIRE (pos != widgets_.end(), "the given iterator must yield previously hooked-up elements");
Attachment existing{*pos};
this->remove (existing.widget);
this->addDummy(existing.widget, existing.posX,existing.posY);
}
};
}
@ -175,9 +191,13 @@ namespace test {
/*************************************************************************************//**
* @test verify the mechanism to attach widgets to a canvas, while keeping the
* canvas widget itself opaque.
* - bla
* - blubb
* canvas implementation itself opaque.
* - manage the attachment and detach automatically
* - ability to adjust the location parameter of an existing attachment
* - ability to re-attach existing attachments in a new sequence order
* @remark this test focuses on the concepts and the API, and thus uses a
* dummy implementation of the "Canvas", which just registers a
* list of widgets with a dedicated "position" for each.
* @see view-hook.hpp
*/
class ViewHook_test : public Test

View file

@ -4987,7 +4987,7 @@
<node CREATED="1483921070115" ID="ID_398046799" MODIFIED="1518487921058" TEXT="Prototyp-Service"/>
<node CREATED="1483921132114" ID="ID_1652398711" MODIFIED="1518487921058" TEXT="liefert dekorierte Command-ID"/>
<node CREATED="1483921149368" ID="ID_1028150245" MODIFIED="1518487921058" TEXT="im GUI nur noch Command-IDs"/>
<node CREATED="1483924872930" ID="ID_242219866" MODIFIED="1575063775187">
<node CREATED="1483924872930" ID="ID_242219866" MODIFIED="1575667686400">
<richcontent TYPE="NODE"><html>
<head>
@ -18532,7 +18532,7 @@
</richcontent>
<icon BUILTIN="help"/>
</node>
<node COLOR="#435e98" CREATED="1573314915266" FOLDED="true" ID="ID_1550703494" MODIFIED="1575580223038" TEXT="Quer-Beweglichkeit zwischen Typen">
<node COLOR="#435e98" CREATED="1573314915266" FOLDED="true" ID="ID_1550703494" MODIFIED="1575667987460" TEXT="Quer-Beweglichkeit zwischen Typen">
<arrowlink COLOR="#b80305" DESTINATION="ID_912776786" ENDARROW="Default" ENDINCLINATION="-582;30;" ID="Arrow_ID_739783685" STARTARROW="None" STARTINCLINATION="212;897;"/>
<linktarget COLOR="#61a5df" DESTINATION="ID_1550703494" ENDARROW="Default" ENDINCLINATION="-180;0;" ID="Arrow_ID_1915156143" SOURCE="ID_1631103689" STARTARROW="None" STARTINCLINATION="-615;17;"/>
<icon BUILTIN="stop-sign"/>
@ -19021,12 +19021,16 @@
<node CREATED="1575223786739" ID="ID_926999216" MODIFIED="1575223802333" TEXT="aber ViewHook&lt;TrackBody&gt; hat einen TrackBody*"/>
<node CREATED="1575223803377" ID="ID_1526084839" MODIFIED="1575223813779" TEXT="auf das direkt daneben stehende TrackBody-Objekt"/>
</node>
<node CREATED="1575239328453" ID="ID_1096729219" MODIFIED="1575239453843" TEXT="Idee: ViewHooked&lt;Widget&gt;">
<node CREATED="1575239328453" ID="ID_1096729219" MODIFIED="1575667946076" TEXT="Idee: ViewHooked&lt;Widget&gt;">
<linktarget COLOR="#e79332" DESTINATION="ID_1096729219" ENDARROW="Default" ENDINCLINATION="-1237;46;" ID="Arrow_ID_1348207622" SOURCE="ID_1416159951" STARTARROW="None" STARTINCLINATION="2421;0;"/>
<icon BUILTIN="idea"/>
<node CREATED="1575239353279" ID="ID_1137161464" MODIFIED="1575239358488" TEXT="statt ViewHook"/>
<node CREATED="1575239360140" ID="ID_1769045218" MODIFIED="1575239745292" TEXT="also direkt an die Lebensdauer des Widget gekoppelt"/>
<node CREATED="1575239401247" ID="ID_1821251711" MODIFIED="1575566053491" TEXT="dann geht der hook()-Vorgang anders herum"/>
<node CREATED="1575239411717" ID="ID_1412083065" MODIFIED="1575239472817" TEXT="ViewHooked braucht als ctor-Parameter ein ViewHookable&amp;"/>
<node CREATED="1575239411717" ID="ID_1412083065" MODIFIED="1575239472817" TEXT="ViewHooked braucht als ctor-Parameter ein ViewHookable&amp;">
<node CREATED="1575667806989" ID="ID_334793743" MODIFIED="1575667821044" TEXT="ViewHookable::hook() wird eine void-Operation"/>
<node CREATED="1575667821800" ID="ID_722923687" MODIFIED="1575667833698" TEXT="aber der ctor garantiert (RAII) da&#xdf; sie aufgerufen wurde"/>
</node>
<node CREATED="1575239483404" ID="ID_397271082" MODIFIED="1575239488770" TEXT="und wird noncopyable">
<icon BUILTIN="ksmiletris"/>
</node>
@ -19264,11 +19268,11 @@
<node CREATED="1575581015219" ID="ID_1015965713" MODIFIED="1575581026974" TEXT="f&#xfc;r den Widget -&gt; Canvas - Fall"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575057172259" ID="ID_1193961919" MODIFIED="1575580937582" TEXT="Umordnen">
<node COLOR="#338800" CREATED="1575057172259" ID="ID_1193961919" MODIFIED="1575670553256" TEXT="Umordnen">
<linktarget COLOR="#507b9b" DESTINATION="ID_1193961919" ENDARROW="Default" ENDINCLINATION="-877;88;" ID="Arrow_ID_1469804818" SOURCE="ID_876124745" STARTARROW="None" STARTINCLINATION="576;33;"/>
<linktarget COLOR="#507b9b" DESTINATION="ID_1193961919" ENDARROW="Default" ENDINCLINATION="-877;88;" ID="Arrow_ID_624713040" SOURCE="ID_673183519" STARTARROW="None" STARTINCLINATION="706;62;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1575057384974" ID="ID_1385277309" MODIFIED="1575057397107" TEXT="komplexe Interation, die den ViewHook nur involviert">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1575057384974" ID="ID_1385277309" MODIFIED="1575670539095" TEXT="komplexe Interaktion, die den ViewHook nur involviert">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1575057402196" ID="ID_876005200" MODIFIED="1575057410423" TEXT="auch eine Vater-Kinder-Manipulation"/>
<node CREATED="1575057430215" ID="ID_581733037" MODIFIED="1575062500354" TEXT="Ablauf einer Umordnung">
@ -19310,8 +19314,8 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1575062926828" ID="ID_1755767601" MODIFIED="1575062944928" TEXT="geeignete Form finden">
<icon BUILTIN="flag-pink"/>
<node COLOR="#338800" CREATED="1575062926828" ID="ID_1755767601" MODIFIED="1575670525681" TEXT="geeignete Form finden">
<icon BUILTIN="button_ok"/>
<node CREATED="1575062976413" ID="ID_332468301" MODIFIED="1575062979193" TEXT="Diskussion">
<node CREATED="1575062980979" ID="ID_1034492398" MODIFIED="1575062997550" TEXT="Ansatz-1 Variante-b">
<node CREATED="1575063012169" ID="ID_1112616431" MODIFIED="1575063016956" TEXT="erscheint nat&#xfc;rlich"/>
@ -19393,9 +19397,9 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575063747039" ID="ID_46486640" MODIFIED="1575660470554" TEXT="versuchsweise (im Test) zu implementieren">
<node COLOR="#338800" CREATED="1575063747039" ID="ID_46486640" MODIFIED="1575670509535" TEXT="versuchsweise (im Test) zu implementieren">
<arrowlink COLOR="#4983c7" DESTINATION="ID_1374959238" ENDARROW="Default" ENDINCLINATION="-123;-10;" ID="Arrow_ID_463400867" STARTARROW="None" STARTINCLINATION="-428;25;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575063819852" ID="ID_1018000905" MODIFIED="1575132493276" TEXT="versuchsweise f&#xfc;r Track-Head und Track-Body zu konkretisieren">
<arrowlink COLOR="#261eb7" DESTINATION="ID_237283777" ENDARROW="Default" ENDINCLINATION="396;-703;" ID="Arrow_ID_119083900" STARTARROW="None" STARTINCLINATION="-962;0;"/>
@ -19503,13 +19507,26 @@
</richcontent>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575580366411" ID="ID_1747264667" MODIFIED="1575660718766" TEXT="API f&#xfc;r Umordnen">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575667886287" ID="ID_1416159951" MODIFIED="1575667946076" TEXT="Umbau auf ein ViewHooked&lt;W&gt;">
<arrowlink COLOR="#e79332" DESTINATION="ID_1096729219" ENDARROW="Default" ENDINCLINATION="-1237;46;" ID="Arrow_ID_1348207622" STARTARROW="None" STARTINCLINATION="2421;0;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1575239353279" HGAP="53" ID="ID_777015627" MODIFIED="1575668026370" TEXT="statt frei stehendem ViewHook" VSHIFT="32">
<icon BUILTIN="info"/>
<node CREATED="1575239360140" ID="ID_1324997848" MODIFIED="1575239745292" TEXT="also direkt an die Lebensdauer des Widget gekoppelt"/>
<node CREATED="1575239401247" ID="ID_460745873" MODIFIED="1575566053491" TEXT="dann geht der hook()-Vorgang anders herum"/>
<node CREATED="1575239411717" ID="ID_1117119564" MODIFIED="1575239472817" TEXT="ViewHooked braucht als ctor-Parameter ein ViewHookable&amp;">
<node CREATED="1575667806989" ID="ID_553544414" MODIFIED="1575667821044" TEXT="ViewHookable::hook() wird eine void-Operation"/>
<node CREATED="1575667821800" ID="ID_394226309" MODIFIED="1575667833698" TEXT="aber der ctor garantiert (RAII) da&#xdf; sie aufgerufen wurde"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1575580366411" ID="ID_1747264667" MODIFIED="1575670501324" TEXT="API f&#xfc;r Umordnen">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1575660738481" ID="ID_316759979" MODIFIED="1575660770786" TEXT="einfachst m&#xf6;gliche Iterator-L&#xf6;sung">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575660751327" ID="ID_1263771356" MODIFIED="1575660762658" TEXT="generische Standard-Implementierung mit entwerfen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1575660751327" ID="ID_1263771356" MODIFIED="1575670503370" TEXT="generische Standard-Implementierung mit entwerfen">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1573242259267" ID="ID_1903570032" MODIFIED="1573242269170" TEXT="Test">
@ -19523,9 +19540,9 @@
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1573242357830" ID="ID_1431447719" MODIFIED="1573242368189" TEXT="relatives Kind-Hook">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575063870245" ID="ID_1374959238" MODIFIED="1575660470554" TEXT="Umordnen">
<node COLOR="#338800" CREATED="1575063870245" ID="ID_1374959238" MODIFIED="1575670505352" TEXT="Umordnen">
<linktarget COLOR="#4983c7" DESTINATION="ID_1374959238" ENDARROW="Default" ENDINCLINATION="-123;-10;" ID="Arrow_ID_463400867" SOURCE="ID_46486640" STARTARROW="None" STARTINCLINATION="-428;25;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
@ -21669,8 +21686,8 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575579955362" ID="ID_931838684" MODIFIED="1575580643672" STYLE="fork" TEXT="strukturell-generische Implementierung">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575579955362" ID="ID_931838684" MODIFIED="1575670594063" STYLE="fork" TEXT="strukturell-generische Implementierung">
<icon BUILTIN="pencil"/>
<node COLOR="#435e98" CREATED="1575579987443" ID="ID_1007243980" MODIFIED="1575580655105" TEXT="Analyse allgemein">
<arrowlink COLOR="#2e1d90" DESTINATION="ID_274573678" ENDARROW="Default" ENDINCLINATION="-1890;235;" ID="Arrow_ID_1905963364" STARTARROW="None" STARTINCLINATION="532;69;"/>
<icon BUILTIN="button_ok"/>
@ -21679,9 +21696,9 @@
<arrowlink COLOR="#4d81bf" DESTINATION="ID_350484232" ENDARROW="Default" ENDINCLINATION="-77;-68;" ID="Arrow_ID_658076840" STARTARROW="None" STARTINCLINATION="-201;12;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575576971732" ID="ID_673183519" MODIFIED="1575580875613" TEXT="Mechanismus zum Umordnen">
<node COLOR="#338800" CREATED="1575576971732" ID="ID_673183519" MODIFIED="1575670587273" TEXT="Mechanismus zum Umordnen">
<arrowlink COLOR="#507b9b" DESTINATION="ID_1193961919" ENDARROW="Default" ENDINCLINATION="-877;88;" ID="Arrow_ID_624713040" STARTARROW="None" STARTINCLINATION="706;62;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1575050224708" ID="ID_1911321905" MODIFIED="1575050229199" TEXT="Trigger">
@ -36037,7 +36054,7 @@
<node CREATED="1492205732389" ID="ID_1080697951" MODIFIED="1518487921090" TEXT="wir k&#xf6;nnen stets gleich triggern"/>
</node>
<node CREATED="1492205741483" ID="ID_1132272888" MODIFIED="1518487921090" TEXT="Command wird sofort nach dem Binden getriggert"/>
<node COLOR="#338800" CREATED="1483925280108" HGAP="30" ID="ID_1479669922" MODIFIED="1575063775187" TEXT="Protokoll-Erweiterung" VSHIFT="8">
<node COLOR="#338800" CREATED="1483925280108" HGAP="30" ID="ID_1479669922" MODIFIED="1575667686400" TEXT="Protokoll-Erweiterung" VSHIFT="8">
<arrowlink COLOR="#e9ba2d" DESTINATION="ID_242219866" ENDARROW="Default" ENDINCLINATION="-944;1604;" ID="Arrow_ID_1617518648" STARTARROW="None" STARTINCLINATION="3617;-1097;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1483925298713" ID="ID_347702585" MODIFIED="1518487921090" TEXT="Command-Prototyp forken"/>