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

View file

@ -19507,9 +19507,9 @@
</richcontent>
<icon BUILTIN="flag-yellow"/>
</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;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="pencil"/>
<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"/>
@ -19519,6 +19519,35 @@
<node CREATED="1575667821800" ID="ID_394226309" MODIFIED="1575667833698" TEXT="aber der ctor garantiert (RAII) da&#xdf; sie aufgerufen wurde"/>
</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 COLOR="#338800" CREATED="1575580366411" ID="ID_1747264667" MODIFIED="1575670501324" TEXT="API f&#xfc;r Umordnen">
<icon BUILTIN="button_ok"/>
@ -19537,6 +19566,9 @@
<node COLOR="#338800" CREATED="1573242278975" ID="ID_1541691410" MODIFIED="1573245310701" TEXT="Verschieben">
<icon BUILTIN="button_ok"/>
</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">
<icon BUILTIN="flag-yellow"/>
</node>