diff --git a/TODO.md b/TODO.md index 82bef68c..f95f717d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,5 @@ - consider calling setAppleMenu: for the application menu; it doesn't seem to make much of a difference but - make the name of the variable to refer to a single tab page consistent (already decided to make them all `page`) -- clean up windows resizing logic - - make it so that only top-level window resizes trigger an update; container resizes do not update - - windows resizing logic is simply not comprehensive enough (no null resizes allowed) to do things - - we control resizes of all children so we can reliably update after a resize - - we already need to do this in uiContainer :/ - make it so Windows API calls that do logLastError(), etc. abort whatever they're doing and not try to continue, just like wintable - 32-bit Mac OS X support (requires lots of code changes) - change the build system to be more receptive to arch changes @@ -29,9 +24,7 @@ ultimately: - make OS-specific headers generated by an IDL - figure out what to do on Windows and GTK+ if we don't have menus but the user wants a menubar (zero-height widget? don't bother? complain?) - bin.c - - find a way to consolidate the duplicate code across OSs - find a way to move the has parent check at the beginning of binDestroy() - - determine whether or not margins count in preferredSize() when there is no main control - menu item state change while the menu is visible (not in response to user action) - OS X: requires an [NSMenu update] call after changing state - Windows: requires getting current menu state when amending it in sync() diff --git a/darwin/bin.m b/darwin/bin.m index 45e75272..bb584668 100644 --- a/darwin/bin.m +++ b/darwin/bin.m @@ -1,118 +1,33 @@ // 28 april 2015 #import "uipriv_darwin.h" -struct bin { - uiContainer c; - void (*baseDestroy)(uiControl *); - uiControl *mainControl; - intmax_t marginLeft; - intmax_t marginTop; - intmax_t marginRight; - intmax_t marginBottom; -}; - -static void binDestroy(uiControl *c) +int binHasOSParent(uiBin *b) { - struct bin *b = (struct bin *) c; NSView *v; - // ensure clean removal by making sure the bin has no OS parent // note that: // - the superview of a NSWindow content view is the window frame // - the superview of *the active NSTabView page* is the NSTabView itself (we don't have to worry about other pages because if there are pages, then at least one page will be active, so we will eventually get here) v = (NSView *) uiControlHandle(uiControl(b)); - if ([v superview] != nil) - complain("attempt to destroy bin %p while it has an OS parent", b); - // don't chain up to base here; we need to destroy children ourselves first - if (b->mainControl != NULL) { - uiControlSetParent(b->mainControl, NULL); - uiControlDestroy(b->mainControl); - } - // NOW we can chain up to base - (*(b->baseDestroy))(uiControl(b)); - uiFree(b); + return [v superview] != nil; } -static void binPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height) +void binSetOSParent(uiBin *b, uintptr_t osParent) { - struct bin *b = (struct bin *) c; - intmax_t marginX, marginY; - - if (b->mainControl == NULL) { - *width = 0; - *height = 0; - return; - } - uiControlPreferredSize(b->mainControl, d, width, height); - marginX = b->marginLeft + b->marginRight; - marginY = b->marginTop + b->marginBottom; - *width += marginX; - *height += marginY; + complain("TODO"); } -static void binSysFunc(uiControl *c, uiControlSysFuncParams *p) +void binRemoveOSParent(uiBin *b) { - struct bin *b = (struct bin *) c; - - if (b->mainControl != NULL) - uiControlSysFunc(b->mainControl, p); + complain("TODO"); } -static void binResizeChildren(uiContainer *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) +void binResizeRootAndUpdate(uiBin *b, intmax_t x, intmax_t y, intmax_t width, intmax_t height) { - struct bin *b = (struct bin *) c; - - if (b->mainControl == NULL) - return; - x += b->marginLeft; - y += b->marginTop; - width -= b->marginLeft + b->marginRight; - height -= b->marginTop + b->marginBottom; - uiControlResize(b->mainControl, x, y, width, height, d); + // not used on OS X } -uiContainer *newBin(void) +void binTranslateMargins(uiBin *b, intmax_t *left, intmax_t *top, intmax_t *right, intmax_t *bottom, uiSizing *d) { - struct bin *b; - - b = uiNew(struct bin); - - uiMakeContainer(uiContainer(b)); - - b->baseDestroy = uiControl(b)->Destroy; - uiControl(b)->Destroy = binDestroy; - uiControl(b)->PreferredSize = binPreferredSize; - uiControl(b)->SysFunc = binSysFunc; - - uiContainer(b)->ResizeChildren = binResizeChildren; - - return uiContainer(b); -} - -void binSetMainControl(uiContainer *c, uiControl *mainControl) -{ - struct bin *b = (struct bin *) c; - - if (b->mainControl != NULL) - uiControlSetParent(b->mainControl, NULL); - b->mainControl = mainControl; - if (b->mainControl != NULL) - uiControlSetParent(b->mainControl, uiContainer(b)); - uiContainerUpdate(uiContainer(b)); -} - -void binSetMargins(uiContainer *c, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom) -{ - struct bin *b = (struct bin *) c; - - b->marginLeft = left; - b->marginRight = right; - b->marginTop = top; - b->marginBottom = bottom; - uiContainerUpdate(uiContainer(b)); -} - -void binSetParent(uiContainer *c, uintptr_t osParent) -{ - complain("binSetParent() ineffective on OS X; specific selectors need to be called instead"); + // not used on OS X } diff --git a/darwin/tab.m b/darwin/tab.m index 1aacbdb9..35a06514 100644 --- a/darwin/tab.m +++ b/darwin/tab.m @@ -1,6 +1,8 @@ // 12 april 2015 #import "uipriv_darwin.h" +// TODO rewrite this whole file to take advantage of bin functions + struct tab { uiTab t; NSTabView *tabview; @@ -22,9 +24,9 @@ static void destroy(void *data) // the above loop serves the purpose of binSetParent() [t->pages enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { NSValue *v = (NSValue *) obj; - uiContainer *p; + uiBin *p; - p = (uiContainer *) [v pointerValue]; + p = (uiBin *) [v pointerValue]; uiControlDestroy(uiControl(p)); }]; // and finally destroy ourselves @@ -52,9 +54,9 @@ static void tabEnable(uiControl *c) (*(t->baseEnable))(uiControl(t)); [t->pages enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { NSValue *v = (NSValue *) obj; - uiContainer *p; + uiBin *p; - p = (uiContainer *) [v pointerValue]; + p = (uiBin *) [v pointerValue]; uiControlEnable(uiControl(p)); }]; } @@ -66,9 +68,9 @@ static void tabDisable(uiControl *c) (*(t->baseDisable))(uiControl(t)); [t->pages enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { NSValue *v = (NSValue *) obj; - uiContainer *p; + uiBin *p; - p = (uiContainer *) [v pointerValue]; + p = (uiBin *) [v pointerValue]; uiControlDisable(uiControl(p)); }]; } @@ -80,9 +82,9 @@ static void tabSysFunc(uiControl *c, uiControlSysFuncParams *p) (*(t->baseSysFunc))(uiControl(t), p); [t->pages enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { NSValue *v = (NSValue *) obj; - uiContainer *pp; + uiBin *pp; - pp = (uiContainer *) [v pointerValue]; + pp = (uiBin *) [v pointerValue]; uiControlSysFunc(uiControl(pp), p); }]; } @@ -90,11 +92,11 @@ static void tabSysFunc(uiControl *c, uiControlSysFuncParams *p) static void tabAppendPage(uiTab *tt, const char *name, uiControl *child) { struct tab *t = (struct tab *) tt; - uiContainer *page; + uiBin *page; NSTabViewItem *i; page = newBin(); - binSetMainControl(page, child); + uiBinSetMainControl(page, child); [t->pages addObject:[NSValue valueWithPointer:page]]; [t->margined addObject:[NSNumber numberWithInt:0]]; @@ -107,11 +109,11 @@ static void tabAppendPage(uiTab *tt, const char *name, uiControl *child) static void tabInsertPageBefore(uiTab *tt, const char *name, uintmax_t n, uiControl *child) { struct tab *t = (struct tab *) tt; - uiContainer *page; + uiBin *page; NSTabViewItem *i; page = newBin(); - binSetMainControl(page, child); + uiBinSetMainControl(page, child); [t->pages insertObject:[NSValue valueWithPointer:page] atIndex:n]; [t->margined insertObject:[NSNumber numberWithInt:0] atIndex:n]; @@ -125,19 +127,19 @@ static void tabDeletePage(uiTab *tt, uintmax_t n) { struct tab *t = (struct tab *) tt; NSValue *v; - uiContainer *p; + uiBin *p; NSTabViewItem *i; v = (NSValue *) [t->pages objectAtIndex:n]; - p = (uiContainer *) [v pointerValue]; + p = (uiBin *) [v pointerValue]; [t->pages removeObjectAtIndex:n]; [t->margined removeObjectAtIndex:n]; // make sure the children of the tab aren't destroyed - binSetMainControl(p, NULL); + uiBinSetMainControl(p, NULL); // remove the bin from the tab view - // this serves the purpose of binSetParent() + // this serves the purpose of uiBinRemoveOSParent() i = [t->tabview tabViewItemAtIndex:n]; [t->tabview removeTabViewItem:i]; @@ -177,16 +179,16 @@ static void tabSetMargined(uiTab *tt, uintmax_t n, int margined) struct tab *t = (struct tab *) tt; NSNumber *v; NSValue *binv; - uiContainer *bin; + uiBin *bin; v = [NSNumber numberWithInt:margined]; [t->margined replaceObjectAtIndex:n withObject:v]; binv = (NSValue *) [t->pages objectAtIndex:n]; - bin = (uiContainer *) [binv pointerValue]; + bin = (uiBin *) [binv pointerValue]; if ([v intValue]) - binSetMargins(bin, tabLeftMargin, tabTopMargin, tabRightMargin, tabBottomMargin); + uiBinSetMargins(bin, tabLeftMargin, tabTopMargin, tabRightMargin, tabBottomMargin); else - binSetMargins(bin, 0, 0, 0, 0); + uiBinSetMargins(bin, 0, 0, 0, 0); } uiTab *uiNewTab(void) diff --git a/darwin/window.m b/darwin/window.m index 57ce6f7e..525a1212 100644 --- a/darwin/window.m +++ b/darwin/window.m @@ -1,6 +1,8 @@ // 28 april 2015 #import "uipriv_darwin.h" +// TODO rewrite this file to take advantage of bins + @interface windowDelegate : NSObject { uiWindow *w; int (*onClosing)(uiWindow *, void *); @@ -42,7 +44,7 @@ struct window { uiWindow w; NSWindow *window; windowDelegate *delegate; - uiContainer *bin; + uiBin *bin; int hidden; int margined; }; @@ -156,7 +158,7 @@ static void windowSetChild(uiWindow *ww, uiControl *child) { struct window *w = (struct window *) ww; - binSetMainControl(w->bin, child); + uiBinSetMainControl(w->bin, child); } static int windowMargined(uiWindow *ww) @@ -172,9 +174,9 @@ static void windowSetMargined(uiWindow *ww, int margined) w->margined = margined; if (w->margined) - binSetMargins(w->bin, macXMargin, macYMargin, macXMargin, macYMargin); + uiBinSetMargins(w->bin, macXMargin, macYMargin, macXMargin, macYMargin); else - binSetMargins(w->bin, 0, 0, 0, 0); + uiBinSetMargins(w->bin, 0, 0, 0, 0); } uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)