svn merge -r 21041:21301 https://svn.blender.org/svnroot/bf-blender/branches/blender2...
[blender.git] / source / blender / editors / interface / interface_layout.c
index 9101fd743ee895e184d19cdd35fde750e0ed5294..f9816235b88e993cd866ba0086dc018c37f64d61 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_layout.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -455,9 +455,10 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr,
 }
 
 /* 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;
 
        sub= uiLayoutRow(layout, 0);
@@ -473,12 +474,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 *************************/
@@ -601,7 +603,7 @@ void uiItemsEnumO(uiLayout *layout, char *opname, char *propname)
                RNA_property_enum_items(&ptr, prop, &item, &totitem);
 
                for(i=0; i<totitem; i++)
-                       uiItemEnumO(layout, NULL, 0, opname, propname, item[i].value);
+                       uiItemEnumO(layout, (char*)item[i].name, item[i].icon, opname, propname, item[i].value);
        }
 }
 
@@ -716,6 +718,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;
@@ -745,9 +749,11 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
        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) {
@@ -778,8 +784,10 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
        else if(type == PROP_ENUM && expand)
                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);
@@ -850,6 +858,142 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
        }
 }
 
+/* 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 */
 static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
 {
@@ -1267,7 +1411,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;
@@ -1348,6 +1491,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
                }
        }
 
+       litem->w= x;
        litem->h= litem->y - miny;
 }
 
@@ -1453,9 +1597,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;
@@ -1466,15 +1610,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);