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:
parent
ffcac2ea1e
commit
99e367f33b
2 changed files with 109 additions and 45 deletions
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
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;
|
FakeCanvas canvas;
|
||||||
DummyWidget w1, w2, w3;
|
HookedWidget w1{canvas.hookedAt(x1,y1)};
|
||||||
WidgetViewHook h1 = canvas.hook (w1, w1.x,w1.y);
|
HookedWidget w3{canvas.hookedAt(x3,y3)};
|
||||||
WidgetViewHook h3 = canvas.hook (w3, w3.x,w3.y);
|
|
||||||
|
int id2;
|
||||||
{
|
{
|
||||||
WidgetViewHook h2 = canvas.hook (w2, w2.x,w2.y);
|
HookedWidget w2{canvas.hookedAt(x2,y2)};
|
||||||
CHECK (canvas.testVerifyPos (w2, w2.x,w2.y));
|
id2 = w2.i;
|
||||||
|
CHECK (canvas.testContains (id2));
|
||||||
|
CHECK (canvas.testVerifyPos (w2, x2,y2));
|
||||||
|
|
||||||
int newX = ++w2.x;
|
int newX = ++x2;
|
||||||
int newY = --w2.y;
|
int newY = --y2;
|
||||||
h2.moveTo (newX,newY);
|
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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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<W>">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1575667886287" ID="ID_1416159951" MODIFIED="1575835656408" TEXT="Umbau auf ein ViewHooked<W>">
|
||||||
<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ß sie aufgerufen wurde"/>
|
<node CREATED="1575667821800" ID="ID_394226309" MODIFIED="1575667833698" TEXT="aber der ctor garantiert (RAII) daß 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üpfung mehr möglich">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
weil nun ViewHooked schon als ctor-Parameter einen ViewHook bekommen muß...
|
||||||
|
</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ä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ö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ür Umordnen">
|
<node COLOR="#338800" CREATED="1575580366411" ID="ID_1747264667" MODIFIED="1575670501324" TEXT="API fü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>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue