summaryrefslogtreecommitdiff
path: root/src/ui/widget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-05 13:03:25 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-05 13:03:25 +0200
commit8417c4fb637351587e1527b94c69b752d9988323 (patch)
tree9d3cc97895ffbf59ee48f64c14dbc282b65e90c6 /src/ui/widget.c
parentc2aa1be37d0daad7c0654ae62d6ae3faca3e8715 (diff)
Widget: Debugging reference keeping
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r--src/ui/widget.c54
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
69void releaseChildren_Widget(iWidget *d) { 69void 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
88void deinit_Widget(iWidget *d) { 91void 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
818iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { 824iAny *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"
1097static 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
1113void printTree_Widget(const iWidget *d) {
1114 printTree_Widget_(d, 0);
1115}
1116
1086iBeginDefineClass(Widget) 1117iBeginDefineClass(Widget)
1087 .processEvent = processEvent_Widget, 1118 .processEvent = processEvent_Widget,
1088 .draw = draw_Widget, 1119 .draw = draw_Widget,
1089iEndDefineClass(Widget) 1120iEndDefineClass(Widget)
1121