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); bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlContainerVisible(bc->c)) if (!uiControlContainerVisible(bc->c))
continue; continue;
// TODO dchild
uiControlPreferredSize(bc->c, d, &preferredWidth, &preferredHeight); uiControlPreferredSize(bc->c, d, &preferredWidth, &preferredHeight);
if (bc->stretchy) { if (bc->stretchy) {
nStretchy++; nStretchy++;
@ -129,11 +130,9 @@ static void boxResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intm
intmax_t stretchywid, stretchyht; intmax_t stretchywid, stretchyht;
uintmax_t i; uintmax_t i;
intmax_t preferredWidth, preferredHeight; intmax_t preferredWidth, preferredHeight;
uiSizing *dchild;
(*(b->baseResize))(uiControl(b), x, y, width, height, d); (*(b->baseResize))(uiControl(b), x, y, width, height, d);
// TODO
x = 0;
y = 0;
if (b->controls->len == 0) if (b->controls->len == 0)
return; 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 // 3) now we can position controls
dchild = uiControlSizing(uiControl(b));
for (i = 0; i < b->controls->len; i++) { for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i); bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlContainerVisible(bc->c)) if (!uiControlContainerVisible(bc->c))
continue; continue;
uiControlResize(bc->c, x, y, bc->width, bc->height, d); uiControlResize(bc->c, x, y, bc->width, bc->height, dchild);
if (b->vertical) if (b->vertical)
y += bc->height + ypadding; y += bc->height + ypadding;
else else
x += bc->width + xpadding; x += bc->width + xpadding;
} }
uiFreeSizing(dchild);
} }
static void boxSysFunc(uiControl *c, uiControlSysFuncParams *p) 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. // This contains the Windows-specific parts of the uiSizing structure.
// BaseX and BaseY are the dialog base units. // 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. // 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 { struct uiSizingSys {
int BaseX; int BaseX;
int BaseY; int BaseY;
LONG InternalLeading; LONG InternalLeading;
HWND CoordFrom;
HWND CoordTo;
}; };
// Use these in your preferredSize() implementation with baseX and baseY. // Use these in your preferredSize() implementation with baseX and baseY.
#define uiWindowsDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4) #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); 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) static void singleQueueResize(uiControl *c)

View File

@ -15,19 +15,27 @@ 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
for (;;) { c = findToplevel(c);
if (uiIsWindow(c)) if (c == NULL)
break;
if (uiControlParent(c) == NULL) // not in a window; don't bother resizing
return; return;
c = uiControlParent(c);
}
// make sure we're only queued once // make sure we're only queued once
for (i = 0 ; i < resizes->len; i++) { for (i = 0 ; i < resizes->len; i++) {
d = ptrArrayIndex(resizes, uiControl *, i); d = ptrArrayIndex(resizes, uiControl *, i);
@ -58,12 +66,20 @@ void doResizes(void)
#define swpflags (SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW) #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()"); 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) 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) if (SetWindowPos(hwnd, insertAfter, x, y, width, height, swpflags) == 0)
@ -83,6 +99,7 @@ uiSizing *uiWindowsSizing(uiControl *c)
HFONT prevfont; HFONT prevfont;
TEXTMETRICW tm; TEXTMETRICW tm;
SIZE size; SIZE size;
uiControl *toplevel;
d = uiNew(uiSizing); d = uiNew(uiSizing);
d->Sys = uiNew(uiSizingSys); d->Sys = uiNew(uiSizingSys);
@ -113,6 +130,13 @@ uiSizing *uiWindowsSizing(uiControl *c)
d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->Sys->BaseX); d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->Sys->BaseX);
d->YPadding = uiWindowsDlgUnitsToY(winYPadding, d->Sys->BaseY); 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) 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; LRESULT n;
struct tabPage *page; struct tabPage *page;
RECT r; RECT r;
uiSizing *dchild;
(*(t->baseResize))(uiControl(t), x, y, width, height, d); (*(t->baseResize))(uiControl(t), x, y, width, height, d);
n = curpage(t); n = curpage(t);
if (n == (LRESULT) (-1)) if (n == (LRESULT) (-1))
return; return;
page = ptrArrayIndex(t->pages, struct tabPage *, n); 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.left = x;
r.top = y; r.top = y;
r.right = x + width; r.right = x + width;
r.bottom = y + height; 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)); 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) { if (page->margined) {
// TODO // 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) 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 = uiNew(struct tabPage);
page->control = child; page->control = child;
uiControlSetParent(page->control, uiControl(t)); 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); ptrArrayInsertAt(t->pages, n, page);
ZeroMemory(&item, sizeof (TCITEMW)); ZeroMemory(&item, sizeof (TCITEMW));

View File

@ -68,7 +68,7 @@ extern void initResizes(void);
extern void uninitResizes(void); extern void uninitResizes(void);
extern void queueResize(uiControl *); extern void queueResize(uiControl *);
extern void doResizes(void); 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); extern void moveAndReorderWindow(HWND, HWND, intmax_t, intmax_t, intmax_t, intmax_t);
// utilwindow.c // utilwindow.c