- fixed size estimation for manual breaks when wrappingpull/1/head
@@ -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); | |||
} | |||
@@ -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 | |||