diff --git a/README.md b/README.md index bb4fb2a1..8ab69cbf 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ This README is being written.
*Note that today's entry may be updated later today.* +* **12 June 2016** + * Added `uiGrid`, a new container control that arranges controls in rows and columns, with stretchy ("expanding") rows, stretchy ("expanding") columns, cells that span rows and columns, and cells whose content is aligned in either direction rather than just filling. It's quite powerful, is it? =P + * **8 June 2016** * Added `uiForm`, a new container control that arranges controls vertically, with properly aligned labels on each. Have fun! diff --git a/_grid/adjacent.m b/_grid/adjacent.m deleted file mode 100644 index 5bf80468..00000000 --- a/_grid/adjacent.m +++ /dev/null @@ -1,40 +0,0 @@ - // now find all horizontally adjacent views and string them together - for (y = 0; y < ycount; y++) - for (x = 0; x < xcount - 1; x++) { - if (gg[y][x] == -1) - continue; - if (gg[y][x + 1] == -1) - continue; - if (gg[y][x] == gg[y][x + 1]) // spanning - continue; - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - firstView = [gc view]; - gc = (gridChild *) [self->children objectAtIndex:gg[y][x + 1]]; - c = mkConstraint(firstView, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - [gc view], NSLayoutAttributeLeading, - 1, -padding, - @"uiGrid inside trailing attribute"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - // and same for vertically adjacent - for (x = 0; x < xcount; x++) - for (y = 0; y < ycount - 1; y++) { - if (gg[y][x] == -1) - continue; - if (gg[y + 1][x] == -1) - continue; - if (gg[y][x] == gg[y + 1][x]) // spanning - continue; - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - firstView = [gc view]; - gc = (gridChild *) [self->children objectAtIndex:gg[y + 1][x]]; - c = mkConstraint(firstView, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - [gc view], NSLayoutAttributeTop, - 1, -padding, - @"uiGrid inside bottom attribute"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } diff --git a/_grid/expand.m b/_grid/expand.m deleted file mode 100644 index 8bd15eec..00000000 --- a/_grid/expand.m +++ /dev/null @@ -1,36 +0,0 @@ - // now figure out which rows and columns really expand - hexpand = (BOOL *) uiAlloc(xcount * sizeof (BOOL), "BOOL[]"); - vexpand = (BOOL *) uiAlloc(ycount * sizeof (BOOL), "BOOL[]"); - // first, which don't span - for (gc in self->children) { - if (gc.hexpand && gc.xspan == 1) - hexpand[gc.left - xmin] = YES; - if (gc.vexpand && gc.yspan == 1) - vexpand[gc.top - ymin] = YES; - } - // 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 (gc.hexpand && gc.xspan != 1) { - doit = YES; - for (x = gc.left; x < gc.left + gc.xspan; x++) - if (hexpand[x - xmin]) { - doit = NO; - break; - } - if (doit) - for (x = gc.left; x < gc.left + gc.xspan; x++) - hexpand[x - xmin] = YES; - } - if (gc.vexpand && gc.yspan != 1) { - doit = YES; - for (y = gc.top; y < gc.top + gc.yspan; y++) - if (vexpand[y - ymin]) { - doit = NO; - break; - } - if (doit) - for (y = gc.top; y < gc.top + gc.yspan; y++) - vexpand[y - ymin] = YES; - } - } diff --git a/_grid/reduce.m b/_grid/reduce.m deleted file mode 100644 index e3c9b676..00000000 --- a/_grid/reduce.m +++ /dev/null @@ -1,30 +0,0 @@ - // 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++) - if (gg[y][x] != -1) { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - if (gc.yspan == 1 || gc.top - ymin == y) { - onlyEmptyAndSpanning = NO; - break; - } - } - if (onlyEmptyAndSpanning) - for (x = 0; x < xcount; x++) - gg[y][x] = gg[y - 1][x]; - } - for (x = 0; x < xcount; x++) { - onlyEmptyAndSpanning = YES; - for (y = 0; y < ycount; y++) - if (gg[y][x] != -1) { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - if (gc.xspan == 1 || gc.left - xmin == x) { - onlyEmptyAndSpanning = NO; - break; - } - } - if (onlyEmptyAndSpanning) - for (y = 0; y < ycount; y++) - gg[y][x] = gg[y][x - 1]; - } diff --git a/_grid/samerowcol.m b/_grid/samerowcol.m deleted file mode 100644 index cf20f8ce..00000000 --- a/_grid/samerowcol.m +++ /dev/null @@ -1,47 +0,0 @@ - // now put all the views in the same row and column together - for (x = 0; x < xcount; x++) { - [set removeAllObjects]; - for (y = 0; y < ycount; y++) - [set addObject:[NSNumber numberWithInt:gg[y][x]]]; - first = YES; - for (number in set) { - if ([number intValue] == -1) - continue; - gc = (gridChild *) [self->children objectAtIndex:[number intValue]]; - if (first) { - firstView = [gc view]; - first = NO; - continue; - } - c = mkConstraint([gc view], NSLayoutAttributeLeading, - NSLayoutRelationEqual, - firstView, NSLayoutAttributeLeading, - 1, 0, - @"uiGrid column left edge constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - } - } - for (y = 0; y < ycount; y++) { - [set removeAllObjects]; - for (x = 0; x < xcount; x++) - [set addObject:[NSNumber numberWithInt:gg[y][x]]]; - first = YES; - for (number in set) { - if ([number intValue] == -1) - continue; - gc = (gridChild *) [self->children objectAtIndex:[number intValue]]; - if (first) { - firstView = [gc view]; - first = NO; - continue; - } - c = mkConstraint([gc view], NSLayoutAttributeTop, - NSLayoutRelationEqual, - firstView, NSLayoutAttributeTop, - 1, 0, - @"uiGrid row top edge constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - } - } diff --git a/_grid/tieany.m b/_grid/tieany.m deleted file mode 100644 index e8da979e..00000000 --- a/_grid/tieany.m +++ /dev/null @@ -1,66 +0,0 @@ - NSView **colviews, **rowviews; - // now go through every row and column and extract SOME view from that row and column for the inner constraints - // if it turns out that a row or column is totally empty, duplicate the one to the left (this has the effect of collapsing empty rows) - // note that the edges cannot be empty because we built a smallest fitting rectangle way back in step 1 - colviews = (NSView **) uiAlloc(xcount * sizeof (NSView *), "NSView *[]"); - for (x = 0; x < xcount; x++) { - for (y = 0; y < ycount; y++) - if (gg[y][x] != -1) { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - colviews[x] = [gc view]; - break; - } - if (colviews[x] == nil) - colviews[x] = colviews[x - 1]; - } - rowviews = (NSView **) uiAlloc(ycount * sizeof (NSView *), "NSView *[]"); - for (y = 0; y < ycount; y++) { - for (x = 0; x < xcount; x++) - if (gg[y][x] != -1) { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - rowviews[y] = [gc view]; - break; - } - if (rowviews[y] == nil) - rowviews[y] = rowviews[y - 1]; - } - - // now string all the views together - for (gc in self->children) { - if (gc.left != xmin) { - c = mkConstraint([gc view], NSLayoutAttributeLeading, - NSLayoutRelationEqual, - colviews[(gc.left - 1) - xmin], NSLayoutAttributeTrailing, - 1, padding, - @"uiGrid leading constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - if (gc.top != ymin) { - c = mkConstraint([gc view], NSLayoutAttributeTop, - NSLayoutRelationEqual, - rowviews[(gc.top - 1) - ymin], NSLayoutAttributeBottom, - 1, padding, - @"uiGrid top constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - if ((gc.left + gc.xspan) != xmax) { - c = mkConstraint([gc view], NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - colviews[(gc.left + gc.xspan) - xmin], NSLayoutAttributeLeading, - 1, -padding, - @"uiGrid trailing constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - if ((gc.top + gc.yspan) != ymax) { - c = mkConstraint([gc view], NSLayoutAttributeBottom, - NSLayoutRelationEqual, - rowviews[(gc.top + gc.yspan) - ymin], NSLayoutAttributeTop, - 1, -padding, - @"uiGrid bottom constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - }