From cb81518e0fbb863d85e65d9761c48cccf4aaa537 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Tue, 14 Jun 2016 11:18:38 -0400 Subject: [PATCH] Implemented proper hiding and showing behavior on OS X on uiForm and uiGrid. --- README.md | 5 +++- darwin/form.m | 35 ++++++++++++++++++++----- darwin/grid.m | 71 +++++++++++++++++++++++++++++++++++++++------------ test/page13.c | 16 +++++++++++- 4 files changed, 101 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 1c06f42f..04fa0104 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,10 @@ This README is being written.
## 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** * `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. diff --git a/darwin/form.m b/darwin/form.m index 75edf23a..966a1495 100644 --- a/darwin/form.m +++ b/darwin/form.m @@ -23,7 +23,6 @@ uiForm *f; NSMutableArray *children; int padded; - int nStretchy; NSLayoutConstraint *first; NSMutableArray *inBetweens; @@ -45,6 +44,7 @@ - (void)setPadded:(int)p; - (BOOL)hugsTrailing; - (BOOL)hugsBottom; +- (int)nStretchy; @end struct uiForm { @@ -123,7 +123,6 @@ struct uiForm { self->f = ff; self->padded = 0; self->children = [NSMutableArray new]; - self->nStretchy = 0; self->inBetweens = [NSMutableArray new]; self->widths = [NSMutableArray new]; @@ -221,6 +220,9 @@ struct uiForm { // first arrange the children vertically and make them the same width prev = nil; for (fc in self->children) { + [fc setHidden:!uiControlVisible(fc.c)]; + if (!uiControlVisible(fc.c)) + continue; if (prev == nil) { // first view self->first = mkConstraint(self, NSLayoutAttributeTop, NSLayoutRelationEqual, @@ -259,6 +261,8 @@ struct uiForm { prev = [fc view]; prevlabel = fc; } + if (prev == nil) // all hidden; act as if nothing there + return; self->last = mkConstraint(prev, NSLayoutAttributeBottom, NSLayoutRelationEqual, self, NSLayoutAttributeBottom, @@ -269,6 +273,8 @@ struct uiForm { // now arrange the controls horizontally for (fc in self->children) { + if (!uiControlVisible(fc.c)) + continue; c = mkConstraint(self, NSLayoutAttributeLeading, NSLayoutRelationEqual, fc, NSLayoutAttributeLeading, @@ -313,6 +319,8 @@ struct uiForm { // and make all stretchy controls have the same height prev = nil; for (fc in self->children) { + if (!uiControlVisible(fc.c)) + continue; if (!fc.stretchy) continue; if (prev == nil) { @@ -375,15 +383,13 @@ struct uiForm { @"uiForm baseline constraint"); [self addConstraint:fc.baseline]; + oldnStretchy = [self nStretchy]; [self->children addObject:fc]; [self establishOurConstraints]; - if (fc.stretchy) { - oldnStretchy = self->nStretchy; - self->nStretchy++; + if (fc.stretchy) if (oldnStretchy == 0) uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->f)); - } [fc release]; // we don't need the initial reference now } @@ -416,7 +422,22 @@ struct uiForm { - (BOOL)hugsBottom { // 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 diff --git a/darwin/grid.m b/darwin/grid.m index b6d6a513..200c2a1b 100644 --- a/darwin/grid.m +++ b/darwin/grid.m @@ -25,8 +25,6 @@ uiGrid *g; NSMutableArray *children; int padded; - int nhexpand; - int nvexpand; NSMutableArray *edges; NSMutableArray *inBetweens; @@ -45,6 +43,8 @@ - (void)setPadded:(int)p; - (BOOL)hugsTrailing; - (BOOL)hugsBottom; +- (int)nhexpand; +- (int)nvexpand; @end struct uiGrid { @@ -70,8 +70,6 @@ struct uiGrid { self->g = gg; self->padded = 0; self->children = [NSMutableArray new]; - self->nhexpand = 0; - self->nvexpand = 0; self->edges = [NSMutableArray new]; self->inBetweens = [NSMutableArray new]; @@ -132,6 +130,7 @@ struct uiGrid { return uiDarwinPaddingAmount(NULL); } +// LONGTERM stop early if all controls are hidden - (void)establishOurConstraints { gridChild *gc; @@ -156,8 +155,11 @@ struct uiGrid { padding = [self paddingAmount]; // first, figure out the minimum and maximum row and column numbers + // ignore hidden controls first = YES; for (gc in self->children) { + if (!uiControlVisible(gc.c)) + continue; if (first) { xmin = gc.left; ymin = gc.top; @@ -180,6 +182,7 @@ struct uiGrid { // 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 + // treat hidden controls by keeping the indices -1 gg = (int **) uiAlloc(ycount * sizeof (int *), "int[][]"); gspan = (BOOL **) uiAlloc(ycount * sizeof (BOOL *), "BOOL[][]"); for (y = 0; y < ycount; y++) { @@ -190,6 +193,8 @@ struct uiGrid { } for (i = 0; i < [self->children count]; i++) { gc = (gridChild *) [self->children objectAtIndex: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++) { gg[y - ymin][x - xmin] = i; @@ -255,6 +260,8 @@ struct uiGrid { vexpand = (BOOL *) uiAlloc(ycount * sizeof (BOOL), "BOOL[]"); // first, which don't span for (gc in self->children) { + if (!uiControlVisible(gc.c)) + continue; if (gc.hexpand && gc.xspan == 1) hexpand[gc.left - xmin] = YES; if (gc.vexpand && gc.yspan == 1) @@ -263,6 +270,8 @@ struct uiGrid { // second, which do span // 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) { + if (!uiControlVisible(gc.c)) + continue; if (gc.hexpand && gc.xspan != 1) { doit = YES; for (x = gc.left; x < gc.left + gc.xspan; x++) @@ -391,6 +400,8 @@ struct uiGrid { for (gc in self->children) { NSLayoutPriority priority; + if (!uiControlVisible(gc.c)) + continue; if (hexpand[gc.left - xmin] || gc.xspan != 1) priority = NSLayoutPriorityDefaultLow; else @@ -422,7 +433,7 @@ struct uiGrid { - (void)append:(gridChild *)gc { BOOL update; - int oldn; + int oldnh, oldnv; uiControlSetParent(gc.c, uiControl(self->g)); uiDarwinControlSetSuperview(uiDarwinControl(gc.c), self); @@ -430,22 +441,18 @@ struct uiGrid { // no need to set priority here; that's done in establishOurConstraints + oldnh = [self nhexpand]; + oldnv = [self nvexpand]; [self->children addObject:gc]; [self establishOurConstraints]; update = NO; - if (gc.hexpand) { - oldn = self->nhexpand; - self->nhexpand++; - if (oldn == 0) + if (gc.hexpand) + if (oldnh == 0) update = YES; - } - if (gc.vexpand) { - oldn = self->nvexpand; - self->nvexpand++; - if (oldn == 0) + if (gc.vexpand) + if (oldnv == 0) update = YES; - } if (update) uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->g)); @@ -524,13 +531,43 @@ dispatch_get_main_queue(), - (BOOL)hugsTrailing { // only hug if we have horizontally expanding - return self->nhexpand != 0; + return [self nhexpand] != 0; } - (BOOL)hugsBottom { // 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 diff --git a/test/page13.c b/test/page13.c index 514fe94f..519fb347 100644 --- a/test/page13.c +++ b/test/page13.c @@ -65,6 +65,16 @@ static void entryChanged(uiEntry *e, void *data) 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 *page13; @@ -95,7 +105,6 @@ uiBox *makePage13(void) uiBoxAppend(page13, uiControl(b), 0); f = newForm(); - uiBoxAppend(page13, uiControl(f), 1); e = uiNewPasswordEntry(); uiEntryOnChanged(e, entryChanged, "password"); @@ -107,5 +116,10 @@ uiBox *makePage13(void) 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; }