summaryrefslogtreecommitdiff
path: root/new/windows/tab.c
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-04-16 20:33:28 -0400
committerPietro Gagliardi <[email protected]>2015-04-16 20:33:28 -0400
commite34c561ed5bedeb180437ec165882b98d70d38c1 (patch)
treed095e5db16d7a23e883526c8c1d3c524639c97cf /new/windows/tab.c
parentde9d72299fb89a8b6cdc8963cd6b6ae708a81e80 (diff)
Split the rewrite into a new repository.
Diffstat (limited to 'new/windows/tab.c')
-rw-r--r--new/windows/tab.c190
1 files changed, 0 insertions, 190 deletions
diff --git a/new/windows/tab.c b/new/windows/tab.c
deleted file mode 100644
index d2cbd62..0000000
--- a/new/windows/tab.c
+++ /dev/null
@@ -1,190 +0,0 @@
-// 12 april 2015
-#include "uipriv_windows.h"
-
-// TODO
-// - tab change notifications aren't being sent on wine (anymore...? TODO)
-// - tell wine developers that tab controls do respond to parent changes on real windows (at least comctl6 tab controls do)
-
-struct tab {
- uiTab t;
- uiParent **pages;
- uintmax_t len;
- uintmax_t cap;
-};
-
-static BOOL onWM_COMMAND(uiControl *c, WORD code, LRESULT *lResult)
-{
- return FALSE;
-}
-
-// we have to handle hiding and showing of tab pages ourselves
-static BOOL onWM_NOTIFY(uiControl *c, NMHDR *nm, LRESULT *lResult)
-{
- struct tab *t = (struct tab *) c;
- LRESULT n;
-
- switch (nm->code) {
- case TCN_SELCHANGING:
- n = SendMessageW(uiControlHWND(c), TCM_GETCURSEL, 0, 0);
- if (n != (LRESULT) (-1)) // if we're changing to a real tab
- ShowWindow(uiParentHWND(t->pages[n]), SW_HIDE);
- *lResult = FALSE; // and allow the change
- return TRUE;
- case TCN_SELCHANGE:
- n = SendMessageW(uiControlHWND(c), TCM_GETCURSEL, 0, 0);
- if (n != (LRESULT) (-1)) { // if we're changing to a real tab
- ShowWindow(uiParentHWND(t->pages[n]), SW_SHOW);
- // because we only resize the current child on resize, we'll need to trigger an update here
- // don't call uiParentUpdate(); doing that won't size the content area (so we'll still have a 0x0 content area, for instance)
- SendMessageW(uiControlHWND(c), msgUpdateChild, 0, 0);
- }
- *lResult = 0;
- return TRUE;
- }
- return FALSE;
-}
-
-static void onWM_DESTROY(uiControl *c)
-{
- struct tab *t = (struct tab *) c;
-
- // no need to worry about freeing the pages themselves; they'll destroy themselves after we return
- uiFree(t->pages);
- uiFree(t);
-}
-
-static void preferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
-{
- // TODO
-}
-
-// common code for resizes
-static void resizeTab(uiControl *c, LONG width, LONG height)
-{
- struct tab *t = (struct tab *) c;
- HWND hwnd;
- LRESULT n;
- RECT r;
-
- hwnd = uiControlHWND(c);
-
- n = SendMessageW(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(hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) (&r));
-
- if (MoveWindow(uiParentHWND(t->pages[n]), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE) == 0)
- logLastError("error resizing current tab page in resizeTab()");
-}
-
-// and finally, because we have to resize parents, we have to handle resizes and updates
-static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
-{
- uiControl *c = (uiControl *) dwRefData;
- WINDOWPOS *wp = (WINDOWPOS *) lParam;
- LRESULT lResult;
- RECT r;
-
- switch (uMsg) {
- case WM_WINDOWPOSCHANGED:
- if ((wp->flags & SWP_NOSIZE) != 0)
- break;
- // first, let the tab control handle it
- lResult = (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
- // we have the window rect width as part of the WINDOWPOS; resize
- resizeTab(c, wp->cx, wp->cy);
- return lResult;
- case msgUpdateChild:
- if (GetWindowRect(uiControlHWND(c), &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 (thanks TODOTODOTODOTODOTODOTODOTODO)
- resizeTab(c, r.right - r.left, r.bottom - r.top);
- return 0;
- case WM_NCDESTROY:
- if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, uIdSubclass) == FALSE)
- logLastError("error removing Tab resize handling subclass in tabSubProc()");
- break;
- }
- return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
-}
-
-#define tabCapGrow 32
-
-void addPage(uiTab *tt, const char *name, uiControl *child)
-{
- struct tab *t = (struct tab *) tt;
- HWND hwnd;
- TCITEMW item;
- LRESULT n;
- uiParent *parent;
- WCHAR *wname;
-
- if (t->len >= t->cap) {
- t->cap += tabCapGrow;
- t->pages = (uiParent **) uiRealloc(t->pages, t->cap * sizeof (uiParent *), "uiParent *[]");
- }
-
- hwnd = uiControlHWND(uiControl(t));
- n = SendMessageW(hwnd, TCM_GETITEMCOUNT, 0, 0);
-
- parent = uiNewParent((uintptr_t) hwnd);
- uiParentSetChild(parent, child);
- uiParentUpdate(parent);
- if (n != 0) // if this isn't the first page, we have to hide the other controls
- ShowWindow(uiParentHWND(parent), SW_HIDE);
- t->pages[t->len] = parent;
- t->len++;
-
- ZeroMemory(&item, sizeof (TCITEMW));
- item.mask = TCIF_TEXT;
- wname = toUTF16(name);
- item.pszText = wname;
- // MSDN's example code uses the first invalid index directly for this
- if (SendMessageW(hwnd, TCM_INSERTITEM, (WPARAM) n, (LPARAM) (&item)) == (LRESULT) -1)
- logLastError("error adding tab to Tab in uiTabAddPage()");
- uiFree(wname);
-
- // if this is the first tab, Windows will automatically show it /without/ sending a TCN_SELCHANGE notification
- // (TODO verify that)
- // so we need to manually resize the tab ourselves
- // don't use uiUpdateParent() for the same reason as in the TCN_SELCHANGE handler
- SendMessageW(hwnd, msgUpdateChild, 0, 0);
-}
-
-uiTab *uiNewTab(void)
-{
- struct tab *t;
- uiWindowsNewControlParams p;
- HWND hwnd;
-
- t = uiNew(struct tab);
-
- p.dwExStyle = 0; // don't set WS_EX_CONTROLPARENT yet; we do that dynamically in the message loop (see main_windows.c)
- p.lpClassName = WC_TABCONTROLW;
- p.lpWindowName = L"";
- p.dwStyle = TCS_TOOLTIPS | WS_TABSTOP;
- p.hInstance = hInstance;
- p.useStandardControlFont = TRUE;
- p.onWM_COMMAND = onWM_COMMAND;
- p.onWM_NOTIFY = onWM_NOTIFY;
- p.onWM_DESTROY = onWM_DESTROY;
- uiWindowsNewControl(uiControl(t), &p);
-
- hwnd = uiControlHWND(uiControl(t));
- if ((*fv_SetWindowSubclass)(hwnd, tabSubProc, 0, (DWORD_PTR) t) == FALSE)
- logLastError("error subclassing Tab to give it its own resize handler in uiNewTab()");
-
- uiControl(t)->PreferredSize = preferredSize;
-
- uiTab(t)->AddPage = addPage;
-
- return uiTab(t);
-}