diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-05 13:03:25 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-05 13:03:25 +0200 |
commit | 8417c4fb637351587e1527b94c69b752d9988323 (patch) | |
tree | 9d3cc97895ffbf59ee48f64c14dbc282b65e90c6 /src/ui/widget.c | |
parent | c2aa1be37d0daad7c0654ae62d6ae3faca3e8715 (diff) |
Widget: Debugging reference keeping
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r-- | src/ui/widget.c | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c index f9c84c7a..75aa91bd 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -57,16 +57,19 @@ void destroyPending_Widget(void) { | |||
57 | iForEach(PtrSet, i, rootData_.pendingDestruction) { | 57 | iForEach(PtrSet, i, rootData_.pendingDestruction) { |
58 | iWidget *widget = *i.value; | 58 | iWidget *widget = *i.value; |
59 | if (widget->parent) { | 59 | if (widget->parent) { |
60 | iRelease(removeChild_Widget(widget->parent, widget)); | 60 | removeChild_Widget(widget->parent, widget); |
61 | } | ||
62 | else { | ||
63 | iRelease(widget); | ||
64 | } | 61 | } |
62 | iAssert(widget->parent == NULL); | ||
63 | // iAssert(widget->object.refCount == 1); /* ref could be held in garbage still */ | ||
64 | iRelease(widget); | ||
65 | remove_PtrSetIterator(&i); | 65 | remove_PtrSetIterator(&i); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | void releaseChildren_Widget(iWidget *d) { | 69 | void releaseChildren_Widget(iWidget *d) { |
70 | iForEach(ObjectList, i, d->children) { | ||
71 | ((iWidget *) i.object)->parent = NULL; /* the actual reference being held */ | ||
72 | } | ||
70 | iReleasePtr(&d->children); | 73 | iReleasePtr(&d->children); |
71 | } | 74 | } |
72 | 75 | ||
@@ -87,8 +90,11 @@ void init_Widget(iWidget *d) { | |||
87 | 90 | ||
88 | void deinit_Widget(iWidget *d) { | 91 | void deinit_Widget(iWidget *d) { |
89 | releaseChildren_Widget(d); | 92 | releaseChildren_Widget(d); |
93 | #if !defined (NDEBUG) | ||
94 | printf("widget %p (%s) deleted (on top:%d)\n", d, cstr_String(&d->id), | ||
95 | d->flags & keepOnTop_WidgetFlag ? 1 : 0); | ||
96 | #endif | ||
90 | deinit_String(&d->id); | 97 | deinit_String(&d->id); |
91 | // printf("widget %p deleted (on top:%d)\n", d, d->flags & keepOnTop_WidgetFlag ? 1 : 0); | ||
92 | if (d->flags & keepOnTop_WidgetFlag) { | 98 | if (d->flags & keepOnTop_WidgetFlag) { |
93 | removeAll_PtrArray(onTop_RootData_(), d); | 99 | removeAll_PtrArray(onTop_RootData_(), d); |
94 | } | 100 | } |
@@ -817,7 +823,7 @@ iAny *addChildFlags_Widget(iWidget *d, iAnyObject *child, int64_t childFlags) { | |||
817 | 823 | ||
818 | iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { | 824 | iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { |
819 | iAssert(child); | 825 | iAssert(child); |
820 | ref_Object(child); | 826 | ref_Object(child); /* we take a reference, parent releases its */ |
821 | iBool found = iFalse; | 827 | iBool found = iFalse; |
822 | iForEach(ObjectList, i, d->children) { | 828 | iForEach(ObjectList, i, d->children) { |
823 | if (i.object == child) { | 829 | if (i.object == child) { |
@@ -859,7 +865,12 @@ iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { | |||
859 | /* Check for on-top widgets first. */ | 865 | /* Check for on-top widgets first. */ |
860 | if (!d->parent) { | 866 | if (!d->parent) { |
861 | iForEach(PtrArray, i, onTop_RootData_()) { | 867 | iForEach(PtrArray, i, onTop_RootData_()) { |
862 | iAny *found = hitChild_Widget(constAs_Widget(i.ptr), coord); | 868 | iWidget *child = i.ptr; |
869 | // printf("ontop: %s (%s) hidden:%d hittable:%d\n", cstr_String(id_Widget(child)), | ||
870 | // class_Widget(child)->name, | ||
871 | // child->flags & hidden_WidgetFlag ? 1 : 0, | ||
872 | // child->flags & unhittable_WidgetFlag ? 0 : 1); | ||
873 | iAny *found = hitChild_Widget(constAs_Widget(child), coord); | ||
863 | if (found) return found; | 874 | if (found) return found; |
864 | } | 875 | } |
865 | } | 876 | } |
@@ -870,10 +881,9 @@ iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { | |||
870 | if (found) return found; | 881 | if (found) return found; |
871 | } | 882 | } |
872 | } | 883 | } |
873 | if (class_Widget(d) == &Class_Widget) { | 884 | if ((d->flags & overflowScrollable_WidgetFlag || class_Widget(d) != &Class_Widget) && |
874 | return NULL; /* Plain widgets are not hittable. */ | 885 | ~d->flags & unhittable_WidgetFlag && |
875 | } | 886 | contains_Widget(d, coord)) { |
876 | if (~d->flags & unhittable_WidgetFlag && contains_Widget(d, coord)) { | ||
877 | return iConstCast(iWidget *, d); | 887 | return iConstCast(iWidget *, d); |
878 | } | 888 | } |
879 | return NULL; | 889 | return NULL; |
@@ -1083,7 +1093,29 @@ void refresh_Widget(const iAnyObject *d) { | |||
1083 | postRefresh_App(); | 1093 | postRefresh_App(); |
1084 | } | 1094 | } |
1085 | 1095 | ||
1096 | #include "labelwidget.h" | ||
1097 | static void printTree_Widget_(const iWidget *d, int indent) { | ||
1098 | for (int i = 0; i < indent; ++i) { | ||
1099 | fwrite(" ", 4, 1, stdout); | ||
1100 | } | ||
1101 | printf("[%p] %s:\"%s\" ", d, class_Widget(d)->name, cstr_String(&d->id)); | ||
1102 | if (isInstance_Object(d, &Class_LabelWidget)) { | ||
1103 | printf("(%s|%s) ", | ||
1104 | cstr_String(text_LabelWidget((const iLabelWidget *) d)), | ||
1105 | cstr_String(command_LabelWidget((const iLabelWidget *) d))); | ||
1106 | } | ||
1107 | printf("size:%dx%d flags:%08llx\n", d->rect.size.x, d->rect.size.y, d->flags); | ||
1108 | iConstForEach(ObjectList, i, d->children) { | ||
1109 | printTree_Widget_(i.object, indent + 1); | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | void printTree_Widget(const iWidget *d) { | ||
1114 | printTree_Widget_(d, 0); | ||
1115 | } | ||
1116 | |||
1086 | iBeginDefineClass(Widget) | 1117 | iBeginDefineClass(Widget) |
1087 | .processEvent = processEvent_Widget, | 1118 | .processEvent = processEvent_Widget, |
1088 | .draw = draw_Widget, | 1119 | .draw = draw_Widget, |
1089 | iEndDefineClass(Widget) | 1120 | iEndDefineClass(Widget) |
1121 | |||