diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-03 04:04:48 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-03 04:04:48 +0400 |
commit | 9ed9acaf9a5a64a3471b4eca6a9e91bb8f0bc23e (patch) | |
tree | dad45a3df73dcda5a7defc2710f44986997b502d /source/blender/editors/interface/interface_layout.c | |
parent | 7498561cfb27166569ae6f0b154bf8391a0cdd9f (diff) |
UI:
* Implemented scale_x/scale_y for layouts.
* Implemented left/right/center/expand alignment for row layouts.
Diffstat (limited to 'source/blender/editors/interface/interface_layout.c')
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 172 |
1 files changed, 129 insertions, 43 deletions
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 2e123c28339..bb2be0da874 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -115,6 +115,7 @@ typedef enum uiItemType { typedef struct uiItem { void *next, *prev; uiItemType type; + int flag; } uiItem; typedef struct uiButtonItem { @@ -130,7 +131,7 @@ struct uiLayout { ListBase items; int x, y, w, h; - float scale; + float scale[2]; short space; char align; char active; @@ -177,26 +178,29 @@ static char *ui_item_name_add_colon(char *name, char namestr[UI_MAX_NAME_STR]) return name; } -#define UI_FIT_EXPAND 1 - -static int ui_item_fit(int item, int pos, int all, int available, int spacing, int last, int flag) +static int ui_item_fit(int item, int pos, int all, int available, int last, int alignment, int *offset) { /* available == 0 is unlimited */ - - if(available != 0 && all > available-spacing) { + if(available == 0) + return item; + + if(offset) + *offset= 0; + + if(all > available) { /* contents is bigger than available space */ if(last) return available-pos; else - return (item*(available-spacing))/all; + return (item*available)/all; } else { /* contents is smaller or equal to available space */ - if(available != 0 && (flag & UI_FIT_EXPAND)) { + if(alignment == UI_LAYOUT_ALIGN_EXPAND) { if(last) return available-pos; else - return (item*(available-spacing))/all; + return (item*available)/all; } else return item; @@ -655,9 +659,6 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA subtype= RNA_property_subtype(prop); len= RNA_property_array_length(prop); - if(ELEM(type, PROP_STRING, PROP_ENUM)) - w += 10*UI_UNIT_X; - /* increase height for arrays */ if(index == RNA_NO_INDEX && len > 0) { if(strcmp(name, "") == 0 && icon == 0) @@ -1033,14 +1034,22 @@ static void ui_litem_estimate_row(uiLayout *litem) } } +static int ui_litem_min_width(int itemw) +{ + return MIN2(UI_UNIT_X, itemw); +} + static void ui_litem_layout_row(uiLayout *litem) { uiItem *item; - int neww, itemw, itemh, x, y, w, tot= 0, totw= 0, extra=0, available=0; + int x, y, w, tot, totw, neww, itemw, minw, itemh, offset; + int fixedw, freew, fixedx, freex, flag= 0, lastw= 0; x= litem->x; y= litem->y; w= litem->w; + totw= 0; + tot= 0; for(item=litem->items.first; item; item=item->next) { ui_item_size(item, &itemw, &itemh); @@ -1051,40 +1060,81 @@ static void ui_litem_layout_row(uiLayout *litem) if(totw == 0) return; - /* two step to enforce minimum button with .. could be better */ - for(item=litem->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); + if(w != 0) + w -= (tot-1)*litem->space; + fixedw= 0; - itemw= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND); - x += itemw; + /* keep clamping items to fixed minimum size until all are done */ + do { + freew= 0; + x= 0; + flag= 0; - if(itemw < UI_UNIT_X) - extra += UI_UNIT_X - itemw; - else - available += itemw - UI_UNIT_X; + for(item=litem->items.first; item; item=item->next) { + if(item->flag) + continue; - if(item->next) - x += litem->space; - } + ui_item_size(item, &itemw, &itemh); + minw= ui_litem_min_width(itemw); + + if(w - lastw > 0) + neww= ui_item_fit(itemw, x, totw, w-lastw, !item->next, litem->alignment, NULL); + else + neww= 0; /* no space left, all will need clamping to minimum size */ + x += neww; + + if(neww < minw && w != 0) { + /* fixed size */ + item->flag= 1; + fixedw += minw; + flag= 1; + totw -= itemw; + } + else { + /* keep free size */ + item->flag= 0; + freew += itemw; + } + } + + lastw= fixedw; + } while(flag); + + freex= 0; + fixedx= 0; x= litem->x; for(item=litem->items.first; item; item=item->next) { ui_item_size(item, &itemw, &itemh); + minw= ui_litem_min_width(itemw); - neww= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND); - if(neww < UI_UNIT_X) { - if(item->next) - itemw= UI_UNIT_X; - else - itemw= litem->w - (x-litem->x); + if(item->flag) { + /* fixed minimum size items */ + itemw= ui_item_fit(minw, fixedx, fixedw, MIN2(w, fixedw), !item->next, litem->alignment, NULL); + fixedx += itemw; + } + else { + /* free size item */ + itemw= ui_item_fit(itemw, freex, freew, w-fixedw, !item->next, litem->alignment, NULL); + freex += itemw; } - else - itemw= ui_item_fit(itemw, x-litem->x, totw, w-extra, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND); - ui_item_position(item, x, y-itemh, itemw, itemh); - x += itemw; + /* align right/center */ + offset= 0; + if(litem->alignment == UI_LAYOUT_ALIGN_RIGHT) { + if(fixedw == 0 && freew < w-fixedw) + offset= (w - fixedw) - freew; + } + else if(litem->alignment == UI_LAYOUT_ALIGN_CENTER) { + if(fixedw == 0 && freew < w-fixedw) + offset= ((w - fixedw) - freew)/2; + } + + /* position item */ + ui_item_position(item, x+offset, y-itemh, itemw, itemh); + x += itemw; if(item->next) x += litem->space; } @@ -1263,7 +1313,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem; uiItem *item; int col, x, y, w, emh, emy, miny, itemw, itemh; - int toth, totitem; + int toth, totitem, offset; /* compute max needed width and total height */ toth= 0; @@ -1280,18 +1330,18 @@ static void ui_litem_layout_column_flow(uiLayout *litem) emy= 0; miny= 0; - w= litem->w; + w= litem->w - (flow->totcol-1)*style->columnspace; emh= toth/flow->totcol; /* create column per column */ col= 0; for(item=litem->items.first; item; item=item->next) { ui_item_size(item, NULL, &itemh); - itemw= ui_item_fit(1, x-litem->x, flow->totcol, w, (flow->totcol-1)*style->columnspace, col == flow->totcol-1, UI_FIT_EXPAND); + itemw= ui_item_fit(1, x-litem->x, flow->totcol, w, col == flow->totcol-1, litem->alignment, &offset); y -= itemh; emy -= itemh; - ui_item_position(item, x, y, itemw, itemh); + ui_item_position(item, x+offset, y, itemw, itemh); y -= style->buttonspacey; miny= MIN2(miny, y); @@ -1578,9 +1628,14 @@ void uiLayoutSetAlignment(uiLayout *layout, int alignment) layout->alignment= alignment; } -void uiLayoutSetScale(uiLayout *layout, float scale) +void uiLayoutSetScaleX(uiLayout *layout, float scale) { - layout->scale= scale; + layout->scale[0]= scale; +} + +void uiLayoutSetScaleY(uiLayout *layout, float scale) +{ + layout->scale[1]= scale; } int uiLayoutGetActive(uiLayout *layout) @@ -1608,13 +1663,41 @@ int uiLayoutGetAlignment(uiLayout *layout) return layout->alignment; } -float uiLayoutGetScale(uiLayout *layout) +float uiLayoutGetScaleX(uiLayout *layout) { - return layout->scale; + return layout->scale[0]; +} + +float uiLayoutGetScaleY(uiLayout *layout) +{ + return layout->scale[0]; } /********************** Layout *******************/ +static void ui_item_scale(uiLayout *litem, float scale[2]) +{ + uiItem *item; + int x, y, w, h; + + for(item=litem->items.last; item; item=item->prev) { + ui_item_size(item, &w, &h); + ui_item_offset(item, &x, &y); + + if(scale[0] != 0.0f) { + x *= scale[0]; + w *= scale[0]; + } + + if(scale[1] != 0.0f) { + y *= scale[1]; + h *= scale[1]; + } + + ui_item_position(item, x, y, w, h); + } +} + static void ui_item_estimate(uiItem *item) { uiItem *subitem; @@ -1628,6 +1711,9 @@ static void ui_item_estimate(uiItem *item) if(litem->items.first == NULL) return; + if(litem->scale[0] != 0.0f || litem->scale[1] != 0.0f) + ui_item_scale(litem, litem->scale); + switch(litem->item.type) { case ITEM_LAYOUT_COLUMN: ui_litem_estimate_column(litem); |