Merge with 2.5 -r 21619:21756.
[blender.git] / source / blender / editors / interface / interface_layout.c
index 7144e9b866f9d924760a9974e99945dcb4054631..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 */
@@ -427,35 +428,57 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
        uiBlockSetCurLayout(block, layout);
 }
 
-static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int x, int y, int w, int h)
+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;
-       int a, totitem, itemw;
-       const char *propname;
+       EnumPropertyItem *item;
+       const char *identifier;
+       char *name;
+       int a, totitem, itemw, icon, value, free;
 
-       propname= RNA_property_identifier(prop);
-       RNA_property_enum_items(ptr, prop, &item, &totitem);
+       identifier= RNA_property_identifier(prop);
+       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++) {
-               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);
+               if(!item[a].identifier[0])
+                       continue;
+
+               name= (!uiname || uiname[0])? (char*)item[a].name: "";
+               icon= item[a].icon;
+               value= item[a].value;
+               itemw= ui_text_icon_width(block->curlayout, name, icon);
+
+               if(icon && strcmp(name, "") != 0)
+                       uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+               else if(icon)
+                       uiDefIconButR(block, ROW, 0, icon, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+               else
+                       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 */
-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)
+static uiBut *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)
 {
        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);
@@ -463,12 +486,13 @@ static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int
        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 */
+               but= 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 */
        }
        else
-               uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
+               but= uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
 
        uiBlockSetCurLayout(block, layout);
+       return but;
 }
 
 /********************* Button Items *************************/
@@ -497,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;
 
@@ -530,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;
 
@@ -543,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 "";
@@ -565,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;
 
@@ -585,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, NULL, 0, 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);
        }
 }
 
@@ -602,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);
@@ -625,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);
 }
@@ -683,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)
@@ -706,6 +747,8 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA
        else if(ui_layout_vary_direction(layout) == UI_ITEM_VARY_X) {
                if(type == PROP_BOOLEAN && strcmp(name, "") != 0)
                        w += UI_UNIT_X;
+               else if(type == PROP_ENUM)
+                       w += UI_UNIT_X/2;
        }
 
        *r_w= w;
@@ -732,10 +775,14 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
        /* set name and icon */
        if(!name)
                name= (char*)RNA_property_ui_name(prop);
+       if(!icon)
+               icon= RNA_property_ui_icon(prop);
 
-       if(ELEM5(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_ENUM, PROP_POINTER))
+       if(ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER))
+               name= ui_item_name_add_colon(name, namestr);
+       else if(type == PROP_BOOLEAN && len)
                name= ui_item_name_add_colon(name, namestr);
-       if(type == PROP_BOOLEAN && len)
+       else if(type == PROP_ENUM && index != RNA_ENUM_VALUE)
                name= ui_item_name_add_colon(name, namestr);
 
        if(layout->root->type == UI_LAYOUT_MENU) {
@@ -764,10 +811,12 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
        }
        /* expanded enum */
        else if(type == PROP_ENUM && expand)
-               ui_item_enum_row(layout, block, ptr, prop, 0, 0, w, h);
+               ui_item_enum_row(layout, block, ptr, prop, name, 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);
+       else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
+               but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+               ui_but_add_search(but, ptr, prop, NULL, NULL);
+       }
        /* single button */
        else {
                but= uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h);
@@ -807,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;
@@ -828,14 +914,156 @@ 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);
+       }
+}
+
+/* Pointer RNA button with search */
+
+static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, uiSearchItems *items)
+{
+       Scene *scene= CTX_data_scene(C);
+       uiBut *but= arg_but;
+       char *name;
+       int i, iconid;
+
+       i = 0;
+       RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
+               iconid= 0;
+               if(RNA_struct_is_ID(itemptr.type))
+                       iconid= ui_id_icon_get(scene, itemptr.data);
+
+               name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+               if(name) {
+                       if(BLI_strcasestr(name, str)) {
+                               if(!uiSearchItemAdd(items, name, SET_INT_IN_POINTER(i), iconid)) {
+                                       MEM_freeN(name);
+                                       break;
+                               }
+                       }
+
+                       MEM_freeN(name);
+               }
+
+               i++;
        }
+       RNA_PROP_END;
+}
+
+static void search_id_collection(StructRNA *ptype, PointerRNA *ptr, PropertyRNA **prop)
+{
+       StructRNA *srna;
+
+       /* look for collection property in Main */
+       RNA_main_pointer_create(G.main, ptr);
+
+       *prop= NULL;
+
+       RNA_STRUCT_BEGIN(ptr, iprop) {
+               /* if it's a collection and has same pointer type, we've got it */
+               if(RNA_property_type(iprop) == PROP_COLLECTION) {
+                       srna= RNA_property_pointer_type(ptr, iprop);
+
+                       if(ptype == srna) {
+                               *prop= iprop;
+                               break;
+                       }
+               }
+       }
+       RNA_STRUCT_END;
+}
+
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
+{
+       StructRNA *ptype;
+       PointerRNA sptr;
+
+       /* for ID's we do automatic lookup */
+       if(!searchprop) {
+               if(RNA_property_type(prop) == PROP_POINTER) {
+                       ptype= RNA_property_pointer_type(ptr, prop);
+                       search_id_collection(ptype, &sptr, &searchprop);
+                       searchptr= &sptr;
+               }
+       }
+
+       /* turn button into search button */
+       if(searchprop) {
+               but->type= SEARCH_MENU;
+               but->hardmax= MAX2(but->hardmax, 256);
+               but->rnasearchpoin= *searchptr;
+               but->rnasearchprop= searchprop;
+               but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT;
+
+               uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL);
+       }
+}
+
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname)
+{
+       PropertyRNA *prop, *searchprop;
+       PropertyType type;
+       uiBut *but;
+       uiBlock *block;
+       StructRNA *icontype;
+       int w, h;
+       
+       /* validate arguments */
+       if(!ptr->data || !searchptr->data)
+               return;
+
+       prop= RNA_struct_find_property(ptr, propname);
+
+       if(!prop) {
+               printf("uiItemPointerR: property not found: %s\n", propname);
+               return;
+       }
+       
+       type= RNA_property_type(prop);
+       if(!ELEM(type, PROP_POINTER, PROP_STRING)) {
+               printf("uiItemPointerR: property %s must be a pointer or string.\n", propname);
+               return;
+       }
+
+       searchprop= RNA_struct_find_property(searchptr, searchpropname);
+
+       if(!searchprop || RNA_property_type(searchprop) != PROP_COLLECTION) {
+               printf("uiItemPointerR: search collection property not found: %s\n", searchpropname);
+               return;
+       }
+
+       /* get icon & name */
+       if(!icon) {
+               if(type == PROP_POINTER)
+                       icontype= RNA_property_pointer_type(ptr, prop);
+               else
+                       icontype= RNA_property_pointer_type(searchptr, searchprop);
+
+               icon= RNA_struct_ui_icon(icontype);
+       }
+       if(!name)
+               name= (char*)RNA_property_ui_name(prop);
+
+       /* create button */
+       block= uiLayoutGetBlock(layout);
+
+       ui_item_rna_size(layout, name, icon, prop, 0, &w, &h);
+       but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h);
+
+       ui_but_add_search(but, ptr, prop, searchptr, searchprop);
 }
 
 /* menu item */
@@ -858,7 +1086,7 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun
        uiBlockSetCurLayout(block, layout);
 
        if(layout->root->type == UI_LAYOUT_HEADER)
-               uiBlockSetEmboss(block, UI_EMBOSSP);
+               uiBlockSetEmboss(block, UI_EMBOSS);
 
        if(!name)
                name= "";
@@ -869,7 +1097,7 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun
        h= UI_UNIT_Y;
 
        if(layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */
-               w -= 3;
+               w -= 10;
 
        if(icon)
                but= uiDefIconTextMenuBut(block, func, arg, icon, (char*)name, 0, 0, w, h, "");
@@ -902,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 */
@@ -991,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) {
@@ -1068,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)
@@ -1255,7 +1485,6 @@ static void ui_litem_layout_box(uiLayout *litem)
        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;
@@ -1336,6 +1565,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
                }
        }
 
+       litem->w= x;
        litem->h= litem->y - miny;
 }
 
@@ -1441,9 +1671,9 @@ static void ui_litem_layout_free(uiLayout *litem)
        totw -= minx;
        toth -= miny;
 
-       if(litem->w && totw > litem->w)
+       if(litem->w && totw > 0)
                scalex= (float)litem->w/(float)totw;
-       if(litem->h && toth > litem->h)
+       if(litem->h && toth > 0)
                scaley= (float)litem->h/(float)toth;
        
        x= litem->x;
@@ -1454,15 +1684,15 @@ static void ui_litem_layout_free(uiLayout *litem)
                ui_item_size(item, &itemw, &itemh);
 
                if(scalex != 1.0f) {
-                       newx= itemx*scalex;
-                       itemw= (itemx + itemw)*scalex - newx;
-                       itemx= newx;
+                       newx= (itemx - minx)*scalex;
+                       itemw= (itemx - minx + itemw)*scalex - newx;
+                       itemx= minx + newx;
                }
 
                if(scaley != 1.0f) {
-                       newy= itemy*scaley;
-                       itemh= (itemy + itemh)*scaley - newy;
-                       itemy= newy;
+                       newy= (itemy - miny)*scaley;
+                       itemh= (itemy - miny + itemh)*scaley - newy;
+                       itemy= miny + newy;
                }
 
                ui_item_position(item, x+itemx-minx, y+itemy-miny, itemw, itemh);
@@ -1484,6 +1714,7 @@ static void ui_litem_layout_split(uiLayout *litem)
 {
        uiLayoutItemSplt *split= (uiLayoutItemSplt*)litem;
        uiItem *item;
+       float percentage;
        int itemh, x, y, w, tot=0, colw=0;
 
        x= litem->x;
@@ -1495,8 +1726,10 @@ static void ui_litem_layout_split(uiLayout *litem)
        if(tot == 0)
                return;
        
+       percentage= (split->percentage == 0.0f)? 1.0f/(float)tot: split->percentage;
+       
        w= (litem->w - (tot-1)*litem->space);
-       colw= w*split->percentage;
+       colw= w*percentage;
        colw= MAX2(colw, 0);
 
        for(item=litem->items.first; item; item=item->next) {
@@ -1506,7 +1739,7 @@ static void ui_litem_layout_split(uiLayout *litem)
                x += colw;
 
                if(item->next) {
-                       colw= (w - (w*split->percentage))/(tot-1);
+                       colw= (w - (int)(w*percentage))/(tot-1);
                        colw= MAX2(colw, 0);
 
                        x += litem->space;
@@ -1578,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;
 
@@ -1593,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;
@@ -1637,7 +1886,7 @@ uiLayout *uiLayoutSplit(uiLayout *layout, float percentage)
        split->litem.enabled= 1;
        split->litem.context= layout->context;
        split->litem.space= layout->root->style->columnspace;
-       split->percentage= (percentage == 0.0f)? 0.5f: percentage;
+       split->percentage= percentage;
        BLI_addtail(&layout->items, split);
 
        uiBlockSetCurLayout(layout->root->block, &split->litem);
@@ -1902,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);
 }
 
@@ -1951,6 +2203,12 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout)
        return layout->root->block;
 }
 
+int uiLayoutGetOperatorContext(uiLayout *layout)
+{
+       return layout->root->opcontext;
+}
+
+
 void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout)
 {
        block->curlayout= layout;