diff options
Diffstat (limited to 'source/blender/editors/interface/interface_layout.c')
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 362 |
1 files changed, 296 insertions, 66 deletions
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 723e48e5970..284da29f0d2 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -427,35 +427,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 +485,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 +520,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 +553,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 +566,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 +591,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 +611,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 +634,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 +660,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,14 +718,17 @@ 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) && strcmp(name, "") == 0) + name= "non-empty"; + + 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) @@ -706,6 +744,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 +772,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 +808,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 +853,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,16 +911,158 @@ 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 */ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) { @@ -858,7 +1083,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 +1094,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 +1127,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 +1218,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 +1295,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 +1482,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 +1562,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) } } + litem->w= x; litem->h= litem->y - miny; } @@ -1441,9 +1668,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 +1681,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 +1711,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 +1723,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 +1736,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; @@ -1637,7 +1867,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); |