Implemented proper hiding and showing behavior on OS X on uiForm and uiGrid.
This commit is contained in:
parent
44b4fa9c68
commit
cb81518e0f
|
@ -16,7 +16,10 @@ This README is being written.<br>
|
||||||
|
|
||||||
## Updates
|
## Updates
|
||||||
|
|
||||||
*Note that today's entry may be updated later today.*
|
*Note that today's entry may be updated later today Eastern Time.*
|
||||||
|
|
||||||
|
* **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.
|
||||||
|
|
||||||
* **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.
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
uiForm *f;
|
uiForm *f;
|
||||||
NSMutableArray *children;
|
NSMutableArray *children;
|
||||||
int padded;
|
int padded;
|
||||||
int nStretchy;
|
|
||||||
|
|
||||||
NSLayoutConstraint *first;
|
NSLayoutConstraint *first;
|
||||||
NSMutableArray *inBetweens;
|
NSMutableArray *inBetweens;
|
||||||
|
@ -45,6 +44,7 @@
|
||||||
- (void)setPadded:(int)p;
|
- (void)setPadded:(int)p;
|
||||||
- (BOOL)hugsTrailing;
|
- (BOOL)hugsTrailing;
|
||||||
- (BOOL)hugsBottom;
|
- (BOOL)hugsBottom;
|
||||||
|
- (int)nStretchy;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
struct uiForm {
|
struct uiForm {
|
||||||
|
@ -123,7 +123,6 @@ struct uiForm {
|
||||||
self->f = ff;
|
self->f = ff;
|
||||||
self->padded = 0;
|
self->padded = 0;
|
||||||
self->children = [NSMutableArray new];
|
self->children = [NSMutableArray new];
|
||||||
self->nStretchy = 0;
|
|
||||||
|
|
||||||
self->inBetweens = [NSMutableArray new];
|
self->inBetweens = [NSMutableArray new];
|
||||||
self->widths = [NSMutableArray new];
|
self->widths = [NSMutableArray new];
|
||||||
|
@ -221,6 +220,9 @@ struct uiForm {
|
||||||
// first arrange the children vertically and make them the same width
|
// first arrange the children vertically and make them the same width
|
||||||
prev = nil;
|
prev = nil;
|
||||||
for (fc in self->children) {
|
for (fc in self->children) {
|
||||||
|
[fc setHidden:!uiControlVisible(fc.c)];
|
||||||
|
if (!uiControlVisible(fc.c))
|
||||||
|
continue;
|
||||||
if (prev == nil) { // first view
|
if (prev == nil) { // first view
|
||||||
self->first = mkConstraint(self, NSLayoutAttributeTop,
|
self->first = mkConstraint(self, NSLayoutAttributeTop,
|
||||||
NSLayoutRelationEqual,
|
NSLayoutRelationEqual,
|
||||||
|
@ -259,6 +261,8 @@ struct uiForm {
|
||||||
prev = [fc view];
|
prev = [fc view];
|
||||||
prevlabel = fc;
|
prevlabel = fc;
|
||||||
}
|
}
|
||||||
|
if (prev == nil) // all hidden; act as if nothing there
|
||||||
|
return;
|
||||||
self->last = mkConstraint(prev, NSLayoutAttributeBottom,
|
self->last = mkConstraint(prev, NSLayoutAttributeBottom,
|
||||||
NSLayoutRelationEqual,
|
NSLayoutRelationEqual,
|
||||||
self, NSLayoutAttributeBottom,
|
self, NSLayoutAttributeBottom,
|
||||||
|
@ -269,6 +273,8 @@ struct uiForm {
|
||||||
|
|
||||||
// now arrange the controls horizontally
|
// now arrange the controls horizontally
|
||||||
for (fc in self->children) {
|
for (fc in self->children) {
|
||||||
|
if (!uiControlVisible(fc.c))
|
||||||
|
continue;
|
||||||
c = mkConstraint(self, NSLayoutAttributeLeading,
|
c = mkConstraint(self, NSLayoutAttributeLeading,
|
||||||
NSLayoutRelationEqual,
|
NSLayoutRelationEqual,
|
||||||
fc, NSLayoutAttributeLeading,
|
fc, NSLayoutAttributeLeading,
|
||||||
|
@ -313,6 +319,8 @@ struct uiForm {
|
||||||
// and make all stretchy controls have the same height
|
// and make all stretchy controls have the same height
|
||||||
prev = nil;
|
prev = nil;
|
||||||
for (fc in self->children) {
|
for (fc in self->children) {
|
||||||
|
if (!uiControlVisible(fc.c))
|
||||||
|
continue;
|
||||||
if (!fc.stretchy)
|
if (!fc.stretchy)
|
||||||
continue;
|
continue;
|
||||||
if (prev == nil) {
|
if (prev == nil) {
|
||||||
|
@ -375,15 +383,13 @@ struct uiForm {
|
||||||
@"uiForm baseline constraint");
|
@"uiForm baseline constraint");
|
||||||
[self addConstraint:fc.baseline];
|
[self addConstraint:fc.baseline];
|
||||||
|
|
||||||
|
oldnStretchy = [self nStretchy];
|
||||||
[self->children addObject:fc];
|
[self->children addObject:fc];
|
||||||
|
|
||||||
[self establishOurConstraints];
|
[self establishOurConstraints];
|
||||||
if (fc.stretchy) {
|
if (fc.stretchy)
|
||||||
oldnStretchy = self->nStretchy;
|
|
||||||
self->nStretchy++;
|
|
||||||
if (oldnStretchy == 0)
|
if (oldnStretchy == 0)
|
||||||
uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->f));
|
uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->f));
|
||||||
}
|
|
||||||
|
|
||||||
[fc release]; // we don't need the initial reference now
|
[fc release]; // we don't need the initial reference now
|
||||||
}
|
}
|
||||||
|
@ -416,7 +422,22 @@ struct uiForm {
|
||||||
- (BOOL)hugsBottom
|
- (BOOL)hugsBottom
|
||||||
{
|
{
|
||||||
// only hug if we have stretchy
|
// only hug if we have stretchy
|
||||||
return self->nStretchy != 0;
|
return [self nStretchy] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)nStretchy
|
||||||
|
{
|
||||||
|
formChild *fc;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (fc in self->children) {
|
||||||
|
if (!uiControlVisible(fc.c))
|
||||||
|
continue;
|
||||||
|
if (fc.stretchy)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
uiGrid *g;
|
uiGrid *g;
|
||||||
NSMutableArray *children;
|
NSMutableArray *children;
|
||||||
int padded;
|
int padded;
|
||||||
int nhexpand;
|
|
||||||
int nvexpand;
|
|
||||||
|
|
||||||
NSMutableArray *edges;
|
NSMutableArray *edges;
|
||||||
NSMutableArray *inBetweens;
|
NSMutableArray *inBetweens;
|
||||||
|
@ -45,6 +43,8 @@
|
||||||
- (void)setPadded:(int)p;
|
- (void)setPadded:(int)p;
|
||||||
- (BOOL)hugsTrailing;
|
- (BOOL)hugsTrailing;
|
||||||
- (BOOL)hugsBottom;
|
- (BOOL)hugsBottom;
|
||||||
|
- (int)nhexpand;
|
||||||
|
- (int)nvexpand;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
struct uiGrid {
|
struct uiGrid {
|
||||||
|
@ -70,8 +70,6 @@ struct uiGrid {
|
||||||
self->g = gg;
|
self->g = gg;
|
||||||
self->padded = 0;
|
self->padded = 0;
|
||||||
self->children = [NSMutableArray new];
|
self->children = [NSMutableArray new];
|
||||||
self->nhexpand = 0;
|
|
||||||
self->nvexpand = 0;
|
|
||||||
|
|
||||||
self->edges = [NSMutableArray new];
|
self->edges = [NSMutableArray new];
|
||||||
self->inBetweens = [NSMutableArray new];
|
self->inBetweens = [NSMutableArray new];
|
||||||
|
@ -132,6 +130,7 @@ struct uiGrid {
|
||||||
return uiDarwinPaddingAmount(NULL);
|
return uiDarwinPaddingAmount(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LONGTERM stop early if all controls are hidden
|
||||||
- (void)establishOurConstraints
|
- (void)establishOurConstraints
|
||||||
{
|
{
|
||||||
gridChild *gc;
|
gridChild *gc;
|
||||||
|
@ -156,8 +155,11 @@ struct uiGrid {
|
||||||
padding = [self paddingAmount];
|
padding = [self paddingAmount];
|
||||||
|
|
||||||
// first, figure out the minimum and maximum row and column numbers
|
// first, figure out the minimum and maximum row and column numbers
|
||||||
|
// ignore hidden controls
|
||||||
first = YES;
|
first = YES;
|
||||||
for (gc in self->children) {
|
for (gc in self->children) {
|
||||||
|
if (!uiControlVisible(gc.c))
|
||||||
|
continue;
|
||||||
if (first) {
|
if (first) {
|
||||||
xmin = gc.left;
|
xmin = gc.left;
|
||||||
ymin = gc.top;
|
ymin = gc.top;
|
||||||
|
@ -180,6 +182,7 @@ struct uiGrid {
|
||||||
|
|
||||||
// now build a topological map of the grid gg[y][x]
|
// now build a topological map of the grid gg[y][x]
|
||||||
// also figure out which cells contain spanned views so they can be ignored later
|
// also figure out which cells contain spanned views so they can be ignored later
|
||||||
|
// treat hidden controls by keeping the indices -1
|
||||||
gg = (int **) uiAlloc(ycount * sizeof (int *), "int[][]");
|
gg = (int **) uiAlloc(ycount * sizeof (int *), "int[][]");
|
||||||
gspan = (BOOL **) uiAlloc(ycount * sizeof (BOOL *), "BOOL[][]");
|
gspan = (BOOL **) uiAlloc(ycount * sizeof (BOOL *), "BOOL[][]");
|
||||||
for (y = 0; y < ycount; y++) {
|
for (y = 0; y < ycount; y++) {
|
||||||
|
@ -190,6 +193,8 @@ struct uiGrid {
|
||||||
}
|
}
|
||||||
for (i = 0; i < [self->children count]; i++) {
|
for (i = 0; i < [self->children count]; i++) {
|
||||||
gc = (gridChild *) [self->children objectAtIndex:i];
|
gc = (gridChild *) [self->children objectAtIndex: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++) {
|
||||||
gg[y - ymin][x - xmin] = i;
|
gg[y - ymin][x - xmin] = i;
|
||||||
|
@ -255,6 +260,8 @@ struct uiGrid {
|
||||||
vexpand = (BOOL *) uiAlloc(ycount * sizeof (BOOL), "BOOL[]");
|
vexpand = (BOOL *) uiAlloc(ycount * sizeof (BOOL), "BOOL[]");
|
||||||
// first, which don't span
|
// first, which don't span
|
||||||
for (gc in self->children) {
|
for (gc in self->children) {
|
||||||
|
if (!uiControlVisible(gc.c))
|
||||||
|
continue;
|
||||||
if (gc.hexpand && gc.xspan == 1)
|
if (gc.hexpand && gc.xspan == 1)
|
||||||
hexpand[gc.left - xmin] = YES;
|
hexpand[gc.left - xmin] = YES;
|
||||||
if (gc.vexpand && gc.yspan == 1)
|
if (gc.vexpand && gc.yspan == 1)
|
||||||
|
@ -263,6 +270,8 @@ struct uiGrid {
|
||||||
// second, which do span
|
// second, which do span
|
||||||
// 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 (gc in self->children) {
|
for (gc in self->children) {
|
||||||
|
if (!uiControlVisible(gc.c))
|
||||||
|
continue;
|
||||||
if (gc.hexpand && gc.xspan != 1) {
|
if (gc.hexpand && gc.xspan != 1) {
|
||||||
doit = YES;
|
doit = YES;
|
||||||
for (x = gc.left; x < gc.left + gc.xspan; x++)
|
for (x = gc.left; x < gc.left + gc.xspan; x++)
|
||||||
|
@ -391,6 +400,8 @@ struct uiGrid {
|
||||||
for (gc in self->children) {
|
for (gc in self->children) {
|
||||||
NSLayoutPriority priority;
|
NSLayoutPriority priority;
|
||||||
|
|
||||||
|
if (!uiControlVisible(gc.c))
|
||||||
|
continue;
|
||||||
if (hexpand[gc.left - xmin] || gc.xspan != 1)
|
if (hexpand[gc.left - xmin] || gc.xspan != 1)
|
||||||
priority = NSLayoutPriorityDefaultLow;
|
priority = NSLayoutPriorityDefaultLow;
|
||||||
else
|
else
|
||||||
|
@ -422,7 +433,7 @@ struct uiGrid {
|
||||||
- (void)append:(gridChild *)gc
|
- (void)append:(gridChild *)gc
|
||||||
{
|
{
|
||||||
BOOL update;
|
BOOL update;
|
||||||
int oldn;
|
int oldnh, oldnv;
|
||||||
|
|
||||||
uiControlSetParent(gc.c, uiControl(self->g));
|
uiControlSetParent(gc.c, uiControl(self->g));
|
||||||
uiDarwinControlSetSuperview(uiDarwinControl(gc.c), self);
|
uiDarwinControlSetSuperview(uiDarwinControl(gc.c), self);
|
||||||
|
@ -430,22 +441,18 @@ struct uiGrid {
|
||||||
|
|
||||||
// no need to set priority here; that's done in establishOurConstraints
|
// no need to set priority here; that's done in establishOurConstraints
|
||||||
|
|
||||||
|
oldnh = [self nhexpand];
|
||||||
|
oldnv = [self nvexpand];
|
||||||
[self->children addObject:gc];
|
[self->children addObject:gc];
|
||||||
|
|
||||||
[self establishOurConstraints];
|
[self establishOurConstraints];
|
||||||
update = NO;
|
update = NO;
|
||||||
if (gc.hexpand) {
|
if (gc.hexpand)
|
||||||
oldn = self->nhexpand;
|
if (oldnh == 0)
|
||||||
self->nhexpand++;
|
|
||||||
if (oldn == 0)
|
|
||||||
update = YES;
|
update = YES;
|
||||||
}
|
if (gc.vexpand)
|
||||||
if (gc.vexpand) {
|
if (oldnv == 0)
|
||||||
oldn = self->nvexpand;
|
|
||||||
self->nvexpand++;
|
|
||||||
if (oldn == 0)
|
|
||||||
update = YES;
|
update = YES;
|
||||||
}
|
|
||||||
if (update)
|
if (update)
|
||||||
uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->g));
|
uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->g));
|
||||||
|
|
||||||
|
@ -524,13 +531,43 @@ dispatch_get_main_queue(),
|
||||||
- (BOOL)hugsTrailing
|
- (BOOL)hugsTrailing
|
||||||
{
|
{
|
||||||
// only hug if we have horizontally expanding
|
// only hug if we have horizontally expanding
|
||||||
return self->nhexpand != 0;
|
return [self nhexpand] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)hugsBottom
|
- (BOOL)hugsBottom
|
||||||
{
|
{
|
||||||
// only hug if we have vertically expanding
|
// only hug if we have vertically expanding
|
||||||
return self->nvexpand != 0;
|
return [self nvexpand] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)nhexpand
|
||||||
|
{
|
||||||
|
gridChild *gc;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (gc in self->children) {
|
||||||
|
if (!uiControlVisible(gc.c))
|
||||||
|
continue;
|
||||||
|
if (gc.hexpand)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)nvexpand
|
||||||
|
{
|
||||||
|
gridChild *gc;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (gc in self->children) {
|
||||||
|
if (!uiControlVisible(gc.c))
|
||||||
|
continue;
|
||||||
|
if (gc.vexpand)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -65,6 +65,16 @@ static void entryChanged(uiEntry *e, void *data)
|
||||||
uiFreeText(text);
|
uiFreeText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void showHide(uiButton *b, void *data)
|
||||||
|
{
|
||||||
|
uiControl *c = uiControl(data);
|
||||||
|
|
||||||
|
if (uiControlVisible(c))
|
||||||
|
uiControlHide(c);
|
||||||
|
else
|
||||||
|
uiControlShow(c);
|
||||||
|
}
|
||||||
|
|
||||||
uiBox *makePage13(void)
|
uiBox *makePage13(void)
|
||||||
{
|
{
|
||||||
uiBox *page13;
|
uiBox *page13;
|
||||||
|
@ -95,7 +105,6 @@ uiBox *makePage13(void)
|
||||||
uiBoxAppend(page13, uiControl(b), 0);
|
uiBoxAppend(page13, uiControl(b), 0);
|
||||||
|
|
||||||
f = newForm();
|
f = newForm();
|
||||||
uiBoxAppend(page13, uiControl(f), 1);
|
|
||||||
|
|
||||||
e = uiNewPasswordEntry();
|
e = uiNewPasswordEntry();
|
||||||
uiEntryOnChanged(e, entryChanged, "password");
|
uiEntryOnChanged(e, entryChanged, "password");
|
||||||
|
@ -107,5 +116,10 @@ uiBox *makePage13(void)
|
||||||
|
|
||||||
uiFormAppend(f, "MLE", uiControl(uiNewMultilineEntry()), 1);
|
uiFormAppend(f, "MLE", uiControl(uiNewMultilineEntry()), 1);
|
||||||
|
|
||||||
|
b = uiNewButton("Show/Hide");
|
||||||
|
uiButtonOnClicked(b, showHide, e);
|
||||||
|
uiBoxAppend(page13, uiControl(b), 0);
|
||||||
|
uiBoxAppend(page13, uiControl(f), 1);
|
||||||
|
|
||||||
return page13;
|
return page13;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue