diff --git a/redo/windows/tab.c b/redo/windows/tab.c index b47e2d2a..8a2a08ed 100644 --- a/redo/windows/tab.c +++ b/redo/windows/tab.c @@ -4,8 +4,40 @@ struct tab { uiTab t; HWND hwnd; + struct ptrArray *pages; + void (*baseResize)(uiControl *, intmax_t, intmax_t, intmax_t, intmax_t, uiSizing *); }; +struct tabPage { + uiControl *control; + int margined; +}; + +// utility functions + +static LRESULT curpage(struct tab *t) +{ + return SendMessageW(t->hwnd, TCM_GETCURSEL, 0, 0); +} + +static void showHidePage(struct tab *t, LRESULT which, int hide) +{ + struct tabPage *page; + + if (which == (LRESULT) (-1)) + return; + page = ptrArrayIndex(t->pages, struct tabPage *, which); + if (hide) + uiControlContainerHide(page->control); + else { + uiControlContainerShow(page->control); + // we only resize the current page, so we have to do this here + uiControlQueueResize(page->control); + } +} + +// control implementation + static BOOL onWM_COMMAND(uiControl *c, WORD code, LRESULT *lResult) { return FALSE; @@ -26,30 +58,90 @@ static void tabPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_ // TODO } +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 n; + struct tabPage *page; + RECT r; + + (*(t->baseResize))(uiControl(t), x, y, width, height, d); + n = curpage(t); + if (n == (LRESULT) (-1)) + return; + page = ptrArrayIndex(t->pages, struct tabPage *, n); + r.left = x; + r.top = y; + r.right = x + width; + r.bottom = y + height; + // TODO convert from parent window coordinates to screen coordinates + SendMessageW(t->hwnd, TCM_ADJUSTRECT, (WPARAM) FALSE, (LPARAM) (&r)); + // TODO convert back to parent window coordinates + if (page->margined) { + // TODO + } + uiControlResize(page->control, x, y, width, height, d); +} + static void tabAppend(uiTab *tt, const char *name, uiControl *child) { + struct tab *t = (struct tab *) tt; + + uiTabInsertAt(tt, name, t->pages->len, child); } static void tabInsertAt(uiTab *tt, const char *name, uintmax_t n, uiControl *child) { + struct tab *t = (struct tab *) tt; + struct tabPage *page; + LRESULT hide, show; + TCITEMW item; + WCHAR *wname; + + // see below + hide = curpage(t); + + page = uiNew(struct tabPage); + page->control = child; + uiControlSetParent(page->control, uiControl(t)); + ptrArrayInsertAt(t->pages, n, page); + + ZeroMemory(&item, sizeof (TCITEMW)); + item.mask = TCIF_TEXT; + wname = toUTF16(name); + item.pszText = wname; + if (SendMessageW(t->hwnd, TCM_INSERTITEM, (WPARAM) n, (LPARAM) (&item)) == (LRESULT) -1) + logLastError("error adding tab to uiTab in uiTabInsertAt()"); + uiFree(wname); + + // we need to do this because adding the first tab doesn't send a TCN_SELCHANGE; it just shows the page + show = curpage(t); + if (show != hide) { + showHidePage(t, hide, 1); + showHidePage(t, show, 0); + } } static void tabDelete(uiTab *tt, uintmax_t n) { + // TODO } static uintmax_t tabNumPages(uiTab *tt) { + // TODO return 0; } static int tabMargined(uiTab *tt, uintmax_t n) { + // TODO return 0; } static void tabSetMargined(uiTab *tt, uintmax_t n, int margined) { + // TODO } uiTab *uiNewTab(void) @@ -75,7 +167,11 @@ uiTab *uiNewTab(void) t->hwnd = (HWND) uiControlHandle(uiControl(t)); + t->pages = newPtrArray(); + uiControl(t)->PreferredSize = tabPreferredSize; + t->baseResize = uiControl(t)->Resize; + uiControl(t)->Resize = tabResize; uiTab(t)->Append = tabAppend; uiTab(t)->InsertAt = tabInsertAt;