Structure-Change: draft other API for hooking up widgets

...basically it occurred to me that in practice we will never have to deal
with isolated ViewHooks, rather with widgets-combinded-with-a-hook.
So the idea is to combine both into a template ViewHooked<W>
This commit is contained in:
Fischlurch 2019-12-08 21:06:28 +01:00
parent ffcac2ea1e
commit 99e367f33b
2 changed files with 109 additions and 45 deletions

View file

@ -55,8 +55,6 @@ namespace test {
struct DummyWidget struct DummyWidget
{ {
int x = rand() % 100;
int y = rand() % 100;
int i = rand(); // "identity" int i = rand(); // "identity"
friend bool friend bool
@ -66,7 +64,7 @@ namespace test {
} }
}; };
using WidgetViewHook = ViewHook<DummyWidget>; using HookedWidget = ViewHook<DummyWidget>;
@ -87,12 +85,12 @@ namespace test {
} }
auto auto
allWidgets() const allWidgetIDs() const
{ {
return lib::treeExplore(widgets_) return lib::treeExplore(widgets_)
.transform([](Attachment const& entry) .transform([](Attachment const& entry)
{ {
return entry.widget; return entry.widget.i;
}); });
} }
@ -113,9 +111,9 @@ namespace test {
} }
bool bool
testContains (DummyWidget const& someWidget) testContains (int someWidgetID)
{ {
return util::linearSearch (allWidgets(), someWidget); return util::linearSearch (allWidgetIDs(), someWidgetID);
} }
bool bool
@ -148,11 +146,11 @@ namespace test {
/* === Interface ViewHookable === */ /* === Interface ViewHookable === */
WidgetViewHook HookedWidget
hook (DummyWidget& elm, int xPos, int yPos) override hook (DummyWidget& elm, int xPos, int yPos) override
{ {
addDummy(elm, xPos,yPos); addDummy(elm, xPos,yPos);
return WidgetViewHook{elm, *this}; return HookedWidget{elm, *this};
} }
void void
@ -175,7 +173,7 @@ namespace test {
void void
rehook (WidgetViewHook& existingHook) noexcept override rehook (HookedWidget& existingHook) noexcept override
{ {
auto pos = findEntry (*existingHook); auto pos = findEntry (*existingHook);
REQUIRE (pos != widgets_.end(), "the given iterator must yield previously hooked-up elements"); REQUIRE (pos != widgets_.end(), "the given iterator must yield previously hooked-up elements");
@ -207,6 +205,7 @@ namespace test {
run (Arg) run (Arg)
{ {
verify_standardUsage(); verify_standardUsage();
verify_multiplicity();
relocateWidget(); relocateWidget();
reOrderHooked(); reOrderHooked();
} }
@ -218,42 +217,80 @@ namespace test {
verify_standardUsage() verify_standardUsage()
{ {
FakeCanvas canvas; FakeCanvas canvas;
DummyWidget widget; CHECK (canvas.empty());
{ {
WidgetViewHook hook = canvas.hook (widget, widget.x, widget.y); HookedWidget widget{canvas};
CHECK (isSameObject (*hook, widget)); CHECK (canvas.testContains (widget.i));
CHECK (canvas.testContains (widget));
CHECK (not canvas.empty()); CHECK (not canvas.empty());
}// hook goes out of scope... }// hook goes out of scope...
CHECK (not canvas.testContains (widget));
CHECK (canvas.empty()); CHECK (canvas.empty());
} }
/** @test relocate a widget on the canvas through the ViewHook handle /** @test each hooking has a distinct identity and is managed on its own.
*/
void
verify_multiplicity()
{
FakeCanvas canvas;
CHECK (canvas.empty());
HookedWidget widget{canvas};
CHECK (canvas.testContains (widget.i));
CHECK (not canvas.empty());
int someID;
{
HookedWidget otherWidget{canvas};
someID = otherWidget.i;
CHECK (canvas.testContains (someID));
CHECK (canvas.testContains (widget.i));
}// hook goes out of scope...
CHECK (not canvas.testContains (someID));
CHECK (canvas.testContains (widget.i));
CHECK (not canvas.empty());
DummyWidget cloneWidget{std::move (widget)};
CHECK (not canvas.testContains (cloneWidget.i));
CHECK (canvas.empty());
}
/** @test hook a widget at a specific position and then later
* relocate it on the canvas through the ViewHookable front-end.
*/ */
void void
relocateWidget() relocateWidget()
{ {
FakeCanvas canvas; int x1 = rand() % 100;
DummyWidget w1, w2, w3; int y1 = rand() % 100;
WidgetViewHook h1 = canvas.hook (w1, w1.x,w1.y); int x2 = rand() % 100;
WidgetViewHook h3 = canvas.hook (w3, w3.x,w3.y); int y2 = rand() % 100;
{ int x3 = rand() % 100;
WidgetViewHook h2 = canvas.hook (w2, w2.x,w2.y); int y3 = rand() % 100;
CHECK (canvas.testVerifyPos (w2, w2.x,w2.y));
int newX = ++w2.x; FakeCanvas canvas;
int newY = --w2.y; HookedWidget w1{canvas.hookedAt(x1,y1)};
h2.moveTo (newX,newY); HookedWidget w3{canvas.hookedAt(x3,y3)};
int id2;
{
HookedWidget w2{canvas.hookedAt(x2,y2)};
id2 = w2.i;
CHECK (canvas.testContains (id2));
CHECK (canvas.testVerifyPos (w2, x2,y2));
int newX = ++x2;
int newY = --y2;
w2.moveTo (newX,newY);
CHECK (canvas.testVerifyPos (w2, newX,newY)); CHECK (canvas.testVerifyPos (w2, newX,newY));
CHECK (canvas.testVerifyPos (w1, w1.x,w1.y)); CHECK (canvas.testVerifyPos (w1, x1,y1));
CHECK (canvas.testVerifyPos (w3, w3.x,w3.y)); CHECK (canvas.testVerifyPos (w3, x3,y3));
} }
CHECK (canvas.testVerifyPos (w1, w1.x,w1.y)); CHECK (not canvas.testContains (id2));
CHECK (canvas.testVerifyPos (w3, w3.x,w3.y)); CHECK (canvas.testVerifyPos (w1, x1,y1));
CHECK (not canvas.testContains (w2)); CHECK (canvas.testVerifyPos (w3, x3,y3));
} }
@ -262,29 +299,24 @@ namespace test {
void void
reOrderHooked() reOrderHooked()
{ {
using WidgetVec = vector<DummyWidget>; using WidgetVec = vector<HookedWidget>;
using HookVec = vector<WidgetViewHook>;
// create 20 (random) widgets and hook them onto the canvas // create 20 (random) widgets and hook them onto the canvas
WidgetVec widgets{20}; WidgetVec widgets;
FakeCanvas canvas; FakeCanvas canvas;
HookVec hooks; for (uint i=0; i<10; ++i)
for (auto& w : widgets) widgets.emplace_back (canvas);
hooks.emplace_back (canvas.hook (w, w.x,w.y));
CHECK (canvas.testContainsSequence (hooks)); CHECK (canvas.testContainsSequence (widgets));
// now lets assume the relevant order of the widgets has been altered // now lets assume the relevant order of the widgets has been altered
shuffle (hooks.begin(),hooks.end(), std::random_device()); shuffle (widgets.begin(),widgets.end(), std::random_device());
CHECK (not canvas.testContainsSequence (hooks)); CHECK (not canvas.testContainsSequence (widgets));
// so we need to re-construct the canvas attachments in the new order // so we need to re-construct the canvas attachments in the new order
canvas.reOrder (eachElm (hooks)); canvas.reOrder (eachElm (widgets));
CHECK (canvas.testContainsSequence (hooks)); CHECK (canvas.testContainsSequence (widgets));
} }
/** @test */
}; };

View file

@ -19507,9 +19507,9 @@
</richcontent> </richcontent>
<icon BUILTIN="flag-yellow"/> <icon BUILTIN="flag-yellow"/>
</node> </node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575667886287" ID="ID_1416159951" MODIFIED="1575667946076" TEXT="Umbau auf ein ViewHooked&lt;W&gt;"> <node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575667886287" ID="ID_1416159951" MODIFIED="1575835656408" 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;"/> <arrowlink COLOR="#e79332" DESTINATION="ID_1096729219" ENDARROW="Default" ENDINCLINATION="-1237;46;" ID="Arrow_ID_1348207622" STARTARROW="None" STARTINCLINATION="2421;0;"/>
<icon BUILTIN="flag-yellow"/> <icon BUILTIN="pencil"/>
<node CREATED="1575239353279" HGAP="53" ID="ID_777015627" MODIFIED="1575668026370" TEXT="statt frei stehendem ViewHook" VSHIFT="32"> <node CREATED="1575239353279" HGAP="53" ID="ID_777015627" MODIFIED="1575668026370" TEXT="statt frei stehendem ViewHook" VSHIFT="32">
<icon BUILTIN="info"/> <icon BUILTIN="info"/>
<node CREATED="1575239360140" ID="ID_1324997848" MODIFIED="1575239745292" TEXT="also direkt an die Lebensdauer des Widget gekoppelt"/> <node CREATED="1575239360140" ID="ID_1324997848" MODIFIED="1575239745292" TEXT="also direkt an die Lebensdauer des Widget gekoppelt"/>
@ -19519,6 +19519,35 @@
<node CREATED="1575667821800" ID="ID_394226309" MODIFIED="1575667833698" TEXT="aber der ctor garantiert (RAII) da&#xdf; sie aufgerufen wurde"/> <node CREATED="1575667821800" ID="ID_394226309" MODIFIED="1575667833698" TEXT="aber der ctor garantiert (RAII) da&#xdf; sie aufgerufen wurde"/>
</node> </node>
</node> </node>
<node CREATED="1575833524632" HGAP="120" ID="ID_231779182" MODIFIED="1575833541157" TEXT="Problem ctor" VSHIFT="1">
<node CREATED="1575833555676" ID="ID_737726791" MODIFIED="1575833614784" TEXT="keine zwingende Verkn&#xfc;pfung mehr m&#xf6;glich">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
weil nun ViewHooked schon als ctor-Parameter einen ViewHook bekommen mu&#223;...
</p>
</body>
</html>
</richcontent>
<node CREATED="1575833618837" ID="ID_887542907" MODIFIED="1575833631133" TEXT="ist aber auch nicht schlecht"/>
<node CREATED="1575833632321" ID="ID_1044442678" MODIFIED="1575833656034" TEXT="denn andererseits ist ja jetzt ein Ctor-Parameter (ViewHook) Pflicht"/>
</node>
<node CREATED="1575833658571" ID="ID_655849348" MODIFIED="1575833684255" TEXT="Organisieren der zus&#xe4;tzlichen ctor-Parameter">
<node CREATED="1575833685238" ID="ID_82723715" MODIFIED="1575833692549" TEXT="das Widget kann beliebige Parameter haben"/>
<node CREATED="1575833693396" ID="ID_277553736" MODIFIED="1575833711002" TEXT="(optional) kann der Hook sofort mit Koordinaten gemacht werden"/>
<node CREATED="1575833718110" ID="ID_1601089341" MODIFIED="1575833729995" TEXT="das wird eine problematische Signatur...">
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1575833751257" ID="ID_1701112838" MODIFIED="1575833756633" TEXT="L&#xf6;sung">
<icon BUILTIN="idea"/>
<node CREATED="1575833758080" ID="ID_1219297677" MODIFIED="1575833762271" TEXT="zwei overloads"/>
<node CREATED="1575833763086" ID="ID_1612844126" MODIFIED="1575833769762" TEXT="mit einem Parameter-Objekt"/>
</node>
</node>
</node>
</node> </node>
<node COLOR="#338800" CREATED="1575580366411" ID="ID_1747264667" MODIFIED="1575670501324" TEXT="API f&#xfc;r Umordnen"> <node COLOR="#338800" CREATED="1575580366411" ID="ID_1747264667" MODIFIED="1575670501324" TEXT="API f&#xfc;r Umordnen">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
@ -19537,6 +19566,9 @@
<node COLOR="#338800" CREATED="1573242278975" ID="ID_1541691410" MODIFIED="1573245310701" TEXT="Verschieben"> <node COLOR="#338800" CREATED="1573242278975" ID="ID_1541691410" MODIFIED="1573245310701" TEXT="Verschieben">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
</node> </node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575835636260" ID="ID_586282311" MODIFIED="1575835646635" TEXT="umgebautes API">
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1573242357830" ID="ID_1431447719" MODIFIED="1573242368189" TEXT="relatives Kind-Hook"> <node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1573242357830" ID="ID_1431447719" MODIFIED="1573242368189" TEXT="relatives Kind-Hook">
<icon BUILTIN="flag-yellow"/> <icon BUILTIN="flag-yellow"/>
</node> </node>