Merge with 2.5 -r 21619:21756.
[blender.git] / source / blender / editors / interface / interface_layout.c
index 56183bfb314c84cf0e796c8e7963ddfc878cf731..07fe2686317d953f4a131739dab79d14fe4717b9 100644 (file)
@@ -51,8 +51,6 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
-#include "BIF_gl.h"
-
 #include "ED_util.h"
 #include "ED_types.h"
 #include "ED_screen.h"
@@ -115,6 +113,7 @@ typedef enum uiItemType {
 typedef struct uiItem {
        void *next, *prev;
        uiItemType type;
+       int flag;
 } uiItem;
 
 typedef struct uiButtonItem {
@@ -126,11 +125,18 @@ struct uiLayout {
        uiItem item;
 
        uiLayoutRoot *root;
+       bContextStore *context;
        ListBase items;
 
        int x, y, w, h;
-       int space;
-       int align;
+       float scale[2];
+       short space;
+       char align;
+       char active;
+       char enabled;
+       char redalert;
+       char keepaspect;
+       char alignment;
 };
 
 typedef struct uiLayoutItemFlow {
@@ -139,16 +145,17 @@ typedef struct uiLayoutItemFlow {
        int totcol;
 } uiLayoutItemFlow;
 
-typedef struct uiLayoutItemSplt {
-       uiLayout litem;
-       int number;
-       int lr;
-} uiLayoutItemSplt;
-
 typedef struct uiLayoutItemBx {
        uiLayout litem;
+       uiBut *roundbox;
+       ListBase items;
 } uiLayoutItemBx;
 
+typedef struct uiLayoutItemSplt {
+       uiLayout litem;
+       float percentage;
+} uiLayoutItemSplt;
+
 typedef struct uiLayoutItemRoot {
        uiLayout litem;
 } uiLayoutItemRoot;
@@ -169,26 +176,29 @@ static char *ui_item_name_add_colon(char *name, char namestr[UI_MAX_NAME_STR])
        return name;
 }
 
-#define UI_FIT_EXPAND 1
-
-static int ui_item_fit(int item, int pos, int all, int available, int spacing, int last, int flag)
+static int ui_item_fit(int item, int pos, int all, int available, int last, int alignment, int *offset)
 {
        /* available == 0 is unlimited */
-
-       if(available != 0 && all > available-spacing) {
+       if(available == 0)
+               return item;
+       
+       if(offset)
+               *offset= 0;
+       
+       if(all > available) {
                /* contents is bigger than available space */
                if(last)
                        return available-pos;
                else
-                       return (item*(available-spacing))/all;
+                       return (item*available)/all;
        }
        else {
                /* contents is smaller or equal to available space */
-               if(available != 0 && (flag & UI_FIT_EXPAND)) {
+               if(alignment == UI_LAYOUT_ALIGN_EXPAND) {
                        if(last)
                                return available-pos;
                        else
-                               return (item*(available-spacing))/all;
+                               return (item*available)/all;
                }
                else
                        return item;
@@ -201,7 +211,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i
 
 static int ui_layout_vary_direction(uiLayout *layout)
 {
-       return (layout->root->type == UI_LAYOUT_HEADER)? UI_ITEM_VARY_X: UI_ITEM_VARY_Y;
+       return (layout->root->type == UI_LAYOUT_HEADER || layout->alignment != UI_LAYOUT_ALIGN_EXPAND)? UI_ITEM_VARY_X: UI_ITEM_VARY_Y;
 }
 
 /* estimated size of text + icon */
@@ -209,12 +219,12 @@ 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) + UI_UNIT_X: 10*UI_UNIT_X; /* icon + text */
+               return (variable)? UI_GetStringWidth(name) + 4 + UI_UNIT_X: 10*UI_UNIT_X; /* icon + text */
        else
-               return (variable)? UI_GetStringWidth(name) + UI_UNIT_X: 10*UI_UNIT_X; /* text only */
+               return (variable)? UI_GetStringWidth(name) + 4 + UI_UNIT_X: 10*UI_UNIT_X; /* text only */
 }
 
 static void ui_item_size(uiItem *item, int *r_w, int *r_h)
@@ -418,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);
@@ -454,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 *************************/
@@ -488,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;
 
@@ -521,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;
 
@@ -534,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 "";
@@ -556,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;
 
@@ -576,14 +612,58 @@ 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);
+       }
+}
+
+/* for use in cases where we have */
+void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value_str)
+{
+       PointerRNA ptr;
+       
+       /* for getting the enum */
+       PropertyRNA *prop;
+       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(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);
+               return;
        }
+       
+       RNA_property_enum_set(&ptr, prop, value);
+       
+       /* same as uiItemEnumO */
+       if(!name)
+               name= ui_menu_enumpropname(layout, opname, propname, value);
+
+       uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext);
 }
 
 void uiItemBooleanO(uiLayout *layout, char *name, int icon, char *opname, char *propname, int value)
@@ -639,20 +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(type == PROP_STRING)
-               w += 10*UI_UNIT_X;
+       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)
@@ -665,13 +747,15 @@ 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;
        *r_h= h;
 }
 
-void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int expand, int slider)
+void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int expand, int slider, int toggle)
 {
        uiBlock *block= layout->root->block;
        uiBut *but;
@@ -691,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);
-       if(type == PROP_BOOLEAN && len)
+       else if(type == PROP_BOOLEAN && len)
+               name= ui_item_name_add_colon(name, namestr);
+       else if(type == PROP_ENUM && index != RNA_ENUM_VALUE)
                name= ui_item_name_add_colon(name, namestr);
 
        if(layout->root->type == UI_LAYOUT_MENU) {
@@ -723,20 +811,25 @@ 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);
 
                if(slider && but->type==NUM)
                        but->type= NUMSLI;
+
+               if(toggle && but->type==OPTION)
+                       but->type= TOG;
        }
 }
 
-void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider)
+void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle)
 {
        PropertyRNA *prop;
 
@@ -751,7 +844,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop
                return;
        }
 
-       uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand, slider);
+       uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand, slider, toggle);
 }
 
 void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value)
@@ -763,13 +856,50 @@ 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);
+       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)
@@ -784,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 */
@@ -814,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= "";
@@ -825,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, "");
@@ -839,6 +1111,8 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun
 
        if(layout->root->type == UI_LAYOUT_HEADER)
                uiBlockSetEmboss(block, UI_EMBOSS);
+       else if(layout->root->type == UI_LAYOUT_PANEL)
+               but->type= MENU;
 }
 
 void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname)
@@ -856,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 */
@@ -939,13 +1215,13 @@ static void menu_item_enum_opname_menu(bContext *C, uiLayout *layout, void *arg)
 {
        MenuItemLevel *lvl= (MenuItemLevel*)(((uiBut*)arg)->func_argN);
 
-       uiLayoutContext(layout, WM_OP_EXEC_REGION_WIN);
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
        uiItemsEnumO(layout, lvl->opname, lvl->propname);
 }
 
 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) {
@@ -970,7 +1246,7 @@ static void menu_item_enum_rna_menu(bContext *C, uiLayout *layout, void *arg)
 {
        MenuItemLevel *lvl= (MenuItemLevel*)(((uiBut*)arg)->func_argN);
 
-       uiLayoutContext(layout, lvl->opcontext);
+       uiLayoutSetOperatorContext(layout, lvl->opcontext);
        uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname);
 }
 
@@ -1020,14 +1296,22 @@ static void ui_litem_estimate_row(uiLayout *litem)
        }
 }
 
+static int ui_litem_min_width(int itemw)
+{
+       return MIN2(2*UI_UNIT_X, itemw);
+}
+
 static void ui_litem_layout_row(uiLayout *litem)
 {
        uiItem *item;
-       int neww, itemw, itemh, x, y, w, tot= 0, totw= 0, extra=0, available=0;
+       int x, y, w, tot, totw, neww, itemw, minw, itemh, offset;
+       int fixedw, freew, fixedx, freex, flag= 0, lastw= 0;
 
        x= litem->x;
        y= litem->y;
        w= litem->w;
+       totw= 0;
+       tot= 0;
 
        for(item=litem->items.first; item; item=item->next) {
                ui_item_size(item, &itemw, &itemh);
@@ -1038,40 +1322,81 @@ static void ui_litem_layout_row(uiLayout *litem)
        if(totw == 0)
                return;
        
-       /* two step to enforce minimum button with .. could be better */
-       for(item=litem->items.first; item; item=item->next) {
-               ui_item_size(item, &itemw, &itemh);
+       if(w != 0)
+               w -= (tot-1)*litem->space;
+       fixedw= 0;
 
-               itemw= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND);
-               x += itemw;
+       /* keep clamping items to fixed minimum size until all are done */
+       do {
+               freew= 0;
+               x= 0;
+               flag= 0;
 
-               if(itemw < UI_UNIT_X)
-                       extra += UI_UNIT_X - itemw;
-               else
-                       available += itemw - UI_UNIT_X;
+               for(item=litem->items.first; item; item=item->next) {
+                       if(item->flag)
+                               continue;
 
-               if(item->next)
-                       x += litem->space;
-       }
+                       ui_item_size(item, &itemw, &itemh);
+                       minw= ui_litem_min_width(itemw);
+
+                       if(w - lastw > 0)
+                               neww= ui_item_fit(itemw, x, totw, w-lastw, !item->next, litem->alignment, NULL);
+                       else
+                               neww= 0; /* no space left, all will need clamping to minimum size */
 
+                       x += neww;
+
+                       if((neww < minw || itemw == minw) && w != 0) {
+                               /* fixed size */
+                               item->flag= 1;
+                               fixedw += minw;
+                               flag= 1;
+                               totw -= itemw;
+                       }
+                       else {
+                               /* keep free size */
+                               item->flag= 0;
+                               freew += itemw;
+                       }
+               }
+
+               lastw= fixedw;
+       } while(flag);
+
+       freex= 0;
+       fixedx= 0;
        x= litem->x;
 
        for(item=litem->items.first; item; item=item->next) {
                ui_item_size(item, &itemw, &itemh);
+               minw= ui_litem_min_width(itemw);
 
-               neww= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND);
-               if(neww < UI_UNIT_X) {
-                       if(item->next)
-                               itemw= UI_UNIT_X;
-                       else
-                               itemw= litem->w - (x-litem->x);
+               if(item->flag) {
+                       /* fixed minimum size items */
+                       itemw= ui_item_fit(minw, fixedx, fixedw, MIN2(w, fixedw), !item->next, litem->alignment, NULL);
+                       fixedx += itemw;
+               }
+               else {
+                       /* free size item */
+                       itemw= ui_item_fit(itemw, freex, freew, w-fixedw, !item->next, litem->alignment, NULL);
+                       freex += itemw;
                }
-               else
-                       itemw= ui_item_fit(itemw, x-litem->x, totw, w-extra, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND);
 
-               ui_item_position(item, x, y-itemh, itemw, itemh);
-               x += itemw;
+               /* align right/center */
+               offset= 0;
+               if(litem->alignment == UI_LAYOUT_ALIGN_RIGHT) {
+                       if(fixedw == 0 && freew < w-fixedw)
+                               offset= (w - fixedw) - freew;
+               }
+               else if(litem->alignment == UI_LAYOUT_ALIGN_CENTER) {
+                       if(fixedw == 0 && freew < w-fixedw)
+                               offset= ((w - fixedw) - freew)/2;
+               }
 
+               /* position item */
+               ui_item_position(item, x+offset, y-itemh, itemw, itemh);
+
+               x += itemw;
                if(item->next)
                        x += litem->space;
        }
@@ -1146,19 +1471,20 @@ static void ui_litem_estimate_box(uiLayout *litem)
 
        ui_litem_estimate_column(litem);
        litem->w += 2*style->boxspace;
-       litem->h += 2*style->boxspace;
+       litem->h += style->boxspace;
 }
 
 static void ui_litem_layout_box(uiLayout *litem)
 {
+       uiLayoutItemBx *box= (uiLayoutItemBx*)litem;
        uiStyle *style= litem->root->style;
+       uiBut *but;
        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;
@@ -1169,10 +1495,14 @@ static void ui_litem_layout_box(uiLayout *litem)
        litem->y -= style->boxspace;
 
        if(w != 0) litem->w += 2*style->boxspace;
-       if(h != 0) litem->h += 2*style->boxspace;
+       if(h != 0) litem->h += style->boxspace;
 
        /* roundbox around the sublayout */
-       uiDefBut(litem->root->block, ROUNDBOX, 0, "", litem->x, litem->y, litem->w, litem->h, NULL, 7.0, 0.0, 3, 20, "");
+       but= box->roundbox;
+       but->x1= litem->x;
+       but->y1= litem->y;
+       but->x2= litem->x+litem->w;
+       but->y2= litem->y+litem->h;
 }
 
 /* multi-column layout, automatically flowing to the next */
@@ -1235,6 +1565,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
                }
        }
 
+       litem->w= x;
        litem->h= litem->y - miny;
 }
 
@@ -1244,7 +1575,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
        uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem;
        uiItem *item;
        int col, x, y, w, emh, emy, miny, itemw, itemh;
-       int toth, totitem;
+       int toth, totitem, offset;
 
        /* compute max needed width and total height */
        toth= 0;
@@ -1261,18 +1592,18 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
        emy= 0;
        miny= 0;
 
-       w= litem->w;
+       w= litem->w - (flow->totcol-1)*style->columnspace;
        emh= toth/flow->totcol;
 
        /* create column per column */
        col= 0;
        for(item=litem->items.first; item; item=item->next) {
                ui_item_size(item, NULL, &itemh);
-               itemw= ui_item_fit(1, x-litem->x, flow->totcol, w, (flow->totcol-1)*style->columnspace, col == flow->totcol-1, UI_FIT_EXPAND);
+               itemw= ui_item_fit(1, x-litem->x, flow->totcol, w, col == flow->totcol-1, litem->alignment, &offset);
        
                y -= itemh;
                emy -= itemh;
-               ui_item_position(item, x, y, itemw, itemh);
+               ui_item_position(item, x+offset, y, itemw, itemh);
                y -= style->buttonspacey;
                miny= MIN2(miny, y);
 
@@ -1340,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;
@@ -1353,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);
@@ -1381,12 +1712,13 @@ static void ui_litem_estimate_split(uiLayout *litem)
 
 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;
        y= litem->y;
-       w= litem->w;
 
        for(item=litem->items.first; item; item=item->next)
                tot++;
@@ -1394,7 +1726,10 @@ static void ui_litem_layout_split(uiLayout *litem)
        if(tot == 0)
                return;
        
-       colw= (litem->w - (tot-1)*litem->space)/tot;
+       percentage= (split->percentage == 0.0f)? 1.0f/(float)tot: split->percentage;
+       
+       w= (litem->w - (tot-1)*litem->space);
+       colw= w*percentage;
        colw= MAX2(colw, 0);
 
        for(item=litem->items.first; item; item=item->next) {
@@ -1403,8 +1738,12 @@ static void ui_litem_layout_split(uiLayout *litem)
                ui_item_position(item, x, y-itemh, colw, itemh);
                x += colw;
 
-               if(item->next)
+               if(item->next) {
+                       colw= (w - (int)(w*percentage))/(tot-1);
+                       colw= MAX2(colw, 0);
+
                        x += litem->space;
+               }
        }
 
        litem->w= x - litem->x;
@@ -1422,6 +1761,9 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align)
        litem->item.type= ITEM_LAYOUT_ROW;
        litem->root= layout->root;
        litem->align= align;
+       litem->active= 1;
+       litem->enabled= 1;
+       litem->context= layout->context;
        litem->space= (align)? 0: layout->root->style->buttonspacex;
        BLI_addtail(&layout->items, litem);
 
@@ -1438,6 +1780,9 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align)
        litem->item.type= ITEM_LAYOUT_COLUMN;
        litem->root= layout->root;
        litem->align= align;
+       litem->active= 1;
+       litem->enabled= 1;
+       litem->context= layout->context;
        litem->space= (litem->align)? 0: layout->root->style->buttonspacey;
        BLI_addtail(&layout->items, litem);
 
@@ -1454,6 +1799,9 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
        flow->litem.item.type= ITEM_LAYOUT_COLUMN_FLOW;
        flow->litem.root= layout->root;
        flow->litem.align= align;
+       flow->litem.active= 1;
+       flow->litem.enabled= 1;
+       flow->litem.context= layout->context;
        flow->litem.space= (flow->litem.align)? 0: layout->root->style->columnspace;
        flow->number= number;
        BLI_addtail(&layout->items, flow);
@@ -1463,21 +1811,42 @@ 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;
 
        box= MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx");
        box->litem.item.type= ITEM_LAYOUT_BOX;
        box->litem.root= layout->root;
+       box->litem.active= 1;
+       box->litem.enabled= 1;
+       box->litem.context= layout->context;
        box->litem.space= layout->root->style->columnspace;
        BLI_addtail(&layout->items, box);
 
        uiBlockSetCurLayout(layout->root->block, &box->litem);
 
+       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;
@@ -1486,6 +1855,9 @@ uiLayout *uiLayoutFree(uiLayout *layout, int align)
        litem->item.type= ITEM_LAYOUT_FREE;
        litem->root= layout->root;
        litem->align= align;
+       litem->active= 1;
+       litem->enabled= 1;
+       litem->context= layout->context;
        BLI_addtail(&layout->items, litem);
 
        uiBlockSetCurLayout(layout->root->block, litem);
@@ -1497,28 +1869,126 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout)
 {
        uiBlock *block;
 
-       block= uiLayoutBlock(layout);
+       block= uiLayoutGetBlock(layout);
        uiLayoutFree(layout, 0);
 
        return block;
 }
 
-uiLayout *uiLayoutSplit(uiLayout *layout)
+uiLayout *uiLayoutSplit(uiLayout *layout, float percentage)
 {
-       uiLayout *litem;
+       uiLayoutItemSplt *split;
 
-       litem= uiLayoutRow(layout, 0);
-       litem->item.type = ITEM_LAYOUT_SPLIT;
-       litem->root= layout->root;
-       litem->space= layout->root->style->columnspace;
+       split= MEM_callocN(sizeof(uiLayoutItemSplt), "uiLayoutItemSplt");
+       split->litem.item.type= ITEM_LAYOUT_SPLIT;
+       split->litem.root= layout->root;
+       split->litem.active= 1;
+       split->litem.enabled= 1;
+       split->litem.context= layout->context;
+       split->litem.space= layout->root->style->columnspace;
+       split->percentage= percentage;
+       BLI_addtail(&layout->items, split);
 
-       uiBlockSetCurLayout(layout->root->block, litem);
+       uiBlockSetCurLayout(layout->root->block, &split->litem);
 
-       return litem;
+       return &split->litem;
+}
+
+void uiLayoutSetActive(uiLayout *layout, int active)
+{
+       layout->active= active;
+}
+
+void uiLayoutSetEnabled(uiLayout *layout, int enabled)
+{
+       layout->enabled= enabled;
+}
+
+void uiLayoutSetRedAlert(uiLayout *layout, int redalert)
+{
+       layout->redalert= redalert;
+}
+
+void uiLayoutSetKeepAspect(uiLayout *layout, int keepaspect)
+{
+       layout->keepaspect= keepaspect;
+}
+
+void uiLayoutSetAlignment(uiLayout *layout, int alignment)
+{
+       layout->alignment= alignment;
+}
+
+void uiLayoutSetScaleX(uiLayout *layout, float scale)
+{
+       layout->scale[0]= scale;
+}
+
+void uiLayoutSetScaleY(uiLayout *layout, float scale)
+{
+       layout->scale[1]= scale;
+}
+
+int uiLayoutGetActive(uiLayout *layout)
+{
+       return layout->active;
+}
+
+int uiLayoutGetEnabled(uiLayout *layout)
+{
+       return layout->enabled;
+}
+
+int uiLayoutGetRedAlert(uiLayout *layout)
+{
+       return layout->redalert;
+}
+
+int uiLayoutGetKeepAspect(uiLayout *layout)
+{
+       return layout->keepaspect;
+}
+
+int uiLayoutGetAlignment(uiLayout *layout)
+{
+       return layout->alignment;
+}
+
+float uiLayoutGetScaleX(uiLayout *layout)
+{
+       return layout->scale[0];
+}
+
+float uiLayoutGetScaleY(uiLayout *layout)
+{
+       return layout->scale[0];
 }
 
 /********************** Layout *******************/
 
+static void ui_item_scale(uiLayout *litem, float scale[2])
+{
+       uiItem *item;
+       int x, y, w, h;
+
+       for(item=litem->items.last; item; item=item->prev) {
+               ui_item_size(item, &w, &h);
+               ui_item_offset(item, &x, &y);
+
+               if(scale[0] != 0.0f) {
+                       x *= scale[0];
+                       w *= scale[0];
+               }
+
+               if(scale[1] != 0.0f) {
+                       y *= scale[1];
+                       h *= scale[1];
+               }
+
+               ui_item_position(item, x, y, w, h);
+       }
+}
+
 static void ui_item_estimate(uiItem *item)
 {
        uiItem *subitem;
@@ -1532,6 +2002,9 @@ static void ui_item_estimate(uiItem *item)
                if(litem->items.first == NULL)
                        return;
 
+               if(litem->scale[0] != 0.0f || litem->scale[1] != 0.0f)
+                       ui_item_scale(litem, litem->scale);
+
                switch(litem->item.type) {
                        case ITEM_LAYOUT_COLUMN:
                                ui_litem_estimate_column(litem);
@@ -1564,19 +2037,43 @@ static void ui_item_align(uiLayout *litem, int nr)
 {
        uiItem *item;
        uiButtonItem *bitem;
+       uiLayoutItemBx *box;
 
-       for(item=litem->items.first; item; item=item->next) {
+       for(item=litem->items.last; item; item=item->prev) {
                if(item->type == ITEM_BUTTON) {
                        bitem= (uiButtonItem*)item;
                        if(ui_but_can_align(bitem->but))
-                               bitem->but->alignnr= nr;
+                               if(!bitem->but->alignnr)
+                                       bitem->but->alignnr= nr;
+               }
+               else if(item->type == ITEM_LAYOUT_FREE);
+               else if(item->type == ITEM_LAYOUT_BOX) {
+                       box= (uiLayoutItemBx*)item;
+                       box->roundbox->alignnr= nr;
+                       BLI_remlink(&litem->root->block->buttons, box->roundbox);
+                       BLI_addhead(&litem->root->block->buttons, box->roundbox);
                }
                else
                        ui_item_align((uiLayout*)item, nr);
        }
 }
 
-static void ui_item_layout(uiItem *item, int align)
+static void ui_item_flag(uiLayout *litem, int flag)
+{
+       uiItem *item;
+       uiButtonItem *bitem;
+
+       for(item=litem->items.last; item; item=item->prev) {
+               if(item->type == ITEM_BUTTON) {
+                       bitem= (uiButtonItem*)item;
+                       bitem->but->flag |= flag;
+               }
+               else
+                       ui_item_flag((uiLayout*)item, flag);
+       }
+}
+
+static void ui_item_layout(uiItem *item)
 {
        uiItem *subitem;
 
@@ -1586,8 +2083,12 @@ static void ui_item_layout(uiItem *item, int align)
                if(litem->items.first == NULL)
                        return;
 
-               if(litem->align && !align)
+               if(litem->align)
                        ui_item_align(litem, ++litem->root->block->alignnr);
+               if(!litem->active)
+                       ui_item_flag(litem, UI_BUT_INACTIVE);
+               if(!litem->enabled)
+                       ui_item_flag(litem, UI_BUT_DISABLED);
 
                switch(litem->item.type) {
                        case ITEM_LAYOUT_COLUMN:
@@ -1616,14 +2117,14 @@ static void ui_item_layout(uiItem *item, int align)
                }
 
                for(subitem=litem->items.first; subitem; subitem=subitem->next)
-                       ui_item_layout(subitem, litem->align || align);
+                       ui_item_layout(subitem);
        }
 }
 
 static void ui_layout_items(const bContext *C, uiBlock *block, uiLayout *layout)
 {
        ui_item_estimate(&layout->item);
-       ui_item_layout(&layout->item, 0);
+       ui_item_layout(&layout->item);
 }
 
 static void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
@@ -1650,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);
 }
 
@@ -1671,6 +2175,9 @@ uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int siz
        layout->y= y;
        layout->root= root;
        layout->space= style->templatespace;
+       layout->active= 1;
+       layout->enabled= 1;
+       layout->context= NULL;
 
        if(type == UI_LAYOUT_MENU)
                layout->space= 0;
@@ -1691,11 +2198,17 @@ uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int siz
        return layout;
 }
 
-uiBlock *uiLayoutBlock(uiLayout *layout)
+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;
@@ -1709,14 +2222,19 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
        bitem->item.type= ITEM_BUTTON;
        bitem->but= but;
        BLI_addtail(&layout->items, bitem);
+
+       if(layout->context) {
+               but->context= layout->context;
+               but->context->used= 1;
+       }
 }
 
-void uiLayoutContext(uiLayout *layout, int opcontext)
+void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
 {
        layout->root->opcontext= opcontext;
 }
 
-void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
+void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
 {
        layout->root->handlefunc= handlefunc;
        layout->root->argv= argv;
@@ -1747,8 +2265,9 @@ void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y)
        }
 }
 
-float uiBlockAspect(uiBlock *block)
+void uiLayoutSetContextPointer(uiLayout *layout, char *name, PointerRNA *ptr)
 {
-       return block->aspect; /* temporary */
+       uiBlock *block= layout->root->block;
+       layout->context= CTX_store_add(&block->contexts, name, ptr);
 }