From 170209cf926e2f714d507fefaa6b30fd245811ad Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Tue, 27 Apr 2021 11:40:50 +0300 Subject: Refactor: Moving RootData so it can become non-global state --- src/ui/widget.c | 96 ++++++++++++++++++--------------------------------------- 1 file changed, 30 insertions(+), 66 deletions(-) (limited to 'src/ui/widget.c') diff --git a/src/ui/widget.c b/src/ui/widget.c index b7458528..b3f7b27f 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c @@ -39,42 +39,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ # include "../ios.h" #endif -iDeclareType(RootData) - -/* TODO: Move to root.c, one instance per root widget. */ -struct Impl_RootData { - iWidget *hover; - iWidget *mouseGrab; - iWidget *focus; - iPtrArray *onTop; /* order is important; last one is topmost */ - iPtrSet *pendingDestruction; -}; - -static iRootData rootData_; - -iPtrArray *onTop_RootData_(void) { - if (!rootData_.onTop) { - rootData_.onTop = new_PtrArray(); - } - return rootData_.onTop; -} - -void destroyPending_Widget(void) { - iForEach(PtrSet, i, rootData_.pendingDestruction) { - iWidget *widget = *i.value; - if (!isFinished_Anim(&widget->visualOffset)) { - continue; - } - if (widget->parent) { - removeChild_Widget(widget->parent, widget); - } - iAssert(widget->parent == NULL); -// iAssert(widget->object.refCount == 1); /* ref could be held in garbage still */ - iRelease(widget); - remove_PtrSetIterator(&i); - } -} - void releaseChildren_Widget(iWidget *d) { iForEach(ObjectList, i, d->children) { ((iWidget *) i.object)->parent = NULL; /* the actual reference being held */ @@ -117,7 +81,7 @@ void deinit_Widget(iWidget *d) { //#endif deinit_String(&d->id); if (d->flags & keepOnTop_WidgetFlag) { - removeAll_PtrArray(onTop_RootData_(), d); + removeAll_PtrArray(onTop_RootData(), d); } if (d->flags & visualOffset_WidgetFlag) { removeTicker_App(visualOffsetAnimation_Widget_, d); @@ -131,10 +95,10 @@ static void aboutToBeDestroyed_Widget_(iWidget *d) { return; } if (flags_Widget(d) & keepOnTop_WidgetFlag) { - removeOne_PtrArray(onTop_RootData_(), d); + removeOne_PtrArray(onTop_RootData(), d); } if (isHover_Widget(d)) { - rootData_.hover = NULL; + data_Root()->hover = NULL; } iForEach(ObjectList, i, d->children) { aboutToBeDestroyed_Widget_(as_Widget(i.object)); @@ -147,10 +111,10 @@ void destroy_Widget(iWidget *d) { postRefresh_App(); } aboutToBeDestroyed_Widget_(d); - if (!rootData_.pendingDestruction) { - rootData_.pendingDestruction = new_PtrSet(); + if (!data_Root()->pendingDestruction) { + data_Root()->pendingDestruction = new_PtrSet(); } - insert_PtrSet(rootData_.pendingDestruction, d); + insert_PtrSet(data_Root()->pendingDestruction, d); } } @@ -174,7 +138,7 @@ void setFlags_Widget(iWidget *d, int64_t flags, iBool set) { } iChangeFlags(d->flags, flags, set); if (flags & keepOnTop_WidgetFlag) { - iPtrArray *onTop = onTop_RootData_(); + iPtrArray *onTop = onTop_RootData(); if (set) { iAssert(indexOf_PtrArray(onTop, d) == iInvalidPos); pushBack_PtrArray(onTop, d); @@ -769,24 +733,24 @@ static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { } void unhover_Widget(void) { - rootData_.hover = NULL; + data_Root()->hover = NULL; } iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { if (!d->parent) { - setCurrent_Root(d); + //setCurrent_Root(d); if (ev->type == SDL_MOUSEMOTION) { /* Hover widget may change. */ setHover_Widget(NULL); } - if (rootData_.focus && isKeyboardEvent_(ev)) { + if (data_Root()->focus && isKeyboardEvent_(ev)) { /* Root dispatches keyboard events directly to the focused widget. */ - if (dispatchEvent_Widget(rootData_.focus, ev)) { + if (dispatchEvent_Widget(data_Root()->focus, ev)) { return iTrue; } } /* Root offers events first to widgets on top. */ - iReverseForEach(PtrArray, i, rootData_.onTop) { + iReverseForEach(PtrArray, i, data_Root()->onTop) { iWidget *widget = *i.value; if (isVisible_Widget(widget) && dispatchEvent_Widget(widget, ev)) { #if 0 @@ -810,7 +774,7 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { } } else if (ev->type == SDL_MOUSEMOTION && - (!rootData_.hover || hasParent_Widget(d, rootData_.hover)) && + (!data_Root()->hover || hasParent_Widget(d, data_Root()->hover)) && flags_Widget(d) & hover_WidgetFlag && ~flags_Widget(d) & hidden_WidgetFlag && ~flags_Widget(d) & disabled_WidgetFlag) { if (contains_Widget(d, init_I2(ev->motion.x, ev->motion.y))) { @@ -828,7 +792,7 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { handle the events first. */ iReverseForEach(ObjectList, i, d->children) { iWidget *child = as_Widget(i.object); - if (child == rootData_.focus && isKeyboardEvent_(ev)) { + if (child == data_Root()->focus && isKeyboardEvent_(ev)) { continue; /* Already dispatched. */ } if (isVisible_Widget(child) && child->flags & keepOnTop_WidgetFlag) { @@ -1117,7 +1081,7 @@ void drawChildren_Widget(const iWidget *d) { } /* Root draws the on-top widgets on top of everything else. */ if (!d->parent) { - iConstForEach(PtrArray, i, onTop_RootData_()) { + iConstForEach(PtrArray, i, onTop_RootData()) { const iWidget *top = *i.value; draw_Widget(top); } @@ -1234,7 +1198,7 @@ iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { } /* Check for on-top widgets first. */ if (!d->parent) { - iReverseForEach(PtrArray, i, onTop_RootData_()) { + iReverseForEach(PtrArray, i, onTop_RootData()) { iWidget *child = i.ptr; // printf("ontop: %s (%s) hidden:%d hittable:%d\n", cstr_String(id_Widget(child)), // class_Widget(child)->name, @@ -1322,12 +1286,12 @@ iBool isDisabled_Widget(const iAnyObject *d) { iBool isFocused_Widget(const iAnyObject *d) { iAssert(isInstance_Object(d, &Class_Widget)); - return rootData_.focus == d; + return data_Root()->focus == d; } iBool isHover_Widget(const iAnyObject *d) { iAssert(isInstance_Object(d, &Class_Widget)); - return rootData_.hover == d; + return data_Root()->hover == d; } iBool isSelected_Widget(const iAnyObject *d) { @@ -1373,12 +1337,12 @@ iBool isAffectedByVisualOffset_Widget(const iWidget *d) { } void setFocus_Widget(iWidget *d) { - if (rootData_.focus != d) { - if (rootData_.focus) { - iAssert(!contains_PtrSet(rootData_.pendingDestruction, rootData_.focus)); - postCommand_Widget(rootData_.focus, "focus.lost"); + if (data_Root()->focus != d) { + if (data_Root()->focus) { + iAssert(!contains_PtrSet(data_Root()->pendingDestruction, data_Root()->focus)); + postCommand_Widget(data_Root()->focus, "focus.lost"); } - rootData_.focus = d; + data_Root()->focus = d; if (d) { iAssert(flags_Widget(d) & focusable_WidgetFlag); postCommand_Widget(d, "focus.gained"); @@ -1387,15 +1351,15 @@ void setFocus_Widget(iWidget *d) { } iWidget *focus_Widget(void) { - return rootData_.focus; + return data_Root()->focus; } void setHover_Widget(iWidget *d) { - rootData_.hover = d; + data_Root()->hover = d; } iWidget *hover_Widget(void) { - return rootData_.hover; + return data_Root()->hover; } static const iWidget *findFocusable_Widget_(const iWidget *d, const iWidget *startFrom, @@ -1451,14 +1415,14 @@ iAny *findFocusable_Widget(const iWidget *startFrom, enum iWidgetFocusDir focusD } void setMouseGrab_Widget(iWidget *d) { - if (rootData_.mouseGrab != d) { - rootData_.mouseGrab = d; + if (data_Root()->mouseGrab != d) { + data_Root()->mouseGrab = d; SDL_CaptureMouse(d != NULL); } } iWidget *mouseGrab_Widget(void) { - return rootData_.mouseGrab; + return data_Root()->mouseGrab; } void postCommand_Widget(const iAnyObject *d, const char *cmd, ...) { @@ -1492,7 +1456,7 @@ void refresh_Widget(const iAnyObject *d) { } void raise_Widget(iWidget *d) { - iPtrArray *onTop = onTop_RootData_(); + iPtrArray *onTop = onTop_RootData(); if (d->flags & keepOnTop_WidgetFlag) { iAssert(indexOf_PtrArray(onTop, d) != iInvalidPos); removeOne_PtrArray(onTop, d); -- cgit v1.2.3