- fixed size estimation for manual breaks when wrappingpull/1/head
@@ -952,16 +952,20 @@ void fill_wrap_row_box(int box) { | |||||
switch(rand()%4) { | switch(rand()%4) { | ||||
default: break; | default: break; | ||||
case 0: { | 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; | } break; | ||||
case 1: { | 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; | } break; | ||||
case 2: { | 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; | } break; | ||||
case 3: { | 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; | } break; | ||||
} | } | ||||
@@ -986,16 +990,20 @@ void fill_wrap_column_box(int box) { | |||||
switch(rand()%4) { | switch(rand()%4) { | ||||
default: break; | default: break; | ||||
case 0: { | 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; | } break; | ||||
case 1: { | 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; | } break; | ||||
case 2: { | 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; | } break; | ||||
case 3: { | 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; | } break; | ||||
} | } | ||||
@@ -1016,19 +1024,24 @@ void build_wrapdemo(int parent) { | |||||
const int T = 50; | const int T = 50; | ||||
int box; | 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); | 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); | 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); | 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); | 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); | fill_wrap_column_box(box); | ||||
} | } | ||||
@@ -1302,6 +1302,30 @@ UI_INLINE void uiComputeStackedSize(UIitem *pitem, int dim) { | |||||
pitem->size[dim] = need_size; | 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 | // compute bounding box of all items stacked + wrapped | ||||
UI_INLINE void uiComputeWrappedSize(UIitem *pitem, int dim) { | UI_INLINE void uiComputeWrappedSize(UIitem *pitem, int dim) { | ||||
int wdim = dim+2; | int wdim = dim+2; | ||||
@@ -1350,7 +1374,7 @@ static void uiComputeSize(int item, int dim) { | |||||
case UI_ROW|UI_WRAP: { | case UI_ROW|UI_WRAP: { | ||||
// flex model | // flex model | ||||
if (!dim) // direction | if (!dim) // direction | ||||
uiComputeStackedSize(pitem, 0); | |||||
uiComputeWrappedStackedSize(pitem, 0); | |||||
else | else | ||||
uiComputeWrappedSize(pitem, 1); | uiComputeWrappedSize(pitem, 1); | ||||
} break; | } 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]); | 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 | // 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; | int wdim = dim+2; | ||||
short offset = pitem->margins[dim]; | short offset = pitem->margins[dim]; | ||||
@@ -1514,7 +1577,7 @@ UI_INLINE short uiArrangeWrappedImposed(UIitem *pitem, int dim) { | |||||
UIitem *pkid = uiItemPtr(kid); | UIitem *pkid = uiItemPtr(kid); | ||||
if (pkid->flags & UI_BREAK) { | 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; | offset += need_size; | ||||
start_kid = kid; | start_kid = kid; | ||||
// newline | // newline | ||||
@@ -1527,7 +1590,7 @@ UI_INLINE short uiArrangeWrappedImposed(UIitem *pitem, int dim) { | |||||
kid = uiNextSibling(kid); | kid = uiNextSibling(kid); | ||||
} | } | ||||
uiArrangeImposedRange(pitem, dim, start_kid, -1, offset, need_size); | |||||
uiArrangeImposedSqueezedRange(pitem, dim, start_kid, -1, offset, need_size); | |||||
offset += need_size; | offset += need_size; | ||||
return offset; | return offset; | ||||
} | } | ||||
@@ -1541,7 +1604,7 @@ static void uiArrange(int item, int dim) { | |||||
if (dim) { // direction | if (dim) { // direction | ||||
uiArrangeStacked(pitem, 1, true); | uiArrangeStacked(pitem, 1, true); | ||||
// this retroactive resize will not effect parent widths | // 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]; | pitem->size[0] = offset - pitem->margins[0]; | ||||
} | } | ||||
} break; | } break; | ||||
@@ -1550,7 +1613,7 @@ static void uiArrange(int item, int dim) { | |||||
if (!dim) { // direction | if (!dim) { // direction | ||||
uiArrangeStacked(pitem, 0, true); | uiArrangeStacked(pitem, 0, true); | ||||
} else { | } else { | ||||
uiArrangeWrappedImposed(pitem, 1); | |||||
uiArrangeWrappedImposedSqueezed(pitem, 1); | |||||
} | } | ||||
} break; | } break; | ||||
case UI_COLUMN: | case UI_COLUMN: | ||||
@@ -1559,7 +1622,7 @@ static void uiArrange(int item, int dim) { | |||||
if ((pitem->flags & 1) == (unsigned int)dim) // direction | if ((pitem->flags & 1) == (unsigned int)dim) // direction | ||||
uiArrangeStacked(pitem, dim, false); | uiArrangeStacked(pitem, dim, false); | ||||
else | else | ||||
uiArrangeImposed(pitem, dim); | |||||
uiArrangeImposedSqueezed(pitem, dim); | |||||
} break; | } break; | ||||
default: { | default: { | ||||
// layout model | // layout model | ||||