Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/include/UI_interface.h13
-rw-r--r--source/blender/editors/interface/interface_layout.c172
-rw-r--r--source/blender/makesrna/intern/rna_ui.c26
3 files changed, 157 insertions, 54 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index e66c4ef827b..45f26ecdcab 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -556,9 +556,10 @@ uiBut *uiDefMenuTogR(uiBlock *block, struct PointerRNA *ptr, char *propname, cha
#define UI_UNIT_X 20
#define UI_UNIT_Y 20
-#define UI_LAYOUT_ALIGN_LEFT 0
-#define UI_LAYOUT_ALIGN_CENTER 1
-#define UI_LAYOUT_ALIGN_RIGHT 2
+#define UI_LAYOUT_ALIGN_EXPAND 0
+#define UI_LAYOUT_ALIGN_LEFT 1
+#define UI_LAYOUT_ALIGN_CENTER 2
+#define UI_LAYOUT_ALIGN_RIGHT 3
uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style);
void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout);
@@ -575,14 +576,16 @@ void uiLayoutSetEnabled(uiLayout *layout, int enabled);
void uiLayoutSetRedAlert(uiLayout *layout, int redalert);
void uiLayoutSetAlignment(uiLayout *layout, int alignment);
void uiLayoutSetKeepAspect(uiLayout *layout, int keepaspect);
-void uiLayoutSetScale(uiLayout *layout, float scale);
+void uiLayoutSetScaleX(uiLayout *layout, float scale);
+void uiLayoutSetScaleY(uiLayout *layout, float scale);
int uiLayoutGetActive(uiLayout *layout);
int uiLayoutGetEnabled(uiLayout *layout);
int uiLayoutGetRedAlert(uiLayout *layout);
int uiLayoutGetAlignment(uiLayout *layout);
int uiLayoutGetKeepAspect(uiLayout *layout);
-float uiLayoutGetScale(uiLayout *layout);
+float uiLayoutGetScaleX(uiLayout *layout);
+float uiLayoutGetScaleY(uiLayout *layout);
/* layout specifiers */
uiLayout *uiLayoutRow(uiLayout *layout, int align);
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);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 7ca0c586d47..796817e1018 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -458,14 +458,24 @@ static void rna_UILayout_alignment_set(struct PointerRNA *ptr, int value)
return uiLayoutSetAlignment(ptr->data, value);
}
-static float rna_UILayout_scale_get(struct PointerRNA *ptr)
+static float rna_UILayout_scale_x_get(struct PointerRNA *ptr)
{
- return uiLayoutGetScale(ptr->data);
+ return uiLayoutGetScaleX(ptr->data);
}
-static void rna_UILayout_scale_set(struct PointerRNA *ptr, float value)
+static void rna_UILayout_scale_x_set(struct PointerRNA *ptr, float value)
{
- return uiLayoutSetScale(ptr->data, value);
+ return uiLayoutSetScaleX(ptr->data, value);
+}
+
+static float rna_UILayout_scale_y_get(struct PointerRNA *ptr)
+{
+ return uiLayoutGetScaleY(ptr->data);
+}
+
+static void rna_UILayout_scale_y_set(struct PointerRNA *ptr, float value)
+{
+ return uiLayoutSetScaleY(ptr->data, value);
}
#else
@@ -476,6 +486,7 @@ static void rna_def_ui_layout(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem alignment_items[] = {
+ {UI_LAYOUT_ALIGN_EXPAND, "EXPAND", "Expand", ""},
{UI_LAYOUT_ALIGN_LEFT, "LEFT", "Left", ""},
{UI_LAYOUT_ALIGN_CENTER, "CENTER", "Center", ""},
{UI_LAYOUT_ALIGN_RIGHT, "RIGHT", "RIght", ""},
@@ -501,8 +512,11 @@ static void rna_def_ui_layout(BlenderRNA *brna)
prop= RNA_def_property(srna, "keep_aspect", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UILayout_keep_aspect_get", "rna_UILayout_keep_aspect_set");
- prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_UNSIGNED);
- RNA_def_property_float_funcs(prop, "rna_UILayout_scale_get", "rna_UILayout_scale_set", NULL);
+ prop= RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_funcs(prop, "rna_UILayout_scale_x_get", "rna_UILayout_scale_x_set", NULL);
+
+ prop= RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
RNA_api_ui_layout(srna);
}