Merge with 2.5 -r 21619:21756.
[blender.git] / source / blender / editors / interface / interface_layout.c
index f9816235b88e993cd866ba0086dc018c37f64d61..07fe2686317d953f4a131739dab79d14fe4717b9 100644 (file)
@@ -148,6 +148,7 @@ typedef struct uiLayoutItemFlow {
 typedef struct uiLayoutItemBx {
        uiLayout litem;
        uiBut *roundbox;
+       ListBase items;
 } uiLayoutItemBx;
 
 typedef struct uiLayoutItemSplt {
@@ -218,7 +219,7 @@ 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)
+       if(icon && !name[0])
                return UI_UNIT_X; /* icon only */
        else if(icon)
                return (variable)? UI_GetStringWidth(name) + 4 + UI_UNIT_X: 10*UI_UNIT_X; /* icon + text */
@@ -429,16 +430,19 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
 
 static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, char *uiname, int x, int y, int w, int h)
 {
-       const EnumPropertyItem *item;
+       EnumPropertyItem *item;
        const char *identifier;
        char *name;
-       int a, totitem, itemw, icon, value;
+       int a, totitem, itemw, icon, value, free;
 
        identifier= RNA_property_identifier(prop);
-       RNA_property_enum_items(ptr, prop, &item, &totitem);
+       RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
 
        uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
        for(a=0; a<totitem; a++) {
+               if(!item[a].identifier[0])
+                       continue;
+
                name= (!uiname || uiname[0])? (char*)item[a].name: "";
                icon= item[a].icon;
                value= item[a].value;
@@ -452,6 +456,9 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr,
                        uiDefButR(block, ROW, 0, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
        }
        uiBlockSetCurLayout(block, layout);
+
+       if(free)
+               MEM_freeN(item);
 }
 
 /* create label + button for RNA property */
@@ -460,13 +467,18 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i
        uiLayout *sub;
        uiBut *but;
        PropertySubType subtype;
+       int labelw;
 
        sub= uiLayoutRow(layout, 0);
        uiBlockSetCurLayout(block, sub);
 
        if(strcmp(name, "") != 0) {
-               w= w/2;
-               uiDefBut(block, LABEL, 0, name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+               /* XXX UI_GetStringWidth is not accurate
+               labelw= UI_GetStringWidth(name);
+               CLAMP(labelw, w/4, 3*w/4);*/
+               labelw= w/2;
+               uiDefBut(block, LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, "");
+               w= w-labelw;
        }
 
        subtype= RNA_property_subtype(prop);
@@ -509,7 +521,7 @@ static void ui_item_disabled(uiLayout *layout, char *name)
 void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context)
 {
        uiBlock *block= layout->root->block;
-       wmOperatorType *ot= WM_operatortype_find(idname);
+       wmOperatorType *ot= WM_operatortype_find(idname, 0);
        uiBut *but;
        int w;
 
@@ -542,9 +554,9 @@ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDPropert
        }
 }
 
-static char *ui_menu_enumpropname(char *opname, char *propname, int retval)
+static char *ui_menu_enumpropname(uiLayout *layout, char *opname, char *propname, int retval)
 {
-       wmOperatorType *ot= WM_operatortype_find(opname);
+       wmOperatorType *ot= WM_operatortype_find(opname, 0);
        PointerRNA ptr;
        PropertyRNA *prop;
 
@@ -555,15 +567,18 @@ static char *ui_menu_enumpropname(char *opname, char *propname, int retval)
        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;
+               EnumPropertyItem *item;
+               int totitem, free;
+               const char *name;
+
+               RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, &totitem, &free);
+               if(RNA_enum_name(item, retval, &name)) {
+                       if(free) MEM_freeN(item);
+                       return (char*)name;
                }
+               
+               if(free)
+                       MEM_freeN(item);
        }
 
        return "";
@@ -577,14 +592,14 @@ void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *pro
        RNA_enum_set(&ptr, propname, value);
 
        if(!name)
-               name= ui_menu_enumpropname(opname, propname, value);
+               name= ui_menu_enumpropname(layout, opname, propname, value);
 
        uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext);
 }
 
 void uiItemsEnumO(uiLayout *layout, char *opname, char *propname)
 {
-       wmOperatorType *ot= WM_operatortype_find(opname);
+       wmOperatorType *ot= WM_operatortype_find(opname, 0);
        PointerRNA ptr;
        PropertyRNA *prop;
 
@@ -597,13 +612,19 @@ void uiItemsEnumO(uiLayout *layout, char *opname, char *propname)
        prop= RNA_struct_find_property(&ptr, propname);
 
        if(prop && RNA_property_type(prop) == PROP_ENUM) {
-               const EnumPropertyItem *item;
-               int totitem, i;
+               EnumPropertyItem *item;
+               int totitem, i, free;
 
-               RNA_property_enum_items(&ptr, prop, &item, &totitem);
+               RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, &totitem, &free);
 
                for(i=0; i<totitem; i++)
-                       uiItemEnumO(layout, (char*)item[i].name, item[i].icon, opname, propname, item[i].value);
+                       if(item[i].identifier[0])
+                               uiItemEnumO(layout, (char*)item[i].name, item[i].icon, opname, propname, item[i].value);
+                       else
+                               uiItemS(layout);
+
+               if(free)
+                       MEM_freeN(item);
        }
 }
 
@@ -614,19 +635,22 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch
        
        /* for getting the enum */
        PropertyRNA *prop;
-       const EnumPropertyItem *item;
-       int totitem;
-       int value;
+       EnumPropertyItem *item;
+       int value, free;
 
        WM_operator_properties_create(&ptr, opname);
        
        /* enum lookup */
        if((prop= RNA_struct_find_property(&ptr, propname))) {
-               RNA_property_enum_items(&ptr, prop, &item, &totitem);
+               RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
                if(RNA_enum_value_from_id(item, value_str, &value)==0) {
+                       if(free) MEM_freeN(item);
                        printf("uiItemEnumO_string: %s.%s, enum %s not found.\n", RNA_struct_identifier(ptr.type), propname, value_str);
                        return;
                }
+
+               if(free)
+                       MEM_freeN(item);
        }
        else {
                printf("uiItemEnumO_string: %s.%s not found.\n", RNA_struct_identifier(ptr.type), propname);
@@ -637,7 +661,7 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch
        
        /* same as uiItemEnumO */
        if(!name)
-               name= ui_menu_enumpropname(opname, propname, value);
+               name= ui_menu_enumpropname(layout, opname, propname, value);
 
        uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext);
 }
@@ -695,17 +719,22 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA
        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(ELEM(type, PROP_STRING, PROP_POINTER) && !name[0])
+               name= "non-empty";
+       else if(type == PROP_BOOLEAN && !name[0])
+               icon= ICON_DOT;
+
+       w= ui_text_icon_width(layout, name, icon);
+       h= UI_UNIT_Y;
+
        /* increase height for arrays */
        if(index == RNA_NO_INDEX && len > 0) {
-               if(strcmp(name, "") == 0 && icon == 0)
+               if(!name[0] && icon == 0)
                        h= 0;
 
                if(type == PROP_BOOLEAN && len == 20)
@@ -827,15 +856,52 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr,
 
        prop= RNA_struct_find_property(ptr, propname);
 
-       if(!prop) {
+       if(!prop || RNA_property_type(prop) != PROP_ENUM) {
                ui_item_disabled(layout, propname);
-               printf("uiItemEnumR: property not found: %s\n", propname);
+               printf("uiItemEnumR: enum property not found: %s\n", propname);
                return;
        }
 
        uiItemFullR(layout, name, icon, ptr, prop, RNA_ENUM_VALUE, value, 0, 0, 0);
 }
 
+void uiItemEnumR_string(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value)
+{
+       PropertyRNA *prop;
+       EnumPropertyItem *item;
+       int ivalue, a, free;
+
+       if(!ptr->data || !propname)
+               return;
+
+       prop= RNA_struct_find_property(ptr, propname);
+
+       if(!prop || RNA_property_type(prop) != PROP_ENUM) {
+               ui_item_disabled(layout, propname);
+               printf("uiItemEnumR: enum property not found: %s\n", propname);
+               return;
+       }
+
+       RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
+
+       if(!RNA_enum_value_from_id(item, value, &ivalue)) {
+               if(free) MEM_freeN(item);
+               ui_item_disabled(layout, propname);
+               printf("uiItemEnumR: enum property value not found: %s\n", value);
+               return;
+       }
+
+       for(a=0; item[a].identifier; a++) {
+               if(item[a].value == ivalue) {
+                       uiItemFullR(layout, (char*)item[a].name, item[a].icon, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, 0, 0);
+                       break;
+               }
+       }
+
+       if(free)
+               MEM_freeN(item);
+}
+
 void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
 {
        PropertyRNA *prop;
@@ -848,13 +914,19 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
        }
 
        if(RNA_property_type(prop) == PROP_ENUM) {
-               const EnumPropertyItem *item;
-               int totitem, i;
+               EnumPropertyItem *item;
+               int totitem, i, free;
 
-               RNA_property_enum_items(ptr, prop, &item, &totitem);
+               RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free);
 
                for(i=0; i<totitem; i++)
-                       uiItemEnumR(layout, (char*)item[i].name, 0, ptr, propname, item[i].value);
+                       if(item[i].identifier[0])
+                               uiItemEnumR(layout, (char*)item[i].name, 0, ptr, propname, item[i].value);
+                       else
+                               uiItemS(layout);
+
+               if(free)
+                       MEM_freeN(item);
        }
 }
 
@@ -1058,9 +1130,11 @@ void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname
                        if(layout->root->type == UI_LAYOUT_MENU && !icon)
                                icon= ICON_BLANK1;
                        ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL);
-                       break;
+                       return;
                }
        }
+
+       printf("uiItemM: not found %s\n", menuname);
 }
 
 /* label item */
@@ -1147,7 +1221,7 @@ 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);
+       wmOperatorType *ot= WM_operatortype_find(opname, 0);
        MenuItemLevel *lvl;
 
        if(!ot || !ot->srna) {
@@ -1224,7 +1298,7 @@ static void ui_litem_estimate_row(uiLayout *litem)
 
 static int ui_litem_min_width(int itemw)
 {
-       return MIN2(UI_UNIT_X, itemw);
+       return MIN2(2*UI_UNIT_X, itemw);
 }
 
 static void ui_litem_layout_row(uiLayout *litem)
@@ -1737,7 +1811,7 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
        return &flow->litem;
 }
 
-uiLayout *uiLayoutBox(uiLayout *layout)
+static uiLayout *ui_layout_box(uiLayout *layout, int type)
 {
        uiLayoutItemBx *box;
 
@@ -1752,11 +1826,27 @@ uiLayout *uiLayoutBox(uiLayout *layout)
 
        uiBlockSetCurLayout(layout->root->block, &box->litem);
 
-       box->roundbox= uiDefBut(layout->root->block, ROUNDBOX, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
+       box->roundbox= uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
 
        return &box->litem;
 }
 
+uiLayout *uiLayoutBox(uiLayout *layout)
+{
+       return ui_layout_box(layout, ROUNDBOX);
+}
+
+uiLayout *uiLayoutListBox(uiLayout *layout)
+{
+       return ui_layout_box(layout, LISTBOX);
+}
+
+ListBase *uiLayoutBoxGetList(uiLayout *layout)
+{
+       uiLayoutItemBx *box= (uiLayoutItemBx*)layout;
+       return &box->items;
+}
+
 uiLayout *uiLayoutFree(uiLayout *layout, int align)
 {
        uiLayout *litem;
@@ -2061,6 +2151,9 @@ static void ui_layout_free(uiLayout *layout)
                        ui_layout_free((uiLayout*)item);
        }
 
+       if(layout->item.type == ITEM_LAYOUT_BOX)
+               BLI_freelistN(&((uiLayoutItemBx*)layout)->items);
+
        MEM_freeN(layout);
 }