commit
578ff39525
|
@ -20,6 +20,9 @@ This README is being written.<br>
|
||||||
|
|
||||||
* **14 June 2016**
|
* **14 June 2016**
|
||||||
* uiDarwinControl now has a `ChildVisibilityChanged()` method and a corresponding `NotifyVisibilityChanged()` function that is called by the default show/hide handlers. This is used to make visibility changes work on OS X; uiBox, uiForm, and uiGrid all respect these now.
|
* uiDarwinControl now has a `ChildVisibilityChanged()` method and a corresponding `NotifyVisibilityChanged()` function that is called by the default show/hide handlers. This is used to make visibility changes work on OS X; uiBox, uiForm, and uiGrid all respect these now.
|
||||||
|
* The same has been done on the Windows side as well.
|
||||||
|
* Hiding and showing controls and padding calculations are now correct on Windows at long last.
|
||||||
|
* Hiding a control in a uiForm now hides its label on all platforms.
|
||||||
|
|
||||||
* **13 June 2016**
|
* **13 June 2016**
|
||||||
* `intmax_t` and `uintmax_t` are no longer used for libui API functions; now we use `int`. This should make things much easier for bindings. `int` should be at least 32 bits wide; this should be sufficient for all but the most extreme cases.
|
* `intmax_t` and `uintmax_t` are no longer used for libui API functions; now we use `int`. This should make things much easier for bindings. `int` should be at least 32 bits wide; this should be sufficient for all but the most extreme cases.
|
||||||
|
|
|
@ -148,6 +148,7 @@ struct uiGrid {
|
||||||
int firstx, firsty;
|
int firstx, firsty;
|
||||||
BOOL *hexpand, *vexpand;
|
BOOL *hexpand, *vexpand;
|
||||||
BOOL doit;
|
BOOL doit;
|
||||||
|
BOOL onlyEmptyAndSpanning;
|
||||||
|
|
||||||
[self removeOurConstraints];
|
[self removeOurConstraints];
|
||||||
if ([self->children count] == 0)
|
if ([self->children count] == 0)
|
||||||
|
@ -158,6 +159,7 @@ struct uiGrid {
|
||||||
// ignore hidden controls
|
// ignore hidden controls
|
||||||
first = YES;
|
first = YES;
|
||||||
for (gc in self->children) {
|
for (gc in self->children) {
|
||||||
|
// this bit is important: it ensures row ymin and column xmin have at least one cell to draw, so the onlyEmptyAndSpanning logic below will never run on those rows
|
||||||
if (!uiControlVisible(gc.c))
|
if (!uiControlVisible(gc.c))
|
||||||
continue;
|
continue;
|
||||||
if (first) {
|
if (first) {
|
||||||
|
@ -177,6 +179,8 @@ struct uiGrid {
|
||||||
if (ymax < (gc.top + gc.yspan))
|
if (ymax < (gc.top + gc.yspan))
|
||||||
ymax = gc.top + gc.yspan;
|
ymax = gc.top + gc.yspan;
|
||||||
}
|
}
|
||||||
|
if (first != NO) // the entire grid is hidden; do nothing
|
||||||
|
return;
|
||||||
xcount = xmax - xmin;
|
xcount = xmax - xmin;
|
||||||
ycount = ymax - ymin;
|
ycount = ymax - ymin;
|
||||||
|
|
||||||
|
@ -204,7 +208,6 @@ struct uiGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a row or column only contains emptys and spanning cells of a opposite-direction spannings, remove it by duplicating the previous row or column
|
// if a row or column only contains emptys and spanning cells of a opposite-direction spannings, remove it by duplicating the previous row or column
|
||||||
BOOL onlyEmptyAndSpanning;
|
|
||||||
for (y = 0; y < ycount; y++) {
|
for (y = 0; y < ycount; y++) {
|
||||||
onlyEmptyAndSpanning = YES;
|
onlyEmptyAndSpanning = YES;
|
||||||
for (x = 0; x < xcount; x++)
|
for (x = 0; x < xcount; x++)
|
||||||
|
|
16
ui_windows.h
16
ui_windows.h
|
@ -26,6 +26,7 @@ struct uiWindowsControl {
|
||||||
void (*MinimumSizeChanged)(uiWindowsControl *);
|
void (*MinimumSizeChanged)(uiWindowsControl *);
|
||||||
void (*LayoutRect)(uiWindowsControl *c, RECT *r);
|
void (*LayoutRect)(uiWindowsControl *c, RECT *r);
|
||||||
void (*AssignControlIDZOrder)(uiWindowsControl *, LONG_PTR *, HWND *);
|
void (*AssignControlIDZOrder)(uiWindowsControl *, LONG_PTR *, HWND *);
|
||||||
|
void (*ChildVisibilityChanged)(uiWindowsControl *);
|
||||||
};
|
};
|
||||||
#define uiWindowsControl(this) ((uiWindowsControl *) (this))
|
#define uiWindowsControl(this) ((uiWindowsControl *) (this))
|
||||||
// TODO document
|
// TODO document
|
||||||
|
@ -35,6 +36,7 @@ _UI_EXTERN void uiWindowsControlMinimumSize(uiWindowsControl *, int *, int *);
|
||||||
_UI_EXTERN void uiWindowsControlMinimumSizeChanged(uiWindowsControl *);
|
_UI_EXTERN void uiWindowsControlMinimumSizeChanged(uiWindowsControl *);
|
||||||
_UI_EXTERN void uiWindowsControlLayoutRect(uiWindowsControl *, RECT *);
|
_UI_EXTERN void uiWindowsControlLayoutRect(uiWindowsControl *, RECT *);
|
||||||
_UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_PTR *, HWND *);
|
_UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_PTR *, HWND *);
|
||||||
|
_UI_EXTERN void uiWindowsControlChildVisibilityChanged(uiWindowsControl *);
|
||||||
|
|
||||||
// TODO document
|
// TODO document
|
||||||
#define uiWindowsControlDefaultDestroy(type) \
|
#define uiWindowsControlDefaultDestroy(type) \
|
||||||
|
@ -74,12 +76,14 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
|
||||||
{ \
|
{ \
|
||||||
uiWindowsControl(c)->visible = 1; \
|
uiWindowsControl(c)->visible = 1; \
|
||||||
ShowWindow(type(c)->hwnd, SW_SHOW); \
|
ShowWindow(type(c)->hwnd, SW_SHOW); \
|
||||||
|
uiWindowsControlNotifyVisibilityChanged(uiWindowsControl(c)); \
|
||||||
}
|
}
|
||||||
#define uiWindowsControlDefaultHide(type) \
|
#define uiWindowsControlDefaultHide(type) \
|
||||||
static void type ## Hide(uiControl *c) \
|
static void type ## Hide(uiControl *c) \
|
||||||
{ \
|
{ \
|
||||||
uiWindowsControl(c)->visible = 0; \
|
uiWindowsControl(c)->visible = 0; \
|
||||||
ShowWindow(type(c)->hwnd, SW_HIDE); \
|
ShowWindow(type(c)->hwnd, SW_HIDE); \
|
||||||
|
uiWindowsControlNotifyVisibilityChanged(uiWindowsControl(c)); \
|
||||||
}
|
}
|
||||||
#define uiWindowsControlDefaultEnabled(type) \
|
#define uiWindowsControlDefaultEnabled(type) \
|
||||||
static int type ## Enabled(uiControl *c) \
|
static int type ## Enabled(uiControl *c) \
|
||||||
|
@ -131,6 +135,11 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
|
||||||
{ \
|
{ \
|
||||||
uiWindowsEnsureAssignControlIDZOrder(type(c)->hwnd, controlID, insertAfter); \
|
uiWindowsEnsureAssignControlIDZOrder(type(c)->hwnd, controlID, insertAfter); \
|
||||||
}
|
}
|
||||||
|
#define uiWindowsControlDefaultChildVisibilityChanged(type) \
|
||||||
|
static void type ## ChildVisibilityChanged(uiWindowsControl *c) \
|
||||||
|
{ \
|
||||||
|
/* do nothing */ \
|
||||||
|
}
|
||||||
|
|
||||||
#define uiWindowsControlAllDefaultsExceptDestroy(type) \
|
#define uiWindowsControlAllDefaultsExceptDestroy(type) \
|
||||||
uiWindowsControlDefaultHandle(type) \
|
uiWindowsControlDefaultHandle(type) \
|
||||||
|
@ -147,7 +156,8 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
|
||||||
uiWindowsControlDefaultSetParentHWND(type) \
|
uiWindowsControlDefaultSetParentHWND(type) \
|
||||||
uiWindowsControlDefaultMinimumSizeChanged(type) \
|
uiWindowsControlDefaultMinimumSizeChanged(type) \
|
||||||
uiWindowsControlDefaultLayoutRect(type) \
|
uiWindowsControlDefaultLayoutRect(type) \
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(type)
|
uiWindowsControlDefaultAssignControlIDZOrder(type) \
|
||||||
|
uiWindowsControlDefaultChildVisibilityChanged(type)
|
||||||
|
|
||||||
#define uiWindowsControlAllDefaults(type) \
|
#define uiWindowsControlAllDefaults(type) \
|
||||||
uiWindowsControlDefaultDestroy(type) \
|
uiWindowsControlDefaultDestroy(type) \
|
||||||
|
@ -173,6 +183,7 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
|
||||||
uiWindowsControl(var)->MinimumSizeChanged = type ## MinimumSizeChanged; \
|
uiWindowsControl(var)->MinimumSizeChanged = type ## MinimumSizeChanged; \
|
||||||
uiWindowsControl(var)->LayoutRect = type ## LayoutRect; \
|
uiWindowsControl(var)->LayoutRect = type ## LayoutRect; \
|
||||||
uiWindowsControl(var)->AssignControlIDZOrder = type ## AssignControlIDZOrder; \
|
uiWindowsControl(var)->AssignControlIDZOrder = type ## AssignControlIDZOrder; \
|
||||||
|
uiWindowsControl(var)->ChildVisibilityChanged = type ## ChildVisibilityChanged; \
|
||||||
uiWindowsControl(var)->visible = 1; \
|
uiWindowsControl(var)->visible = 1; \
|
||||||
uiWindowsControl(var)->enabled = 1;
|
uiWindowsControl(var)->enabled = 1;
|
||||||
// TODO document
|
// TODO document
|
||||||
|
@ -246,6 +257,9 @@ _UI_EXTERN void uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl *);
|
||||||
// TODO document
|
// TODO document
|
||||||
_UI_EXTERN BOOL uiWindowsShouldStopSyncEnableState(uiWindowsControl *c, int enabled);
|
_UI_EXTERN BOOL uiWindowsShouldStopSyncEnableState(uiWindowsControl *c, int enabled);
|
||||||
|
|
||||||
|
// TODO document
|
||||||
|
_UI_EXTERN void uiWindowsControlNotifyVisibilityChanged(uiWindowsControl *c);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,6 +8,7 @@ struct formChild {
|
||||||
GtkAlign oldhalign;
|
GtkAlign oldhalign;
|
||||||
gboolean oldvexpand;
|
gboolean oldvexpand;
|
||||||
GtkAlign oldvalign;
|
GtkAlign oldvalign;
|
||||||
|
GBinding *labelBinding;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uiForm {
|
struct uiForm {
|
||||||
|
@ -82,7 +83,10 @@ void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy)
|
||||||
gtk_grid_attach(f->grid, fc.label,
|
gtk_grid_attach(f->grid, fc.label,
|
||||||
0, row,
|
0, row,
|
||||||
1, 1);
|
1, 1);
|
||||||
gtk_widget_show_all(fc.label);
|
// and make them share visibility so if the control is hidden, so is its label
|
||||||
|
fc.labelBinding = g_object_bind_property(GTK_WIDGET(uiControlHandle(fc.c)), "visible",
|
||||||
|
fc.label, "visible",
|
||||||
|
G_BINDING_SYNC_CREATE);
|
||||||
|
|
||||||
uiControlSetParent(fc.c, uiControl(f));
|
uiControlSetParent(fc.c, uiControl(f));
|
||||||
uiUnixControlSetContainer(uiUnixControl(fc.c), f->container, FALSE);
|
uiUnixControlSetContainer(uiUnixControl(fc.c), f->container, FALSE);
|
||||||
|
|
|
@ -37,6 +37,7 @@ static void boxRelayout(uiBox *b)
|
||||||
int stretchywid, stretchyht;
|
int stretchywid, stretchyht;
|
||||||
int i;
|
int i;
|
||||||
int minimumWidth, minimumHeight;
|
int minimumWidth, minimumHeight;
|
||||||
|
int nVisible;
|
||||||
uiWindowsSizing *d;
|
uiWindowsSizing *d;
|
||||||
|
|
||||||
if (b->controls->size() == 0)
|
if (b->controls->size() == 0)
|
||||||
|
@ -51,21 +52,16 @@ static void boxRelayout(uiBox *b)
|
||||||
// -1) get this Box's padding
|
// -1) get this Box's padding
|
||||||
boxPadding(b, &xpadding, &ypadding);
|
boxPadding(b, &xpadding, &ypadding);
|
||||||
|
|
||||||
// 0) inset the available rect by the needed padding
|
|
||||||
// TODO this is incorrect if any controls are hidden
|
|
||||||
if (b->vertical)
|
|
||||||
height -= (b->controls->size() - 1) * ypadding;
|
|
||||||
else
|
|
||||||
width -= (b->controls->size() - 1) * xpadding;
|
|
||||||
|
|
||||||
// 1) get width and height of non-stretchy controls
|
// 1) get width and height of non-stretchy controls
|
||||||
// this will tell us how much space will be left for stretchy controls
|
// this will tell us how much space will be left for stretchy controls
|
||||||
stretchywid = width;
|
stretchywid = width;
|
||||||
stretchyht = height;
|
stretchyht = height;
|
||||||
nStretchy = 0;
|
nStretchy = 0;
|
||||||
|
nVisible = 0;
|
||||||
for (struct boxChild &bc : *(b->controls)) {
|
for (struct boxChild &bc : *(b->controls)) {
|
||||||
if (!uiControlVisible(bc.c))
|
if (!uiControlVisible(bc.c))
|
||||||
continue;
|
continue;
|
||||||
|
nVisible++;
|
||||||
if (bc.stretchy) {
|
if (bc.stretchy) {
|
||||||
nStretchy++;
|
nStretchy++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -81,24 +77,35 @@ static void boxRelayout(uiBox *b)
|
||||||
stretchywid -= minimumWidth;
|
stretchywid -= minimumWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (nVisible == 0) // nothing to do
|
||||||
|
return;
|
||||||
|
|
||||||
// 2) now get the size of stretchy controls
|
// 2) now inset the available rect by the needed padding
|
||||||
if (nStretchy != 0)
|
if (b->vertical) {
|
||||||
|
height -= (nVisible - 1) * ypadding;
|
||||||
|
stretchyht -= (nVisible - 1) * ypadding;
|
||||||
|
} else {
|
||||||
|
width -= (nVisible - 1) * xpadding;
|
||||||
|
stretchywid -= (nVisible - 1) * xpadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) now get the size of stretchy controls
|
||||||
|
if (nStretchy != 0) {
|
||||||
if (b->vertical)
|
if (b->vertical)
|
||||||
stretchyht /= nStretchy;
|
stretchyht /= nStretchy;
|
||||||
else
|
else
|
||||||
stretchywid /= nStretchy;
|
stretchywid /= nStretchy;
|
||||||
// TODO put this in the above if
|
for (struct boxChild &bc : *(b->controls)) {
|
||||||
for (struct boxChild &bc : *(b->controls)) {
|
if (!uiControlVisible(bc.c))
|
||||||
if (!uiControlVisible(bc.c))
|
continue;
|
||||||
continue;
|
if (bc.stretchy) {
|
||||||
if (bc.stretchy) {
|
bc.width = stretchywid;
|
||||||
bc.width = stretchywid;
|
bc.height = stretchyht;
|
||||||
bc.height = stretchyht;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) now we can position controls
|
// 4) now we can position controls
|
||||||
// first, make relative to the top-left corner of the container
|
// first, make relative to the top-left corner of the container
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
|
@ -159,6 +166,7 @@ static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
int maxStretchyWidth, maxStretchyHeight;
|
int maxStretchyWidth, maxStretchyHeight;
|
||||||
int i;
|
int i;
|
||||||
int minimumWidth, minimumHeight;
|
int minimumWidth, minimumHeight;
|
||||||
|
int nVisible;
|
||||||
uiWindowsSizing sizing;
|
uiWindowsSizing sizing;
|
||||||
|
|
||||||
*width = 0;
|
*width = 0;
|
||||||
|
@ -169,21 +177,16 @@ static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
// 0) get this Box's padding
|
// 0) get this Box's padding
|
||||||
boxPadding(b, &xpadding, &ypadding);
|
boxPadding(b, &xpadding, &ypadding);
|
||||||
|
|
||||||
// 1) initialize the desired rect with the needed padding
|
// 1) add in the size of non-stretchy controls and get (but not add in) the largest widths and heights of stretchy controls
|
||||||
// TODO this is wrong if any controls are hidden
|
|
||||||
if (b->vertical)
|
|
||||||
*height = (b->controls->size() - 1) * ypadding;
|
|
||||||
else
|
|
||||||
*width = (b->controls->size() - 1) * xpadding;
|
|
||||||
|
|
||||||
// 2) add in the size of non-stretchy controls and get (but not add in) the largest widths and heights of stretchy controls
|
|
||||||
// we still add in like direction of stretchy controls
|
// we still add in like direction of stretchy controls
|
||||||
nStretchy = 0;
|
nStretchy = 0;
|
||||||
maxStretchyWidth = 0;
|
maxStretchyWidth = 0;
|
||||||
maxStretchyHeight = 0;
|
maxStretchyHeight = 0;
|
||||||
|
nVisible = 0;
|
||||||
for (const struct boxChild &bc : *(b->controls)) {
|
for (const struct boxChild &bc : *(b->controls)) {
|
||||||
if (!uiControlVisible(bc.c))
|
if (!uiControlVisible(bc.c))
|
||||||
continue;
|
continue;
|
||||||
|
nVisible++;
|
||||||
uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight);
|
uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight);
|
||||||
if (bc.stretchy) {
|
if (bc.stretchy) {
|
||||||
nStretchy++;
|
nStretchy++;
|
||||||
|
@ -204,6 +207,14 @@ static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
*height = minimumHeight;
|
*height = minimumHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (nVisible == 0) // just return 0x0
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 2) now outset the desired rect with the needed padding
|
||||||
|
if (b->vertical)
|
||||||
|
*height += (nVisible - 1) * ypadding;
|
||||||
|
else
|
||||||
|
*width += (nVisible - 1) * xpadding;
|
||||||
|
|
||||||
// 3) and now we can add in stretchy controls
|
// 3) and now we can add in stretchy controls
|
||||||
if (b->vertical)
|
if (b->vertical)
|
||||||
|
@ -226,6 +237,12 @@ static void uiBoxMinimumSizeChanged(uiWindowsControl *c)
|
||||||
uiWindowsControlDefaultLayoutRect(uiBox)
|
uiWindowsControlDefaultLayoutRect(uiBox)
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(uiBox)
|
uiWindowsControlDefaultAssignControlIDZOrder(uiBox)
|
||||||
|
|
||||||
|
static void uiBoxChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO eliminate the redundancy
|
||||||
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
||||||
static void boxArrangeChildren(uiBox *b)
|
static void boxArrangeChildren(uiBox *b)
|
||||||
{
|
{
|
||||||
LONG_PTR controlID;
|
LONG_PTR controlID;
|
||||||
|
|
|
@ -21,6 +21,7 @@ void uiWindowsControlMinimumSizeChanged(uiWindowsControl *c)
|
||||||
(*(c->MinimumSizeChanged))(c);
|
(*(c->MinimumSizeChanged))(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO get rid of this
|
||||||
void uiWindowsControlLayoutRect(uiWindowsControl *c, RECT *r)
|
void uiWindowsControlLayoutRect(uiWindowsControl *c, RECT *r)
|
||||||
{
|
{
|
||||||
(*(c->LayoutRect))(c, r);
|
(*(c->LayoutRect))(c, r);
|
||||||
|
@ -31,6 +32,11 @@ void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *contro
|
||||||
(*(c->AssignControlIDZOrder))(c, controlID, insertAfter);
|
(*(c->AssignControlIDZOrder))(c, controlID, insertAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uiWindowsControlChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
(*(c->ChildVisibilityChanged))(c);
|
||||||
|
}
|
||||||
|
|
||||||
HWND uiWindowsEnsureCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont)
|
HWND uiWindowsEnsureCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont)
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
@ -106,3 +112,10 @@ void uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl *c)
|
||||||
if (parent != NULL)
|
if (parent != NULL)
|
||||||
uiWindowsControlMinimumSizeChanged(uiWindowsControl(parent));
|
uiWindowsControlMinimumSizeChanged(uiWindowsControl(parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO rename this nad the OS X this and hugging ones to NotifyChild
|
||||||
|
void uiWindowsControlNotifyVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO we really need to figure this out; the duplication is a mess
|
||||||
|
uiWindowsControlContinueMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ static void formRelayout(uiForm *f)
|
||||||
int minimumWidth, minimumHeight;
|
int minimumWidth, minimumHeight;
|
||||||
uiWindowsSizing sizing;
|
uiWindowsSizing sizing;
|
||||||
int labelht, labelyoff;
|
int labelht, labelyoff;
|
||||||
|
int nVisible;
|
||||||
|
|
||||||
if (f->controls->size() == 0)
|
if (f->controls->size() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -53,22 +54,22 @@ static void formRelayout(uiForm *f)
|
||||||
width = r.right - r.left;
|
width = r.right - r.left;
|
||||||
height = r.bottom - r.top;
|
height = r.bottom - r.top;
|
||||||
|
|
||||||
// -1) get this Form's padding
|
// 0) get this Form's padding
|
||||||
formPadding(f, &xpadding, &ypadding);
|
formPadding(f, &xpadding, &ypadding);
|
||||||
|
|
||||||
// 0) inset the available rect by the needed padding
|
|
||||||
// TODO this is incorrect if any controls are hidden
|
|
||||||
width -= xpadding;
|
|
||||||
height -= (f->controls->size() - 1) * ypadding;
|
|
||||||
|
|
||||||
// 1) get width of labels and height of non-stretchy controls
|
// 1) get width of labels and height of non-stretchy controls
|
||||||
// this will tell us how much space will be left for controls
|
// this will tell us how much space will be left for controls
|
||||||
labelwid = 0;
|
labelwid = 0;
|
||||||
stretchyht = height;
|
stretchyht = height;
|
||||||
nStretchy = 0;
|
nStretchy = 0;
|
||||||
|
nVisible = 0;
|
||||||
for (struct formChild &fc : *(f->controls)) {
|
for (struct formChild &fc : *(f->controls)) {
|
||||||
if (!uiControlVisible(fc.c))
|
if (!uiControlVisible(fc.c)) {
|
||||||
|
ShowWindow(fc.label, SW_HIDE);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
ShowWindow(fc.label, SW_SHOW);
|
||||||
|
nVisible++;
|
||||||
thiswid = uiWindowsWindowTextWidth(fc.label);
|
thiswid = uiWindowsWindowTextWidth(fc.label);
|
||||||
if (labelwid < thiswid)
|
if (labelwid < thiswid)
|
||||||
labelwid = thiswid;
|
labelwid = thiswid;
|
||||||
|
@ -80,8 +81,15 @@ static void formRelayout(uiForm *f)
|
||||||
fc.height = minimumHeight;
|
fc.height = minimumHeight;
|
||||||
stretchyht -= minimumHeight;
|
stretchyht -= minimumHeight;
|
||||||
}
|
}
|
||||||
|
if (nVisible == 0) // nothing to do
|
||||||
|
return;
|
||||||
|
|
||||||
// 2) now get the width of controls and the height of stretchy controls
|
// 2) inset the available rect by the needed padding
|
||||||
|
width -= xpadding;
|
||||||
|
height -= (nVisible - 1) * ypadding;
|
||||||
|
stretchyht -= (nVisible - 1) * ypadding;
|
||||||
|
|
||||||
|
// 3) now get the width of controls and the height of stretchy controls
|
||||||
width -= labelwid;
|
width -= labelwid;
|
||||||
if (nStretchy != 0) {
|
if (nStretchy != 0) {
|
||||||
stretchyht /= nStretchy;
|
stretchyht /= nStretchy;
|
||||||
|
@ -93,12 +101,12 @@ static void formRelayout(uiForm *f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) get the y offset
|
// 4) get the y offset
|
||||||
labelyoff = labelYOffset;
|
labelyoff = labelYOffset;
|
||||||
uiWindowsGetSizing(f->hwnd, &sizing);
|
uiWindowsGetSizing(f->hwnd, &sizing);
|
||||||
uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &labelyoff);
|
uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &labelyoff);
|
||||||
|
|
||||||
// 4) now we can position controls
|
// 5) now we can position controls
|
||||||
// first, make relative to the top-left corner of the container
|
// first, make relative to the top-left corner of the container
|
||||||
// also prefer left alignment on Windows
|
// also prefer left alignment on Windows
|
||||||
x = labelwid + xpadding;
|
x = labelwid + xpadding;
|
||||||
|
@ -164,6 +172,7 @@ static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
int labelwid;
|
int labelwid;
|
||||||
int i;
|
int i;
|
||||||
int minimumWidth, minimumHeight;
|
int minimumWidth, minimumHeight;
|
||||||
|
int nVisible;
|
||||||
uiWindowsSizing sizing;
|
uiWindowsSizing sizing;
|
||||||
|
|
||||||
*width = 0;
|
*width = 0;
|
||||||
|
@ -174,20 +183,17 @@ static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
// 0) get this Form's padding
|
// 0) get this Form's padding
|
||||||
formPadding(f, &xpadding, &ypadding);
|
formPadding(f, &xpadding, &ypadding);
|
||||||
|
|
||||||
// 1) initialize the desired rect with the needed padding
|
// 1) determine the longest width of all controls and labels; add in the height of non-stretchy controls and get (but not add in) the largest heights of stretchy controls
|
||||||
// TODO this is wrong if any controls are hidden
|
|
||||||
*width = xpadding;
|
|
||||||
*height = (f->controls->size() - 1) * ypadding;
|
|
||||||
|
|
||||||
// 2) determine the longest width of all controls and labels; add in the height of non-stretchy controls and get (but not add in) the largest heights of stretchy controls
|
|
||||||
// we still add in like direction of stretchy controls
|
// we still add in like direction of stretchy controls
|
||||||
nStretchy = 0;
|
nStretchy = 0;
|
||||||
maxLabelWidth = 0;
|
maxLabelWidth = 0;
|
||||||
maxControlWidth = 0;
|
maxControlWidth = 0;
|
||||||
maxStretchyHeight = 0;
|
maxStretchyHeight = 0;
|
||||||
|
nVisible = 0;
|
||||||
for (const struct formChild &fc : *(f->controls)) {
|
for (const struct formChild &fc : *(f->controls)) {
|
||||||
if (!uiControlVisible(fc.c))
|
if (!uiControlVisible(fc.c))
|
||||||
continue;
|
continue;
|
||||||
|
nVisible++;
|
||||||
labelwid = uiWindowsWindowTextWidth(fc.label);
|
labelwid = uiWindowsWindowTextWidth(fc.label);
|
||||||
if (maxLabelWidth < labelwid)
|
if (maxLabelWidth < labelwid)
|
||||||
maxLabelWidth = labelwid;
|
maxLabelWidth = labelwid;
|
||||||
|
@ -202,8 +208,14 @@ static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
if (!fc.stretchy)
|
if (!fc.stretchy)
|
||||||
*height += minimumHeight;
|
*height += minimumHeight;
|
||||||
}
|
}
|
||||||
|
if (nVisible == 0) // nothing to show; return 0x0
|
||||||
|
return;
|
||||||
*width += maxLabelWidth + maxControlWidth;
|
*width += maxLabelWidth + maxControlWidth;
|
||||||
|
|
||||||
|
// 2) outset the desired rect with the needed padding
|
||||||
|
*width += xpadding;
|
||||||
|
*height += (nVisible - 1) * ypadding;
|
||||||
|
|
||||||
// 3) and now we can add in stretchy controls
|
// 3) and now we can add in stretchy controls
|
||||||
*height += nStretchy * maxStretchyHeight;
|
*height += nStretchy * maxStretchyHeight;
|
||||||
}
|
}
|
||||||
|
@ -222,6 +234,12 @@ static void uiFormMinimumSizeChanged(uiWindowsControl *c)
|
||||||
uiWindowsControlDefaultLayoutRect(uiForm)
|
uiWindowsControlDefaultLayoutRect(uiForm)
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(uiForm)
|
uiWindowsControlDefaultAssignControlIDZOrder(uiForm)
|
||||||
|
|
||||||
|
static void uiFormChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO eliminate the redundancy
|
||||||
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
||||||
static void formArrangeChildren(uiForm *f)
|
static void formArrangeChildren(uiForm *f)
|
||||||
{
|
{
|
||||||
LONG_PTR controlID;
|
LONG_PTR controlID;
|
||||||
|
|
140
windows/grid.cpp
140
windows/grid.cpp
|
@ -6,7 +6,7 @@
|
||||||
// - what happens if you call Append() twice?
|
// - what happens if you call Append() twice?
|
||||||
|
|
||||||
// TODOs
|
// TODOs
|
||||||
// - make ALL the controls handle hidden children right
|
// - the Assorted page has clipping and repositioning issues
|
||||||
|
|
||||||
struct gridChild {
|
struct gridChild {
|
||||||
uiControl *c;
|
uiControl *c;
|
||||||
|
@ -36,25 +36,59 @@ struct uiGrid {
|
||||||
int xmax, ymax;
|
int xmax, ymax;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool gridRecomputeMinMax(uiGrid *g)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (struct gridChild *gc : *(g->children)) {
|
||||||
|
// this is important; we want g->xmin/g->ymin to satisfy gridLayoutData::visibleRow()/visibleColumn()
|
||||||
|
if (!uiControlVisible(gc->c))
|
||||||
|
continue;
|
||||||
|
if (first) {
|
||||||
|
g->xmin = gc->left;
|
||||||
|
g->ymin = gc->top;
|
||||||
|
g->xmax = gc->left + gc->xspan;
|
||||||
|
g->ymax = gc->top + gc->yspan;
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (g->xmin > gc->left)
|
||||||
|
g->xmin = gc->left;
|
||||||
|
if (g->ymin > gc->top)
|
||||||
|
g->ymin = gc->top;
|
||||||
|
if (g->xmax < (gc->left + gc->xspan))
|
||||||
|
g->xmax = gc->left + gc->xspan;
|
||||||
|
if (g->ymax < (gc->top + gc->yspan))
|
||||||
|
g->ymax = gc->top + gc->yspan;
|
||||||
|
}
|
||||||
|
return first != false;
|
||||||
|
}
|
||||||
|
|
||||||
#define xcount(g) ((g)->xmax - (g)->xmin)
|
#define xcount(g) ((g)->xmax - (g)->xmin)
|
||||||
#define ycount(g) ((g)->ymax - (g)->ymin)
|
#define ycount(g) ((g)->ymax - (g)->ymin)
|
||||||
#define toxindex(g, x) ((x) - (g)->xmin)
|
#define toxindex(g, x) ((x) - (g)->xmin)
|
||||||
#define toyindex(g, y) ((y) - (g)->ymin)
|
#define toyindex(g, y) ((y) - (g)->ymin)
|
||||||
|
|
||||||
class gridLayoutData {
|
class gridLayoutData {
|
||||||
size_t ycount;
|
int ycount;
|
||||||
public:
|
public:
|
||||||
int **gg; // topological map gg[y][x] = control index
|
int **gg; // topological map gg[y][x] = control index
|
||||||
int *colwidths;
|
int *colwidths;
|
||||||
int *rowheights;
|
int *rowheights;
|
||||||
bool *hexpand;
|
bool *hexpand;
|
||||||
bool *vexpand;
|
bool *vexpand;
|
||||||
|
int nVisibleRows;
|
||||||
|
int nVisibleColumns;
|
||||||
|
|
||||||
|
bool noVisible;
|
||||||
|
|
||||||
gridLayoutData(uiGrid *g)
|
gridLayoutData(uiGrid *g)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
this->noVisible = gridRecomputeMinMax(g);
|
||||||
|
|
||||||
this->gg = new int *[ycount(g)];
|
this->gg = new int *[ycount(g)];
|
||||||
for (y = 0; y < ycount(g); y++) {
|
for (y = 0; y < ycount(g); y++) {
|
||||||
this->gg[y] = new int[xcount(g)];
|
this->gg[y] = new int[xcount(g)];
|
||||||
|
@ -66,6 +100,8 @@ public:
|
||||||
struct gridChild *gc;
|
struct gridChild *gc;
|
||||||
|
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
if (!uiControlVisible(gc->c))
|
||||||
|
continue;
|
||||||
for (y = gc->top; y < gc->top + gc->yspan; y++)
|
for (y = gc->top; y < gc->top + gc->yspan; y++)
|
||||||
for (x = gc->left; x < gc->left + gc->xspan; x++)
|
for (x = gc->left; x < gc->left + gc->xspan; x++)
|
||||||
this->gg[toyindex(g, y)][toxindex(g, x)] = i;
|
this->gg[toyindex(g, y)][toxindex(g, x)] = i;
|
||||||
|
@ -81,6 +117,19 @@ public:
|
||||||
ZeroMemory(this->vexpand, ycount(g) * sizeof (bool));
|
ZeroMemory(this->vexpand, ycount(g) * sizeof (bool));
|
||||||
|
|
||||||
this->ycount = ycount(g);
|
this->ycount = ycount(g);
|
||||||
|
|
||||||
|
// if a row or column only contains emptys and spanning cells of a opposite-direction spannings, it is invisible and should not be considered for padding amount calculations
|
||||||
|
// note that the first row and column will always be visible because gridRecomputeMinMax() computed a smallest fitting rectangle
|
||||||
|
if (this->noVisible)
|
||||||
|
return;
|
||||||
|
this->nVisibleRows = 0;
|
||||||
|
for (y = 0; y < this->ycount; y++)
|
||||||
|
if (this->visibleRow(g, y))
|
||||||
|
this->nVisibleRows++;
|
||||||
|
this->nVisibleColumns = 0;
|
||||||
|
for (x = 0; x < xcount(g); x++)
|
||||||
|
if (this->visibleColumn(g, x))
|
||||||
|
this->nVisibleColumns++;
|
||||||
}
|
}
|
||||||
|
|
||||||
~gridLayoutData()
|
~gridLayoutData()
|
||||||
|
@ -95,6 +144,34 @@ public:
|
||||||
delete[] this->gg[y];
|
delete[] this->gg[y];
|
||||||
delete[] this->gg;
|
delete[] this->gg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool visibleRow(uiGrid *g, int y)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
struct gridChild *gc;
|
||||||
|
|
||||||
|
for (x = 0; x < xcount(g); x++)
|
||||||
|
if (this->gg[y][x] != -1) {
|
||||||
|
gc = (*(g->children))[this->gg[y][x]];
|
||||||
|
if (gc->yspan == 1 || gc->top - g->ymin == y)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visibleColumn(uiGrid *g, int x)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
struct gridChild *gc;
|
||||||
|
|
||||||
|
for (y = 0; y < this->ycount; y++)
|
||||||
|
if (this->gg[y][x] != -1) {
|
||||||
|
gc = (*(g->children))[this->gg[y][x]];
|
||||||
|
if (gc->xspan == 1 || gc->left - g->xmin == x)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gridPadding(uiGrid *g, int *xpadding, int *ypadding)
|
static void gridPadding(uiGrid *g, int *xpadding, int *ypadding)
|
||||||
|
@ -132,10 +209,14 @@ static void gridRelayout(uiGrid *g)
|
||||||
|
|
||||||
gridPadding(g, &xpadding, &ypadding);
|
gridPadding(g, &xpadding, &ypadding);
|
||||||
ld = new gridLayoutData(g);
|
ld = new gridLayoutData(g);
|
||||||
|
if (ld->noVisible) { // nothing to do
|
||||||
|
delete ld;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 0) discount padding from width/height
|
// 0) discount padding from width/height
|
||||||
width -= (xcount(g) - 1) * xpadding;
|
width -= (ld->nVisibleColumns - 1) * xpadding;
|
||||||
height -= (ycount(g) - 1) * ypadding;
|
height -= (ld->nVisibleRows - 1) * ypadding;
|
||||||
|
|
||||||
// 1) compute colwidths and rowheights before handling expansion
|
// 1) compute colwidths and rowheights before handling expansion
|
||||||
// we only count non-spanning controls to avoid weirdness
|
// we only count non-spanning controls to avoid weirdness
|
||||||
|
@ -161,6 +242,8 @@ static void gridRelayout(uiGrid *g)
|
||||||
// we need to know which expanding rows/columns don't span before we can handle the ones that do
|
// we need to know which expanding rows/columns don't span before we can handle the ones that do
|
||||||
for (i = 0; i < g->children->size(); i++) {
|
for (i = 0; i < g->children->size(); i++) {
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
if (!uiControlVisible(gc->c))
|
||||||
|
continue;
|
||||||
if (gc->hexpand && gc->xspan == 1)
|
if (gc->hexpand && gc->xspan == 1)
|
||||||
ld->hexpand[toxindex(g, gc->left)] = true;
|
ld->hexpand[toxindex(g, gc->left)] = true;
|
||||||
if (gc->vexpand && gc->yspan == 1)
|
if (gc->vexpand && gc->yspan == 1)
|
||||||
|
@ -171,6 +254,8 @@ static void gridRelayout(uiGrid *g)
|
||||||
// the way we handle this is simple: if none of the spanned rows/columns expand, make all rows/columns expand
|
// the way we handle this is simple: if none of the spanned rows/columns expand, make all rows/columns expand
|
||||||
for (i = 0; i < g->children->size(); i++) {
|
for (i = 0; i < g->children->size(); i++) {
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
if (!uiControlVisible(gc->c))
|
||||||
|
continue;
|
||||||
if (gc->hexpand && gc->xspan != 1) {
|
if (gc->hexpand && gc->xspan != 1) {
|
||||||
bool doit = true;
|
bool doit = true;
|
||||||
|
|
||||||
|
@ -197,7 +282,6 @@ static void gridRelayout(uiGrid *g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 4) compute and assign expanded widths/heights
|
// 4) compute and assign expanded widths/heights
|
||||||
nhexpand = 0;
|
nhexpand = 0;
|
||||||
nvexpand = 0;
|
nvexpand = 0;
|
||||||
|
@ -221,6 +305,8 @@ static void gridRelayout(uiGrid *g)
|
||||||
// 5) reset the final coordinates for the next step
|
// 5) reset the final coordinates for the next step
|
||||||
for (i = 0; i < g->children->size(); i++) {
|
for (i = 0; i < g->children->size(); i++) {
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
if (!uiControlVisible(gc->c))
|
||||||
|
continue;
|
||||||
gc->finalx = 0;
|
gc->finalx = 0;
|
||||||
gc->finaly = 0;
|
gc->finaly = 0;
|
||||||
gc->finalwidth = 0;
|
gc->finalwidth = 0;
|
||||||
|
@ -235,6 +321,8 @@ static void gridRelayout(uiGrid *g)
|
||||||
curx = 0;
|
curx = 0;
|
||||||
prev = -1;
|
prev = -1;
|
||||||
for (ix = 0; ix < xcount(g); ix++) {
|
for (ix = 0; ix < xcount(g); ix++) {
|
||||||
|
if (!ld->visibleColumn(g, ix))
|
||||||
|
continue;
|
||||||
i = ld->gg[iy][ix];
|
i = ld->gg[iy][ix];
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
@ -257,6 +345,8 @@ static void gridRelayout(uiGrid *g)
|
||||||
cury = 0;
|
cury = 0;
|
||||||
prev = -1;
|
prev = -1;
|
||||||
for (iy = 0; iy < ycount(g); iy++) {
|
for (iy = 0; iy < ycount(g); iy++) {
|
||||||
|
if (!ld->visibleRow(g, iy))
|
||||||
|
continue;
|
||||||
i = ld->gg[iy][ix];
|
i = ld->gg[iy][ix];
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
@ -277,6 +367,8 @@ static void gridRelayout(uiGrid *g)
|
||||||
// this is why we saved minwidth/minheight above
|
// this is why we saved minwidth/minheight above
|
||||||
for (i = 0; i < g->children->size(); i++) {
|
for (i = 0; i < g->children->size(); i++) {
|
||||||
gc = (*(g->children))[i];
|
gc = (*(g->children))[i];
|
||||||
|
if (!uiControlVisible(gc->c))
|
||||||
|
continue;
|
||||||
if (gc->halign != uiAlignFill) {
|
if (gc->halign != uiAlignFill) {
|
||||||
switch (gc->halign) {
|
switch (gc->halign) {
|
||||||
case uiAlignEnd:
|
case uiAlignEnd:
|
||||||
|
@ -375,6 +467,10 @@ static void uiGridMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
|
|
||||||
gridPadding(g, &xpadding, &ypadding);
|
gridPadding(g, &xpadding, &ypadding);
|
||||||
ld = new gridLayoutData(g);
|
ld = new gridLayoutData(g);
|
||||||
|
if (ld->noVisible) { // nothing to do; return 0x0
|
||||||
|
delete ld;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 1) compute colwidths and rowheights before handling expansion
|
// 1) compute colwidths and rowheights before handling expansion
|
||||||
// TODO put this in its own function (but careful about the spanning calculation in gridRelayout())
|
// TODO put this in its own function (but careful about the spanning calculation in gridRelayout())
|
||||||
|
@ -404,8 +500,8 @@ static void uiGridMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
rowheight += ld->rowheights[y];
|
rowheight += ld->rowheights[y];
|
||||||
|
|
||||||
// and that's it; just account for padding
|
// and that's it; just account for padding
|
||||||
*width = colwidth + (g->xmax-1) * xpadding;
|
*width = colwidth + (ld->nVisibleColumns - 1) * xpadding;
|
||||||
*height = rowheight + (g->ymax-1) * ypadding;
|
*height = rowheight + (ld->nVisibleRows - 1) * ypadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uiGridMinimumSizeChanged(uiWindowsControl *c)
|
static void uiGridMinimumSizeChanged(uiWindowsControl *c)
|
||||||
|
@ -422,6 +518,12 @@ static void uiGridMinimumSizeChanged(uiWindowsControl *c)
|
||||||
uiWindowsControlDefaultLayoutRect(uiGrid)
|
uiWindowsControlDefaultLayoutRect(uiGrid)
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(uiGrid)
|
uiWindowsControlDefaultAssignControlIDZOrder(uiGrid)
|
||||||
|
|
||||||
|
static void uiGridChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO eliminate the redundancy
|
||||||
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
||||||
// must have called gridRecomputeMinMax() first
|
// must have called gridRecomputeMinMax() first
|
||||||
static void gridArrangeChildren(uiGrid *g)
|
static void gridArrangeChildren(uiGrid *g)
|
||||||
{
|
{
|
||||||
|
@ -455,30 +557,6 @@ static void gridArrangeChildren(uiGrid *g)
|
||||||
delete ld;
|
delete ld;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gridRecomputeMinMax(uiGrid *g)
|
|
||||||
{
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
for (struct gridChild *gc : *(g->children)) {
|
|
||||||
if (first) {
|
|
||||||
g->xmin = gc->left;
|
|
||||||
g->ymin = gc->top;
|
|
||||||
g->xmax = gc->left + gc->xspan;
|
|
||||||
g->ymax = gc->top + gc->yspan;
|
|
||||||
first = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (g->xmin > gc->left)
|
|
||||||
g->xmin = gc->left;
|
|
||||||
if (g->ymin > gc->top)
|
|
||||||
g->ymin = gc->top;
|
|
||||||
if (g->xmax < (gc->left + gc->xspan))
|
|
||||||
g->xmax = gc->left + gc->xspan;
|
|
||||||
if (g->ymax < (gc->top + gc->yspan))
|
|
||||||
g->ymax = gc->top + gc->yspan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct gridChild *toChild(uiControl *c, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign)
|
static struct gridChild *toChild(uiControl *c, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign)
|
||||||
{
|
{
|
||||||
struct gridChild *gc;
|
struct gridChild *gc;
|
||||||
|
|
|
@ -121,6 +121,12 @@ static void uiGroupMinimumSizeChanged(uiWindowsControl *c)
|
||||||
uiWindowsControlDefaultLayoutRect(uiGroup)
|
uiWindowsControlDefaultLayoutRect(uiGroup)
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(uiGroup)
|
uiWindowsControlDefaultAssignControlIDZOrder(uiGroup)
|
||||||
|
|
||||||
|
static void uiGroupChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO eliminate the redundancy
|
||||||
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
||||||
char *uiGroupTitle(uiGroup *g)
|
char *uiGroupTitle(uiGroup *g)
|
||||||
{
|
{
|
||||||
return uiWindowsWindowText(g->hwnd);
|
return uiWindowsWindowText(g->hwnd);
|
||||||
|
|
|
@ -166,6 +166,12 @@ static void uiTabMinimumSizeChanged(uiWindowsControl *c)
|
||||||
uiWindowsControlDefaultLayoutRect(uiTab)
|
uiWindowsControlDefaultLayoutRect(uiTab)
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(uiTab)
|
uiWindowsControlDefaultAssignControlIDZOrder(uiTab)
|
||||||
|
|
||||||
|
static void uiTabChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO eliminate the redundancy
|
||||||
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
||||||
static void tabArrangePages(uiTab *t)
|
static void tabArrangePages(uiTab *t)
|
||||||
{
|
{
|
||||||
LONG_PTR controlID = 100;
|
LONG_PTR controlID = 100;
|
||||||
|
|
|
@ -260,6 +260,12 @@ static void uiWindowLayoutRect(uiWindowsControl *c, RECT *r)
|
||||||
|
|
||||||
uiWindowsControlDefaultAssignControlIDZOrder(uiWindow)
|
uiWindowsControlDefaultAssignControlIDZOrder(uiWindow)
|
||||||
|
|
||||||
|
static void uiWindowChildVisibilityChanged(uiWindowsControl *c)
|
||||||
|
{
|
||||||
|
// TODO eliminate the redundancy
|
||||||
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
|
}
|
||||||
|
|
||||||
char *uiWindowTitle(uiWindow *w)
|
char *uiWindowTitle(uiWindow *w)
|
||||||
{
|
{
|
||||||
return uiWindowsWindowText(w->hwnd);
|
return uiWindowsWindowText(w->hwnd);
|
||||||
|
|
Loading…
Reference in New Issue