More migration. Just control.c left, and then we can build.
This commit is contained in:
parent
413ec1a2c3
commit
cefd262f42
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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++) {
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
Loading…
Reference in New Issue