Handled window coordinates properly in resizes.

This commit is contained in:
Pietro Gagliardi 2015-05-18 12:04:52 -04:00
parent a4cfd3880d
commit e1554c38ef
6 changed files with 57 additions and 18 deletions

View File

@ -92,6 +92,7 @@ static void boxPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlContainerVisible(bc->c))
continue;
// TODO dchild
uiControlPreferredSize(bc->c, d, &preferredWidth, &preferredHeight);
if (bc->stretchy) {
nStretchy++;
@ -129,11 +130,9 @@ static void boxResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intm
intmax_t stretchywid, stretchyht;
uintmax_t i;
intmax_t preferredWidth, preferredHeight;
uiSizing *dchild;
(*(b->baseResize))(uiControl(b), x, y, width, height, d);
// TODO
x = 0;
y = 0;
if (b->controls->len == 0)
return;
@ -195,16 +194,18 @@ static void boxResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intm
}
// 3) now we can position controls
dchild = uiControlSizing(uiControl(b));
for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlContainerVisible(bc->c))
continue;
uiControlResize(bc->c, x, y, bc->width, bc->height, d);
uiControlResize(bc->c, x, y, bc->width, bc->height, dchild);
if (b->vertical)
y += bc->height + ypadding;
else
x += bc->width + xpadding;
}
uiFreeSizing(dchild);
}
static void boxSysFunc(uiControl *c, uiControlSysFuncParams *p)

View File

@ -38,10 +38,13 @@ _UI_EXTERN void uiWindowsMakeControl(uiControl *c, uiWindowsMakeControlParams *p
// This contains the Windows-specific parts of the uiSizing structure.
// BaseX and BaseY are the dialog base units.
// InternalLeading is the standard control font's internal leading; labels in uiForms use this for correct Y positioning.
// CoordFrom and CoordTo are the window handles to convert coordinates passed to uiControlResize() from and to (viaa MapWindowRect()) before passing to one of the Windows API resizing functions.
struct uiSizingSys {
int BaseX;
int BaseY;
LONG InternalLeading;
HWND CoordFrom;
HWND CoordTo;
};
// Use these in your preferredSize() implementation with baseX and baseY.
#define uiWindowsDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4)

View File

@ -59,7 +59,7 @@ static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, i
{
struct singleHWND *s = (struct singleHWND *) (c->Internal);
moveWindow(s->hwnd, x, y, width, height);
moveWindow(s->hwnd, x, y, width, height, d);
}
static void singleQueueResize(uiControl *c)

View File

@ -15,19 +15,27 @@ 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
for (;;) {
if (uiIsWindow(c))
break;
if (uiControlParent(c) == NULL) // not in a window; don't bother resizing
return;
c = uiControlParent(c);
}
c = findToplevel(c);
if (c == NULL)
return;
// make sure we're only queued once
for (i = 0 ; i < resizes->len; i++) {
d = ptrArrayIndex(resizes, uiControl *, i);
@ -58,12 +66,20 @@ void doResizes(void)
#define swpflags (SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW)
void moveWindow(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
void moveWindow(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
{
if (SetWindowPos(hwnd, NULL, x, y, width, height, swpflags | SWP_NOZORDER) == 0)
RECT r;
r.left = x;
r.top = y;
r.right = x + width;
r.bottom = y + height;
mapWindowRect(d->Sys->CoordFrom, d->Sys->CoordTo, &r);
if (SetWindowPos(hwnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, swpflags | SWP_NOZORDER) == 0)
logLastError("error moving window in moveWindow()");
}
// TODO
void moveAndReorderWindow(HWND hwnd, HWND insertAfter, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
{
if (SetWindowPos(hwnd, insertAfter, x, y, width, height, swpflags) == 0)
@ -83,6 +99,7 @@ uiSizing *uiWindowsSizing(uiControl *c)
HFONT prevfont;
TEXTMETRICW tm;
SIZE size;
uiControl *toplevel;
d = uiNew(uiSizing);
d->Sys = uiNew(uiSizingSys);
@ -113,6 +130,13 @@ uiSizing *uiWindowsSizing(uiControl *c)
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;
return d;
}
void uiFreeSizing(uiSizing *d)

View File

@ -64,23 +64,32 @@ static void tabResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intm
LRESULT n;
struct tabPage *page;
RECT r;
uiSizing *dchild;
(*(t->baseResize))(uiControl(t), x, y, width, height, d);
n = curpage(t);
if (n == (LRESULT) (-1))
return;
page = ptrArrayIndex(t->pages, struct tabPage *, n);
dchild = uiControlSizing(uiControl(t));
// now we need to figure out what rect the child goes
// this rect needs to be in toplevel window coordinates, but TCM_ADJUSTRECT wants a window rect, which is screen coordinates
r.left = x;
r.top = y;
r.right = x + width;
r.bottom = y + height;
// TODO convert from parent window coordinates to screen coordinates
mapWindowRect(dchild->Sys->CoordFrom, NULL, &r);
SendMessageW(t->hwnd, TCM_ADJUSTRECT, (WPARAM) FALSE, (LPARAM) (&r));
// TODO convert back to parent window coordinates
mapWindowRect(NULL, dchild->Sys->CoordFrom, &r);
if (page->margined) {
// TODO
}
uiControlResize(page->control, x, y, width, height, d);
uiControlResize(page->control, r.left, r.top, r.right - r.left, r.bottom - r.top, dchild);
uiFreeSizing(dchild);
}
static void tabAppend(uiTab *tt, const char *name, uiControl *child)
@ -104,6 +113,8 @@ static void tabInsertAt(uiTab *tt, const char *name, uintmax_t n, uiControl *chi
page = uiNew(struct tabPage);
page->control = child;
uiControlSetParent(page->control, uiControl(t));
// and make it invisible at first; we show it later if needed
uiControlContainerHide(page->control);
ptrArrayInsertAt(t->pages, n, page);
ZeroMemory(&item, sizeof (TCITEMW));

View File

@ -68,7 +68,7 @@ extern void initResizes(void);
extern void uninitResizes(void);
extern void queueResize(uiControl *);
extern void doResizes(void);
extern void moveWindow(HWND, intmax_t, intmax_t, intmax_t, intmax_t);
extern void moveWindow(HWND, intmax_t, intmax_t, intmax_t, intmax_t, uiSizing *);
extern void moveAndReorderWindow(HWND, HWND, intmax_t, intmax_t, intmax_t, intmax_t);
// utilwindow.c