diff --git a/TODO.md b/TODO.md index be62e75c..40a01a56 100644 --- a/TODO.md +++ b/TODO.md @@ -51,6 +51,7 @@ - drop "Page" from uiTab method names? (uiTabAppendPage() -> uiTabAppend()) - override dock menu quit item to act like our app menu quit item - consider calling setAppleMenu: for the application menu; it doesn't seem to make much of a difference but +- I have a feeling the container enable/disable logic we have won't work with two levels of controls to enable... ultimately: - add some sort of runtime type checking diff --git a/ui_windows.h b/ui_windows.h index 0996a5db..7c24a4d1 100644 --- a/ui_windows.h +++ b/ui_windows.h @@ -54,4 +54,15 @@ extern intmax_t uiWindowsWindowTextWidth(HWND hwnd); extern char *uiWindowsControlText(uiControl *); extern void uiWindowsControlSetText(uiControl *, const char *); +struct uiControlSysFuncParams { + int Func; +}; + +enum { + // These should enable and disable the uiControl while preserving the user enable/disable setting. + // These are needed because while disabling a parent window does cause children to stop receiving events, they are not shown as disabled, which is not what we want. + uiWindowsSysFuncContainerEnable, + uiWindowsSysFuncContainerDisable, +}; + #endif diff --git a/windows/bin.c b/windows/bin.c index ff7ec287..408c59f5 100644 --- a/windows/bin.c +++ b/windows/bin.c @@ -47,6 +47,14 @@ void binPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *heig *height += marginY; } +static void binSysFunc(uiControl *c, uiControlSysFuncParams *p) +{ + struct bin *b = (struct bin *) c; + + if (b->mainControl != NULL) + uiControlSysFunc(b->mainControl, p); +} + void binResizeChildren(uiContainer *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) { struct bin *b = (struct bin *) c; @@ -74,6 +82,7 @@ uiContainer *newBin(void) b->baseDestroy = uiControl(b)->Destroy; uiControl(b)->Destroy = binDestroy; uiControl(b)->PreferredSize = binPreferredSize; + uiControl(b)->SysFunc = binSysFunc; uiContainer(b)->ResizeChildren = binResizeChildren; diff --git a/windows/newcontrol.c b/windows/newcontrol.c index 9a0270ab..ca1628e8 100644 --- a/windows/newcontrol.c +++ b/windows/newcontrol.c @@ -11,6 +11,8 @@ struct singleHWND { void *onDestroyData; uiContainer *parent; int hidden; + int userDisabled; + int containerDisabled; }; static void singleDestroy(uiControl *c) @@ -91,16 +93,37 @@ static void singleEnable(uiControl *c) { singleHWND *s = (singleHWND *) (c->Internal); - EnableWindow(s->hwnd, TRUE); + s->userDisabled = 0; + if (!s->containerDisabled) + EnableWindow(s->hwnd, TRUE); } static void singleDisable(uiControl *c) { singleHWND *s = (singleHWND *) (c->Internal); + s->userDisabled = 1; EnableWindow(s->hwnd, FALSE); } +static void singleEnable(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->Internal); + + switch (p->Func) { + case uiWindowsSysFuncContainerEnabled: + s->containerDisabled = 0; + if (!s->userDisabled) + EnableWindow(s->hwnd, TRUE); + return; + case uiWindowsSysFuncContainerDisable: + s->containerDisabled = 1; + EnableWindow(s->hwnd, FALSE); + return; + } + complain("unknown p->Func %d in singleSysFunc()", p->Func); +} + static LRESULT CALLBACK singleSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { uiControl *c = (uiControl *) dwRefData; @@ -161,6 +184,7 @@ void uiWindowsMakeControl(uiControl *c, uiWindowsMakeControlParams *p) uiControl(c)->Hide = singleHide; uiControl(c)->Enable = singleEnable; uiControl(c)->Disable = singleDisable; + uiControl(c)->SysFunc = singleSysFunc; } char *uiWindowsControlText(uiControl *c)