From ab4c53436087b1312f409c9506ab3e4a707cd8f4 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 15 May 2015 18:54:13 -0400 Subject: [PATCH] Migrated windows/tab.c. --- TODO.md | 1 + {windows => redo/windows}/tab.c | 118 +++++++++++++++----------------- redo/windows/uipriv_windows.h | 7 +- 3 files changed, 59 insertions(+), 67 deletions(-) rename {windows => redo/windows}/tab.c (79%) diff --git a/TODO.md b/TODO.md index 64b9ca0e..54bd7940 100644 --- a/TODO.md +++ b/TODO.md @@ -39,3 +39,4 @@ notes to self - note that type mixing == undefined behavior - note that handling of multiple consecutive separators in menus, leading separators in menus, and trailing separators in menus are all implementation-defined - note that ContainerVisible() returns true if both user and container not hidden; container use only +- note that if we are currently updating, QueueResize() will take effect during the CURRENT update cycle diff --git a/windows/tab.c b/redo/windows/tab.c similarity index 79% rename from windows/tab.c rename to redo/windows/tab.c index 29acd1a0..b1e99000 100644 --- a/windows/tab.c +++ b/redo/windows/tab.c @@ -12,7 +12,7 @@ struct tab { }; struct tabPage { - uiBin *bin; + uiControl *control; int margined; }; @@ -36,16 +36,14 @@ static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult) page = ptrArrayIndex(t->pages, struct tabPage *, n); if (nm->code == TCN_SELCHANGING) { // changing from a real page - uiControlHide(uiControl(page->bin)); + uiControlContainerHide(page->control); *lResult = FALSE; // and allow the change return TRUE; } // otherwise it's TCN_SELCHANGE // and we're changing to a real page - uiControlShow(uiControl(page->bin)); - // because we only resize the current child on resize, we'll need to trigger an update here - // don't call uiContainerUpdate(); doing that won't size the content area (so we'll still have a 0x0 content area, for instance) - SendMessageW(t->hwnd, msgUpdateChild, 0, 0); + uiControlContainerShow(page->control); + uiControlQueueResize(page->control); *lResult = 0; return TRUE; } @@ -62,8 +60,8 @@ static void onDestroy(void *data) while (t->pages->len != 0) { page = ptrArrayIndex(t->pages, struct tabPage *, 0); // we do have to remove the page from the tab control, though - uiBinRemoveOSParent(page->bin); - uiControlDestroy(uiControl(page->bin)); + uiControlSetOSParent(page->control, NULL); + uiControlDestroy(page->control, NULL); ptrArrayDelete(t->pages, 0); uiFree(page); } @@ -72,6 +70,9 @@ static void onDestroy(void *data) uiFree(t); } +// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx +#define tabMargin 7 + static void tabPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height) { struct tab *t = (struct tab *) c; @@ -88,9 +89,10 @@ static void tabPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_ current = SendMessageW(t->hwnd, TCM_GETCURSEL, 0, 0); if (current != (LRESULT) (-1)) { curpage = ptrArrayIndex(t->pages, struct tabPage *, current); - uiControlPreferredSize(uiControl(curpage->bin), d, &curwid, &curht); + uiControlPreferredSize(curpage->control, d, &curwid, &curht); r.right = curwid; r.bottom = curht; + // TODO add margins } } // otherwise just use the rect [0 0 0 0] @@ -100,36 +102,44 @@ static void tabPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_ *height = r.bottom - r.top; } -// common code for resizes -static void resizeTab(struct tab *t, LONG width, LONG height) +static void tabResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) { + struct tab *t = (struct tab *) c; + LRESULT current; + struct tabPage *curpage; + + (*(t->baseResize))(uiControl(t), x, y, width, height, d); + current = SendMessageW(t->hwnd, TCM_GETCURSEL, 0, 0); + if (current != (LRESULT) (-1)) { + curpage = ptrArrayIndex(t->pages, struct tabPage *, current); + uiControlQueueResize(curpage->control); + } +} + +static void tabComputeChildSize(uiControl *c, intmax_t *x, intmax_t *y, intmax_t *width, intmax_t *height, uiSizing *d) +{ + struct tab *t = (struct tab *) c; LRESULT n; RECT r; struct tabPage *page; + // first figure out what the content area for pages is + if (GetWindowRect(t->hwnd, &r) == 0) + logLastError("error getting tab window rect in tabComputeChildSize()"); + // convert to the display rectangle + SendMessageW(t->hwnd, TCM_ADJUSTRECT, (WPARAM) TRUE, (LPARAM) (&r)); + *x = r.left; + *y = r.top; + *width = r.right - r.left; + *height = r.bottom - r.top; + n = SendMessageW(t->hwnd, TCM_GETCURSEL, 0, 0); if (n == (LRESULT) (-1)) // no child selected; do nothing return; - - // make a rect at (0, 0) of the given window size - // this should give us the correct client coordinates - r.left = 0; - r.top = 0; - r.right = width; - r.bottom = height; - // convert to the display rectangle - SendMessageW(t->hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) (&r)); - page = ptrArrayIndex(t->pages, struct tabPage *, n); - uiBinResizeRootAndUpdate(page->bin, r.left, r.top, r.right - r.left, r.bottom - r.top); -} - -static void tabResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) -{ - struct tab *t = (struct tab *) c; - - (*(t->baseResize))(uiControl(t), x, y, width, height, d); - resizeTab(t, width, height); + if (page->margined) { + // TODO + } } static void tabEnable(uiControl *c) @@ -141,7 +151,7 @@ static void tabEnable(uiControl *c) (*(t->baseEnable))(uiControl(t)); for (i = 0; i < t->pages->len; i++) { page = ptrArrayIndex(t->pages, struct tabPage *, i); - uiControlEnable(uiControl(page->bin)); + uiControlContainerEnable(uiControl(page->bin)); } } @@ -154,7 +164,7 @@ static void tabDisable(uiControl *c) (*(t->baseDisable))(uiControl(t)); for (i = 0; i < t->pages->len; i++) { page = ptrArrayIndex(t->pages, struct tabPage *, i); - uiControlDisable(uiControl(page->bin)); + uiControlContainerDisable(uiControl(page->bin)); } } @@ -181,8 +191,6 @@ static void tabSysFunc(uiControl *c, uiControlSysFuncParams *p) } } -// this is where some resizing work is done -// TODO investigate removing it // this is also partially where tab navigation is handled static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { @@ -193,12 +201,6 @@ static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l struct tabPage *page; switch (uMsg) { - case msgUpdateChild: - if (GetWindowRect(t->hwnd, &r) == 0) - logLastError("error getting Tab window rect for synthesized resize message in tabSubProc()"); - // these are in screen coordinates, which match what WM_WINDOWPOSCHANGED gave us (see http://stackoverflow.com/questions/29598334/are-the-coordinates-in-windowpos-on-wm-windowposchanged-in-parent-coordinates-or) - resizeTab(t, r.right - r.left, r.bottom - r.top); - return 0; case msgHasTabStops: n = SendMessageW(t->hwnd, TCM_GETCURSEL, 0, 0); if (n == (LRESULT) (-1)) // no current selection == no tab stops @@ -209,11 +211,11 @@ static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l uiControlSysFunc(uiControl(page->bin), &p); return p.HasTabStops; case WM_NCDESTROY: - if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, uIdSubclass) == FALSE) + if (RemoveWindowSubclass(hwnd, tabSubProc, uIdSubclass) == FALSE) logLastError("error removing Tab resize handling subclass in tabSubProc()"); break; } - return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); + return DefSubclassProc(hwnd, uMsg, wParam, lParam); } #define tabCapGrow 32 @@ -229,11 +231,9 @@ static void tabAppendPage(uiTab *tt, const char *name, uiControl *child) page = uiNew(struct tabPage); n = SendMessageW(t->hwnd, TCM_GETITEMCOUNT, 0, 0); - page->bin = newBin(); - uiBinSetMainControl(page->bin, child); - uiBinSetOSParent(page->bin, (uintptr_t) (t->hwnd)); + page->control = child; if (n != 0) // if this isn't the first page, we have to hide the other controls - uiControlHide(uiControl(page->bin)); + uiControlHide(page->control); ptrArrayAppend(t->pages, page); @@ -249,7 +249,7 @@ static void tabAppendPage(uiTab *tt, const char *name, uiControl *child) // if this is the first tab, Windows will automatically show it /without/ sending a TCN_SELCHANGE notification // so we need to manually resize the tab ourselves // don't use uiContainerUpdate() for the same reason as in the TCN_SELCHANGE handler - SendMessageW(t->hwnd, msgUpdateChild, 0, 0); + uiControlQueueResize(page->control); } static void tabInsertPageBefore(uiTab *tt, const char *name, uintmax_t n, uiControl *child) @@ -261,11 +261,9 @@ static void tabInsertPageBefore(uiTab *tt, const char *name, uintmax_t n, uiCont page = uiNew(struct tabPage); - page->bin = newBin(); - uiBinSetMainControl(page->bin, child); - uiBinSetOSParent(page->bin, (uintptr_t) (t->hwnd)); + page->control = child; // always hide; the current tab doesn't change - uiControlHide(uiControl(page->bin)); + uiControlHide(page->control); ptrArrayInsertBefore(t->pages, n, page); @@ -292,12 +290,9 @@ static void tabDeletePage(uiTab *tt, uintmax_t n) page = ptrArrayIndex(t->pages, struct tabPage *, n); ptrArrayDelete(t->pages, n); - // make sure the page's control isn't destroyed - uiBinSetMainControl(page->bin, NULL); + // and keep the page control alive + uiControlSetParent(page->control, NULL); - // see tabDestroy() above for details - uiBinRemoveOSParent(page->bin); - uiControlDestroy(uiControl(page->bin)); uiFree(page); } @@ -317,9 +312,6 @@ static int tabMargined(uiTab *tt, uintmax_t n) return page->margined; } -// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -#define tabMargin 7 - static void tabSetMargined(uiTab *tt, uintmax_t n, int margined) { struct tab *t = (struct tab *) tt; @@ -327,11 +319,7 @@ static void tabSetMargined(uiTab *tt, uintmax_t n, int margined) page = ptrArrayIndex(t->pages, struct tabPage *, n); page->margined = margined; - if (page->margined) - uiBinSetMargins(page->bin, tabMargin, tabMargin, tabMargin, tabMargin); - else - uiBinSetMargins(page->bin, 0, 0, 0, 0); - uiContainerUpdate(uiContainer(page->bin)); + uiControlQueueResize(page->control); } uiTab *uiNewTab(void) @@ -362,10 +350,12 @@ uiTab *uiNewTab(void) uiControl(t)->PreferredSize = tabPreferredSize; t->baseResize = uiControl(t)->Resize; uiControl(t)->Resize = tabResize; + uiControl(t)->ComputeChildSize = tabComputeChildSize; t->baseEnable = uiControl(t)->Enable; uiControl(t)->Enable = tabEnable; t->baseDisable = uiControl(t)->Disable; uiControl(t)->Disable = tabDisable; + // TODO ContainerEnable/ContainerDisable t->baseSysFunc = uiControl(t)->SysFunc; uiControl(t)->SysFunc = tabSysFunc; diff --git a/redo/windows/uipriv_windows.h b/redo/windows/uipriv_windows.h index d0adedf2..84f1313b 100644 --- a/redo/windows/uipriv_windows.h +++ b/redo/windows/uipriv_windows.h @@ -60,9 +60,6 @@ extern WCHAR *windowText(HWND); -// tab.c -extern void tabEnterTabNavigation(HWND); -extern void tabLeaveTabNavigation(HWND); ///////////////////////////////// @@ -105,3 +102,7 @@ extern void uninitMenus(void); // alloc.c extern int initAlloc(void); extern void uninitAlloc(void); + +// tab.c +extern void tabEnterTabNavigation(HWND); +extern void tabLeaveTabNavigation(HWND);