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:
Diffstat (limited to 'source/blender/editors/interface/interface_layout.c')
-rw-r--r--source/blender/editors/interface/interface_layout.c2160
1 files changed, 1011 insertions, 1149 deletions
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 6a02e992390..ab2bb57a25f 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1,3 +1,26 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contributor(s): Blender Foundation 2009.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
#include <limits.h>
#include <math.h>
@@ -44,163 +67,112 @@
#define RNA_NO_INDEX -1
#define RNA_ENUM_VALUE -2
-#define EM_UNIT_X XIC
-#define EM_UNIT_Y YIC
-
#define EM_SEPR_X 6
#define EM_SEPR_Y 6
-/* Item */
-
-typedef enum uiItemType {
- ITEM_OPERATOR,
- ITEM_RNA_PROPERTY,
- ITEM_MENU,
- ITEM_LABEL,
- ITEM_VALUE,
- ITEM_SEPARATOR
-} uiItemType;
-
-enum uiItemFlag {
- ITEM_ICON,
- ITEM_TEXT
-};
-
-typedef struct uiItem {
- struct uiItem *next, *prev;
- uiItemType type;
- int slot;
-
- char *name;
- char namestr[UI_MAX_NAME_STR];
- int icon;
- int disabled;
-} uiItem;
-
-typedef struct uiItemRNA {
- uiItem item;
-
- PointerRNA ptr;
- PropertyRNA *prop;
- int index, value;
- int expand;
-} uiItemRNA;
+/* uiLayoutCommon */
-typedef struct uiItemOp {
- uiItem item;
+typedef struct uiLayoutCommon {
+ int type;
+ int opcontext;
- wmOperatorType *ot;
- IDProperty *properties;
- int context;
-} uiItemOp;
+ int emw, emh;
-typedef struct uiItemMenu {
- uiItem item;
+ uiMenuHandleFunc handlefunc;
+ void *argv;
- char *menuname;
- uiMenuCreateFunc func;
- void *arg, *argN;
-} uiItemMenu;
+ uiStyle *style;
+ uiBlock *block;
+} uiLayoutCommon;
-typedef struct uiItemValue {
- uiItem item;
+/* Item */
- int argval;
-} uiItemValue;
+typedef enum uiItemType {
+ ITEM_BUTTON,
-/* Template */
+ ITEM_LAYOUT_ROW,
+ ITEM_LAYOUT_COLUMN,
+ ITEM_LAYOUT_COLUMN_FLOW,
+ ITEM_LAYOUT_ROW_FLOW,
+ ITEM_LAYOUT_BOX,
+ ITEM_LAYOUT_FREE,
+ ITEM_LAYOUT_SPLIT,
-typedef enum uiTemplateType {
- TEMPLATE_ROW,
- TEMPLATE_COLUMN,
+ ITEM_LAYOUT_ROOT
+#if 0
TEMPLATE_COLUMN_FLOW,
TEMPLATE_SPLIT,
TEMPLATE_BOX,
TEMPLATE_HEADER,
TEMPLATE_HEADER_ID
-} uiTemplateType;
+#endif
+} uiItemType;
+
+typedef struct uiItem {
+ void *next, *prev;
+ uiItemType type;
+} uiItem;
-typedef struct uiTemplate {
- struct uiTemplate *next, *prev;
- uiTemplateType type;
+typedef struct uiButtonItem {
+ uiItem item;
+ uiBut *but;
+} uiButtonItem;
+
+struct uiLayout {
+ uiItem item;
+ uiLayoutCommon *common;
ListBase items;
- int slot;
-} uiTemplate;
-typedef struct uiTemplateFlow {
- uiTemplate template;
+ int x, y, w, h;
+ int space;
+ int align;
+};
+
+typedef struct uiLayoutItemFlow {
+ uiLayout litem;
int number;
-} uiTemplateFlow;
+ int totcol;
+} uiLayoutItemFlow;
-typedef struct uiTemplateSplt {
- uiTemplate template;
+typedef struct uiLayoutItemSplt {
+ uiLayout litem;
int number;
int lr;
- uiLayout **sublayout;
-} uiTemplateSplt;
-
-typedef struct uiTemplateBx {
- uiTemplate template;
- uiLayout *sublayout;
-} uiTemplateBx;
-
-typedef struct uiTemplateHeadID {
- uiTemplate template;
-
- PointerRNA ptr;
- PropertyRNA *prop;
-
- int flag;
- short browse;
- char *newop;
- char *openop;
- char *unlinkop;
-} uiTemplateHeadID;
-
-/* Layout */
-
-struct uiLayout {
- ListBase templates;
- int opcontext;
- int dir, type;
- int x, y, w, h;
- int emw, emh;
+} uiLayoutItemSplt;
- uiMenuHandleFunc handlefunc;
- void *argv;
+typedef struct uiLayoutItemBx {
+ uiLayout litem;
+} uiLayoutItemBx;
- uiStyle *style;
-};
-
-void ui_layout_free(uiLayout *layout);
-void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y);
+typedef struct uiLayoutItemRoot {
+ uiLayout litem;
+} uiLayoutItemRoot;
/************************** Item ***************************/
-static void ui_item_name(uiItem *item, char *name)
-{
- if(!item->name && name) {
- BLI_strncpy(item->namestr, name, sizeof(item->namestr));
- item->name= item->namestr;
- }
-}
-static void ui_item_name_add_colon(uiItem *item)
+static char *ui_item_name_add_colon(char *name, char namestr[UI_MAX_NAME_STR])
{
- int len= strlen(item->namestr);
+ int len= strlen(name);
- if(len != 0 && len+1 < sizeof(item->namestr)) {
- item->namestr[len]= ':';
- item->namestr[len+1]= '\0';
+ if(len != 0 && len+1 < UI_MAX_NAME_STR) {
+ BLI_strncpy(namestr, name, UI_MAX_NAME_STR);
+ namestr[len]= ':';
+ namestr[len+1]= '\0';
+ return namestr;
}
+
+ 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)
{
- if(all > available-spacing) {
+ /* available == 0 is unlimited */
+
+ if(available != 0 && all > available-spacing) {
/* contents is bigger than available space */
if(last)
return available-pos;
@@ -209,7 +181,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i
}
else {
/* contents is smaller or equal to available space */
- if(flag & UI_FIT_EXPAND) {
+ if(available != 0 && (flag & UI_FIT_EXPAND)) {
if(last)
return available-pos;
else
@@ -220,54 +192,162 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i
}
}
+/* variable button size in which direction? */
+#define UI_ITEM_VARY_X 1
+#define UI_ITEM_VARY_Y 2
+
+static int ui_layout_vary_direction(uiLayout *layout)
+{
+ return (layout->common->type == UI_LAYOUT_HEADER)? UI_ITEM_VARY_X: UI_ITEM_VARY_Y;
+}
+
+/* estimated size of text + icon */
+static int ui_text_icon_width(uiLayout *layout, char *name, int icon)
+{
+ int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X;
+
+ if(icon && strcmp(name, "") == 0)
+ return UI_UNIT_X; /* icon only */
+ else if(icon)
+ return (variable)? UI_GetStringWidth(name) + UI_UNIT_X: 10*UI_UNIT_X; /* icon + text */
+ else
+ return (variable)? UI_GetStringWidth(name) + UI_UNIT_X: 10*UI_UNIT_X; /* text only */
+}
+
+static void ui_item_size(uiItem *item, int *r_w, int *r_h)
+{
+ if(item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem= (uiButtonItem*)item;
+
+ if(r_w) *r_w= bitem->but->x2 - bitem->but->x1;
+ if(r_h) *r_h= bitem->but->y2 - bitem->but->y1;
+ }
+ else {
+ uiLayout *litem= (uiLayout*)item;
+
+ if(r_w) *r_w= litem->w;
+ if(r_h) *r_h= litem->h;
+ }
+}
+
+static void ui_item_offset(uiItem *item, int *r_x, int *r_y)
+{
+ if(item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem= (uiButtonItem*)item;
+
+ if(r_x) *r_x= bitem->but->x1;
+ if(r_y) *r_y= bitem->but->y1;
+ }
+ else {
+ if(r_x) *r_x= 0;
+ if(r_y) *r_y= 0;
+ }
+}
+
+static void ui_item_position(uiItem *item, int x, int y, int w, int h)
+{
+ if(item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem= (uiButtonItem*)item;
+
+ bitem->but->x1= x;
+ bitem->but->y1= y;
+ bitem->but->x2= x+w;
+ bitem->but->y2= y+h;
+ }
+ else {
+ uiLayout *litem= (uiLayout*)item;
+
+ litem->x= x;
+ litem->y= y+h;
+ litem->w= w;
+ litem->h= h;
+ }
+}
+
+/******************** Special RNA Items *********************/
+
+static int ui_layout_local_dir(uiLayout *layout)
+{
+ switch(layout->item.type) {
+ case ITEM_LAYOUT_ROW:
+ case ITEM_LAYOUT_ROOT:
+ return UI_LAYOUT_HORIZONTAL;
+ case ITEM_LAYOUT_COLUMN:
+ case ITEM_LAYOUT_COLUMN_FLOW:
+ case ITEM_LAYOUT_SPLIT:
+ case ITEM_LAYOUT_FREE:
+ case ITEM_LAYOUT_BOX:
+ default:
+ return UI_LAYOUT_VERTICAL;
+ }
+}
+
+static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, int align)
+{
+ uiLayout *sub;
+
+ if(ui_layout_local_dir(test) == UI_LAYOUT_HORIZONTAL)
+ sub= uiLayoutRow(layout, align);
+ else
+ sub= uiLayoutColumn(layout, align);
+
+ sub->space= 0;
+ return sub;
+}
+
/* create buttons for an item with an RNA array */
-static void ui_item_array(uiLayout *layout, uiBlock *block, uiItemRNA *rnaitem, int len, int x, int y, int w, int h)
+static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int h, int expand)
{
- uiStyle *style= layout->style;
+ uiStyle *style= layout->common->style;
PropertyType type;
PropertySubType subtype;
+ uiLayout *sub;
int a;
/* retrieve type and subtype */
- type= RNA_property_type(rnaitem->prop);
- subtype= RNA_property_subtype(rnaitem->prop);
+ type= RNA_property_type(prop);
+ subtype= RNA_property_subtype(prop);
+
+ sub= ui_item_local_sublayout(layout, layout, 0);
+ uiBlockSetCurLayout(block, sub);
/* create label */
- if(strcmp(rnaitem->item.name, "") != 0)
- uiDefBut(block, LABEL, 0, rnaitem->item.name, x, y + h - EM_UNIT_Y, w, EM_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ if(strcmp(name, "") != 0)
+ uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* create buttons */
- uiBlockBeginAlign(block);
-
if(type == PROP_BOOLEAN && len == 20) {
/* special check for layer layout */
- int butw, buth;
+ int butw, buth, unit;
- butw= ui_item_fit(EM_UNIT_X, 0, EM_UNIT_X*10 + style->buttonspacex, w, 0, 0, UI_FIT_EXPAND);
- buth= MIN2(EM_UNIT_Y, butw);
+ uiBlockSetCurLayout(block, uiLayoutFree(layout, 0));
- y += 2*(EM_UNIT_Y - buth);
+ unit= UI_UNIT_X*0.75;
+ butw= unit;
+ buth= unit;
uiBlockBeginAlign(block);
for(a=0; a<5; a++)
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth);
+ uiDefAutoButR(block, ptr, prop, a, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth);
for(a=0; a<5; a++)
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth);
+ uiDefAutoButR(block, ptr, prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth);
uiBlockEndAlign(block);
x += 5*butw + style->buttonspacex;
uiBlockBeginAlign(block);
for(a=0; a<5; a++)
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+5, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth);
+ uiDefAutoButR(block, ptr, prop, a+5, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth);
for(a=0; a<5; a++)
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+15, "", ICON_BLANK1, x + butw*a, y, butw, buth);
+ uiDefAutoButR(block, ptr, prop, a+15, "", ICON_BLANK1, x + butw*a, y, butw, buth);
uiBlockEndAlign(block);
}
else if(subtype == PROP_MATRIX) {
/* matrix layout */
int row, col;
+ uiBlockSetCurLayout(block, uiLayoutFree(layout, 1));
+
len= ceil(sqrt(len));
h /= len;
@@ -278,315 +358,156 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, uiItemRNA *rnaitem,
col= a%len;
row= a/len;
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", 0, x + w*col, y+(row-a-1)*EM_UNIT_Y, w, EM_UNIT_Y);
+ uiDefAutoButR(block, ptr, prop, a, "", 0, x + w*col, y+(row-a-1)*UI_UNIT_Y, w, UI_UNIT_Y);
}
}
else if(len <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
- /* layout for known array subtypes */
- static char vectoritem[4]= {'X', 'Y', 'Z', 'W'};
- static char quatitem[4]= {'W', 'X', 'Y', 'Z'};
- static char coloritem[4]= {'R', 'G', 'B', 'A'};
- char str[3];
-
- for(a=0; a<len; a++) {
- if(len == 4 && subtype == PROP_ROTATION)
- str[0]= quatitem[a];
- else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
- str[0]= vectoritem[a];
- else
- str[0]= coloritem[a];
+ uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, sub, 1));
+
+ if(subtype == PROP_COLOR)
+ uiDefAutoButR(block, ptr, prop, -1, "", 0, 0, 0, w, UI_UNIT_Y);
+
+ if(subtype != PROP_COLOR || expand) {
+ /* layout for known array subtypes */
+ static char vectoritem[4]= {'X', 'Y', 'Z', 'W'};
+ static char quatitem[4]= {'W', 'X', 'Y', 'Z'};
+ static char coloritem[4]= {'R', 'G', 'B', 'A'};
+ char str[3];
+
+ for(a=0; a<len; a++) {
+ if(len == 4 && subtype == PROP_ROTATION)
+ str[0]= quatitem[a];
+ else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
+ str[0]= vectoritem[a];
+ else
+ str[0]= coloritem[a];
+
+ if(type == PROP_BOOLEAN) {
+ str[1]= '\0';
+ }
+ else {
+ str[1]= ':';
+ str[2]= '\0';
+ }
- if(type == PROP_BOOLEAN) {
- str[1]= '\0';
- }
- else {
- str[1]= ':';
- str[2]= '\0';
+ uiDefAutoButR(block, ptr, prop, a, str, 0, 0, 0, w, UI_UNIT_Y);
}
-
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, str, 0, x, y+(len-a-1)*EM_UNIT_Y, w, EM_UNIT_Y);
}
+ else if(subtype == PROP_COLOR && len == 4)
+ uiDefAutoButR(block, ptr, prop, 3, "A:", 0, 0, 0, w, UI_UNIT_Y);
}
else {
/* default array layout */
+ uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, sub, 1));
+
for(a=0; a<len; a++)
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", 0, x, y+(len-a-1)*EM_UNIT_Y, w, EM_UNIT_Y);
+ uiDefAutoButR(block, ptr, prop, a, "", 0, 0, 0, w, UI_UNIT_Y);
}
- uiBlockEndAlign(block);
+ uiBlockSetCurLayout(block, layout);
}
-static void ui_item_enum_row(uiBlock *block, uiItemRNA *rnaitem, int x, int y, int w, int h)
+static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int x, int y, int w, int h)
{
const EnumPropertyItem *item;
- int a, totitem, pos, itemw;
+ int a, totitem, itemw;
const char *propname;
-
- propname= RNA_property_identifier(rnaitem->prop);
- RNA_property_enum_items(&rnaitem->ptr, rnaitem->prop, &item, &totitem);
- uiBlockBeginAlign(block);
- pos= 0;
+ propname= RNA_property_identifier(prop);
+ RNA_property_enum_items(ptr, prop, &item, &totitem);
+
+ uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
for(a=0; a<totitem; a++) {
- itemw= ui_item_fit(1, pos, totitem, w, 0, a == totitem-1, UI_FIT_EXPAND);
- uiDefButR(block, ROW, 0, NULL, x+pos, y, itemw, h, &rnaitem->ptr, propname, -1, 0, item[a].value, -1, -1, NULL);
- pos += itemw;
+ itemw= ui_text_icon_width(block->curlayout, (char*)item[a].name, 0);
+ uiDefButR(block, ROW, 0, NULL, 0, 0, itemw, h, ptr, propname, -1, 0, item[a].value, -1, -1, NULL);
}
- uiBlockEndAlign(block);
+ uiBlockSetCurLayout(block, layout);
}
/* create label + button for RNA property */
-static void ui_item_with_label(uiBlock *block, uiItemRNA *rnaitem, int x, int y, int w, int h)
+static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
{
- if(strcmp(rnaitem->item.name, "") != 0) {
- w= w/2;
- uiDefBut(block, LABEL, 0, rnaitem->item.name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
- x += w;
- }
+ uiLayout *sub;
+ PropertySubType subtype;
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, rnaitem->index, "", rnaitem->item.icon, x, y, w, h);
-}
-
-/* create buttons for an arbitrary item */
-static void ui_item_buts(uiLayout *layout, uiBlock *block, uiItem *item, int x, int y, int w, int h)
-{
- if(item->type == ITEM_RNA_PROPERTY) {
- /* RNA property */
- uiItemRNA *rnaitem= (uiItemRNA*)item;
- PropertyType type;
- int len;
-
- /* retrieve info */
- type= RNA_property_type(rnaitem->prop);
- len= RNA_property_array_length(rnaitem->prop);
-
- /* array property */
- if(rnaitem->index == RNA_NO_INDEX && len > 0)
- ui_item_array(layout, block, rnaitem, len, x, y, w, h);
- /* enum item */
- else if(type == PROP_ENUM && rnaitem->index == RNA_ENUM_VALUE) {
- char *identifier= (char*)RNA_property_identifier(rnaitem->prop);
-
- if(item->icon && strcmp(item->name, "") != 0)
- uiDefIconTextButR(block, ROW, 0, item->icon, item->name, x, y, w, h, &rnaitem->ptr, identifier, -1, 0, rnaitem->value, -1, -1, NULL);
- else if(item->icon)
- uiDefIconButR(block, ROW, 0, item->icon, x, y, w, h, &rnaitem->ptr, identifier, -1, 0, rnaitem->value, -1, -1, NULL);
- else
- uiDefButR(block, ROW, 0, item->name, x, y, w, h, &rnaitem->ptr, identifier, -1, 0, rnaitem->value, -1, -1, NULL);
- }
- /* expanded enum */
- else if(type == PROP_ENUM && rnaitem->expand)
- ui_item_enum_row(block, rnaitem, x, y, w, h);
- /* property with separate label */
- else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER)
- ui_item_with_label(block, rnaitem, x, y, w, h);
- /* single button */
- else
- uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, rnaitem->index, (char*)item->name, item->icon, x, y, w, h);
- }
- else if(item->type == ITEM_OPERATOR) {
- /* operator */
- uiItemOp *opitem= (uiItemOp*)item;
- uiBut *but;
-
- if(item->icon && strcmp(item->name, "") != 0)
- but= uiDefIconTextButO(block, BUT, opitem->ot->idname, opitem->context, item->icon, (char*)item->name, x, y, w, h, NULL);
- else if(item->icon)
- but= uiDefIconButO(block, BUT, opitem->ot->idname, opitem->context, item->icon, x, y, w, h, NULL);
- /* text only */
- else
- but= uiDefButO(block, BUT, opitem->ot->idname, opitem->context, (char*)item->name, x, y, w, h, NULL);
+ sub= uiLayoutRow(layout, 0);
+ uiBlockSetCurLayout(block, sub);
- if(but && opitem->properties) {
- /* assign properties */
- PointerRNA *opptr= uiButGetOperatorPtrRNA(but);
- opptr->data= opitem->properties;
- opitem->properties= NULL;
- }
+ if(strcmp(name, "") != 0) {
+ w= w/2;
+ uiDefBut(block, LABEL, 0, name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
}
- else if(item->type == ITEM_MENU) {
- /* menu */
- uiBut *but;
- uiItemMenu *menuitem= (uiItemMenu*)item;
-
- if(layout->type == UI_LAYOUT_HEADER) { /* ugly .. */
- y -= 2;
- w -= 3;
- h += 4;
- }
- if(item->icon)
- but= uiDefIconTextMenuBut(block, menuitem->func, menuitem->arg, item->icon, (char*)item->name, x, y, w, h, "");
- else
- but= uiDefMenuBut(block, menuitem->func, menuitem->arg, (char*)item->name, x, y, w, h, "");
-
- if(menuitem->argN) { /* ugly .. */
- but->poin= (char*)but;
- but->func_argN= menuitem->argN;
- }
- }
- else if(item->type == ITEM_LABEL) {
- /* label */
- uiBut *but;
-
- if(item->icon && strcmp(item->name, "") != 0)
- but= uiDefIconTextBut(block, LABEL, 0, item->icon, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
- else if(item->icon)
- but= uiDefIconBut(block, LABEL, 0, item->icon, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
- else
- but= uiDefBut(block, LABEL, 0, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+ subtype= RNA_property_subtype(prop);
- if(item->disabled) {
- but->flag |= UI_BUT_DISABLED;
- but->lock = 1;
- but->lockstr = "";
- }
- }
- else if(item->type == ITEM_VALUE) {
- /* label */
- uiItemValue *vitem= (uiItemValue*)item;
- float *retvalue= (block->handle)? &block->handle->retvalue: NULL;
-
- if(item->icon && strcmp(item->name, "") != 0)
- uiDefIconTextButF(block, BUTM, 0, item->icon, (char*)item->name, x, y, w, h, retvalue, 0.0, 0.0, 0, vitem->argval, "");
- else if(item->icon)
- uiDefIconButF(block, BUTM, 0, item->icon, x, y, w, h, retvalue, 0.0, 0.0, 0, vitem->argval, "");
- else
- uiDefButF(block, BUTM, 0, (char*)item->name, x, y, w, h, retvalue, 0.0, 0.0, 0, vitem->argval, "");
- }
- else {
- /* separator */
- uiDefBut(block, SEPR, 0, "", x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+ if(subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
+ uiBlockSetCurLayout(block, uiLayoutRow(sub, 1));
+ uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w-UI_UNIT_X, h);
+ uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
}
-}
-
-/* estimated size of text + icon */
-static int ui_text_icon_width(char *name, int icon, int variable)
-{
- if(icon && strcmp(name, "") == 0)
- return EM_UNIT_X; /* icon only */
- else if(icon)
- return (variable)? UI_GetStringWidth(name) + EM_UNIT_X: 10*EM_UNIT_X; /* icon + text */
else
- return (variable)? UI_GetStringWidth(name) + EM_UNIT_X: 10*EM_UNIT_X; /* text only */
-}
-
-/* estimated size of an item */
-#define UI_ITEM_VARY_X 1
-#define UI_ITEM_VARY_Y 2
-
-static void ui_item_size(uiItem *item, int *r_w, int *r_h, int flag)
-{
- int w, h;
+ uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
- if(item->type == ITEM_RNA_PROPERTY) {
- /* RNA property */
- uiItemRNA *rnaitem= (uiItemRNA*)item;
- PropertyType type;
- PropertySubType subtype;
- int len;
-
- w= ui_text_icon_width(item->name, item->icon, flag & UI_ITEM_VARY_X);
- h= EM_UNIT_Y;
-
- /* arbitrary extended width by type */
- type= RNA_property_type(rnaitem->prop);
- subtype= RNA_property_subtype(rnaitem->prop);
- len= RNA_property_array_length(rnaitem->prop);
-
- if(type == PROP_STRING)
- w += 10*EM_UNIT_X;
-
- /* increase height for arrays */
- if(rnaitem->index == RNA_NO_INDEX && len > 0) {
- if(strcmp(item->name, "") == 0 && item->icon == 0)
- h= 0;
-
- if(type == PROP_BOOLEAN && len == 20)
- h += 2*EM_UNIT_Y;
- else if(subtype == PROP_MATRIX)
- h += ceil(sqrt(len))*EM_UNIT_Y;
- else
- h += len*EM_UNIT_Y;
- }
- else if(flag & UI_ITEM_VARY_X) {
- if(type == PROP_BOOLEAN && strcmp(item->name, "") != 0)
- w += EM_UNIT_X;
- }
- }
- else {
- /* other */
- if(item->type == ITEM_SEPARATOR) {
- w= EM_SEPR_X;
- h= EM_SEPR_Y;
- }
- else {
- w= ui_text_icon_width(item->name, item->icon, flag & UI_ITEM_VARY_X);
- h= EM_UNIT_Y;
- }
- }
-
- if(r_w) *r_w= w;
- if(r_h) *r_h= h;
+ uiBlockSetCurLayout(block, layout);
}
-static void ui_item_free(uiItem *item)
-{
- if(item->type == ITEM_OPERATOR) {
- uiItemOp *opitem= (uiItemOp*)item;
-
- if(opitem->properties) {
- IDP_FreeProperty(opitem->properties);
- MEM_freeN(opitem->properties);
- }
- }
-}
+/********************* Button Items *************************/
/* disabled item */
static void ui_item_disabled(uiLayout *layout, char *name)
{
- uiTemplate *template= layout->templates.last;
- uiItem *item;
-
- if(!template)
- return;
+ uiBlock *block= layout->common->block;
+ uiBut *but;
+ int w;
+
+ uiBlockSetCurLayout(block, layout);
- item= MEM_callocN(sizeof(uiItem), "uiItem");
+ if(!name)
+ name= "";
- ui_item_name(item, name);
- item->disabled= 1;
- item->type= ITEM_LABEL;
- item->slot= template->slot;
+ w= ui_text_icon_width(layout, name, 0);
- BLI_addtail(&template->items, item);
+ but= uiDefBut(block, LABEL, 0, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but->flag |= UI_BUT_DISABLED;
+ but->lock = 1;
+ but->lockstr = "";
}
/* operator items */
void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context)
{
- uiTemplate *template= layout->templates.last;
+ uiBlock *block= layout->common->block;
wmOperatorType *ot= WM_operatortype_find(idname);
- uiItemOp *opitem;
+ uiBut *but;
+ int w;
- if(!template)
- return;
if(!ot) {
ui_item_disabled(layout, idname);
return;
}
- opitem= MEM_callocN(sizeof(uiItemOp), "uiItemOp");
+ if(!name)
+ name= ot->name;
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
- ui_item_name(&opitem->item, name);
- opitem->item.icon= icon;
- opitem->item.type= ITEM_OPERATOR;
- opitem->item.slot= template->slot;
+ /* create button */
+ uiBlockSetCurLayout(block, layout);
- opitem->ot= ot;
- opitem->properties= properties;
- opitem->context= context;
+ w= ui_text_icon_width(layout, name, icon);
+
+ if(icon && strcmp(name, "") != 0)
+ but= uiDefIconTextButO(block, BUT, ot->idname, context, icon, (char*)name, 0, 0, w, UI_UNIT_Y, NULL);
+ else if(icon)
+ but= uiDefIconButO(block, BUT, ot->idname, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
+ else
+ but= uiDefButO(block, BUT, ot->idname, context, (char*)name, 0, 0, w, UI_UNIT_Y, NULL);
- BLI_addtail(&template->items, opitem);
+ /* assign properties */
+ if(properties) {
+ PointerRNA *opptr= uiButGetOperatorPtrRNA(but);
+ opptr->data= properties;
+ }
}
static char *ui_menu_enumpropname(char *opname, char *propname, int retval)
@@ -597,16 +518,16 @@ static char *ui_menu_enumpropname(char *opname, char *propname, int retval)
if(!ot || !ot->srna)
return "";
-
+
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
prop= RNA_struct_find_property(&ptr, propname);
-
+
if(prop) {
const EnumPropertyItem *item;
int totitem, i;
-
+
RNA_property_enum_items(&ptr, prop, &item, &totitem);
-
+
for (i=0; i<totitem; i++) {
if(item[i].value==retval)
return (char*)item[i].name;
@@ -626,7 +547,7 @@ void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *pro
if(!name)
name= ui_menu_enumpropname(opname, propname, value);
- uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext);
+ uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext);
}
void uiItemsEnumO(uiLayout *layout, char *opname, char *propname)
@@ -661,7 +582,7 @@ void uiItemBooleanO(uiLayout *layout, char *name, int icon, char *opname, char *
WM_operator_properties_create(&ptr, opname);
RNA_boolean_set(&ptr, propname, value);
- uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext);
+ uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext);
}
void uiItemIntO(uiLayout *layout, char *name, int icon, char *opname, char *propname, int value)
@@ -671,7 +592,7 @@ void uiItemIntO(uiLayout *layout, char *name, int icon, char *opname, char *prop
WM_operator_properties_create(&ptr, opname);
RNA_int_set(&ptr, propname, value);
- uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext);
+ uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext);
}
void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *propname, float value)
@@ -681,7 +602,7 @@ void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *pr
WM_operator_properties_create(&ptr, opname);
RNA_float_set(&ptr, propname, value);
- uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext);
+ uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext);
}
void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value)
@@ -691,39 +612,112 @@ void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *p
WM_operator_properties_create(&ptr, opname);
RNA_string_set(&ptr, propname, value);
- uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext);
+ uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext);
}
void uiItemO(uiLayout *layout, char *name, int icon, char *opname)
{
- uiItemFullO(layout, name, icon, opname, NULL, layout->opcontext);
+ uiItemFullO(layout, name, icon, opname, NULL, layout->common->opcontext);
}
/* RNA property items */
+
+static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA *prop, int index, int *r_w, int *r_h)
+{
+ PropertyType type;
+ PropertySubType subtype;
+ int len, w, h;
+
+ w= ui_text_icon_width(layout, name, icon);
+ h= UI_UNIT_Y;
+
+ /* arbitrary extended width by type */
+ type= RNA_property_type(prop);
+ subtype= RNA_property_subtype(prop);
+ len= RNA_property_array_length(prop);
+
+ if(type == PROP_STRING)
+ w += 10*UI_UNIT_X;
+
+ /* increase height for arrays */
+ if(index == RNA_NO_INDEX && len > 0) {
+ if(strcmp(name, "") == 0 && icon == 0)
+ h= 0;
+
+ if(type == PROP_BOOLEAN && len == 20)
+ h += 2*UI_UNIT_Y;
+ else if(subtype == PROP_MATRIX)
+ h += ceil(sqrt(len))*UI_UNIT_Y;
+ else
+ h += len*UI_UNIT_Y;
+ }
+ else if(ui_layout_vary_direction(layout) == UI_ITEM_VARY_X) {
+ if(type == PROP_BOOLEAN && strcmp(name, "") != 0)
+ w += UI_UNIT_X;
+ }
+
+ *r_w= w;
+ *r_h= h;
+}
+
void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int expand)
{
- uiTemplate *template= layout->templates.last;
- uiItemRNA *rnaitem;
+ uiBlock *block= layout->common->block;
+ PropertyType type;
+ char namestr[UI_MAX_NAME_STR];
+ int len, w, h;
if(!ptr->data || !prop)
return;
- if(!template)
- return;
- rnaitem= MEM_callocN(sizeof(uiItemRNA), "uiItemRNA");
+ uiBlockSetCurLayout(block, layout);
+
+ /* retrieve info */
+ type= RNA_property_type(prop);
+ len= RNA_property_array_length(prop);
- ui_item_name(&rnaitem->item, name);
- rnaitem->item.icon= icon;
- rnaitem->item.type= ITEM_RNA_PROPERTY;
- rnaitem->item.slot= template->slot;
+ /* set name and icon */
+ if(!name)
+ name= (char*)RNA_property_ui_name(prop);
+
+ if(ELEM5(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_ENUM, PROP_POINTER))
+ name= ui_item_name_add_colon(name, namestr);
+ if(type == PROP_BOOLEAN && len)
+ name= ui_item_name_add_colon(name, namestr);
+
+ if(layout->common->type == UI_LAYOUT_MENU) {
+ if(type == PROP_BOOLEAN)
+ icon= (RNA_property_boolean_get(ptr, prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT;
+ else if(type == PROP_ENUM && index == RNA_ENUM_VALUE)
+ icon= (RNA_property_enum_get(ptr, prop) == value)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT;
+ }
- rnaitem->ptr= *ptr;
- rnaitem->prop= prop;
- rnaitem->index= index;
- rnaitem->value= value;
- rnaitem->expand= expand;
+ /* get size */
+ ui_item_rna_size(layout, name, icon, prop, index, &w, &h);
- BLI_addtail(&template->items, rnaitem);
+ /* array property */
+ if(index == RNA_NO_INDEX && len > 0)
+ ui_item_array(layout, block, name, icon, ptr, prop, len, 0, 0, w, h, expand);
+ /* enum item */
+ else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) {
+ char *identifier= (char*)RNA_property_identifier(prop);
+
+ if(icon && strcmp(name, "") != 0)
+ uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ else if(icon)
+ uiDefIconButR(block, ROW, 0, icon, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ else
+ uiDefButR(block, ROW, 0, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ }
+ /* expanded enum */
+ else if(type == PROP_ENUM && expand)
+ ui_item_enum_row(layout, block, ptr, prop, 0, 0, w, h);
+ /* property with separate label */
+ else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER)
+ ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+ /* single button */
+ else
+ uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h);
}
void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand)
@@ -740,7 +734,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop
printf("uiItemR: property not found: %s\n", propname);
return;
}
-
+
uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand);
}
@@ -758,7 +752,7 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr,
printf("uiItemEnumR: property not found: %s\n", propname);
return;
}
-
+
uiItemFullR(layout, name, icon, ptr, prop, RNA_ENUM_VALUE, value, 0);
}
@@ -795,106 +789,127 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
mt->draw(C, &menu);
}
-void uiItemM(uiLayout *layout, char *name, int icon, char *menuname)
+static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN)
{
- uiTemplate *template= layout->templates.last;
- uiItemMenu *menuitem;
-
- if(!template)
- return;
- if(!menuname)
- return;
+ uiBlock *block= layout->common->block;
+ uiBut *but;
+ int w, h;
+
+ uiBlockSetCurLayout(block, layout);
+
+ if(layout->common->type == UI_LAYOUT_HEADER)
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+
+ if(!name)
+ name= "";
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
+
+ w= ui_text_icon_width(layout, name, icon);
+ h= UI_UNIT_Y;
+
+ if(layout->common->type == UI_LAYOUT_HEADER) /* ugly .. */
+ w -= 3;
+
+ if(icon)
+ but= uiDefIconTextMenuBut(block, func, arg, icon, (char*)name, 0, 0, w, h, "");
+ else
+ but= uiDefMenuBut(block, func, arg, (char*)name, 0, 0, w, h, "");
- menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu");
+ if(argN) { /* ugly .. */
+ but->poin= (char*)but;
+ but->func_argN= argN;
+ }
- ui_item_name(&menuitem->item, name);
- menuitem->item.icon= icon;
- menuitem->item.type= ITEM_MENU;
- menuitem->item.slot= template->slot;
+ if(layout->common->type == UI_LAYOUT_HEADER)
+ uiBlockSetEmboss(block, UI_EMBOSS);
+}
- menuitem->func= ui_item_menutype_func;
- menuitem->menuname= menuname;
+void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname)
+{
+ ARegion *ar= CTX_wm_region(C);
+ MenuType *mt;
+
+ if(!menuname)
+ return;
- BLI_addtail(&template->items, menuitem);
+ for(mt=ar->type->menutypes.first; mt; mt=mt->next) {
+ if(strcmp(menuname, mt->idname) == 0) {
+ if(!name)
+ name= mt->label;
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
+ ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL);
+ break;
+ }
+ }
}
/* label item */
void uiItemL(uiLayout *layout, char *name, int icon)
{
- uiTemplate *template= layout->templates.last;
- uiItem *item;
-
- if(!template)
- return;
+ uiBlock *block= layout->common->block;
+ uiBut *but;
+ int w;
- item= MEM_callocN(sizeof(uiItem), "uiItem");
+ uiBlockSetCurLayout(block, layout);
+
+ if(!name)
+ name= "";
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
- ui_item_name(item, name);
- item->icon= icon;
- item->type= ITEM_LABEL;
- item->slot= template->slot;
+ w= ui_text_icon_width(layout, name, icon);
- BLI_addtail(&template->items, item);
+ if(icon && strcmp(name, "") != 0)
+ but= uiDefIconTextBut(block, LABEL, 0, icon, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ else if(icon)
+ but= uiDefIconBut(block, LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ else
+ but= uiDefBut(block, LABEL, 0, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
/* value item */
void uiItemV(uiLayout *layout, char *name, int icon, int argval)
{
- uiTemplate *template= layout->templates.last;
- uiItemValue *vitem;
-
- if(!template)
- return;
+ /* label */
+ uiBlock *block= layout->common->block;
+ float *retvalue= (block->handle)? &block->handle->retvalue: NULL;
+ int w;
- vitem= MEM_callocN(sizeof(uiItemValue), "uiItemValue");
+ uiBlockSetCurLayout(block, layout);
- vitem->item.name= name;
- vitem->item.icon= icon;
- vitem->item.type= ITEM_VALUE;
- vitem->item.slot= template->slot;
- vitem->argval= argval;
+ if(!name)
+ name= "";
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
- BLI_addtail(&template->items, vitem);
+ w= ui_text_icon_width(layout, name, icon);
+
+ if(icon && strcmp(name, "") != 0)
+ uiDefIconTextButF(block, BUTM, 0, icon, (char*)name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, "");
+ else if(icon)
+ uiDefIconButF(block, BUTM, 0, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, "");
+ else
+ uiDefButF(block, BUTM, 0, (char*)name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, "");
}
/* separator item */
void uiItemS(uiLayout *layout)
{
- uiTemplate *template= layout->templates.last;
- uiItem *item;
-
- if(!template)
- return;
-
- item= MEM_callocN(sizeof(uiItem), "uiItem");
+ uiBlock *block= layout->common->block;
- item->type= ITEM_SEPARATOR;
- item->slot= template->slot;
-
- BLI_addtail(&template->items, item);
+ uiBlockSetCurLayout(block, layout);
+ uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, "");
}
/* level items */
void uiItemMenuF(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func)
{
- uiTemplate *template= layout->templates.last;
- uiItemMenu *menuitem;
-
- if(!template)
- return;
if(!func)
return;
- menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu");
-
- ui_item_name(&menuitem->item, name);
- menuitem->item.icon= icon;
- menuitem->item.type= ITEM_MENU;
- menuitem->item.slot= template->slot;
-
- menuitem->func= func;
-
- BLI_addtail(&template->items, menuitem);
+ ui_item_menu(layout, name, icon, func, NULL, NULL);
}
typedef struct MenuItemLevel {
@@ -915,36 +930,24 @@ static void menu_item_enum_opname_menu(bContext *C, uiLayout *layout, void *arg)
void uiItemMenuEnumO(uiLayout *layout, char *name, int icon, char *opname, char *propname)
{
wmOperatorType *ot= WM_operatortype_find(opname);
- uiTemplate *template= layout->templates.last;
- uiItemMenu *menuitem;
MenuItemLevel *lvl;
if(!ot || !ot->srna) {
ui_item_disabled(layout, opname);
return;
}
- if(!template)
- return;
-
- menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu");
if(!name)
name= ot->name;
-
- ui_item_name(&menuitem->item, name);
- menuitem->item.icon= icon;
- menuitem->item.type= ITEM_MENU;
- menuitem->item.slot= template->slot;
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
lvl->opname= opname;
lvl->propname= propname;
- lvl->opcontext= layout->opcontext;
+ lvl->opcontext= layout->common->opcontext;
- menuitem->func= menu_item_enum_opname_menu;
- menuitem->argN= lvl;
-
- BLI_addtail(&template->items, menuitem);
+ ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl);
}
static void menu_item_enum_rna_menu(bContext *C, uiLayout *layout, void *arg)
@@ -957,13 +960,8 @@ static void menu_item_enum_rna_menu(bContext *C, uiLayout *layout, void *arg)
void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname)
{
- uiTemplate *template= layout->templates.last;
- uiItemMenu *menuitem;
MenuItemLevel *lvl;
PropertyRNA *prop;
-
- if(!template)
- return;
prop= RNA_struct_find_property(ptr, propname);
if(!prop) {
@@ -971,118 +969,210 @@ void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *
return;
}
- menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu");
-
if(!name)
name= (char*)RNA_property_ui_name(prop);
-
- ui_item_name(&menuitem->item, name);
- menuitem->item.icon= icon;
- menuitem->item.type= ITEM_MENU;
- menuitem->item.slot= template->slot;
+ if(layout->common->type == UI_LAYOUT_MENU && !icon)
+ icon= ICON_BLANK1;
lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
lvl->rnapoin= *ptr;
lvl->propname= propname;
- lvl->opcontext= layout->opcontext;
-
- menuitem->func= menu_item_enum_rna_menu;
- menuitem->argN= lvl;
+ lvl->opcontext= layout->common->opcontext;
- BLI_addtail(&template->items, menuitem);
+ ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl);
}
-/**************************** Template ***************************/
+/**************************** Layout Items ***************************/
-/* single row layout */
-static void ui_layout_row(uiLayout *layout, uiBlock *block, uiTemplate *template)
+/* single-row layout */
+static void ui_litem_estimate_row(uiLayout *litem)
{
- uiStyle *style= layout->style;
uiItem *item;
- int tot=0, totw= 0, maxh= 0, itemw, itemh, x, w;
+ int itemw, itemh;
+
+ litem->w= 0;
+ litem->h= 0;
+
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
+
+ litem->w += itemw;
+ litem->h= MAX2(itemh, litem->h);
+
+ if(item->next)
+ litem->w += litem->space;
+ }
+}
+
+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;
+
+ x= litem->x;
+ y= litem->y;
+ w= litem->w;
- /* estimate total width of buttons */
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y);
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
totw += itemw;
- maxh= MAX2(maxh, itemh);
tot++;
}
if(totw == 0)
return;
- /* create buttons starting from left */
- x= 0;
- w= layout->w;
+ /* 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);
+
+ itemw= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND);
+ x += itemw;
+
+ if(itemw < UI_UNIT_X)
+ extra += UI_UNIT_X - itemw;
+ else
+ available += itemw - UI_UNIT_X;
+
+ if(item->next)
+ x += litem->space;
+ }
+
+ x= litem->x;
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y);
- itemw= ui_item_fit(itemw, x, totw, w, (tot-1)*style->buttonspacex, !item->next, UI_FIT_EXPAND);
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
- ui_item_buts(layout, block, item, layout->x+x, layout->y-itemh, itemw, itemh);
- x += itemw+style->buttonspacex;
+ 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);
+ }
+ 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;
+
+ if(item->next)
+ x += litem->space;
}
- layout->y -= maxh;
+ litem->w= x - litem->x;
+ litem->h= litem->y - y;
+ litem->x= x;
+ litem->y= y;
}
-/* multi-column layout */
-static void ui_layout_column(uiLayout *layout, uiBlock *block, uiTemplate *template)
+/* single-column layout */
+static void ui_litem_estimate_column(uiLayout *litem)
{
- uiStyle *style= layout->style;
uiItem *item;
- int col, totcol= 0, x, y, miny, itemw, itemh, w;
+ int itemw, itemh;
- /* compute number of columns */
- for(item=template->items.first; item; item=item->next)
- totcol= MAX2(item->slot+1, totcol);
-
- if(totcol == 0)
- return;
-
- x= 0;
- miny= 0;
- w= layout->w;
+ litem->w= 0;
+ litem->h= 0;
- /* create column per column */
- for(col=0; col<totcol; col++) {
- y= 0;
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
- itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*style->columnspace, col == totcol-1, UI_FIT_EXPAND);
+ litem->w= MAX2(litem->w, itemw);
+ litem->h += itemh;
- for(item=template->items.first; item; item=item->next) {
- if(item->slot != col)
- continue;
+ if(item->next)
+ litem->h += litem->space;
+ }
+}
- ui_item_size(item, NULL, &itemh, UI_ITEM_VARY_Y);
+static void ui_litem_layout_column(uiLayout *litem)
+{
+ uiItem *item;
+ int itemh, x, y;
- y -= itemh;
- ui_item_buts(layout, block, item, layout->x+x, layout->y+y, itemw, itemh);
- y -= style->buttonspacey;
- }
+ x= litem->x;
+ y= litem->y;
- x += itemw + style->columnspace;
- miny= MIN2(miny, y);
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, NULL, &itemh);
+
+ y -= itemh;
+ ui_item_position(item, x, y, litem->w, itemh);
+
+ if(item->next)
+ y -= litem->space;
}
- layout->y += miny;
+ litem->h= litem->y - y;
+ litem->x= x;
+ litem->y= y;
+}
+
+/* root layout */
+static void ui_litem_estimate_root(uiLayout *litem)
+{
+ /* nothing to do */
+}
+
+static void ui_litem_layout_root(uiLayout *litem)
+{
+ if(litem->common->type == UI_LAYOUT_HEADER)
+ ui_litem_layout_row(litem);
+ else
+ ui_litem_layout_column(litem);
+}
+
+/* box layout */
+static void ui_litem_estimate_box(uiLayout *litem)
+{
+ uiStyle *style= litem->common->style;
+
+ ui_litem_estimate_column(litem);
+ litem->w += 2*style->boxspace;
+ litem->h += 2*style->boxspace;
+}
+
+static void ui_litem_layout_box(uiLayout *litem)
+{
+ uiStyle *style= litem->common->style;
+ int w, h;
+
+ w= litem->w;
+ h= litem->h;
+
+ litem->x += style->boxspace;
+ litem->y -= style->boxspace;
+
+ if(w != 0) litem->w -= 2*style->boxspace;
+ if(h != 0) litem->h -= 2*style->boxspace;
+
+ ui_litem_layout_column(litem);
+
+ litem->x -= style->boxspace;
+ litem->y -= style->boxspace;
+
+ if(w != 0) litem->w += 2*style->boxspace;
+ if(h != 0) litem->h += 2*style->boxspace;
+
+ /* roundbox around the sublayout */
+ uiDefBut(litem->common->block, ROUNDBOX, 0, "", litem->x, litem->y, litem->w, litem->h, NULL, 7.0, 0.0, 3, 20, "");
}
/* multi-column layout, automatically flowing to the next */
-static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate *template)
+static void ui_litem_estimate_column_flow(uiLayout *litem)
{
- uiStyle *style= layout->style;
- uiTemplateFlow *flow= (uiTemplateFlow*)template;
+ uiStyle *style= litem->common->style;
+ uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem;
uiItem *item;
- int col, x, y, w, emh, emy, miny, itemw, itemh, maxw=0;
- int toth, totcol, totitem;
+ int col, x, y, emh, emy, miny, itemw, itemh, maxw=0;
+ int toth, totitem;
/* compute max needed width and total height */
toth= 0;
totitem= 0;
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y);
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
maxw= MAX2(maxw, itemw);
toth += itemh;
totitem++;
@@ -1090,14 +1180,16 @@ static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate *
if(flow->number <= 0) {
/* auto compute number of columns, not very good */
- if(maxw == 0)
+ if(maxw == 0) {
+ flow->totcol= 1;
return;
+ }
- totcol= MAX2(layout->emw/maxw, 1);
- totcol= MIN2(totcol, totitem);
+ flow->totcol= MAX2(litem->common->emw/maxw, 1);
+ flow->totcol= MIN2(flow->totcol, totitem);
}
else
- totcol= flow->number;
+ flow->totcol= flow->number;
/* compute sizes */
x= 0;
@@ -1105,742 +1197,512 @@ static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate *
emy= 0;
miny= 0;
- w= layout->w;
- emh= toth/totcol;
+ maxw= 0;
+ emh= toth/flow->totcol;
/* create column per column */
col= 0;
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, NULL, &itemh, UI_ITEM_VARY_Y);
- itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*style->columnspace, col == totcol-1, UI_FIT_EXPAND);
-
- y -= itemh;
- emy -= itemh;
- ui_item_buts(layout, block, item, layout->x+x, layout->y+y, itemw, itemh);
- y -= style->buttonspacey;
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
+
+ y -= itemh + style->buttonspacey;
miny= MIN2(miny, y);
+ emy -= itemh;
+ maxw= MAX2(itemw, maxw);
/* decide to go to next one */
- if(col < totcol-1 && emy <= -emh) {
- x += itemw + style->columnspace;
+ if(col < flow->totcol-1 && emy <= -emh) {
+ x += maxw + litem->space;
+ maxw= 0;
y= 0;
col++;
}
}
- layout->y += miny;
+ litem->h= litem->y - miny;
}
-#if 0
-/* left-right layout, with buttons aligned on both sides */
-static void ui_layout_split(uiLayout *layout, uiBlock *block, uiTemplate *template)
+static void ui_litem_layout_column_flow(uiLayout *litem)
{
+ uiStyle *style= litem->common->style;
+ uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem;
uiItem *item;
- int tot=0, totw= 0, maxh= 0, itemw, itemh, lx, rx, w;
+ int col, x, y, w, emh, emy, miny, itemw, itemh;
+ int toth, totitem;
- /* estimate total width of buttons */
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y);
- totw += itemw;
- maxh= MAX2(maxh, itemh);
- tot++;
+ /* compute max needed width and total height */
+ toth= 0;
+ totitem= 0;
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ toth += itemh;
+ totitem++;
}
- if(totw == 0)
- return;
+ /* compute sizes */
+ x= litem->x;
+ y= litem->y;
+ emy= 0;
+ miny= 0;
+
+ w= litem->w;
+ 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);
- /* create buttons starting from left and right */
- lx= 0;
- rx= 0;
- w= layout->w - style->buttonspacex*(tot-1) + style->buttonspacex;
-
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y);
-
- if(item->slot == UI_TSLOT_LR_LEFT) {
- itemw= ui_item_fit(itemw, lx, totw, w, 0, 0);
- ui_item_buts(layout, block, item, layout->x+lx, layout->y-itemh, itemw, itemh);
- lx += itemw + style->buttonspacex;
- }
- else {
- itemw= ui_item_fit(itemw, totw + rx, totw, w, 0, 0);
- rx -= itemw + style->buttonspacex;
- ui_item_buts(layout, block, item, layout->x+layout->w+rx, layout->y-itemh, itemw, itemh);
+ y -= itemh;
+ emy -= itemh;
+ ui_item_position(item, x, y, itemw, itemh);
+ y -= style->buttonspacey;
+ miny= MIN2(miny, y);
+
+ /* decide to go to next one */
+ if(col < flow->totcol-1 && emy <= -emh) {
+ x += itemw + style->columnspace;
+ y= litem->y;
+ col++;
}
}
- layout->y -= maxh;
+ litem->h= litem->y - miny;
+ litem->x= x;
+ litem->y= miny;
}
-#endif
-/* split in columns */
-static void ui_layout_split(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template)
+/* free layout */
+static void ui_litem_estimate_free(uiLayout *litem)
{
- uiStyle *style= layout->style;
- uiTemplateSplt *split= (uiTemplateSplt*)template;
- uiLayout *sublayout;
- int a, x, y, miny, w= layout->w, h= layout->h, splitw;
-
- x= 0;
- y= 0;
- miny= layout->y;
-
- for(a=0; a<split->number; a++) {
- sublayout= split->sublayout[a];
+ uiItem *item;
+ int itemx, itemy, itemw, itemh, minx, miny;
- splitw= ui_item_fit(1, x, split->number, w, (split->number-1)*style->columnspace, a == split->number-1, UI_FIT_EXPAND);
- sublayout->x= layout->x + x;
- sublayout->w= splitw;
- sublayout->y= layout->y;
- sublayout->h= h;
+ minx= 1e6;
+ miny= 1e6;
+ litem->w= 0;
+ litem->h= 0;
- sublayout->emw= layout->emw/split->number;
- sublayout->emh= layout->emh;
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_offset(item, &itemx, &itemy);
+ ui_item_size(item, &itemw, &itemh);
- /* do layout for elements in sublayout */
- ui_layout_end(C, block, sublayout, NULL, &y);
- miny= MIN2(y, miny);
+ minx= MIN2(minx, itemx);
+ miny= MIN2(miny, itemy);
- x += splitw + style->columnspace;
+ litem->w= MAX2(litem->w, itemx+itemw);
+ litem->h= MAX2(litem->h, itemy+itemh);
}
- layout->y= miny;
+ litem->w -= minx;
+ litem->h -= miny;
}
-/* element in a box layout */
-static void ui_layout_box(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template)
+static void ui_litem_layout_free(uiLayout *litem)
{
- uiStyle *style= layout->style;
- uiTemplateBx *box= (uiTemplateBx*)template;
- int starty, startx, w= layout->w, h= layout->h;
+ uiItem *item;
+ float scalex=1.0f, scaley=1.0f;
+ int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth;
- startx= layout->x;
- starty= layout->y;
+ minx= 1e6;
+ miny= 1e6;
+ totw= 0;
+ toth= 0;
- /* some extra padding */
- box->sublayout->x= layout->x + style->boxspace;
- box->sublayout->w= w - 2*style->boxspace;
- box->sublayout->y= layout->y - style->boxspace;
- box->sublayout->h= h;
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_offset(item, &itemx, &itemy);
+ ui_item_size(item, &itemw, &itemh);
- box->sublayout->emw= layout->emw;
- box->sublayout->emh= layout->emh;
+ minx= MIN2(minx, itemx);
+ miny= MIN2(miny, itemy);
- /* do layout for elements in sublayout */
- ui_layout_end(C, block, box->sublayout, NULL, &layout->y);
+ totw= MAX2(totw, itemx+itemw);
+ toth= MAX2(toth, itemy+itemh);
+ }
- /* roundbox around the sublayout */
- uiDefBut(block, ROUNDBOX, 0, "", startx, layout->y, w, starty - layout->y, NULL, 7.0, 0.0, 3, 20, "");
-}
+ totw -= minx;
+ toth -= miny;
-static void ui_layout_header_buttons(uiLayout *layout, uiBlock *block, uiTemplate *template)
-{
- uiItem *item;
- int itemw, itemh;
+ if(litem->w && totw > litem->w)
+ scalex= (float)litem->w/(float)totw;
+ if(litem->h && toth > litem->h)
+ scaley= (float)litem->h/(float)toth;
- uiBlockBeginAlign(block);
+ x= litem->x;
+ y= litem->y - scalex*toth;
- for(item=template->items.first; item; item=item->next) {
- ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_X);
- ui_item_buts(layout, block, item, layout->x, layout->y, itemw, itemh);
- layout->x += itemw;
- }
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_offset(item, &itemx, &itemy);
+ ui_item_size(item, &itemw, &itemh);
- uiBlockEndAlign(block);
-}
-
-static void ui_layout_header(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template)
-{
- ScrArea *sa= CTX_wm_area(C);
+ if(scalex != 1.0f) {
+ newx= itemx*scalex;
+ itemw= (itemx + itemw)*scalex - newx;
+ itemx= newx;
+ }
- layout->x= ED_area_header_standardbuttons(C, block, layout->y);
+ if(scaley != 1.0f) {
+ newy= itemy*scaley;
+ itemh= (itemy + itemh)*scaley - newy;
+ itemy= newy;
+ }
- if((sa->flag & HEADER_NO_PULLDOWN)==0) {
- uiBlockSetEmboss(block, UI_EMBOSSP);
- ui_layout_header_buttons(layout, block, template);
+ ui_item_position(item, x+itemx-minx, y+itemy-miny, itemw, itemh);
}
- uiBlockSetEmboss(block, UI_EMBOSS);
+ litem->w= scalex*totw;
+ litem->h= litem->y - y;
+ litem->x= x + litem->w;
+ litem->y= y;
}
-static void header_id_cb(bContext *C, void *arg_template, void *arg_event)
+/* split layout */
+static void ui_litem_estimate_split(uiLayout *litem)
{
- uiTemplateHeadID *idtemplate= (uiTemplateHeadID*)arg_template;
- PointerRNA idptr= RNA_property_pointer_get(&idtemplate->ptr, idtemplate->prop);
- ID *idtest, *id= idptr.data;
- ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT); // XXX
- int nr, event= GET_INT_FROM_POINTER(arg_event);
-
- if(event == UI_ID_BROWSE && idtemplate->browse == 32767)
- event= UI_ID_ADD_NEW;
- else if(event == UI_ID_BROWSE && idtemplate->browse == 32766)
- event= UI_ID_OPEN;
-
- switch(event) {
- case UI_ID_BROWSE: {
- if(id==0) id= lb->first;
- if(id==0) return;
-
- if(idtemplate->browse== -2) {
- /* XXX implement or find a replacement
- * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &idtemplate->browse, do_global_buttons); */
- return;
- }
- if(idtemplate->browse < 0)
- return;
-
- for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
- if(nr==idtemplate->browse) {
- if(id == idtest)
- return;
-
- id= idtest;
- RNA_id_pointer_create(id, &idptr);
- RNA_property_pointer_set(&idtemplate->ptr, idtemplate->prop, idptr);
- RNA_property_update(C, &idtemplate->ptr, idtemplate->prop);
- /* XXX */
-
- break;
- }
- }
- break;
- }
-#if 0
- case UI_ID_DELETE:
- id= NULL;
- break;
- case UI_ID_FAKE_USER:
- if(id) {
- if(id->flag & LIB_FAKEUSER) id->us++;
- else id->us--;
- }
- else return;
- break;
-#endif
- case UI_ID_PIN:
- break;
- case UI_ID_ADD_NEW:
- WM_operator_name_call(C, idtemplate->newop, WM_OP_INVOKE_REGION_WIN, NULL);
- break;
- case UI_ID_OPEN:
- WM_operator_name_call(C, idtemplate->openop, WM_OP_INVOKE_REGION_WIN, NULL);
- break;
-#if 0
- case UI_ID_ALONE:
- if(!id || id->us < 1)
- return;
- break;
- case UI_ID_LOCAL:
- if(!id || id->us < 1)
- return;
- break;
- case UI_ID_AUTO_NAME:
- break;
-#endif
- }
+ ui_litem_estimate_row(litem);
}
-static void ui_layout_header_id(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template)
+static void ui_litem_layout_split(uiLayout *litem)
{
- uiTemplateHeadID *duptemplate, *idtemplate= (uiTemplateHeadID*)template;
- uiBut *but;
- PointerRNA idptr= RNA_property_pointer_get(&idtemplate->ptr, idtemplate->prop);
- ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT); // XXX
-
- if(idtemplate->flag & UI_ID_BROWSE) {
- char *extrastr, *str;
-
- if((idtemplate->flag & UI_ID_ADD_NEW) && (idtemplate->flag && UI_ID_OPEN))
- extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
- else if(idtemplate->flag & UI_ID_ADD_NEW)
- extrastr= "ADD NEW %x 32767";
- else if(idtemplate->flag & UI_ID_OPEN)
- extrastr= "OPEN NEW %x 32766";
- else
- extrastr= NULL;
+ uiItem *item;
+ int itemh, x, y, w, tot=0, colw=0;
- duptemplate= MEM_dupallocN(idtemplate);
- IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse);
+ x= litem->x;
+ y= litem->y;
+ w= litem->w;
- but= uiDefButS(block, MENU, 0, str, layout->x, layout->y, EM_UNIT_X, EM_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new");
- uiButSetNFunc(but, header_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE));
- layout->x+= EM_UNIT_X;
+ for(item=litem->items.first; item; item=item->next)
+ tot++;
- MEM_freeN(str);
- }
+ if(tot == 0)
+ return;
+
+ colw= (litem->w - (tot-1)*litem->space)/tot;
+ colw= MAX2(colw, 0);
- /* text button with name */
- if(idptr.data) {
- char name[64];
+ for(item=litem->items.first; item; item=item->next) {
+ ui_item_size(item, NULL, &itemh);
- text_idbutton(idptr.data, name);
- but= uiDefButR(block, TEX, 0, name, layout->x, layout->y, EM_UNIT_X*6, EM_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
- uiButSetNFunc(but, header_id_cb, MEM_dupallocN(idtemplate), SET_INT_IN_POINTER(UI_ID_RENAME));
- layout->x += EM_UNIT_X*6;
+ ui_item_position(item, x, y-itemh, colw, itemh);
+ x += colw;
- /* delete button */
- if(idtemplate->flag & UI_ID_DELETE) {
- but= uiDefIconButO(block, BUT, idtemplate->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, layout->x, layout->y, EM_UNIT_X, EM_UNIT_Y, NULL);
- layout->x += EM_UNIT_X;
- }
+ if(item->next)
+ x += litem->space;
}
+
+ litem->w= x - litem->x;
+ litem->h= litem->y - y;
+ litem->x= x;
+ litem->y= y;
}
-void ui_template_free(uiTemplate *template)
+/* layout create functions */
+uiLayout *uiLayoutRow(uiLayout *layout, int align)
{
- uiItem *item;
- int a;
-
- if(template->type == TEMPLATE_BOX) {
- uiTemplateBx *box= (uiTemplateBx*)template;
- ui_layout_free(box->sublayout);
- }
- if(template->type == TEMPLATE_SPLIT) {
- uiTemplateSplt *split= (uiTemplateSplt*)template;
-
- for(a=0; a<split->number; a++)
- ui_layout_free(split->sublayout[a]);
- MEM_freeN(split->sublayout);
- }
+ uiLayout *litem;
- for(item=template->items.first; item; item=item->next)
- ui_item_free(item);
+ litem= MEM_callocN(sizeof(uiLayout), "uiLayoutRow");
+ litem->item.type= ITEM_LAYOUT_ROW;
+ litem->common= layout->common;
+ litem->align= align;
+ litem->space= (align)? 0: layout->common->style->buttonspacex;
+ BLI_addtail(&layout->items, litem);
- BLI_freelistN(&template->items);
+ return litem;
}
-/* template create functions */
-void uiLayoutRow(uiLayout *layout)
+uiLayout *uiLayoutColumn(uiLayout *layout, int align)
{
- uiTemplate *template;
+ uiLayout *litem;
- template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
- template->type= TEMPLATE_ROW;
+ litem= MEM_callocN(sizeof(uiLayout), "uiLayoutColumn");
+ litem->item.type= ITEM_LAYOUT_COLUMN;
+ litem->common= layout->common;
+ litem->align= align;
+ litem->space= (litem->align)? 0: layout->common->style->buttonspacey;
+ BLI_addtail(&layout->items, litem);
- BLI_addtail(&layout->templates, template);
+ return litem;
}
-void uiLayoutColumn(uiLayout *layout)
+uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
{
- uiTemplate *template;
+ uiLayoutItemFlow *flow;
- template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
- template->type= TEMPLATE_COLUMN;
+ flow= MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow");
+ flow->litem.item.type= ITEM_LAYOUT_COLUMN_FLOW;
+ flow->litem.common= layout->common;
+ flow->litem.align= align;
+ flow->litem.space= (flow->litem.align)? 0: layout->common->style->columnspace;
+ flow->number= number;
+ BLI_addtail(&layout->items, flow);
- BLI_addtail(&layout->templates, template);
+ return &flow->litem;
}
-void uiLayoutColumnFlow(uiLayout *layout, int number)
+uiLayout *uiLayoutBox(uiLayout *layout)
{
- uiTemplateFlow *flow;
+ uiLayoutItemBx *box;
- flow= MEM_callocN(sizeof(uiTemplateFlow), "uiTemplateFlow");
- flow->template.type= TEMPLATE_COLUMN_FLOW;
- flow->number= number;
- BLI_addtail(&layout->templates, flow);
+ box= MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx");
+ box->litem.item.type= ITEM_LAYOUT_BOX;
+ box->litem.common= layout->common;
+ box->litem.space= layout->common->style->columnspace;
+ BLI_addtail(&layout->items, box);
+
+ return &box->litem;
}
-uiLayout *uiLayoutBox(uiLayout *layout)
+uiLayout *uiLayoutFree(uiLayout *layout, int align)
{
- uiTemplateBx *box;
+ uiLayout *litem;
- box= MEM_callocN(sizeof(uiTemplateBx), "uiTemplateBx");
- box->template.type= TEMPLATE_BOX;
- box->sublayout= uiLayoutBegin(layout->dir, layout->type, 0, 0, 0, 0, layout->style);
- BLI_addtail(&layout->templates, box);
+ litem= MEM_callocN(sizeof(uiLayout), "uiLayoutFree");
+ litem->item.type= ITEM_LAYOUT_FREE;
+ litem->common= layout->common;
+ litem->align= align;
+ BLI_addtail(&layout->items, litem);
- return box->sublayout;
+ return litem;
}
-void uiLayoutSplit(uiLayout *layout, int number, int lr)
+uiLayout *uiLayoutSplit(uiLayout *layout)
{
- uiTemplateSplt *split;
- int a;
+ uiLayout *litem;
- split= MEM_callocN(sizeof(uiTemplateSplt), "uiTemplateSplt");
- split->template.type= TEMPLATE_SPLIT;
- split->number= number;
- split->lr= lr;
- split->sublayout= MEM_callocN(sizeof(uiLayout*)*number, "uiTemplateSpltSub");
+ litem= uiLayoutRow(layout, 0);
+ litem->item.type = ITEM_LAYOUT_SPLIT;
+ litem->common= layout->common;
+ litem->space= layout->common->style->columnspace;
- for(a=0; a<number; a++)
- split->sublayout[a]= uiLayoutBegin(layout->dir, layout->type, 0, 0, 0, 0, layout->style);
-
- BLI_addtail(&layout->templates, split);
+ return litem;
}
-uiLayout *uiLayoutSub(uiLayout *layout, int n)
+/********************** Layout *******************/
+
+static void ui_item_estimate(uiItem *item)
{
- uiTemplate *template= layout->templates.last;
+ uiItem *subitem;
+
+ if(item->type != ITEM_BUTTON) {
+ uiLayout *litem= (uiLayout*)item;
+
+ for(subitem=litem->items.first; subitem; subitem=subitem->next)
+ ui_item_estimate(subitem);
- if(template) {
- switch(template->type) {
- case TEMPLATE_SPLIT:
- if(n >= 0 && n < ((uiTemplateSplt*)template)->number)
- return ((uiTemplateSplt*)template)->sublayout[n];
+ switch(litem->item.type) {
+ case ITEM_LAYOUT_COLUMN:
+ ui_litem_estimate_column(litem);
+ break;
+ case ITEM_LAYOUT_COLUMN_FLOW:
+ ui_litem_estimate_column_flow(litem);
+ break;
+ case ITEM_LAYOUT_ROW:
+ ui_litem_estimate_row(litem);
+ break;
+ case ITEM_LAYOUT_BOX:
+ ui_litem_estimate_box(litem);
+ break;
+ case ITEM_LAYOUT_ROOT:
+ ui_litem_estimate_root(litem);
break;
- case TEMPLATE_BOX:
- return ((uiTemplateBx*)template)->sublayout;
+ case ITEM_LAYOUT_FREE:
+ ui_litem_estimate_free(litem);
+ break;
+ case ITEM_LAYOUT_SPLIT:
+ ui_litem_estimate_split(litem);
break;
default:
break;
}
}
-
- return NULL;
}
-void uiTemplateHeader(uiLayout *layout)
+static void ui_item_align(uiLayout *litem, int nr)
{
- uiTemplate *template;
-
- template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
- template->type= TEMPLATE_HEADER;
+ uiItem *item;
- BLI_addtail(&layout->templates, template);
+ for(item=litem->items.first; item; item=item->next) {
+ if(item->type == ITEM_BUTTON)
+ ((uiButtonItem*)item)->but->alignnr= nr;
+ else
+ ui_item_align((uiLayout*)item, nr);
+ }
}
-void uiTemplateHeaderID(uiLayout *layout, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+static void ui_item_layout(uiItem *item, int align)
{
- uiTemplateHeadID *idtemplate;
- PropertyRNA *prop;
-
- if(!ptr->data)
- return;
+ uiItem *subitem;
- prop= RNA_struct_find_property(ptr, propname);
+ if(item->type != ITEM_BUTTON) {
+ uiLayout *litem= (uiLayout*)item;
- if(!prop) {
- printf("uiTemplateHeaderID: property not found: %s\n", propname);
- return;
- }
+ if(litem->align && !align)
+ ui_item_align(litem, ++litem->common->block->alignnr);
- idtemplate= MEM_callocN(sizeof(uiTemplateHeadID), "uiTemplateHeadID");
- idtemplate->template.type= TEMPLATE_HEADER_ID;
- idtemplate->ptr= *ptr;
- idtemplate->prop= prop;
- idtemplate->flag= UI_ID_BROWSE|UI_ID_RENAME;
+ switch(litem->item.type) {
+ case ITEM_LAYOUT_COLUMN:
+ ui_litem_layout_column(litem);
+ break;
+ case ITEM_LAYOUT_COLUMN_FLOW:
+ ui_litem_layout_column_flow(litem);
+ break;
+ case ITEM_LAYOUT_ROW:
+ ui_litem_layout_row(litem);
+ break;
+ case ITEM_LAYOUT_BOX:
+ ui_litem_layout_box(litem);
+ break;
+ case ITEM_LAYOUT_ROOT:
+ ui_litem_layout_root(litem);
+ break;
+ case ITEM_LAYOUT_FREE:
+ ui_litem_layout_free(litem);
+ break;
+ case ITEM_LAYOUT_SPLIT:
+ ui_litem_layout_split(litem);
+ break;
+ default:
+ break;
+ }
- if(newop) {
- idtemplate->flag |= UI_ID_ADD_NEW;
- idtemplate->newop= newop;
+ for(subitem=litem->items.first; subitem; subitem=subitem->next)
+ ui_item_layout(subitem, litem->align || align);
}
- if(openop) {
- idtemplate->flag |= UI_ID_OPEN;
- idtemplate->openop= openop;
- }
- if(unlinkop) {
- idtemplate->flag |= UI_ID_DELETE;
- idtemplate->unlinkop= unlinkop;
- }
-
- BLI_addtail(&layout->templates, idtemplate);
}
-void uiTemplateSlot(uiLayout *layout, int slot)
+static void ui_layout_items(const bContext *C, uiBlock *block, uiLayout *layout)
{
- uiTemplate *template= layout->templates.last;
-
- if(template)
- template->slot= slot;
+ ui_item_estimate(&layout->item);
+ ui_item_layout(&layout->item, 0);
}
-/********************** Layout *******************/
-
-static void ui_layout_init_items(const bContext *C, uiLayout *layout)
+static void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
{
- ARegion *ar= CTX_wm_region(C);
- MenuType *mt;
- uiTemplate *template;
- uiItem *item;
- uiItemMenu *menuitem;
- uiItemRNA *rnaitem;
- uiItemOp *opitem;
- PropertyType type;
-
- for(template=layout->templates.first; template; template=template->next) {
- for(item=template->items.first; item; item=item->next) {
- /* initialize buttons names */
- if(item->type == ITEM_MENU) {
- menuitem= (uiItemMenu*)item;
-
- if(menuitem->menuname) {
- for(mt=ar->type->menutypes.first; mt; mt=mt->next) {
- if(strcmp(menuitem->menuname, mt->idname) == 0) {
- menuitem->arg= mt;
- ui_item_name(item, mt->label);
- break;
- }
- }
- }
- }
- else if(item->type == ITEM_RNA_PROPERTY) {
- rnaitem= (uiItemRNA*)item;
- type= RNA_property_type(rnaitem->prop);
+ if(layout->common->handlefunc)
+ uiBlockSetButmFunc(block, layout->common->handlefunc, layout->common->argv);
- ui_item_name(item, (char*)RNA_property_ui_name(rnaitem->prop));
+ ui_layout_items(C, block, layout);
- if(ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_ENUM))
- ui_item_name_add_colon(item);
- }
- else if(item->type == ITEM_OPERATOR) {
- opitem= (uiItemOp*)item;
- ui_item_name(item, opitem->ot->name);
- }
-
- ui_item_name(item, "");
+ if(x) *x= layout->x;
+ if(y) *y= layout->y;
+}
- /* initialize icons */
- if(layout->type == UI_LAYOUT_MENU) {
- if(item->type == ITEM_RNA_PROPERTY) {
- rnaitem= (uiItemRNA*)item;
- type= RNA_property_type(rnaitem->prop);
+static void ui_layout_free(uiLayout *layout)
+{
+ uiItem *item, *next;
- if(type == PROP_BOOLEAN)
- item->icon= (RNA_property_boolean_get(&rnaitem->ptr, rnaitem->prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT;
- else if(type == PROP_ENUM && rnaitem->index == RNA_ENUM_VALUE)
- item->icon= (RNA_property_enum_get(&rnaitem->ptr, rnaitem->prop) == rnaitem->value)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT;
- }
+ for(item=layout->items.first; item; item=next) {
+ next= item->next;
- if(!item->icon)
- item->icon= ICON_BLANK1;
- }
- }
+ if(item->type == ITEM_BUTTON)
+ MEM_freeN(item);
+ else
+ ui_layout_free((uiLayout*)item);
}
+
+ MEM_freeN(layout);
}
-static void ui_layout_templates(const bContext *C, uiBlock *block, uiLayout *layout)
+uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, uiStyle *style)
{
- uiStyle *style= layout->style;
- uiTemplate *template;
+ uiLayout *layout;
+ uiLayoutCommon *common;
- ui_layout_init_items(C, layout);
+ if(!block->layout) {
+ common= MEM_callocN(sizeof(uiLayoutCommon), "uiLayoutCommon");
+ common->type= type;
+ common->style= style;
+ common->block= block;
+ common->opcontext= WM_OP_INVOKE_REGION_WIN;
- if(layout->dir == UI_LAYOUT_HORIZONTAL) {
- for(template=layout->templates.first; template; template=template->next) {
- switch(template->type) {
- case TEMPLATE_HEADER:
- ui_layout_header(C, layout, block, template);
- break;
- case TEMPLATE_HEADER_ID:
- ui_layout_header_id(C, layout, block, template);
- break;
- default:
- ui_layout_header_buttons(layout, block, template);
- break;
- }
+ layout= MEM_callocN(sizeof(uiLayout), "uiLayout");
+ layout->item.type= ITEM_LAYOUT_ROOT;
- layout->x += style->templatespace;
- }
- }
- else {
- for(template=layout->templates.first; template; template=template->next) {
- switch(template->type) {
- case TEMPLATE_ROW:
- ui_layout_row(layout, block, template);
- break;
- case TEMPLATE_COLUMN_FLOW:
- ui_layout_column_flow(layout, block, template);
- break;
- case TEMPLATE_SPLIT:
- ui_layout_split(C, layout, block, template);
- break;
- case TEMPLATE_BOX:
- ui_layout_box(C, layout, block, template);
- break;
- case TEMPLATE_COLUMN:
- default:
- ui_layout_column(layout, block, template);
- break;
- }
+ layout->x= x;
+ layout->y= y;
+ layout->common= common;
+ layout->space= style->templatespace;
+
+ if(type == UI_LAYOUT_MENU)
+ layout->space= 0;
- layout->y -= style->templatespace;
+ if(dir == UI_LAYOUT_HORIZONTAL) {
+ layout->h= size;
+ layout->common->emh= em*UI_UNIT_Y;
}
+ else {
+ layout->w= size;
+ layout->common->emw= em*UI_UNIT_X;
+ }
+
+ block->curlayout= layout;
+ block->layout= layout;
}
+
+ return block->layout;
}
-void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
+uiBlock *uiLayoutBlock(uiLayout *layout)
{
- if(layout->handlefunc)
- uiBlockSetButmFunc(block, layout->handlefunc, layout->argv);
-
- ui_layout_templates(C, block, layout);
-
- if(x) *x= layout->x;
- if(y) *y= layout->y;
-
+ return layout->common->block;
}
-void ui_layout_free(uiLayout *layout)
+void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout)
{
- uiTemplate *template;
-
- for(template=layout->templates.first; template; template=template->next)
- ui_template_free(template);
-
- BLI_freelistN(&layout->templates);
- MEM_freeN(layout);
+ block->curlayout= layout;
}
-uiLayout *uiLayoutBegin(int dir, int type, int x, int y, int size, int em, uiStyle *style)
+void ui_layout_add_but(uiLayout *layout, uiBut *but)
{
- uiLayout *layout;
-
- layout= MEM_callocN(sizeof(uiLayout), "uiLayout");
- layout->opcontext= WM_OP_INVOKE_REGION_WIN;
- layout->dir= dir;
- layout->type= type;
- layout->x= x;
- layout->y= y;
- layout->style= style;
-
- if(dir == UI_LAYOUT_HORIZONTAL) {
- layout->h= size;
- layout->emh= em*EM_UNIT_Y;
- }
- else {
- layout->w= size;
- layout->emw= em*EM_UNIT_X;
- }
-
- return layout;
+ uiButtonItem *bitem;
+
+ bitem= MEM_callocN(sizeof(uiButtonItem), "uiButtonItem");
+ bitem->item.type= ITEM_BUTTON;
+ bitem->but= but;
+ BLI_addtail(&layout->items, bitem);
}
void uiLayoutContext(uiLayout *layout, int opcontext)
{
- layout->opcontext= opcontext;
+ layout->common->opcontext= opcontext;
}
void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
{
- layout->handlefunc= handlefunc;
- layout->argv= argv;
+ layout->common->handlefunc= handlefunc;
+ layout->common->argv= argv;
}
-void uiLayoutEnd(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
+void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y)
{
- ui_layout_end(C, block, layout, x, y);
- ui_layout_free(layout);
-}
+ uiLayout *layout= block->layout;
-/************************ Utilities ************************/
+ if(layout) {
+ /* NULL in advance so we don't interfere when adding button */
+ block->layout= NULL;
+ block->curlayout= NULL;
-void uiRegionPanelLayout(const bContext *C, ARegion *ar, int vertical, char *context)
-{
- uiStyle *style= U.uistyles.first;
- uiBlock *block;
- PanelType *pt;
- Panel *panel;
- float col[3];
- int xco, yco, x=PNL_DIST, y=-PNL_HEADER-PNL_DIST, w, em;
-
- // XXX this only hides cruft
-
- /* clear */
- UI_GetThemeColor3fv(TH_BACK, col);
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(C, &ar->v2d);
-
- uiBeginPanels(C, ar);
-
- for(pt= ar->type->paneltypes.first; pt; pt= pt->next) {
- if(context)
- if(!pt->context || strcmp(context, pt->context) != 0)
- continue;
-
- if(pt->draw && (!pt->poll || pt->poll(C, pt))) {
- block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
- panel= uiBeginPanel(ar, block, pt);
-
- if(panel) {
- if(vertical) {
- w= (ar->type->minsizex)? ar->type->minsizex-12: block->aspect*ar->winx-12;
- em= (ar->type->minsizex)? 10: 20;
- }
- else {
- w= (ar->type->minsizex)? ar->type->minsizex-12: UI_PANEL_WIDTH-12;
- em= (ar->type->minsizex)? 10: 20;
- }
-
- panel->type= pt;
- panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, PNL_SAFETY, 0, w-2*PNL_SAFETY, em, style);
-
- pt->draw(C, panel);
-
- uiLayoutEnd(C, block, panel->layout, &xco, &yco);
- panel->layout= NULL;
- uiEndPanel(block, w, -yco + 12);
- }
- else {
- w= PNL_HEADER;
- yco= PNL_HEADER;
- }
-
- uiEndBlock(C, block);
-
- if(vertical)
- y += yco+PNL_DIST;
- else
- x += w+PNL_DIST;
- }
+ ui_layout_end(C, block, layout, x, y);
+ MEM_freeN(layout->common);
+ ui_layout_free(layout);
+ }
+ else {
+ if(x) *x= 0;
+ if(y) *y= 0;
}
- uiEndPanels(C, ar);
-
- /* restore view matrix? */
- UI_view2d_view_restore(C);
+ /* XXX silly trick, interface_templates.c doesn't get linked
+ * because it's not used by other files in this module? */
+ {
+ void ui_template_fix_linking();
+ ui_template_fix_linking();
+ }
}
-void uiRegionHeaderLayout(const bContext *C, ARegion *ar)
+float uiBlockAspect(uiBlock *block)
{
- uiStyle *style= U.uistyles.first;
- uiBlock *block;
- uiLayout *layout;
- HeaderType *ht;
- Header header = {0};
- float col[3];
- int xco, yco;
-
- // XXX this only hides cruft
-
- /* clear */
- if(ED_screen_area_active(C))
- UI_GetThemeColor3fv(TH_HEADER, col);
- else
- UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(C, &ar->v2d);
-
- xco= 8;
- yco= 3;
-
- /* draw all headers types */
- for(ht= ar->type->headertypes.first; ht; ht= ht->next) {
- block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS);
- layout= uiLayoutBegin(UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, 24, 1, style);
-
- if(ht->draw) {
- header.type= ht;
- header.layout= layout;
- ht->draw(C, &header);
- }
-
- uiLayoutEnd(C, block, layout, &xco, &yco);
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
- }
-
- /* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
-
- /* restore view matrix? */
- UI_view2d_view_restore(C);
+ return block->aspect; /* temporary */
}