- 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 | |||