@@ -861,7 +861,7 @@ void build_columndemo(int parent) { | |||||
} | } | ||||
} | } | ||||
void fill_wrap_box(int box) { | |||||
void fill_wrap_row_box(int box) { | |||||
const int M = 5; | const int M = 5; | ||||
const int S = 100; | const int S = 100; | ||||
const int T = 50; | const int T = 50; | ||||
@@ -877,7 +877,7 @@ void fill_wrap_box(int box) { | |||||
demorect(box, "Layout( UI_TOP )", hue, 0, UI_TOP, width, T, M, M, M, M); | demorect(box, "Layout( UI_TOP )", hue, 0, UI_TOP, width, T, M, M, M, M); | ||||
} break; | } break; | ||||
case 1: { | case 1: { | ||||
demorect(box, "Layout( UI_VCENTER )", hue, 0, UI_VCENTER, width, T/2, M, 0, M, 0); | |||||
demorect(box, "Layout( UI_VCENTER )", hue, 0, UI_VCENTER, width, T/2, M, M, M, M); | |||||
} break; | } break; | ||||
case 2: { | case 2: { | ||||
demorect(box, "Layout( UI_VFILL )", hue, 0, UI_VFILL, width, T, M, M, M, M); | demorect(box, "Layout( UI_VFILL )", hue, 0, UI_VFILL, width, T, M, M, M, M); | ||||
@@ -890,11 +890,40 @@ void fill_wrap_box(int box) { | |||||
} | } | ||||
void fill_wrap_column_box(int box) { | |||||
const int M = 5; | |||||
const int S = 100; | |||||
const int T = 50; | |||||
srand(303); | |||||
for (int i = 0; i < 20; ++i) { | |||||
float hue = (float)(rand()%360)/360.0f; | |||||
int height = 10 + (rand()%5)*10; | |||||
switch(rand()%4) { | |||||
default: break; | |||||
case 0: { | |||||
demorect(box, "Layout( UI_LEFT )", hue, 0, UI_LEFT, T, height, M, M, M, M); | |||||
} break; | |||||
case 1: { | |||||
demorect(box, "Layout( UI_HCENTER )", hue, 0, UI_HCENTER, T/2, height, M, M, M, M); | |||||
} break; | |||||
case 2: { | |||||
demorect(box, "Layout( UI_HFILL )", hue, 0, UI_HFILL, T, height, M, M, M, M); | |||||
} break; | |||||
case 3: { | |||||
demorect(box, "Layout( UI_RIGHT )", hue, 0, UI_RIGHT, T/2, height, M, M, M, M); | |||||
} break; | |||||
} | |||||
} | |||||
} | |||||
void build_wrapdemo(int parent) { | void build_wrapdemo(int parent) { | ||||
int col = uiItem(); | int col = uiItem(); | ||||
uiAppend(parent, col); | uiAppend(parent, col); | ||||
uiSetBox(col, UI_COLUMN); | uiSetBox(col, UI_COLUMN); | ||||
uiSetLayout(col, UI_HFILL|UI_TOP); | |||||
uiSetLayout(col, UI_FILL); | |||||
const int M = 5; | const int M = 5; | ||||
const int S = 100; | const int S = 100; | ||||
@@ -902,16 +931,19 @@ void build_wrapdemo(int parent) { | |||||
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_HFILL | UI_TOP, 0, 0, M, M, M, M); | ||||
fill_wrap_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_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_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_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); | |||||
fill_wrap_column_box(box); | |||||
} | } | ||||
@@ -648,7 +648,9 @@ OUI_EXPORT short uiGetMarginDown(int item); | |||||
// extra item flags | // extra item flags | ||||
enum { | enum { | ||||
// bit 0-2 | // bit 0-2 | ||||
UI_ITEM_BOX_MASK = 0x00001F, | |||||
UI_ITEM_BOX_MODEL_MASK = 0x000007, | |||||
// bit 0-4 | |||||
UI_ITEM_BOX_MASK = 0x00001F, | |||||
// bit 5-8 | // bit 5-8 | ||||
UI_ITEM_LAYOUT_MASK = 0x0001E0, | UI_ITEM_LAYOUT_MASK = 0x0001E0, | ||||
// bit 9-18 | // bit 9-18 | ||||
@@ -1123,25 +1125,35 @@ static void uiComputeSize(int item, int dim) { | |||||
kid = uiNextSibling(kid); | kid = uiNextSibling(kid); | ||||
} | } | ||||
if (pitem->size[dim]) { | |||||
if (pitem->size[dim]) | |||||
return; | return; | ||||
} else if(pitem->flags & UI_FLEX) { | |||||
if (pitem->flags & UI_WRAP) { | |||||
// flex model | |||||
if ((pitem->flags & 1) == (unsigned int)dim) // direction | |||||
uiComputeStackedSize(pitem, dim); | |||||
else | |||||
uiComputeWrappedSize(pitem, dim); | |||||
} else { | |||||
// flex model | |||||
if ((pitem->flags & 1) == (unsigned int)dim) // direction | |||||
uiComputeStackedSize(pitem, dim); | |||||
else | |||||
uiComputeImposedSize(pitem, dim); | |||||
} | |||||
} else { | |||||
switch(pitem->flags & UI_ITEM_BOX_MODEL_MASK) { | |||||
case UI_COLUMN|UI_WRAP: { | |||||
// flex model | |||||
if (dim) // direction | |||||
uiComputeStackedSize(pitem, 1); | |||||
else | |||||
uiComputeImposedSize(pitem, 0); | |||||
} break; | |||||
case UI_ROW|UI_WRAP: { | |||||
// flex model | |||||
if (!dim) // direction | |||||
uiComputeStackedSize(pitem, 0); | |||||
else | |||||
uiComputeWrappedSize(pitem, 1); | |||||
} break; | |||||
case UI_COLUMN: | |||||
case UI_ROW: { | |||||
// flex model | |||||
if ((pitem->flags & 1) == (unsigned int)dim) // direction | |||||
uiComputeStackedSize(pitem, dim); | |||||
else | |||||
uiComputeImposedSize(pitem, dim); | |||||
} break; | |||||
default: { | |||||
// layout model | // layout model | ||||
uiComputeImposedSize(pitem, dim); | uiComputeImposedSize(pitem, dim); | ||||
} break; | |||||
} | } | ||||
} | } | ||||
@@ -1171,7 +1183,7 @@ UI_INLINE void uiArrangeStacked(UIitem *pitem, int dim, bool wrap) { | |||||
} else { | } else { | ||||
extend += pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; | extend += pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; | ||||
} | } | ||||
if (wrap && (extend > space) && (total>1)) { | |||||
if (wrap && (extend > space) && total) { | |||||
end_kid = kid; | end_kid = kid; | ||||
// add marker for subsequent queries | // add marker for subsequent queries | ||||
pkid->flags |= UI_ITEM_NEWLINE; | pkid->flags |= UI_ITEM_NEWLINE; | ||||
@@ -1253,7 +1265,7 @@ UI_INLINE void uiArrangeImposedRange(UIitem *pitem, int dim, | |||||
switch(flags & UI_HFILL) { | switch(flags & UI_HFILL) { | ||||
default: break; | default: break; | ||||
case UI_HCENTER: { | case UI_HCENTER: { | ||||
pkid->margins[dim] += (space-pkid->size[dim])/2; | |||||
pkid->margins[dim] += (space-pkid->size[dim])/2 - pkid->margins[wdim]; | |||||
} break; | } break; | ||||
case UI_RIGHT: { | case UI_RIGHT: { | ||||
pkid->margins[dim] = space-pkid->size[dim]-pkid->margins[wdim]; | pkid->margins[dim] = space-pkid->size[dim]-pkid->margins[wdim]; | ||||
@@ -1273,7 +1285,7 @@ UI_INLINE void uiArrangeImposed(UIitem *pitem, int dim) { | |||||
} | } | ||||
// superimpose all items according to their alignment | // superimpose all items according to their alignment | ||||
UI_INLINE void uiArrangeWrappedImposed(UIitem *pitem, int dim) { | |||||
UI_INLINE short uiArrangeWrappedImposed(UIitem *pitem, int dim) { | |||||
int wdim = dim+2; | int wdim = dim+2; | ||||
short offset = pitem->margins[dim]; | short offset = pitem->margins[dim]; | ||||
@@ -1299,28 +1311,43 @@ UI_INLINE void uiArrangeWrappedImposed(UIitem *pitem, int dim) { | |||||
} | } | ||||
uiArrangeImposedRange(pitem, dim, start_kid, -1, offset, need_size); | uiArrangeImposedRange(pitem, dim, start_kid, -1, offset, need_size); | ||||
offset += need_size; | |||||
return offset; | |||||
} | } | ||||
static void uiArrange(int item, int dim) { | static void uiArrange(int item, int dim) { | ||||
UIitem *pitem = uiItemPtr(item); | UIitem *pitem = uiItemPtr(item); | ||||
if(pitem->flags & UI_FLEX) { | |||||
if (pitem->flags & UI_WRAP) { | |||||
if ((pitem->flags & 1) == (unsigned int)dim) { // direction | |||||
uiArrangeStacked(pitem, dim, true); | |||||
} else { | |||||
uiArrangeWrappedImposed(pitem, dim); | |||||
} | |||||
switch(pitem->flags & UI_ITEM_BOX_MODEL_MASK) { | |||||
case UI_COLUMN|UI_WRAP: { | |||||
// flex model, wrapping | |||||
if (dim) { // direction | |||||
uiArrangeStacked(pitem, 1, true); | |||||
// this retroactive resize will not effect parent widths | |||||
short offset = uiArrangeWrappedImposed(pitem, 0); | |||||
pitem->size[0] = offset - pitem->margins[0]; | |||||
} | |||||
} break; | |||||
case UI_ROW|UI_WRAP: { | |||||
// flex model, wrapping | |||||
if (!dim) { // direction | |||||
uiArrangeStacked(pitem, 0, true); | |||||
} else { | } else { | ||||
// flex model | |||||
if ((pitem->flags & 1) == (unsigned int)dim) // direction | |||||
uiArrangeStacked(pitem, dim, false); | |||||
else | |||||
uiArrangeImposed(pitem, dim); | |||||
uiArrangeWrappedImposed(pitem, 1); | |||||
} | } | ||||
} else { | |||||
} break; | |||||
case UI_COLUMN: | |||||
case UI_ROW: { | |||||
// flex model | |||||
if ((pitem->flags & 1) == (unsigned int)dim) // direction | |||||
uiArrangeStacked(pitem, dim, false); | |||||
else | |||||
uiArrangeImposed(pitem, dim); | |||||
} break; | |||||
default: { | |||||
// layout model | // layout model | ||||
uiArrangeImposed(pitem, dim); | uiArrangeImposed(pitem, dim); | ||||
} break; | |||||
} | } | ||||
int kid = uiFirstChild(item); | int kid = uiFirstChild(item); | ||||
@@ -1330,19 +1357,21 @@ static void uiArrange(int item, int dim) { | |||||
} | } | ||||
} | } | ||||
static void uiNestedLayout(int item, int dim) { | |||||
uiComputeSize(item,dim); | |||||
uiArrange(item,dim); | |||||
// vertical layout: | |||||
// compute horizontal: superimposed width of all child items (assume single row) | |||||
// arrange horizontal: arrange all items imposed in-place | |||||
// compute vertical: set size to 0 | |||||
// arrange vertical: stack and wrap, vertically and horizontally | |||||
uiComputeSize(item,1-dim); | |||||
uiArrange(item,1-dim); | |||||
} | |||||
void uiLayout() { | void uiLayout() { | ||||
assert(ui_context); | assert(ui_context); | ||||
if (!ui_context->count) return; | if (!ui_context->count) return; | ||||
uiNestedLayout(0,0); | |||||
uiComputeSize(0,0); | |||||
uiArrange(0,0); | |||||
uiComputeSize(0,1); | |||||
uiArrange(0,1); | |||||
uiValidateStateItems(); | uiValidateStateItems(); | ||||
// drawing routines may require this to be set already | // drawing routines may require this to be set already | ||||