diff --git a/windows/GNUmakeinc.mk b/redo/windows/GNUmakeinc.mk similarity index 100% rename from windows/GNUmakeinc.mk rename to redo/windows/GNUmakeinc.mk diff --git a/redo/windows/main.c b/redo/windows/main.c index 96cde7fd..ad3e9d32 100644 --- a/redo/windows/main.c +++ b/redo/windows/main.c @@ -3,24 +3,6 @@ // #qo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32 -lcomdlg32 -lole32 -loleaut32 -loleacc -luuid -static void msgloop_tab(HWND active, HWND focus, MSG *msg) -{ - BOOL hasChildren; - BOOL idm; - - // THIS BIT IS IMPORTANT: if the current tab has no children, then there will be no children left in the dialog to tab to, and IsDialogMessageW() will loop forever - hasChildren = SendMessageW(focus, msgHasTabStops, 0, 0); - if (hasChildren) - tabEnterTabNavigation(focus); - idm = IsDialogMessageW(active, msg); - if (hasChildren) - tabLeaveTabNavigation(focus); - if (idm != 0) - return; - TranslateMessage(msg); - DispatchMessageW(msg); -} - static void msgloop_else(MSG *msg) { TranslateMessage(msg); @@ -51,13 +33,10 @@ void uiMain(void) // as for Tabs, we can't have both WS_TABSTOP and WS_EX_CONTROLPARENT set at the same time, so we hotswap the two styles to get the behavior we want focus = GetFocus(); if (focus != NULL) { - switch (windowClassOf(focus, L"TODO Area not yet implemented", WC_TABCONTROLW, NULL)) { + switch (windowClassOf(focus, L"TODO Area not yet implemented", NULL)) { case 0: // uiArea // msgloop_area(active, focus, &msg); continue; - case 1: // WC_TABCONTROLW - msgloop_tab(active, focus, &msg); - continue; } // else fall through } diff --git a/windows/menu.c b/redo/windows/menu.c similarity index 67% rename from windows/menu.c rename to redo/windows/menu.c index c6652caa..15707566 100644 --- a/windows/menu.c +++ b/redo/windows/menu.c @@ -3,7 +3,7 @@ // TODO migrate to ptrArray -static struct menu **menus = NULL; +static uiMenu **menus = NULL; static uintmax_t len = 0; static uintmax_t cap = 0; static BOOL menusFinalized = FALSE; @@ -12,16 +12,16 @@ static BOOL hasQuit = FALSE; static BOOL hasPreferences = FALSE; static BOOL hasAbout = FALSE; -struct menu { - uiMenu m; +struct uiMenu { + uiTyped t; WCHAR *name; - struct menuItem **items; + uiMenuItem **items; uintmax_t len; uintmax_t cap; }; -struct menuItem { - uiMenuItem mi; +struct uiMenuItem { + uiTyped t; WCHAR *name; int type; WORD id; @@ -45,7 +45,7 @@ enum { #define grow 32 -static void sync(struct menuItem *item) +static void sync(uiMenuItem *item) { uintmax_t i; MENUITEMINFOW mi; @@ -74,43 +74,33 @@ static void onQuitClicked(uiMenuItem *item, uiWindow *w, void *data) uiQuit(); } -static void menuItemEnable(uiMenuItem *ii) +void uiMenuItemEnable(uiMenuItem *i) { - struct menuItem *item = (struct menuItem *) ii; - item->disabled = FALSE; sync(item); } -static void menuItemDisable(uiMenuItem *ii) +void uiMenuItemDisable(uiMenuItem *i) { - struct menuItem *item = (struct menuItem *) ii; - item->disabled = TRUE; sync(item); } -static void menuItemOnClicked(uiMenuItem *ii, void (*f)(uiMenuItem *, uiWindow *, void *), void *data) +void uiMenuItemOnClicked(uiMenuItem *i, void (*f)(uiMenuItem *, uiWindow *, void *), void *data) { - struct menuItem *item = (struct menuItem *) ii; - if (item->type == typeQuit) complain("attempt to call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead"); item->onClicked = f; item->onClickedData = data; } -static int menuItemChecked(uiMenuItem *ii) +int uiMenuItemChecked(uiMenuItem *i) { - struct menuItem *item = (struct menuItem *) ii; - return item->checked != FALSE; } -static void menuItemSetChecked(uiMenuItem *ii, int checked) +void uiMenuItemSetChecked(uiMenuItem *i, int checked) { - struct menuItem *item = (struct menuItem *) ii; - // use explicit values item->checked = FALSE; if (checked) @@ -118,20 +108,20 @@ static void menuItemSetChecked(uiMenuItem *ii, int checked) sync(item); } -static uiMenuItem *newItem(struct menu *m, int type, const char *name) +static uiMenuItem *newItem(uiMenu *m, int type, const char *name) { - struct menuItem *item; + uiMenuItem *item; if (menusFinalized) complain("attempt to create a new menu item after menus have been finalized"); if (m->len >= m->cap) { m->cap += grow; - m->items = (struct menuItem **) uiRealloc(m->items, m->cap * sizeof (struct menuItem *), "struct menuItem *[]"); + m->items = (uiMenuItem **) uiRealloc(m->items, m->cap * sizeof (uiMenuItem *), "uiMenuitem *[]"); } - item = uiNew(struct menuItem); - uiTyped(item)->Type = uiTypeMenuItem(); + item = uiNew(uiMenuItem); + uiTyped(item)->Type = uiMenuItemType(); m->items[m->len] = item; m->len++; @@ -159,91 +149,79 @@ static uiMenuItem *newItem(struct menu *m, int type, const char *name) curID++; } + // TODO copy this from the unix one item->onClicked = defaultOnClicked; if (item->type == typeQuit) item->onClicked = onQuitClicked; - uiMenuItem(item)->Enable = menuItemEnable; - uiMenuItem(item)->Disable = menuItemDisable; - uiMenuItem(item)->OnClicked = menuItemOnClicked; - uiMenuItem(item)->Checked = menuItemChecked; - uiMenuItem(item)->SetChecked = menuItemSetChecked; - - return uiMenuItem(item); + return item; } -uiMenuItem *menuAppendItem(uiMenu *mm, const char *name) +uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name) { - return newItem((struct menu *) mm, typeRegular, name); + return newItem(m, typeRegular, name); } -uiMenuItem *menuAppendCheckItem(uiMenu *mm, const char *name) +uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name) { - return newItem((struct menu *) mm, typeCheckbox, name); + return newItem(m, typeCheckbox, name); } -uiMenuItem *menuAppendQuitItem(uiMenu *mm) +uiMenuItem *uiMenuAppendQuitItem(uiMenu *m) { if (hasQuit) complain("attempt to add multiple Quit menu items"); hasQuit = TRUE; - newItem((struct menu *) mm, typeSeparator, NULL); - return newItem((struct menu *) mm, typeQuit, NULL); + newItem(m, typeSeparator, NULL); + return newItem(m, typeQuit, NULL); } -uiMenuItem *menuAppendPreferencesItem(uiMenu *mm) +uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m) { if (hasPreferences) complain("attempt to add multiple Preferences menu items"); hasPreferences = TRUE; - newItem((struct menu *) mm, typeSeparator, NULL); - return newItem((struct menu *) mm, typePreferences, NULL); + newItem(m, typeSeparator, NULL); + return newItem(m, typePreferences, NULL); } -uiMenuItem *menuAppendAboutItem(uiMenu *mm) +uiMenuItem *uiMenuAppendAboutItem(uiMenu *mm) { if (hasAbout) complain("attempt to add multiple About menu items"); hasAbout = TRUE; - newItem((struct menu *) mm, typeSeparator, NULL); - return newItem((struct menu *) mm, typeAbout, NULL); + newItem(m, typeSeparator, NULL); + return newItem(m, typeAbout, NULL); } -void menuAppendSeparator(uiMenu *mm) +void uiMenuAppendSeparator(uiMenu *m) { - newItem((struct menu *) mm, typeSeparator, NULL); + newItem(m, typeSeparator, NULL); } uiMenu *uiNewMenu(const char *name) { - struct menu *m; + uiMenu *m; if (menusFinalized) complain("attempt to create a new menu after menus have been finalized"); if (len >= cap) { cap += grow; - menus = (struct menu **) uiRealloc(menus, cap * sizeof (struct menu *), "struct menu *[]"); + menus = (uiMenu **) uiRealloc(menus, cap * sizeof (uiMenu *), "uiMenu *[]"); } - m = uiNew(struct menu); - uiTyped(m)->Type = uiTypeMenu(); + m = uiNew(uiMenu); + uiTyped(m)->Type = uiMenuType(); menus[len] = m; len++; m->name = toUTF16(name); - uiMenu(m)->AppendItem = menuAppendItem; - uiMenu(m)->AppendCheckItem = menuAppendCheckItem; - uiMenu(m)->AppendQuitItem = menuAppendQuitItem; - uiMenu(m)->AppendPreferencesItem = menuAppendPreferencesItem; - uiMenu(m)->AppendAboutItem = menuAppendAboutItem; - uiMenu(m)->AppendSeparator = menuAppendSeparator; - - return uiMenu(m); + return m; } -static void appendMenuItem(HMENU menu, struct menuItem *item) +static void appendMenuItem(HMENU menu, uiMenuItem *item) { UINT uFlags; @@ -266,7 +244,7 @@ static void appendMenuItem(HMENU menu, struct menuItem *item) item->len++; } -static HMENU makeMenu(struct menu *m) +static HMENU makeMenu(uiMenu *m) { HMENU menu; uintmax_t i; @@ -302,8 +280,8 @@ HMENU makeMenubar(void) void runMenuEvent(WORD id, uiWindow *w) { - struct menu *m; - struct menuItem *item; + uiMenu *m; + uiMenuItem *item; uintmax_t i, j; uiMenuItem *umi; @@ -320,20 +298,18 @@ void runMenuEvent(WORD id, uiWindow *w) complain("unknown menu ID %hu in runMenuEvent()", id); found: - umi = uiMenuItem(item); - // first toggle checkboxes, if any if (item->type == typeCheckbox) - uiMenuItemSetChecked(umi, !uiMenuItemChecked(umi)); + uiMenuItemSetChecked(item, !uiMenuItemChecked(item)); // then run the event - (*(item->onClicked))(umi, w, item->onClickedData); + (*(item->onClicked))(item, w, item->onClickedData); } -static void freeMenu(struct menu *m, HMENU submenu) +static void freeMenu(uiMenu *m, HMENU submenu) { uintmax_t i; - struct menuItem *item; + uiMenuItem *item; uintmax_t j; for (i = 0; i < m->len; i++) { @@ -368,8 +344,8 @@ void freeMenubar(HMENU menubar) void uninitMenus(void) { - struct menu *m; - struct menuItem *item; + uiMenu *m; + uiMenuItem *item; uintmax_t i, j; for (i = 0; i < len; i++) { diff --git a/windows/resize.c b/redo/windows/resize.c similarity index 72% rename from windows/resize.c rename to redo/windows/resize.c index b72a26bf..d2ad0f4b 100644 --- a/windows/resize.c +++ b/redo/windows/resize.c @@ -15,25 +15,13 @@ void uninitResizes(void) ptrArrayDestroy(resizes); } -static uiControl *findToplevel(uiControl *c) -{ - for (;;) { - if (uiIsWindow(c)) - break; - if (uiControlParent(c) == NULL) // not in a window - return NULL; - c = uiControlParent(c); - } - return c; -} - void queueResize(uiControl *c) { uintmax_t i; uiControl *d; // resizing a control requires us to reocmpute the sizes of everything in the top-level window - c = findToplevel(c); + c = toplevelOwning(c); if (c == NULL) return; // make sure we're only queued once @@ -47,14 +35,17 @@ void queueResize(uiControl *c) void doResizes(void) { - uiWindow *w; + uiWindowsControl *w; HWND hwnd; + RECT r; while (resizes->len != 0) { - w = ptrArrayIndex(resizes, uiWindow *, 0); + w = ptrArrayIndex(resizes, uiWindowsControl *, 0); ptrArrayDelete(resizes, 0); - uiWindowResizeChild(w); hwnd = (HWND) uiControlHandle(uiControl(w)); + if (GetClientRect(hwnd, &r) == 0) + logLastError("TODO write this"); + (*(w->Relayout))(w, r.left, r.top, r.right - r.left, r.bottom - r.top); // we used SWP_NOREDRAW; we need to queue a redraw ourselves // force all controls to be redrawn; this fixes things like the date-time picker's up-down not showing up until hovered over (and bypasses complications caused by WS_CLIPCHILDREN and WS_CLIPSIBLINGS, which we don't use but other controls might) if (RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN) == 0) @@ -86,56 +77,45 @@ void setWindowInsertAfter(HWND hwnd, HWND insertAfter) #define winXPadding 4 #define winYPadding 4 -uiSizing *uiWindowsSizing(uiControl *c) +uiWindowsSizing *uiWindowsNewSizing(HWND hwnd) { uiSizing *d; HDC dc; - HWND hwnd; HFONT prevfont; TEXTMETRICW tm; SIZE size; - uiControl *toplevel; - d = uiNew(uiSizing); - d->Sys = uiNew(uiSizingSys); - - hwnd = (HWND) uiControlHandle(c); + d = uiNew(uiWindowsSizing); dc = GetDC(hwnd); if (dc == NULL) - logLastError("error getting DC in uiWindowsSizing()"); + logLastError("error getting DC in uiWindowsNewSizing()"); prevfont = (HFONT) SelectObject(dc, hMessageFont); if (prevfont == NULL) - logLastError("error loading control font into device context in uiWindowsSizing()"); + logLastError("error loading control font into device context in uiWindowsNewSizing()"); ZeroMemory(&tm, sizeof (TEXTMETRICW)); if (GetTextMetricsW(dc, &tm) == 0) - logLastError("error getting text metrics in uiWindowsSizing()"); + logLastError("error getting text metrics in uiWindowsNewSizing()"); if (GetTextExtentPoint32W(dc, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size) == 0) - logLastError("error getting text extent point in uiWindowsSizing()"); + logLastError("error getting text extent point in uiWindowsNewSizing()"); - d->Sys->BaseX = (int) ((size.cx / 26 + 1) / 2); - d->Sys->BaseY = (int) tm.tmHeight; - d->Sys->InternalLeading = tm.tmInternalLeading; + d->BaseX = (int) ((size.cx / 26 + 1) / 2); + d->BaseY = (int) tm.tmHeight; + d->InternalLeading = tm.tmInternalLeading; if (SelectObject(dc, prevfont) != hMessageFont) logLastError("error restoring previous font into device context in uiWindowsSizing()"); if (ReleaseDC(hwnd, dc) == 0) logLastError("error releasing DC in uiWindowsSizing()"); - d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->Sys->BaseX); - d->YPadding = uiWindowsDlgUnitsToY(winYPadding, d->Sys->BaseY); - - toplevel = findToplevel(c); - if (toplevel != NULL) - d->Sys->CoordFrom = (HWND) uiControlHandle(toplevel); - d->Sys->CoordTo = hwnd; + d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->BaseX); + d->YPadding = uiWindowsDlgUnitsToY(winYPadding, d->BaseY); return d; } -void uiFreeSizing(uiSizing *d) +void uiWindowsFreeSizing(uiWindowsSizing *d) { - uiFree(d->Sys); uiFree(d); } diff --git a/windows/uipriv_windows.h b/redo/windows/uipriv_windows.h similarity index 74% rename from windows/uipriv_windows.h rename to redo/windows/uipriv_windows.h index cf992c2c..e2d59946 100644 --- a/windows/uipriv_windows.h +++ b/redo/windows/uipriv_windows.h @@ -12,7 +12,6 @@ enum { msgCOMMAND = WM_APP + 0x40, // start offset just to be safe msgNOTIFY, msgHSCROLL, - msgHasTabStops, msgConsoleEndSession, }; @@ -45,7 +44,6 @@ extern WCHAR *windowText(HWND); extern void initResizes(void); extern void uninitResizes(void); extern void doResizes(void); -extern void moveWindow(HWND, intmax_t, intmax_t, intmax_t, intmax_t, uiSizing *); extern void setWindowInsertAfter(HWND, HWND); // utilwindow.c @@ -70,6 +68,7 @@ extern void unregisterWindowClass(void); #define containerClass L"libui_uiContainerClass" extern ATOM initContainer(HICON, HCURSOR); extern void uninitContainer(void); +extern HWND newContainer(void); // menu.c extern HMENU makeMenubar(void); @@ -82,10 +81,6 @@ extern void uninitMenus(void); extern int initAlloc(void); extern void uninitAlloc(void); -// tab.c -extern void tabEnterTabNavigation(HWND); -extern void tabLeaveTabNavigation(HWND); - // events.c extern BOOL runWM_COMMAND(WPARAM, LPARAM, LRESULT *); extern BOOL runWM_NOTIFY(WPARAM, LPARAM, LRESULT *); @@ -100,13 +95,17 @@ extern void uninitDialogHelper(void); extern HWND beginDialogHelper(void); extern void endDialogHelper(HWND); -// control.c -extern void setSingleHWNDFuncs(uiControl *); - -// tabpage.c -extern uiControl *newTabPage(void); -extern int tabPageMargined(uiControl *); -extern void tabPageSetMargined(uiControl *, int); -extern void tabPageDestroyChild(uiControl *); -extern void tabPagePreserveChild(uiControl *); -extern void tabPageSetChild(uiControl *, uiControl *); +// child.c +extern struct child *newChild(uiControl *child, uiControl *parent, HWND parentHWND); +extern struct child *newChildWithTabPage(uiControl *child, uiControl *parent, HWND parentHWND); +extern void childRemove(struct child *c); +extern void childDestroy(struct child *c); +extern HWND childHWND(struct child *c); +extern void childMinimumSize(struct child *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height); +extern void childRelayout(struct child *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height); +extern void childUpdateState(struct child *c); +extern HWND childTabPage(struct child *c); +extern int childMargined(struct child *c); +extern void childSetMargined(struct child *c); +extern int childFlag(struct child *c); +extern void childSetFlag(struct child *c, int flag);