Browse Source

- support for squeezing in ROW/COLUMN mode

- fixed size estimation for manual breaks when wrapping
pull/1/head
Leonard Ritter 10 years ago
parent
commit
d9cba71feb
2 changed files with 96 additions and 20 deletions
  1. +26
    -13
      example.cpp
  2. +70
    -7
      oui.h

+ 26
- 13
example.cpp View File

@@ -952,16 +952,20 @@ void fill_wrap_row_box(int box) {
switch(rand()%4) {
default: break;
case 0: {
u = demorect(box, "Layout( UI_TOP )", hue, 0, UI_TOP, width, T, M, M, M, M);
u = demorect(box, "Layout( UI_TOP )",
hue, 0, UI_TOP, width, T, M, M, M, M);
} break;
case 1: {
u = demorect(box, "Layout( UI_VCENTER )", hue, 0, UI_VCENTER, width, T/2, M, M, M, M);
u = demorect(box, "Layout( UI_VCENTER )",
hue, 0, UI_VCENTER, width, T/2, M, M, M, M);
} break;
case 2: {
u = demorect(box, "Layout( UI_VFILL )", hue, 0, UI_VFILL, width, T, M, M, M, M);
u = demorect(box, "Layout( UI_VFILL )",
hue, 0, UI_VFILL, width, T, M, M, M, M);
} break;
case 3: {
u = demorect(box, "Layout( UI_DOWN )", hue, 0, UI_DOWN, width, T/2, M, M, M, M);
u = demorect(box, "Layout( UI_DOWN )",
hue, 0, UI_DOWN, width, T/2, M, M, M, M);
} break;
}

@@ -986,16 +990,20 @@ void fill_wrap_column_box(int box) {
switch(rand()%4) {
default: break;
case 0: {
u = demorect(box, "Layout( UI_LEFT )", hue, 0, UI_LEFT, T, height, M, M, M, M);
u = demorect(box, "Layout( UI_LEFT )",
hue, 0, UI_LEFT, T, height, M, M, M, M);
} break;
case 1: {
u = demorect(box, "Layout( UI_HCENTER )", hue, 0, UI_HCENTER, T/2, height, M, M, M, M);
u = demorect(box, "Layout( UI_HCENTER )",
hue, 0, UI_HCENTER, T/2, height, M, M, M, M);
} break;
case 2: {
u = demorect(box, "Layout( UI_HFILL )", hue, 0, UI_HFILL, T, height, M, M, M, M);
u = demorect(box, "Layout( UI_HFILL )",
hue, 0, UI_HFILL, T, height, M, M, M, M);
} break;
case 3: {
u = demorect(box, "Layout( UI_RIGHT )", hue, 0, UI_RIGHT, T/2, height, M, M, M, M);
u = demorect(box, "Layout( UI_RIGHT )",
hue, 0, UI_RIGHT, T/2, height, M, M, M, M);
} break;
}

@@ -1016,19 +1024,24 @@ void build_wrapdemo(int parent) {
const int T = 50;

int box;
box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_START )\nLayout( UI_HFILL | UI_TOP )", 0.6f, UI_ROW | UI_WRAP | UI_START, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_START )\nLayout( UI_HFILL | UI_TOP )",
0.6f, UI_ROW | UI_WRAP | UI_START, UI_TOP, 0, 0, M, M, M, M);
fill_wrap_row_box(box);

box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_MIDDLE )\nLayout( UI_HFILL | UI_TOP )", 0.6f, UI_ROW | UI_WRAP, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_MIDDLE )\nLayout( UI_HFILL | UI_TOP )",
0.6f, UI_ROW | UI_WRAP, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
fill_wrap_row_box(box);

box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_END )\nLayout( UI_HFILL | UI_TOP )", 0.6f, UI_ROW | UI_WRAP | UI_END, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_END )\nLayout( UI_HFILL | UI_TOP )",
0.6f, UI_ROW | UI_WRAP | UI_END, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
fill_wrap_row_box(box);

box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_JUSTIFY )\nLayout( UI_HFILL | UI_TOP )", 0.6f, UI_ROW | UI_WRAP | UI_JUSTIFY, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
box = demorect(col, "Box( UI_ROW | UI_WRAP | UI_JUSTIFY )\nLayout( UI_HFILL | UI_TOP )",
0.6f, UI_ROW | UI_WRAP | UI_JUSTIFY, UI_HFILL | UI_TOP, 0, 0, M, M, M, M);
fill_wrap_row_box(box);

box = demorect(col, "Box( UI_COLUMN | UI_WRAP | UI_START )\nLayout( UI_LEFT | UI_VFILL )", 0.6f, UI_COLUMN | UI_WRAP | UI_START, UI_LEFT | UI_VFILL, 0, 0, M, M, M, M);
box = demorect(col, "Box( UI_COLUMN | UI_WRAP | UI_START )\nLayout( UI_LEFT | UI_VFILL )",
0.6f, UI_COLUMN | UI_WRAP | UI_START, UI_LEFT | UI_VFILL, 0, 0, M, M, M, M);
fill_wrap_column_box(box);
}



+ 70
- 7
oui.h View File

@@ -1302,6 +1302,30 @@ UI_INLINE void uiComputeStackedSize(UIitem *pitem, int dim) {
pitem->size[dim] = need_size;
}

// compute bounding box of all items stacked, repeating when breaking
UI_INLINE void uiComputeWrappedStackedSize(UIitem *pitem, int dim) {
int wdim = dim+2;

short need_size = 0;
short need_size2 = 0;
int kid = pitem->firstkid;
while (kid >= 0) {
UIitem *pkid = uiItemPtr(kid);

// if next position moved back, we assume a new line
if (pkid->flags & UI_BREAK) {
need_size2 = ui_max(need_size2, need_size);
// newline
need_size = 0;
}

// width = start margin + calculated width + end margin
need_size += pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim];
kid = uiNextSibling(kid);
}
pitem->size[dim] = ui_max(need_size2, need_size);
}

// compute bounding box of all items stacked + wrapped
UI_INLINE void uiComputeWrappedSize(UIitem *pitem, int dim) {
int wdim = dim+2;
@@ -1350,7 +1374,7 @@ static void uiComputeSize(int item, int dim) {
case UI_ROW|UI_WRAP: {
// flex model
if (!dim) // direction
uiComputeStackedSize(pitem, 0);
uiComputeWrappedStackedSize(pitem, 0);
else
uiComputeWrappedSize(pitem, 1);
} break;
@@ -1501,8 +1525,47 @@ UI_INLINE void uiArrangeImposed(UIitem *pitem, int dim) {
uiArrangeImposedRange(pitem, dim, pitem->firstkid, -1, pitem->margins[dim], pitem->size[dim]);
}

// superimpose all items according to their alignment,
// squeeze items that expand the available space
UI_INLINE void uiArrangeImposedSqueezedRange(UIitem *pitem, int dim,
int start_kid, int end_kid, short offset, short space) {
int wdim = dim+2;

int kid = start_kid;
while (kid != end_kid) {
UIitem *pkid = uiItemPtr(kid);

int flags = (pkid->flags & UI_ITEM_LAYOUT_MASK) >> dim;

short min_size = ui_max(0,space-pkid->margins[dim]-pkid->margins[wdim]);
switch(flags & UI_HFILL) {
default: {
pkid->size[dim] = ui_min(pkid->size[dim], min_size);
} break;
case UI_HCENTER: {
pkid->size[dim] = ui_min(pkid->size[dim], min_size);
pkid->margins[dim] += (space-pkid->size[dim])/2 - pkid->margins[wdim];
} break;
case UI_RIGHT: {
pkid->size[dim] = ui_min(pkid->size[dim], min_size);
pkid->margins[dim] = space-pkid->size[dim]-pkid->margins[wdim];
} break;
case UI_HFILL: {
pkid->size[dim] = min_size;
} break;
}
pkid->margins[dim] += offset;

kid = uiNextSibling(kid);
}
}

UI_INLINE void uiArrangeImposedSqueezed(UIitem *pitem, int dim) {
uiArrangeImposedSqueezedRange(pitem, dim, pitem->firstkid, -1, pitem->margins[dim], pitem->size[dim]);
}

// superimpose all items according to their alignment
UI_INLINE short uiArrangeWrappedImposed(UIitem *pitem, int dim) {
UI_INLINE short uiArrangeWrappedImposedSqueezed(UIitem *pitem, int dim) {
int wdim = dim+2;

short offset = pitem->margins[dim];
@@ -1514,7 +1577,7 @@ UI_INLINE short uiArrangeWrappedImposed(UIitem *pitem, int dim) {
UIitem *pkid = uiItemPtr(kid);

if (pkid->flags & UI_BREAK) {
uiArrangeImposedRange(pitem, dim, start_kid, kid, offset, need_size);
uiArrangeImposedSqueezedRange(pitem, dim, start_kid, kid, offset, need_size);
offset += need_size;
start_kid = kid;
// newline
@@ -1527,7 +1590,7 @@ UI_INLINE short uiArrangeWrappedImposed(UIitem *pitem, int dim) {
kid = uiNextSibling(kid);
}

uiArrangeImposedRange(pitem, dim, start_kid, -1, offset, need_size);
uiArrangeImposedSqueezedRange(pitem, dim, start_kid, -1, offset, need_size);
offset += need_size;
return offset;
}
@@ -1541,7 +1604,7 @@ static void uiArrange(int item, int dim) {
if (dim) { // direction
uiArrangeStacked(pitem, 1, true);
// this retroactive resize will not effect parent widths
short offset = uiArrangeWrappedImposed(pitem, 0);
short offset = uiArrangeWrappedImposedSqueezed(pitem, 0);
pitem->size[0] = offset - pitem->margins[0];
}
} break;
@@ -1550,7 +1613,7 @@ static void uiArrange(int item, int dim) {
if (!dim) { // direction
uiArrangeStacked(pitem, 0, true);
} else {
uiArrangeWrappedImposed(pitem, 1);
uiArrangeWrappedImposedSqueezed(pitem, 1);
}
} break;
case UI_COLUMN:
@@ -1559,7 +1622,7 @@ static void uiArrange(int item, int dim) {
if ((pitem->flags & 1) == (unsigned int)dim) // direction
uiArrangeStacked(pitem, dim, false);
else
uiArrangeImposed(pitem, dim);
uiArrangeImposedSqueezed(pitem, dim);
} break;
default: {
// layout model


Loading…
Cancel
Save