More migration. Just control.c left, and then we can build.

This commit is contained in:
Pietro Gagliardi 2015-08-31 15:14:02 -04:00
parent 413ec1a2c3
commit cefd262f42
5 changed files with 84 additions and 150 deletions

View File

@ -3,24 +3,6 @@
// #qo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32 -lcomdlg32 -lole32 -loleaut32 -loleacc -luuid // #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) static void msgloop_else(MSG *msg)
{ {
TranslateMessage(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 // 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(); focus = GetFocus();
if (focus != NULL) { 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 case 0: // uiArea
// msgloop_area(active, focus, &msg); // msgloop_area(active, focus, &msg);
continue; continue;
case 1: // WC_TABCONTROLW
msgloop_tab(active, focus, &msg);
continue;
} }
// else fall through // else fall through
} }

View File

@ -3,7 +3,7 @@
// TODO migrate to ptrArray // TODO migrate to ptrArray
static struct menu **menus = NULL; static uiMenu **menus = NULL;
static uintmax_t len = 0; static uintmax_t len = 0;
static uintmax_t cap = 0; static uintmax_t cap = 0;
static BOOL menusFinalized = FALSE; static BOOL menusFinalized = FALSE;
@ -12,16 +12,16 @@ static BOOL hasQuit = FALSE;
static BOOL hasPreferences = FALSE; static BOOL hasPreferences = FALSE;
static BOOL hasAbout = FALSE; static BOOL hasAbout = FALSE;
struct menu { struct uiMenu {
uiMenu m; uiTyped t;
WCHAR *name; WCHAR *name;
struct menuItem **items; uiMenuItem **items;
uintmax_t len; uintmax_t len;
uintmax_t cap; uintmax_t cap;
}; };
struct menuItem { struct uiMenuItem {
uiMenuItem mi; uiTyped t;
WCHAR *name; WCHAR *name;
int type; int type;
WORD id; WORD id;
@ -45,7 +45,7 @@ enum {
#define grow 32 #define grow 32
static void sync(struct menuItem *item) static void sync(uiMenuItem *item)
{ {
uintmax_t i; uintmax_t i;
MENUITEMINFOW mi; MENUITEMINFOW mi;
@ -74,43 +74,33 @@ static void onQuitClicked(uiMenuItem *item, uiWindow *w, void *data)
uiQuit(); uiQuit();
} }
static void menuItemEnable(uiMenuItem *ii) void uiMenuItemEnable(uiMenuItem *i)
{ {
struct menuItem *item = (struct menuItem *) ii;
item->disabled = FALSE; item->disabled = FALSE;
sync(item); sync(item);
} }
static void menuItemDisable(uiMenuItem *ii) void uiMenuItemDisable(uiMenuItem *i)
{ {
struct menuItem *item = (struct menuItem *) ii;
item->disabled = TRUE; item->disabled = TRUE;
sync(item); 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) if (item->type == typeQuit)
complain("attempt to call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead"); complain("attempt to call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead");
item->onClicked = f; item->onClicked = f;
item->onClickedData = data; item->onClickedData = data;
} }
static int menuItemChecked(uiMenuItem *ii) int uiMenuItemChecked(uiMenuItem *i)
{ {
struct menuItem *item = (struct menuItem *) ii;
return item->checked != FALSE; 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 // use explicit values
item->checked = FALSE; item->checked = FALSE;
if (checked) if (checked)
@ -118,20 +108,20 @@ static void menuItemSetChecked(uiMenuItem *ii, int checked)
sync(item); 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) if (menusFinalized)
complain("attempt to create a new menu item after menus have been finalized"); complain("attempt to create a new menu item after menus have been finalized");
if (m->len >= m->cap) { if (m->len >= m->cap) {
m->cap += grow; 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); item = uiNew(uiMenuItem);
uiTyped(item)->Type = uiTypeMenuItem(); uiTyped(item)->Type = uiMenuItemType();
m->items[m->len] = item; m->items[m->len] = item;
m->len++; m->len++;
@ -159,91 +149,79 @@ static uiMenuItem *newItem(struct menu *m, int type, const char *name)
curID++; curID++;
} }
// TODO copy this from the unix one
item->onClicked = defaultOnClicked; item->onClicked = defaultOnClicked;
if (item->type == typeQuit) if (item->type == typeQuit)
item->onClicked = onQuitClicked; item->onClicked = onQuitClicked;
uiMenuItem(item)->Enable = menuItemEnable; return item;
uiMenuItem(item)->Disable = menuItemDisable;
uiMenuItem(item)->OnClicked = menuItemOnClicked;
uiMenuItem(item)->Checked = menuItemChecked;
uiMenuItem(item)->SetChecked = menuItemSetChecked;
return uiMenuItem(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) if (hasQuit)
complain("attempt to add multiple Quit menu items"); complain("attempt to add multiple Quit menu items");
hasQuit = TRUE; hasQuit = TRUE;
newItem((struct menu *) mm, typeSeparator, NULL); newItem(m, typeSeparator, NULL);
return newItem((struct menu *) mm, typeQuit, NULL); return newItem(m, typeQuit, NULL);
} }
uiMenuItem *menuAppendPreferencesItem(uiMenu *mm) uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m)
{ {
if (hasPreferences) if (hasPreferences)
complain("attempt to add multiple Preferences menu items"); complain("attempt to add multiple Preferences menu items");
hasPreferences = TRUE; hasPreferences = TRUE;
newItem((struct menu *) mm, typeSeparator, NULL); newItem(m, typeSeparator, NULL);
return newItem((struct menu *) mm, typePreferences, NULL); return newItem(m, typePreferences, NULL);
} }
uiMenuItem *menuAppendAboutItem(uiMenu *mm) uiMenuItem *uiMenuAppendAboutItem(uiMenu *mm)
{ {
if (hasAbout) if (hasAbout)
complain("attempt to add multiple About menu items"); complain("attempt to add multiple About menu items");
hasAbout = TRUE; hasAbout = TRUE;
newItem((struct menu *) mm, typeSeparator, NULL); newItem(m, typeSeparator, NULL);
return newItem((struct menu *) mm, typeAbout, 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) uiMenu *uiNewMenu(const char *name)
{ {
struct menu *m; uiMenu *m;
if (menusFinalized) if (menusFinalized)
complain("attempt to create a new menu after menus have been finalized"); complain("attempt to create a new menu after menus have been finalized");
if (len >= cap) { if (len >= cap) {
cap += grow; 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); m = uiNew(uiMenu);
uiTyped(m)->Type = uiTypeMenu(); uiTyped(m)->Type = uiMenuType();
menus[len] = m; menus[len] = m;
len++; len++;
m->name = toUTF16(name); m->name = toUTF16(name);
uiMenu(m)->AppendItem = menuAppendItem; return m;
uiMenu(m)->AppendCheckItem = menuAppendCheckItem;
uiMenu(m)->AppendQuitItem = menuAppendQuitItem;
uiMenu(m)->AppendPreferencesItem = menuAppendPreferencesItem;
uiMenu(m)->AppendAboutItem = menuAppendAboutItem;
uiMenu(m)->AppendSeparator = menuAppendSeparator;
return uiMenu(m);
} }
static void appendMenuItem(HMENU menu, struct menuItem *item) static void appendMenuItem(HMENU menu, uiMenuItem *item)
{ {
UINT uFlags; UINT uFlags;
@ -266,7 +244,7 @@ static void appendMenuItem(HMENU menu, struct menuItem *item)
item->len++; item->len++;
} }
static HMENU makeMenu(struct menu *m) static HMENU makeMenu(uiMenu *m)
{ {
HMENU menu; HMENU menu;
uintmax_t i; uintmax_t i;
@ -302,8 +280,8 @@ HMENU makeMenubar(void)
void runMenuEvent(WORD id, uiWindow *w) void runMenuEvent(WORD id, uiWindow *w)
{ {
struct menu *m; uiMenu *m;
struct menuItem *item; uiMenuItem *item;
uintmax_t i, j; uintmax_t i, j;
uiMenuItem *umi; uiMenuItem *umi;
@ -320,20 +298,18 @@ void runMenuEvent(WORD id, uiWindow *w)
complain("unknown menu ID %hu in runMenuEvent()", id); complain("unknown menu ID %hu in runMenuEvent()", id);
found: found:
umi = uiMenuItem(item);
// first toggle checkboxes, if any // first toggle checkboxes, if any
if (item->type == typeCheckbox) if (item->type == typeCheckbox)
uiMenuItemSetChecked(umi, !uiMenuItemChecked(umi)); uiMenuItemSetChecked(item, !uiMenuItemChecked(item));
// then run the event // 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; uintmax_t i;
struct menuItem *item; uiMenuItem *item;
uintmax_t j; uintmax_t j;
for (i = 0; i < m->len; i++) { for (i = 0; i < m->len; i++) {
@ -368,8 +344,8 @@ void freeMenubar(HMENU menubar)
void uninitMenus(void) void uninitMenus(void)
{ {
struct menu *m; uiMenu *m;
struct menuItem *item; uiMenuItem *item;
uintmax_t i, j; uintmax_t i, j;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {

View File

@ -15,25 +15,13 @@ void uninitResizes(void)
ptrArrayDestroy(resizes); 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) void queueResize(uiControl *c)
{ {
uintmax_t i; uintmax_t i;
uiControl *d; uiControl *d;
// resizing a control requires us to reocmpute the sizes of everything in the top-level window // 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) if (c == NULL)
return; return;
// make sure we're only queued once // make sure we're only queued once
@ -47,14 +35,17 @@ void queueResize(uiControl *c)
void doResizes(void) void doResizes(void)
{ {
uiWindow *w; uiWindowsControl *w;
HWND hwnd; HWND hwnd;
RECT r;
while (resizes->len != 0) { while (resizes->len != 0) {
w = ptrArrayIndex(resizes, uiWindow *, 0); w = ptrArrayIndex(resizes, uiWindowsControl *, 0);
ptrArrayDelete(resizes, 0); ptrArrayDelete(resizes, 0);
uiWindowResizeChild(w);
hwnd = (HWND) uiControlHandle(uiControl(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 // 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) // 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) 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 winXPadding 4
#define winYPadding 4 #define winYPadding 4
uiSizing *uiWindowsSizing(uiControl *c) uiWindowsSizing *uiWindowsNewSizing(HWND hwnd)
{ {
uiSizing *d; uiSizing *d;
HDC dc; HDC dc;
HWND hwnd;
HFONT prevfont; HFONT prevfont;
TEXTMETRICW tm; TEXTMETRICW tm;
SIZE size; SIZE size;
uiControl *toplevel;
d = uiNew(uiSizing); d = uiNew(uiWindowsSizing);
d->Sys = uiNew(uiSizingSys);
hwnd = (HWND) uiControlHandle(c);
dc = GetDC(hwnd); dc = GetDC(hwnd);
if (dc == NULL) if (dc == NULL)
logLastError("error getting DC in uiWindowsSizing()"); logLastError("error getting DC in uiWindowsNewSizing()");
prevfont = (HFONT) SelectObject(dc, hMessageFont); prevfont = (HFONT) SelectObject(dc, hMessageFont);
if (prevfont == NULL) 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)); ZeroMemory(&tm, sizeof (TEXTMETRICW));
if (GetTextMetricsW(dc, &tm) == 0) 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) 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->BaseX = (int) ((size.cx / 26 + 1) / 2);
d->Sys->BaseY = (int) tm.tmHeight; d->BaseY = (int) tm.tmHeight;
d->Sys->InternalLeading = tm.tmInternalLeading; d->InternalLeading = tm.tmInternalLeading;
if (SelectObject(dc, prevfont) != hMessageFont) if (SelectObject(dc, prevfont) != hMessageFont)
logLastError("error restoring previous font into device context in uiWindowsSizing()"); logLastError("error restoring previous font into device context in uiWindowsSizing()");
if (ReleaseDC(hwnd, dc) == 0) if (ReleaseDC(hwnd, dc) == 0)
logLastError("error releasing DC in uiWindowsSizing()"); logLastError("error releasing DC in uiWindowsSizing()");
d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->Sys->BaseX); d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->BaseX);
d->YPadding = uiWindowsDlgUnitsToY(winYPadding, d->Sys->BaseY); d->YPadding = uiWindowsDlgUnitsToY(winYPadding, d->BaseY);
toplevel = findToplevel(c);
if (toplevel != NULL)
d->Sys->CoordFrom = (HWND) uiControlHandle(toplevel);
d->Sys->CoordTo = hwnd;
return d; return d;
} }
void uiFreeSizing(uiSizing *d) void uiWindowsFreeSizing(uiWindowsSizing *d)
{ {
uiFree(d->Sys);
uiFree(d); uiFree(d);
} }

View File

@ -12,7 +12,6 @@ enum {
msgCOMMAND = WM_APP + 0x40, // start offset just to be safe msgCOMMAND = WM_APP + 0x40, // start offset just to be safe
msgNOTIFY, msgNOTIFY,
msgHSCROLL, msgHSCROLL,
msgHasTabStops,
msgConsoleEndSession, msgConsoleEndSession,
}; };
@ -45,7 +44,6 @@ extern WCHAR *windowText(HWND);
extern void initResizes(void); extern void initResizes(void);
extern void uninitResizes(void); extern void uninitResizes(void);
extern void doResizes(void); extern void doResizes(void);
extern void moveWindow(HWND, intmax_t, intmax_t, intmax_t, intmax_t, uiSizing *);
extern void setWindowInsertAfter(HWND, HWND); extern void setWindowInsertAfter(HWND, HWND);
// utilwindow.c // utilwindow.c
@ -70,6 +68,7 @@ extern void unregisterWindowClass(void);
#define containerClass L"libui_uiContainerClass" #define containerClass L"libui_uiContainerClass"
extern ATOM initContainer(HICON, HCURSOR); extern ATOM initContainer(HICON, HCURSOR);
extern void uninitContainer(void); extern void uninitContainer(void);
extern HWND newContainer(void);
// menu.c // menu.c
extern HMENU makeMenubar(void); extern HMENU makeMenubar(void);
@ -82,10 +81,6 @@ extern void uninitMenus(void);
extern int initAlloc(void); extern int initAlloc(void);
extern void uninitAlloc(void); extern void uninitAlloc(void);
// tab.c
extern void tabEnterTabNavigation(HWND);
extern void tabLeaveTabNavigation(HWND);
// events.c // events.c
extern BOOL runWM_COMMAND(WPARAM, LPARAM, LRESULT *); extern BOOL runWM_COMMAND(WPARAM, LPARAM, LRESULT *);
extern BOOL runWM_NOTIFY(WPARAM, LPARAM, LRESULT *); extern BOOL runWM_NOTIFY(WPARAM, LPARAM, LRESULT *);
@ -100,13 +95,17 @@ extern void uninitDialogHelper(void);
extern HWND beginDialogHelper(void); extern HWND beginDialogHelper(void);
extern void endDialogHelper(HWND); extern void endDialogHelper(HWND);
// control.c // child.c
extern void setSingleHWNDFuncs(uiControl *); extern struct child *newChild(uiControl *child, uiControl *parent, HWND parentHWND);
extern struct child *newChildWithTabPage(uiControl *child, uiControl *parent, HWND parentHWND);
// tabpage.c extern void childRemove(struct child *c);
extern uiControl *newTabPage(void); extern void childDestroy(struct child *c);
extern int tabPageMargined(uiControl *); extern HWND childHWND(struct child *c);
extern void tabPageSetMargined(uiControl *, int); extern void childMinimumSize(struct child *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height);
extern void tabPageDestroyChild(uiControl *); extern void childRelayout(struct child *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height);
extern void tabPagePreserveChild(uiControl *); extern void childUpdateState(struct child *c);
extern void tabPageSetChild(uiControl *, uiControl *); 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);