Handled window coordinates properly in resizes.
This commit is contained in:
parent
a4cfd3880d
commit
e1554c38ef
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue