Merge pull request #1 from andlabs/master

Merge upstream changes
This commit is contained in:
emersion 2016-06-15 10:27:35 +02:00 committed by GitHub
commit 578ff39525
12 changed files with 244 additions and 75 deletions

View File

@ -20,6 +20,9 @@ This README is being written.<br>
* **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.
* 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**
* `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.

View File

@ -148,6 +148,7 @@ struct uiGrid {
int firstx, firsty;
BOOL *hexpand, *vexpand;
BOOL doit;
BOOL onlyEmptyAndSpanning;
[self removeOurConstraints];
if ([self->children count] == 0)
@ -158,6 +159,7 @@ struct uiGrid {
// ignore hidden controls
first = YES;
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))
continue;
if (first) {
@ -177,6 +179,8 @@ struct uiGrid {
if (ymax < (gc.top + gc.yspan))
ymax = gc.top + gc.yspan;
}
if (first != NO) // the entire grid is hidden; do nothing
return;
xcount = xmax - xmin;
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
BOOL onlyEmptyAndSpanning;
for (y = 0; y < ycount; y++) {
onlyEmptyAndSpanning = YES;
for (x = 0; x < xcount; x++)

1
doc/form Normal file
View File

@ -0,0 +1 @@
hiding a control also hides its label

View File

@ -26,6 +26,7 @@ struct uiWindowsControl {
void (*MinimumSizeChanged)(uiWindowsControl *);
void (*LayoutRect)(uiWindowsControl *c, RECT *r);
void (*AssignControlIDZOrder)(uiWindowsControl *, LONG_PTR *, HWND *);
void (*ChildVisibilityChanged)(uiWindowsControl *);
};
#define uiWindowsControl(this) ((uiWindowsControl *) (this))
// TODO document
@ -35,6 +36,7 @@ _UI_EXTERN void uiWindowsControlMinimumSize(uiWindowsControl *, int *, int *);
_UI_EXTERN void uiWindowsControlMinimumSizeChanged(uiWindowsControl *);
_UI_EXTERN void uiWindowsControlLayoutRect(uiWindowsControl *, RECT *);
_UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_PTR *, HWND *);
_UI_EXTERN void uiWindowsControlChildVisibilityChanged(uiWindowsControl *);
// TODO document
#define uiWindowsControlDefaultDestroy(type) \
@ -74,12 +76,14 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
{ \
uiWindowsControl(c)->visible = 1; \
ShowWindow(type(c)->hwnd, SW_SHOW); \
uiWindowsControlNotifyVisibilityChanged(uiWindowsControl(c)); \
}
#define uiWindowsControlDefaultHide(type) \
static void type ## Hide(uiControl *c) \
{ \
uiWindowsControl(c)->visible = 0; \
ShowWindow(type(c)->hwnd, SW_HIDE); \
uiWindowsControlNotifyVisibilityChanged(uiWindowsControl(c)); \
}
#define uiWindowsControlDefaultEnabled(type) \
static int type ## Enabled(uiControl *c) \
@ -131,6 +135,11 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
{ \
uiWindowsEnsureAssignControlIDZOrder(type(c)->hwnd, controlID, insertAfter); \
}
#define uiWindowsControlDefaultChildVisibilityChanged(type) \
static void type ## ChildVisibilityChanged(uiWindowsControl *c) \
{ \
/* do nothing */ \
}
#define uiWindowsControlAllDefaultsExceptDestroy(type) \
uiWindowsControlDefaultHandle(type) \
@ -147,7 +156,8 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
uiWindowsControlDefaultSetParentHWND(type) \
uiWindowsControlDefaultMinimumSizeChanged(type) \
uiWindowsControlDefaultLayoutRect(type) \
uiWindowsControlDefaultAssignControlIDZOrder(type)
uiWindowsControlDefaultAssignControlIDZOrder(type) \
uiWindowsControlDefaultChildVisibilityChanged(type)
#define uiWindowsControlAllDefaults(type) \
uiWindowsControlDefaultDestroy(type) \
@ -173,6 +183,7 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
uiWindowsControl(var)->MinimumSizeChanged = type ## MinimumSizeChanged; \
uiWindowsControl(var)->LayoutRect = type ## LayoutRect; \
uiWindowsControl(var)->AssignControlIDZOrder = type ## AssignControlIDZOrder; \
uiWindowsControl(var)->ChildVisibilityChanged = type ## ChildVisibilityChanged; \
uiWindowsControl(var)->visible = 1; \
uiWindowsControl(var)->enabled = 1;
// TODO document
@ -246,6 +257,9 @@ _UI_EXTERN void uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl *);
// TODO document
_UI_EXTERN BOOL uiWindowsShouldStopSyncEnableState(uiWindowsControl *c, int enabled);
// TODO document
_UI_EXTERN void uiWindowsControlNotifyVisibilityChanged(uiWindowsControl *c);
#ifdef __cplusplus
}
#endif

View File

@ -8,6 +8,7 @@ struct formChild {
GtkAlign oldhalign;
gboolean oldvexpand;
GtkAlign oldvalign;
GBinding *labelBinding;
};
struct uiForm {
@ -82,7 +83,10 @@ void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy)
gtk_grid_attach(f->grid, fc.label,
0, row,
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));
uiUnixControlSetContainer(uiUnixControl(fc.c), f->container, FALSE);

View File

@ -37,6 +37,7 @@ static void boxRelayout(uiBox *b)
int stretchywid, stretchyht;
int i;
int minimumWidth, minimumHeight;
int nVisible;
uiWindowsSizing *d;
if (b->controls->size() == 0)
@ -51,21 +52,16 @@ static void boxRelayout(uiBox *b)
// -1) get this Box's padding
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
// this will tell us how much space will be left for stretchy controls
stretchywid = width;
stretchyht = height;
nStretchy = 0;
nVisible = 0;
for (struct boxChild &bc : *(b->controls)) {
if (!uiControlVisible(bc.c))
continue;
nVisible++;
if (bc.stretchy) {
nStretchy++;
continue;
@ -81,24 +77,35 @@ static void boxRelayout(uiBox *b)
stretchywid -= minimumWidth;
}
}
if (nVisible == 0) // nothing to do
return;
// 2) now get the size of stretchy controls
if (nStretchy != 0)
// 2) now inset the available rect by the needed padding
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)
stretchyht /= nStretchy;
else
stretchywid /= nStretchy;
// TODO put this in the above if
for (struct boxChild &bc : *(b->controls)) {
if (!uiControlVisible(bc.c))
continue;
if (bc.stretchy) {
bc.width = stretchywid;
bc.height = stretchyht;
for (struct boxChild &bc : *(b->controls)) {
if (!uiControlVisible(bc.c))
continue;
if (bc.stretchy) {
bc.width = stretchywid;
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
x = 0;
y = 0;
@ -159,6 +166,7 @@ static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height)
int maxStretchyWidth, maxStretchyHeight;
int i;
int minimumWidth, minimumHeight;
int nVisible;
uiWindowsSizing sizing;
*width = 0;
@ -169,21 +177,16 @@ static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height)
// 0) get this Box's padding
boxPadding(b, &xpadding, &ypadding);
// 1) initialize the desired rect with the needed padding
// 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
// 1) 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
nStretchy = 0;
maxStretchyWidth = 0;
maxStretchyHeight = 0;
nVisible = 0;
for (const struct boxChild &bc : *(b->controls)) {
if (!uiControlVisible(bc.c))
continue;
nVisible++;
uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight);
if (bc.stretchy) {
nStretchy++;
@ -204,6 +207,14 @@ static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height)
*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
if (b->vertical)
@ -226,6 +237,12 @@ static void uiBoxMinimumSizeChanged(uiWindowsControl *c)
uiWindowsControlDefaultLayoutRect(uiBox)
uiWindowsControlDefaultAssignControlIDZOrder(uiBox)
static void uiBoxChildVisibilityChanged(uiWindowsControl *c)
{
// TODO eliminate the redundancy
uiWindowsControlMinimumSizeChanged(c);
}
static void boxArrangeChildren(uiBox *b)
{
LONG_PTR controlID;

View File

@ -21,6 +21,7 @@ void uiWindowsControlMinimumSizeChanged(uiWindowsControl *c)
(*(c->MinimumSizeChanged))(c);
}
// TODO get rid of this
void uiWindowsControlLayoutRect(uiWindowsControl *c, RECT *r)
{
(*(c->LayoutRect))(c, r);
@ -31,6 +32,11 @@ void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *contro
(*(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 hwnd;
@ -106,3 +112,10 @@ void uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl *c)
if (parent != NULL)
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);
}

View File

@ -43,6 +43,7 @@ static void formRelayout(uiForm *f)
int minimumWidth, minimumHeight;
uiWindowsSizing sizing;
int labelht, labelyoff;
int nVisible;
if (f->controls->size() == 0)
return;
@ -53,22 +54,22 @@ static void formRelayout(uiForm *f)
width = r.right - r.left;
height = r.bottom - r.top;
// -1) get this Form's padding
// 0) get this Form's padding
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
// this will tell us how much space will be left for controls
labelwid = 0;
stretchyht = height;
nStretchy = 0;
nVisible = 0;
for (struct formChild &fc : *(f->controls)) {
if (!uiControlVisible(fc.c))
if (!uiControlVisible(fc.c)) {
ShowWindow(fc.label, SW_HIDE);
continue;
}
ShowWindow(fc.label, SW_SHOW);
nVisible++;
thiswid = uiWindowsWindowTextWidth(fc.label);
if (labelwid < thiswid)
labelwid = thiswid;
@ -80,8 +81,15 @@ static void formRelayout(uiForm *f)
fc.height = 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;
if (nStretchy != 0) {
stretchyht /= nStretchy;
@ -93,12 +101,12 @@ static void formRelayout(uiForm *f)
}
}
// 3) get the y offset
// 4) get the y offset
labelyoff = labelYOffset;
uiWindowsGetSizing(f->hwnd, &sizing);
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
// also prefer left alignment on Windows
x = labelwid + xpadding;
@ -164,6 +172,7 @@ static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height)
int labelwid;
int i;
int minimumWidth, minimumHeight;
int nVisible;
uiWindowsSizing sizing;
*width = 0;
@ -174,20 +183,17 @@ static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height)
// 0) get this Form's padding
formPadding(f, &xpadding, &ypadding);
// 1) initialize the desired rect with the needed padding
// 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
// 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
// we still add in like direction of stretchy controls
nStretchy = 0;
maxLabelWidth = 0;
maxControlWidth = 0;
maxStretchyHeight = 0;
nVisible = 0;
for (const struct formChild &fc : *(f->controls)) {
if (!uiControlVisible(fc.c))
continue;
nVisible++;
labelwid = uiWindowsWindowTextWidth(fc.label);
if (maxLabelWidth < labelwid)
maxLabelWidth = labelwid;
@ -202,8 +208,14 @@ static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height)
if (!fc.stretchy)
*height += minimumHeight;
}
if (nVisible == 0) // nothing to show; return 0x0
return;
*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
*height += nStretchy * maxStretchyHeight;
}
@ -222,6 +234,12 @@ static void uiFormMinimumSizeChanged(uiWindowsControl *c)
uiWindowsControlDefaultLayoutRect(uiForm)
uiWindowsControlDefaultAssignControlIDZOrder(uiForm)
static void uiFormChildVisibilityChanged(uiWindowsControl *c)
{
// TODO eliminate the redundancy
uiWindowsControlMinimumSizeChanged(c);
}
static void formArrangeChildren(uiForm *f)
{
LONG_PTR controlID;

View File

@ -6,7 +6,7 @@
// - what happens if you call Append() twice?
// TODOs
// - make ALL the controls handle hidden children right
// - the Assorted page has clipping and repositioning issues
struct gridChild {
uiControl *c;
@ -36,25 +36,59 @@ struct uiGrid {
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 ycount(g) ((g)->ymax - (g)->ymin)
#define toxindex(g, x) ((x) - (g)->xmin)
#define toyindex(g, y) ((y) - (g)->ymin)
class gridLayoutData {
size_t ycount;
int ycount;
public:
int **gg; // topological map gg[y][x] = control index
int *colwidths;
int *rowheights;
bool *hexpand;
bool *vexpand;
int nVisibleRows;
int nVisibleColumns;
bool noVisible;
gridLayoutData(uiGrid *g)
{
size_t i;
int x, y;
this->noVisible = gridRecomputeMinMax(g);
this->gg = new int *[ycount(g)];
for (y = 0; y < ycount(g); y++) {
this->gg[y] = new int[xcount(g)];
@ -66,6 +100,8 @@ public:
struct gridChild *gc;
gc = (*(g->children))[i];
if (!uiControlVisible(gc->c))
continue;
for (y = gc->top; y < gc->top + gc->yspan; y++)
for (x = gc->left; x < gc->left + gc->xspan; x++)
this->gg[toyindex(g, y)][toxindex(g, x)] = i;
@ -81,6 +117,19 @@ public:
ZeroMemory(this->vexpand, ycount(g) * sizeof (bool));
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()
@ -95,6 +144,34 @@ public:
delete[] this->gg[y];
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)
@ -132,10 +209,14 @@ static void gridRelayout(uiGrid *g)
gridPadding(g, &xpadding, &ypadding);
ld = new gridLayoutData(g);
if (ld->noVisible) { // nothing to do
delete ld;
return;
}
// 0) discount padding from width/height
width -= (xcount(g) - 1) * xpadding;
height -= (ycount(g) - 1) * ypadding;
width -= (ld->nVisibleColumns - 1) * xpadding;
height -= (ld->nVisibleRows - 1) * ypadding;
// 1) compute colwidths and rowheights before handling expansion
// 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
for (i = 0; i < g->children->size(); i++) {
gc = (*(g->children))[i];
if (!uiControlVisible(gc->c))
continue;
if (gc->hexpand && gc->xspan == 1)
ld->hexpand[toxindex(g, gc->left)] = true;
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
for (i = 0; i < g->children->size(); i++) {
gc = (*(g->children))[i];
if (!uiControlVisible(gc->c))
continue;
if (gc->hexpand && gc->xspan != 1) {
bool doit = true;
@ -197,7 +282,6 @@ static void gridRelayout(uiGrid *g)
}
}
// 4) compute and assign expanded widths/heights
nhexpand = 0;
nvexpand = 0;
@ -221,6 +305,8 @@ static void gridRelayout(uiGrid *g)
// 5) reset the final coordinates for the next step
for (i = 0; i < g->children->size(); i++) {
gc = (*(g->children))[i];
if (!uiControlVisible(gc->c))
continue;
gc->finalx = 0;
gc->finaly = 0;
gc->finalwidth = 0;
@ -235,6 +321,8 @@ static void gridRelayout(uiGrid *g)
curx = 0;
prev = -1;
for (ix = 0; ix < xcount(g); ix++) {
if (!ld->visibleColumn(g, ix))
continue;
i = ld->gg[iy][ix];
if (i != -1) {
gc = (*(g->children))[i];
@ -257,6 +345,8 @@ static void gridRelayout(uiGrid *g)
cury = 0;
prev = -1;
for (iy = 0; iy < ycount(g); iy++) {
if (!ld->visibleRow(g, iy))
continue;
i = ld->gg[iy][ix];
if (i != -1) {
gc = (*(g->children))[i];
@ -277,6 +367,8 @@ static void gridRelayout(uiGrid *g)
// this is why we saved minwidth/minheight above
for (i = 0; i < g->children->size(); i++) {
gc = (*(g->children))[i];
if (!uiControlVisible(gc->c))
continue;
if (gc->halign != uiAlignFill) {
switch (gc->halign) {
case uiAlignEnd:
@ -375,6 +467,10 @@ static void uiGridMinimumSize(uiWindowsControl *c, int *width, int *height)
gridPadding(g, &xpadding, &ypadding);
ld = new gridLayoutData(g);
if (ld->noVisible) { // nothing to do; return 0x0
delete ld;
return;
}
// 1) compute colwidths and rowheights before handling expansion
// 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];
// and that's it; just account for padding
*width = colwidth + (g->xmax-1) * xpadding;
*height = rowheight + (g->ymax-1) * ypadding;
*width = colwidth + (ld->nVisibleColumns - 1) * xpadding;
*height = rowheight + (ld->nVisibleRows - 1) * ypadding;
}
static void uiGridMinimumSizeChanged(uiWindowsControl *c)
@ -422,6 +518,12 @@ static void uiGridMinimumSizeChanged(uiWindowsControl *c)
uiWindowsControlDefaultLayoutRect(uiGrid)
uiWindowsControlDefaultAssignControlIDZOrder(uiGrid)
static void uiGridChildVisibilityChanged(uiWindowsControl *c)
{
// TODO eliminate the redundancy
uiWindowsControlMinimumSizeChanged(c);
}
// must have called gridRecomputeMinMax() first
static void gridArrangeChildren(uiGrid *g)
{
@ -455,30 +557,6 @@ static void gridArrangeChildren(uiGrid *g)
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)
{
struct gridChild *gc;

View File

@ -121,6 +121,12 @@ static void uiGroupMinimumSizeChanged(uiWindowsControl *c)
uiWindowsControlDefaultLayoutRect(uiGroup)
uiWindowsControlDefaultAssignControlIDZOrder(uiGroup)
static void uiGroupChildVisibilityChanged(uiWindowsControl *c)
{
// TODO eliminate the redundancy
uiWindowsControlMinimumSizeChanged(c);
}
char *uiGroupTitle(uiGroup *g)
{
return uiWindowsWindowText(g->hwnd);

View File

@ -166,6 +166,12 @@ static void uiTabMinimumSizeChanged(uiWindowsControl *c)
uiWindowsControlDefaultLayoutRect(uiTab)
uiWindowsControlDefaultAssignControlIDZOrder(uiTab)
static void uiTabChildVisibilityChanged(uiWindowsControl *c)
{
// TODO eliminate the redundancy
uiWindowsControlMinimumSizeChanged(c);
}
static void tabArrangePages(uiTab *t)
{
LONG_PTR controlID = 100;

View File

@ -260,6 +260,12 @@ static void uiWindowLayoutRect(uiWindowsControl *c, RECT *r)
uiWindowsControlDefaultAssignControlIDZOrder(uiWindow)
static void uiWindowChildVisibilityChanged(uiWindowsControl *c)
{
// TODO eliminate the redundancy
uiWindowsControlMinimumSizeChanged(c);
}
char *uiWindowTitle(uiWindow *w)
{
return uiWindowsWindowText(w->hwnd);