From dda30cdb3c5e580a1ac3007f31390744ea497304 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 24 Apr 2016 19:22:21 -0400 Subject: [PATCH] Started the new uiControl infrastructure. --- common/control.c | 144 +++++++++++++++++--------------------------- darwin/control.m | 2 +- ui.h | 4 ++ unix/control.c | 2 +- windows/control.cpp | 2 +- 5 files changed, 62 insertions(+), 92 deletions(-) diff --git a/common/control.c b/common/control.c index a42e44fd..7528cac1 100644 --- a/common/control.c +++ b/common/control.c @@ -2,23 +2,9 @@ #include "../ui.h" #include "uipriv.h" -struct controlBase { - uiControl *parent; - int hidden; - int disabled; -}; - -#define controlBase(c) ((struct controlBase *) (c->Internal)) - void uiControlDestroy(uiControl *c) { - struct controlBase *cb = controlBase(c); - - if (cb->parent != NULL) - complain("attempt to destroy uiControl %p while it has a parent", c); - (*(c->CommitDestroy))(c); - uiFree(cb); - uiFree(c); + (*(c->Destroy))(c); } uintptr_t uiControlHandle(uiControl *c) @@ -28,114 +14,57 @@ uintptr_t uiControlHandle(uiControl *c) uiControl *uiControlParent(uiControl *c) { - struct controlBase *cb = controlBase(c); - - return cb->parent; -} - -// TODO ask the control instead -int isToplevel(uiControl *c) -{ - return c->TypeSignature == uiWindowSignature; + return (*(c->Parent))(c); } void uiControlSetParent(uiControl *c, uiControl *parent) { - struct controlBase *cb = controlBase(c); - - if (isToplevel(c)) - complain("cannot set a parent on a toplevel (uiWindow)"); - if (parent != NULL && cb->parent != NULL) - complain("attempt to reparent uiControl %p (has parent %p, attempt to give parent %p)", c, cb->parent, parent); - if (parent == NULL && cb->parent == NULL) - complain("attempt to double unparent uiControl %p", c); - cb->parent = parent; - // for situations such as where the old parent was disabled but the new one is not, etc. - controlUpdateState(c); + (*(c->SetParent))(c, parent); } -// only to be called by the immediate parent of a control -int controlSelfVisible(uiControl *c) +void uiControlUpdateChildren(uiControl *c) { - struct controlBase *cb = controlBase(c); - - return !cb->hidden; + (*(c->UpdateChildren))(c); } -static int controlContainerVisible(uiControl *c) +int uiControlToplevel(uiControl *c) { - struct controlBase *cb = controlBase(c); + return (*(c->Toplevel))(c); +} - if (cb->hidden) - return 0; - if (cb->parent == NULL) - return 1; - return controlContainerVisible(cb->parent); +int uiControlVisible(uiControl *c) +{ + return (*(c->Visible))(c); } void uiControlShow(uiControl *c) { - struct controlBase *cb = controlBase(c); - - cb->hidden = 0; - controlUpdateState(c); + (*(c->Show))(c); } void uiControlHide(uiControl *c) { - struct controlBase *cb = controlBase(c); - - cb->hidden = 1; - controlUpdateState(c); + (*(c->Hide))(c); } -static int controlContainerEnabled(uiControl *c) +int uiControlEnabled(uiControl *c) { - struct controlBase *cb = controlBase(c); - - if (cb->disabled) - return 0; - if (cb->parent == NULL) - return 1; - return controlContainerEnabled(cb->parent); + return (*(c->Enabled))(c); } void uiControlEnable(uiControl *c) { - struct controlBase *cb = controlBase(c); - - cb->disabled = 0; - controlUpdateState(c); + (*(c->Enable))(c); } void uiControlDisable(uiControl *c) { - struct controlBase *cb = controlBase(c); - - cb->disabled = 1; - controlUpdateState(c); -} - -void controlUpdateState(uiControl *c) -{ - if (controlContainerVisible(c)) - (*(c->CommitShow))(c); - else - (*(c->CommitHide))(c); - if (controlContainerEnabled(c)) - osCommitEnable(c); - else - osCommitDisable(c); - (*(c->ContainerUpdateState))(c); - // and queue a resize, just in case we showed/hid something - // for instance, on Windows uiBox, if we don't do this, hiding a control will show empty space until the window is resized -//TODO uiControlQueueResize(c); + (*(c->Disable))(c); } #define uiControlSignature 0x7569436F -// TODO should this be public? -uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr) +uiControl *uiAllocControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr) { uiControl *c; @@ -146,3 +75,40 @@ uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char c->Internal = uiNew(struct controlBase); return c; } + +void uiFreeControl(uiControl *c) +{ + uiFree(c); +} + +// TODO except where noted, replace complain() with userbug() + +void uiControlVerifyDestroy(uiControl *c) +{ + if (uiControlParent(c) != NULL) + complain("attempt to destroy uiControl %p while it has a parent", c); +} + +void uiControlVerifySetParent(uiControl *c, uiControl *parent) +{ + uiControl *curParent; + + if (uiControlToplevel(c)) + complain("cannot set a parent on a toplevel (uiWindow)"); + curParent = uiControlParent(c); + if (parent != NULL && curParent != NULL) + complain("attempt to reparent uiControl %p (has parent %p, attempt to give parent %p)", c, curParent, parent); + if (parent == NULL && curParent == NULL) + // TODO implbug() + complain("attempt to double unparent uiControl %p — likely an implementation bug ", c); +} + +int uiControlEnabledToUser(uiControl *c) +{ + while (c != NULL) { + if (!uiControlEnabled(c)) + return 0; + c = uiControlParent(c); + } + return 1; +} diff --git a/darwin/control.m b/darwin/control.m index abff03e6..fc75de50 100644 --- a/darwin/control.m +++ b/darwin/control.m @@ -74,5 +74,5 @@ void uiDarwinSetControlFont(NSControl *c, NSControlSize size) uiDarwinControl *uiDarwinNewControl(size_t n, uint32_t typesig, const char *typenamestr) { - return uiDarwinControl(newControl(n, uiDarwinControlSignature, typesig, typenamestr)); + return uiDarwinControl(uiAllocControl(n, uiDarwinControlSignature, typesig, typenamestr)); } diff --git a/ui.h b/ui.h index ad3c2aa1..7c36bd07 100644 --- a/ui.h +++ b/ui.h @@ -77,6 +77,10 @@ _UI_EXTERN void uiControlDisable(uiControl *); _UI_EXTERN uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const char *typenamestr); _UI_EXTERN void uiFreeControl(uiControl *); +_UI_EXTERN void uiControlVerifyDestroy(uiControl *); +_UI_EXTERN void uiControlVerifySetParent(uiControl *); +_UI_EXTERN int uiControlEnabledToUser(uiControl *); + typedef struct uiWindow uiWindow; #define uiWindow(this) ((uiWindow *) (this)) _UI_EXTERN char *uiWindowTitle(uiWindow *w); diff --git a/unix/control.c b/unix/control.c index 59b59241..3906c04b 100644 --- a/unix/control.c +++ b/unix/control.c @@ -34,5 +34,5 @@ void uiUnixFinishControl(uiControl *c) uiUnixControl *uiUnixNewControl(size_t n, uint32_t typesig, const char *typenamestr) { - return uiUnixControl(newControl(n, uiUnixControlSignature, typesig, typenamestr)); + return uiUnixControl(uiAllocControl(n, uiUnixControlSignature, typesig, typenamestr)); } diff --git a/windows/control.cpp b/windows/control.cpp index 7ee64813..f35b794a 100644 --- a/windows/control.cpp +++ b/windows/control.cpp @@ -66,5 +66,5 @@ void uiWindowsRearrangeControlIDsZOrder(uiControl *c) uiWindowsControl *uiWindowsNewControl(size_t n, uint32_t typesig, const char *typenamestr) { - return uiWindowsControl(newControl(n, uiWindowsControlSignature, typesig, typenamestr)); + return uiWindowsControl(uiAllocControl(n, uiWindowsControlSignature, typesig, typenamestr)); }