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);
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue