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
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
}

View File

@ -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++) {

View File

@ -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);
}

View File

@ -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);