diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-22 22:39:44 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-22 22:39:44 +0400 |
commit | af02a0aa4e0b80c3c1154e7be095f4a387f81179 (patch) | |
tree | 3f714e683c96929cc4e44962570860ab0f635bc9 /source/blender/editors/interface | |
parent | 643d59bb9bf3bdd46f41a0b8c79384146629f9c8 (diff) |
UI
* Headers and menus can now be created in python.
* Replaced the uiMenuItem functions to create menus with equivalent
uiItem functions using a layout, removing duplicated code.
* More uiItem functions are now exposed to python.
* The text editor header, panels and one of its menus are now created
in space_text.py.
* Buttons window data context icon new changes depending on active
object.
Issues
* Icons are not wrapped yet, hardcoded ints at the moment.
* The ID browse template is unfinished.
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r-- | source/blender/editors/interface/interface_anim.c | 32 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_api.c | 99 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 818 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 449 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_utils.c | 17 |
5 files changed, 822 insertions, 593 deletions
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 6775a639597..af8aa91f358 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -114,44 +114,46 @@ void ui_but_anim_remove_driver(bContext *C) // TODO: refine the logic for adding/removing drivers... void ui_but_anim_menu(bContext *C, uiBut *but) { - uiMenuItem *head; + uiPopupMenu *pup; + uiLayout *layout; int length; if(but->rnapoin.data && but->rnaprop) { - head= uiPupMenuBegin(RNA_property_ui_name(but->rnaprop), 0); + pup= uiPupMenuBegin(RNA_property_ui_name(but->rnaprop), 0); + layout= uiPupMenuLayout(pup); length= RNA_property_array_length(but->rnaprop); if(but->flag & UI_BUT_ANIMATED_KEY) { if(length) { - uiMenuItemBooleanO(head, "Delete Keyframes", 0, "ANIM_OT_delete_keyframe_button", "all", 1); - uiMenuItemBooleanO(head, "Delete Single Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0); + uiItemBooleanO(layout, "Delete Keyframes", 0, "ANIM_OT_delete_keyframe_button", "all", 1); + uiItemBooleanO(layout, "Delete Single Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0); - uiMenuItemBooleanO(head, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 1); - uiMenuItemBooleanO(head, "Remove Single Driver", 0, "ANIM_OT_remove_driver_button", "all", 0); + uiItemBooleanO(layout, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 1); + uiItemBooleanO(layout, "Remove Single Driver", 0, "ANIM_OT_remove_driver_button", "all", 0); } else { - uiMenuItemBooleanO(head, "Delete Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0); + uiItemBooleanO(layout, "Delete Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0); - uiMenuItemBooleanO(head, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 0); + uiItemBooleanO(layout, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 0); } } else if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) { if(length) { - uiMenuItemBooleanO(head, "Insert Keyframes", 0, "ANIM_OT_insert_keyframe_button", "all", 1); - uiMenuItemBooleanO(head, "Insert Single Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0); + uiItemBooleanO(layout, "Insert Keyframes", 0, "ANIM_OT_insert_keyframe_button", "all", 1); + uiItemBooleanO(layout, "Insert Single Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0); - uiMenuItemBooleanO(head, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 1); - uiMenuItemBooleanO(head, "Add Single Driver", 0, "ANIM_OT_add_driver_button", "all", 0); + uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 1); + uiItemBooleanO(layout, "Add Single Driver", 0, "ANIM_OT_add_driver_button", "all", 0); } else { - uiMenuItemBooleanO(head, "Insert Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0); + uiItemBooleanO(layout, "Insert Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0); - uiMenuItemBooleanO(head, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0); + uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0); } } - uiPupMenuEnd(C, head); + uiPupMenuEnd(C, pup); } } diff --git a/source/blender/editors/interface/interface_api.c b/source/blender/editors/interface/interface_api.c index a184655df83..3153f13bd0b 100644 --- a/source/blender/editors/interface/interface_api.c +++ b/source/blender/editors/interface/interface_api.c @@ -40,6 +40,15 @@ static void api_ui_item_common(FunctionRNA *func) RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Override automatic icon of the item.", 0, INT_MAX); } +static void api_ui_item_op_common(FunctionRNA *func) +{ + PropertyRNA *parm; + + api_ui_item_common(func); + parm= RNA_def_string(func, "operator", "", 0, "", "Identifier of the operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); +} + void RNA_api_ui_layout(StructRNA *srna) { FunctionRNA *func; @@ -68,9 +77,6 @@ void RNA_api_ui_layout(StructRNA *srna) parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); RNA_def_function_return(func, parm); - func= RNA_def_function(srna, "template_header_menus", "uiTemplateHeaderMenus"); - //func= RNA_def_function(srna, "template_header_ID", "uiTemplateHeaderID"); - /* items */ func= RNA_def_function(srna, "itemR", "uiItemR"); api_ui_item_common(func); @@ -80,12 +86,97 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); - func= RNA_def_function(srna, "itemO", "uiItemO"); + func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_level_enumR", "uiItemLevelEnumR"); + api_ui_item_common(func); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /*func= RNA_def_function(srna, "item_enumR", "uiItemEnumR"); api_ui_item_common(func); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "value", "", 0, "", "Enum property value."); + RNA_def_property_flag(parm, PROP_REQUIRED);*/ + + func= RNA_def_function(srna, "itemO", "uiItemO"); + api_ui_item_op_common(func); + + /*func= RNA_def_function(srna, "item_enumO", "uiItemEnumO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "value", "", 0, "", "Enum property value."); + RNA_def_property_flag(parm, PROP_REQUIRED);*/ + + func= RNA_def_function(srna, "items_enumO", "uiItemsEnumO"); parm= RNA_def_string(func, "operator", "", 0, "", "Identifier of the operator."); RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_level_enumO", "uiItemLevelEnumO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_booleanO", "uiItemBooleanO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_boolean(func, "value", 0, "", "Value of the property to call the operator with."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_intO", "uiItemIntO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_int(func, "value", 0, INT_MIN, INT_MAX, "", "Value of the property to call the operator with.", INT_MIN, INT_MAX); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_floatO", "uiItemFloatO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_float(func, "value", 0, -FLT_MAX, FLT_MAX, "", "Value of the property to call the operator with.", -FLT_MAX, FLT_MAX); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_stringO", "uiItemStringO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "value", "", 0, "", "Value of the property to call the operator with."); + RNA_def_property_flag(parm, PROP_REQUIRED); func= RNA_def_function(srna, "itemL", "uiItemL"); api_ui_item_common(func); + + func= RNA_def_function(srna, "itemM", "uiItemM"); + api_ui_item_common(func); + parm= RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "itemS", "uiItemS"); + + /* templates */ + func= RNA_def_function(srna, "template_header", "uiTemplateHeader"); + + func= RNA_def_function(srna, "template_header_ID", "uiTemplateHeaderID"); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of pointer property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block."); + RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a new ID block."); + RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block."); } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index e0059041774..56acd755205 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -12,10 +12,12 @@ #include "DNA_windowmanager_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_idprop.h" +#include "BKE_library.h" #include "BKE_screen.h" #include "BKE_utildefines.h" @@ -38,16 +40,12 @@ /************************ Structs and Defines *************************/ -#define COLUMN_SPACE 5 -#define TEMPLATE_SPACE 5 -#define BOX_SPACE 5 -#define BUTTON_SPACE_X 5 -#define BUTTON_SPACE_Y 2 - #define RNA_NO_INDEX -1 +#define RNA_ENUM_VALUE -2 #define EM_UNIT_X XIC #define EM_UNIT_Y YIC +#define EM_SEPR_Y 6 /* Item */ @@ -55,7 +53,9 @@ typedef enum uiItemType { ITEM_OPERATOR, ITEM_RNA_PROPERTY, ITEM_MENU, - ITEM_LABEL + ITEM_LABEL, + ITEM_VALUE, + ITEM_SEPARATOR } uiItemType; enum uiItemFlag { @@ -69,7 +69,9 @@ typedef struct uiItem { int slot; char *name; + char namestr[UI_MAX_NAME_STR]; int icon; + int disabled; } uiItem; typedef struct uiItemRNA { @@ -77,7 +79,7 @@ typedef struct uiItemRNA { PointerRNA ptr; PropertyRNA *prop; - int index; + int index, value; int expand; } uiItemRNA; @@ -89,11 +91,19 @@ typedef struct uiItemOp { int context; } uiItemOp; -typedef struct uiItemLMenu { +typedef struct uiItemMenu { uiItem item; + char *menuname; uiMenuCreateFunc func; -} uiItemLMenu; + void *arg, *argN; +} uiItemMenu; + +typedef struct uiItemValue { + uiItem item; + + int argval; +} uiItemValue; /* Template */ @@ -104,8 +114,7 @@ typedef enum uiTemplateType { TEMPLATE_SPLIT, TEMPLATE_BOX, - TEMPLATE_HEADER_MENUS, - TEMPLATE_HEADER_BUTTONS, + TEMPLATE_HEADER, TEMPLATE_HEADER_ID } uiTemplateType; @@ -114,7 +123,7 @@ typedef struct uiTemplate { uiTemplateType type; ListBase items; - int color, slot; + int slot; } uiTemplate; typedef struct uiTemplateFlow { @@ -138,9 +147,13 @@ typedef struct uiTemplateHeadID { uiTemplate template; PointerRNA ptr; - char *propname; + PropertyRNA *prop; + int flag; - uiIDPoinFunc func; + short browse; + char *newop; + char *openop; + char *unlinkop; } uiTemplateHeadID; /* Layout */ @@ -148,9 +161,18 @@ typedef struct uiTemplateHeadID { struct uiLayout { ListBase templates; int opcontext; - int dir; + int dir, type; int x, y, w, h; int emw, emh; + + int column_space; + int template_space; + int box_space; + int button_space_x; + int button_space_y; + + uiMenuHandleFunc handlefunc; + void *argv; }; void ui_layout_free(uiLayout *layout); @@ -158,6 +180,14 @@ void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, /************************** Item ***************************/ +static void ui_item_name(uiItem *item, char *name) +{ + if(!item->name && name) { + BLI_strncpy(item->namestr, name, sizeof(item->namestr)); + item->name= item->namestr; + } +} + #define UI_FIT_EXPAND 1 static int ui_item_fit(int item, int pos, int all, int available, int spacing, int last, int flag) @@ -183,11 +213,10 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i } /* create buttons for an item with an RNA array */ -static void ui_item_array(uiBlock *block, uiItemRNA *rnaitem, int len, int x, int y, int w, int h) +static void ui_item_array(uiLayout *layout, uiBlock *block, uiItemRNA *rnaitem, int len, int x, int y, int w, int h) { PropertyType type; PropertySubType subtype; - char *name; int a; /* retrieve type and subtype */ @@ -195,13 +224,8 @@ static void ui_item_array(uiBlock *block, uiItemRNA *rnaitem, int len, int x, in subtype= RNA_property_subtype(rnaitem->prop); /* create label */ - if(rnaitem->item.name) - name= (char*)rnaitem->item.name; - else - name= (char*)RNA_property_ui_name(rnaitem->prop); - - if(strcmp(name, "") != 0) - uiDefBut(block, LABEL, 0, name, x, y + h - EM_UNIT_Y, w, EM_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + if(strcmp(rnaitem->item.name, "") != 0) + uiDefBut(block, LABEL, 0, rnaitem->item.name, x, y + h - EM_UNIT_Y, w, EM_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* create buttons */ uiBlockBeginAlign(block); @@ -210,7 +234,7 @@ static void ui_item_array(uiBlock *block, uiItemRNA *rnaitem, int len, int x, in /* special check for layer layout */ int butw, buth; - butw= ui_item_fit(EM_UNIT_X, 0, EM_UNIT_X*10 + BUTTON_SPACE_X, w, 0, 0, UI_FIT_EXPAND); + butw= ui_item_fit(EM_UNIT_X, 0, EM_UNIT_X*10 + layout->button_space_x, w, 0, 0, UI_FIT_EXPAND); buth= MIN2(EM_UNIT_Y, butw); y += 2*(EM_UNIT_Y - buth); @@ -222,7 +246,7 @@ static void ui_item_array(uiBlock *block, uiItemRNA *rnaitem, int len, int x, in uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth); uiBlockEndAlign(block); - x += 5*butw + BUTTON_SPACE_X; + x += 5*butw + layout->button_space_x; uiBlockBeginAlign(block); for(a=0; a<5; a++) @@ -305,16 +329,9 @@ static void ui_item_enum_row(uiBlock *block, uiItemRNA *rnaitem, int x, int y, i /* create label + button for RNA property */ static void ui_item_with_label(uiBlock *block, uiItemRNA *rnaitem, int x, int y, int w, int h) { - char *name; - - if(rnaitem->item.name) - name= (char*)rnaitem->item.name; - else - name= (char*)RNA_property_ui_name(rnaitem->prop); - - if(strcmp(name, "") != 0) { + if(strcmp(rnaitem->item.name, "") != 0) { w= w/2; - uiDefBut(block, LABEL, 0, name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, rnaitem->item.name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); x += w; } @@ -322,7 +339,7 @@ static void ui_item_with_label(uiBlock *block, uiItemRNA *rnaitem, int x, int y, } /* create buttons for an arbitrary item */ -static void ui_item_buts(uiBlock *block, uiItem *item, int x, int y, int w, int h) +static void ui_item_buts(uiLayout *layout, uiBlock *block, uiItem *item, int x, int y, int w, int h) { if(item->type == ITEM_RNA_PROPERTY) { /* RNA property */ @@ -336,7 +353,18 @@ static void ui_item_buts(uiBlock *block, uiItem *item, int x, int y, int w, int /* array property */ if(rnaitem->index == RNA_NO_INDEX && len > 0) - ui_item_array(block, rnaitem, len, x, y, w, h); + ui_item_array(layout, block, rnaitem, len, x, y, w, h); + /* enum item */ + else if(type == PROP_ENUM && rnaitem->index == RNA_ENUM_VALUE) { + char *identifier= (char*)RNA_property_identifier(rnaitem->prop); + + if(item->icon && strcmp(item->name, "") != 0) + uiDefIconTextButR(block, ROW, 0, item->icon, item->name, x, y, w, h, &rnaitem->ptr, identifier, -1, 0, rnaitem->value, -1, -1, NULL); + else if(item->icon) + uiDefIconButR(block, ROW, 0, item->icon, x, y, w, h, &rnaitem->ptr, identifier, -1, 0, rnaitem->value, -1, -1, NULL); + else + uiDefButR(block, ROW, 0, item->name, x, y, w, h, &rnaitem->ptr, identifier, -1, 0, rnaitem->value, -1, -1, NULL); + } /* expanded enum */ else if(type == PROP_ENUM && rnaitem->expand) ui_item_enum_row(block, rnaitem, x, y, w, h); @@ -352,7 +380,7 @@ static void ui_item_buts(uiBlock *block, uiItem *item, int x, int y, int w, int uiItemOp *opitem= (uiItemOp*)item; uiBut *but; - if(item->icon && item->name) + if(item->icon && strcmp(item->name, "") != 0) but= uiDefIconTextButO(block, BUT, opitem->ot->idname, opitem->context, item->icon, (char*)item->name, x, y, w, h, NULL); else if(item->icon) but= uiDefIconButO(block, BUT, opitem->ot->idname, opitem->context, item->icon, x, y, w, h, NULL); @@ -369,19 +397,53 @@ static void ui_item_buts(uiBlock *block, uiItem *item, int x, int y, int w, int } else if(item->type == ITEM_MENU) { /* menu */ - uiItemLMenu *menuitem= (uiItemLMenu*)item; + uiBut *but; + uiItemMenu *menuitem= (uiItemMenu*)item; - uiDefMenuBut(block, menuitem->func, NULL, (char*)item->name, x, y-2, w-3, h+4, ""); + if(layout->type == UI_LAYOUT_HEADER) { /* ugly .. */ + y -= 2; + w -= 3; + h += 4; + } + + if(item->icon) + but= uiDefIconTextMenuBut(block, menuitem->func, menuitem->arg, item->icon, (char*)item->name, x, y, w, h, ""); + else + but= uiDefMenuBut(block, menuitem->func, menuitem->arg, (char*)item->name, x, y, w, h, ""); + + if(menuitem->argN) { /* ugly .. */ + but->poin= (char*)but; + but->func_argN= menuitem->argN; + } } else if(item->type == ITEM_LABEL) { /* label */ + uiBut *but; - if(item->icon && item->name) - uiDefIconTextBut(block, LABEL, 0, item->icon, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); + if(item->icon && strcmp(item->name, "") != 0) + but= uiDefIconTextBut(block, LABEL, 0, item->icon, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); else if(item->icon) - uiDefIconBut(block, LABEL, 0, item->icon, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); - else if((char*)item->name) - uiDefBut(block, LABEL, 0, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); + but= uiDefIconBut(block, LABEL, 0, item->icon, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); + else + but= uiDefBut(block, LABEL, 0, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); + + if(item->disabled) { + but->flag |= UI_BUT_DISABLED; + but->lock = 1; + but->lockstr = ""; + } + } + else if(item->type == ITEM_VALUE) { + /* label */ + uiItemValue *vitem= (uiItemValue*)item; + float *retvalue= (block->handle)? &block->handle->retvalue: NULL; + + if(item->icon && strcmp(item->name, "") != 0) + uiDefIconTextButF(block, BUTM, 0, item->icon, (char*)item->name, x, y, w, h, retvalue, 0.0, 0.0, 0, vitem->argval, ""); + else if(item->icon) + uiDefIconButF(block, BUTM, 0, item->icon, x, y, w, h, retvalue, 0.0, 0.0, 0, vitem->argval, ""); + else + uiDefButF(block, BUTM, 0, (char*)item->name, x, y, w, h, retvalue, 0.0, 0.0, 0, vitem->argval, ""); } else { /* separator */ @@ -390,18 +452,21 @@ static void ui_item_buts(uiBlock *block, uiItem *item, int x, int y, int w, int } /* estimated size of text + icon */ -static int ui_text_icon_width(char *name, int icon) +static int ui_text_icon_width(char *name, int icon, int variable) { - if(icon && name && strcmp(name, "") == 0) + if(icon && strcmp(name, "") == 0) return EM_UNIT_X; /* icon only */ else if(icon) - return 10*EM_UNIT_X; /* icon + text */ + return (variable)? UI_GetStringWidth(name) + EM_UNIT_X: 10*EM_UNIT_X; /* icon + text */ else - return 10*EM_UNIT_X; /* text only */ + return (variable)? UI_GetStringWidth(name) + EM_UNIT_X: 10*EM_UNIT_X; /* text only */ } /* estimated size of an item */ -static void ui_item_size(uiItem *item, int *r_w, int *r_h) +#define UI_ITEM_VARY_X 1 +#define UI_ITEM_VARY_Y 2 + +static void ui_item_size(uiItem *item, int *r_w, int *r_h, int flag) { int w, h; @@ -412,7 +477,7 @@ static void ui_item_size(uiItem *item, int *r_w, int *r_h) PropertySubType subtype; int len; - w= ui_text_icon_width(item->name, item->icon); + w= ui_text_icon_width(item->name, item->icon, flag & UI_ITEM_VARY_X); h= EM_UNIT_Y; /* arbitrary extended width by type */ @@ -425,7 +490,7 @@ static void ui_item_size(uiItem *item, int *r_w, int *r_h) /* increase height for arrays */ if(rnaitem->index == RNA_NO_INDEX && len > 0) { - if(item->name && strcmp(item->name, "") == 0 && item->icon == 0) + if(strcmp(item->name, "") == 0 && item->icon == 0) h= 0; if(type == PROP_BOOLEAN && len == 20) @@ -435,11 +500,15 @@ static void ui_item_size(uiItem *item, int *r_w, int *r_h) else h += len*EM_UNIT_Y; } + else if(flag & UI_ITEM_VARY_X) { + if(type == PROP_BOOLEAN && strcmp(item->name, "") != 0) + w += EM_UNIT_X; + } } else { /* other */ - w= ui_text_icon_width(item->name, item->icon); - h= EM_UNIT_Y; + w= ui_text_icon_width(item->name, item->icon, flag & UI_ITEM_VARY_X); + h= (item->type == ITEM_SEPARATOR)? EM_SEPR_Y: EM_UNIT_Y; } if(r_w) *r_w= w; @@ -458,6 +527,25 @@ static void ui_item_free(uiItem *item) } } +/* disabled item */ +static void ui_item_disabled(uiLayout *layout, char *name) +{ + uiTemplate *template= layout->templates.last; + uiItem *item; + + if(!template) + return; + + item= MEM_callocN(sizeof(uiItem), "uiItem"); + + ui_item_name(item, name); + item->disabled= 1; + item->type= ITEM_LABEL; + item->slot= template->slot; + + BLI_addtail(&template->items, item); +} + /* operator items */ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context) { @@ -467,12 +555,14 @@ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDPropert if(!template) return; - if(!ot) + if(!ot) { + ui_item_disabled(layout, idname); return; + } opitem= MEM_callocN(sizeof(uiItemOp), "uiItemOp"); - opitem->item.name= name; + ui_item_name(&opitem->item, name); opitem->item.icon= icon; opitem->item.type= ITEM_OPERATOR; opitem->item.slot= template->slot; @@ -484,6 +574,33 @@ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDPropert BLI_addtail(&template->items, opitem); } +static char *ui_menu_enumpropname(char *opname, char *propname, int retval) +{ + wmOperatorType *ot= WM_operatortype_find(opname); + PointerRNA ptr; + PropertyRNA *prop; + + if(!ot || !ot->srna) + return ""; + + RNA_pointer_create(NULL, ot->srna, NULL, &ptr); + 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; + } + } + + return ""; +} + void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *propname, int value) { PointerRNA ptr; @@ -491,6 +608,9 @@ void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *pro WM_operator_properties_create(&ptr, opname); RNA_enum_set(&ptr, propname, value); + if(!name) + name= ui_menu_enumpropname(opname, propname, value); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext); } @@ -500,8 +620,10 @@ void uiItemsEnumO(uiLayout *layout, char *opname, char *propname) PointerRNA ptr; PropertyRNA *prop; - if(!ot || !ot->srna) + if(!ot || !ot->srna) { + ui_item_disabled(layout, opname); return; + } RNA_pointer_create(NULL, ot->srna, NULL, &ptr); prop= RNA_struct_find_property(&ptr, propname); @@ -513,7 +635,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, "", 0, opname, propname, item[i].value); + uiItemEnumO(layout, NULL, 0, opname, propname, item[i].value); } } @@ -563,7 +685,7 @@ void uiItemO(uiLayout *layout, char *name, int icon, char *opname) } /* RNA property items */ -void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int expand) +void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int expand) { uiTemplate *template= layout->templates.last; uiItemRNA *rnaitem; @@ -575,7 +697,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper rnaitem= MEM_callocN(sizeof(uiItemRNA), "uiItemRNA"); - rnaitem->item.name= name; + ui_item_name(&rnaitem->item, name); rnaitem->item.icon= icon; rnaitem->item.type= ITEM_RNA_PROPERTY; rnaitem->item.slot= template->slot; @@ -583,6 +705,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper rnaitem->ptr= *ptr; rnaitem->prop= prop; rnaitem->index= index; + rnaitem->value= value; rnaitem->expand= expand; BLI_addtail(&template->items, rnaitem); @@ -592,35 +715,90 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop { PropertyRNA *prop; + if(!ptr->data || !propname) + return; + prop= RNA_struct_find_property(ptr, propname); - if(!ptr->data) + if(!prop) { + ui_item_disabled(layout, propname); + printf("uiItemR: property not found: %s\n", propname); return; + } + + uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand); +} + +void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value) +{ + PropertyRNA *prop; + + if(!ptr->data || !propname) + return; + + prop= RNA_struct_find_property(ptr, propname); + if(!prop) { - printf("uiItemR: property not found: %s\n",propname); + ui_item_disabled(layout, propname); + printf("uiItemEnumR: property not found: %s\n", propname); return; } - uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, expand); + uiItemFullR(layout, name, icon, ptr, prop, RNA_ENUM_VALUE, value, 0); +} + +void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname) +{ + PropertyRNA *prop; + + prop= RNA_struct_find_property(ptr, propname); + + if(!prop) { + ui_item_disabled(layout, propname); + return; + } + + if(RNA_property_type(prop) == PROP_ENUM) { + const EnumPropertyItem *item; + int totitem, i; + + RNA_property_enum_items(ptr, prop, &item, &totitem); + + for(i=0; i<totitem; i++) + uiItemEnumR(layout, (char*)item[i].name, 0, ptr, propname, item[i].value); + } } /* menu item */ -void uiItemM(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func) +static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) +{ + MenuType *mt= (MenuType*)arg_mt; + Menu menu = {0}; + + menu.type= mt; + menu.layout= layout; + mt->draw(C, &menu); +} + +void uiItemM(uiLayout *layout, char *name, int icon, char *menuname) { uiTemplate *template= layout->templates.last; - uiItemLMenu *menuitem; + uiItemMenu *menuitem; if(!template) return; + if(!menuname) + return; - menuitem= MEM_callocN(sizeof(uiItemLMenu), "uiItemLMenu"); + menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu"); - menuitem->item.name= name; + ui_item_name(&menuitem->item, name); menuitem->item.icon= icon; menuitem->item.type= ITEM_MENU; menuitem->item.slot= template->slot; - menuitem->func= func; + menuitem->func= ui_item_menutype_func; + menuitem->menuname= menuname; BLI_addtail(&template->items, menuitem); } @@ -636,7 +814,7 @@ void uiItemL(uiLayout *layout, char *name, int icon) item= MEM_callocN(sizeof(uiItem), "uiItem"); - item->name= name; + ui_item_name(item, name); item->icon= icon; item->type= ITEM_LABEL; item->slot= template->slot; @@ -644,6 +822,168 @@ void uiItemL(uiLayout *layout, char *name, int icon) BLI_addtail(&template->items, item); } +/* value item */ +void uiItemV(uiLayout *layout, char *name, int icon, int argval) +{ + uiTemplate *template= layout->templates.last; + uiItemValue *vitem; + + if(!template) + return; + + vitem= MEM_callocN(sizeof(uiItemValue), "uiItemValue"); + + vitem->item.name= name; + vitem->item.icon= icon; + vitem->item.type= ITEM_VALUE; + vitem->item.slot= template->slot; + vitem->argval= argval; + + BLI_addtail(&template->items, vitem); +} + +/* separator item */ +void uiItemS(uiLayout *layout) +{ + uiTemplate *template= layout->templates.last; + uiItem *item; + + if(!template) + return; + + item= MEM_callocN(sizeof(uiItem), "uiItem"); + + item->type= ITEM_SEPARATOR; + item->slot= template->slot; + + BLI_addtail(&template->items, item); +} + +/* level items */ +void uiItemLevel(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func) +{ + uiTemplate *template= layout->templates.last; + uiItemMenu *menuitem; + + if(!template) + return; + if(!func) + return; + + menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu"); + + if(!icon) + icon= ICON_RIGHTARROW_THIN, + + ui_item_name(&menuitem->item, name); + menuitem->item.icon= icon; + menuitem->item.type= ITEM_MENU; + menuitem->item.slot= template->slot; + + menuitem->func= func; + + BLI_addtail(&template->items, menuitem); +} + +typedef struct MenuItemLevel { + int opcontext; + char *opname; + char *propname; + PointerRNA rnapoin; +} MenuItemLevel; + +static void menu_item_enum_opname_menu(bContext *C, uiLayout *layout, void *arg) +{ + MenuItemLevel *lvl= (MenuItemLevel*)(((uiBut*)arg)->func_argN); + + uiLayoutContext(layout, lvl->opcontext); + uiItemsEnumO(layout, lvl->opname, lvl->propname); +} + +void uiItemLevelEnumO(uiLayout *layout, char *name, int icon, char *opname, char *propname) +{ + wmOperatorType *ot= WM_operatortype_find(opname); + uiTemplate *template= layout->templates.last; + uiItemMenu *menuitem; + MenuItemLevel *lvl; + + if(!ot || !ot->srna) { + ui_item_disabled(layout, opname); + return; + } + if(!template) + return; + + menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu"); + + if(!icon) + icon= ICON_RIGHTARROW_THIN; + if(!name) + name= ot->name; + + ui_item_name(&menuitem->item, name); + menuitem->item.icon= icon; + menuitem->item.type= ITEM_MENU; + menuitem->item.slot= template->slot; + + lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); + lvl->opname= opname; + lvl->propname= propname; + lvl->opcontext= layout->opcontext; + + menuitem->func= menu_item_enum_opname_menu; + menuitem->argN= lvl; + + BLI_addtail(&template->items, menuitem); +} + +static void menu_item_enum_rna_menu(bContext *C, uiLayout *layout, void *arg) +{ + MenuItemLevel *lvl= (MenuItemLevel*)(((uiBut*)arg)->func_argN); + + uiLayoutContext(layout, lvl->opcontext); + uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname); +} + +void uiItemLevelEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname) +{ + uiTemplate *template= layout->templates.last; + uiItemMenu *menuitem; + MenuItemLevel *lvl; + PropertyRNA *prop; + + if(!template) + return; + + prop= RNA_struct_find_property(ptr, propname); + if(!prop) { + ui_item_disabled(layout, propname); + return; + } + + menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu"); + + if(!icon) + icon= ICON_RIGHTARROW_THIN; + if(!name) + name= (char*)RNA_property_ui_name(prop); + + ui_item_name(&menuitem->item, name); + menuitem->item.icon= icon; + menuitem->item.type= ITEM_MENU; + menuitem->item.slot= template->slot; + + lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); + lvl->rnapoin= *ptr; + lvl->propname= propname; + lvl->opcontext= layout->opcontext; + + menuitem->func= menu_item_enum_rna_menu; + menuitem->argN= lvl; + + BLI_addtail(&template->items, menuitem); +} + /**************************** Template ***************************/ /* single row layout */ @@ -654,7 +994,7 @@ static void ui_layout_row(uiLayout *layout, uiBlock *block, uiTemplate *template /* estimate total width of buttons */ for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); + ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); totw += itemw; maxh= MAX2(maxh, itemh); tot++; @@ -668,11 +1008,11 @@ static void ui_layout_row(uiLayout *layout, uiBlock *block, uiTemplate *template w= layout->w; for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); - itemw= ui_item_fit(itemw, x, totw, w, (tot-1)*BUTTON_SPACE_X, !item->next, UI_FIT_EXPAND); + ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); + itemw= ui_item_fit(itemw, x, totw, w, (tot-1)*layout->button_space_x, !item->next, UI_FIT_EXPAND); - ui_item_buts(block, item, layout->x+x, layout->y-itemh, itemw, itemh); - x += itemw+BUTTON_SPACE_X; + ui_item_buts(layout, block, item, layout->x+x, layout->y-itemh, itemw, itemh); + x += itemw+layout->button_space_x; } layout->y -= maxh; @@ -699,20 +1039,20 @@ static void ui_layout_column(uiLayout *layout, uiBlock *block, uiTemplate *templ for(col=0; col<totcol; col++) { y= 0; - itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*COLUMN_SPACE, col == totcol-1, UI_FIT_EXPAND); + itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*layout->column_space, col == totcol-1, UI_FIT_EXPAND); for(item=template->items.first; item; item=item->next) { if(item->slot != col) continue; - ui_item_size(item, NULL, &itemh); + ui_item_size(item, NULL, &itemh, UI_ITEM_VARY_Y); y -= itemh; - ui_item_buts(block, item, layout->x+x, layout->y+y, itemw, itemh); - y -= BUTTON_SPACE_Y; + ui_item_buts(layout, block, item, layout->x+x, layout->y+y, itemw, itemh); + y -= layout->button_space_y; } - x += itemw + COLUMN_SPACE; + x += itemw + layout->column_space; miny= MIN2(miny, y); } @@ -731,7 +1071,7 @@ static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate * toth= 0; totitem= 0; for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); + ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); maxw= MAX2(maxw, itemw); toth += itemh; totitem++; @@ -760,18 +1100,18 @@ static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate * /* create column per column */ col= 0; for(item=template->items.first; item; item=item->next) { - ui_item_size(item, NULL, &itemh); - itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*COLUMN_SPACE, col == totcol-1, UI_FIT_EXPAND); + ui_item_size(item, NULL, &itemh, UI_ITEM_VARY_Y); + itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*layout->column_space, col == totcol-1, UI_FIT_EXPAND); y -= itemh; emy -= itemh; - ui_item_buts(block, item, layout->x+x, layout->y+y, itemw, itemh); - y -= BUTTON_SPACE_Y; + ui_item_buts(layout, block, item, layout->x+x, layout->y+y, itemw, itemh); + y -= layout->button_space_y; miny= MIN2(miny, y); /* decide to go to next one */ if(col < totcol-1 && emy <= -emh) { - x += itemw + COLUMN_SPACE; + x += itemw + layout->column_space; y= 0; col++; } @@ -789,7 +1129,7 @@ static void ui_layout_split(uiLayout *layout, uiBlock *block, uiTemplate *templa /* estimate total width of buttons */ for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); + ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); totw += itemw; maxh= MAX2(maxh, itemh); tot++; @@ -801,20 +1141,20 @@ static void ui_layout_split(uiLayout *layout, uiBlock *block, uiTemplate *templa /* create buttons starting from left and right */ lx= 0; rx= 0; - w= layout->w - BUTTON_SPACE_X*(tot-1) + BUTTON_SPACE_X; + w= layout->w - layout->button_space_x*(tot-1) + layout->button_space_x; for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); + ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); if(item->slot == UI_TSLOT_LR_LEFT) { itemw= ui_item_fit(itemw, lx, totw, w, 0, 0); - ui_item_buts(block, item, layout->x+lx, layout->y-itemh, itemw, itemh); - lx += itemw + BUTTON_SPACE_X; + ui_item_buts(layout, block, item, layout->x+lx, layout->y-itemh, itemw, itemh); + lx += itemw + layout->button_space_x; } else { itemw= ui_item_fit(itemw, totw + rx, totw, w, 0, 0); - rx -= itemw + BUTTON_SPACE_X; - ui_item_buts(block, item, layout->x+layout->w+rx, layout->y-itemh, itemw, itemh); + rx -= itemw + layout->button_space_x; + ui_item_buts(layout, block, item, layout->x+layout->w+rx, layout->y-itemh, itemw, itemh); } } @@ -836,7 +1176,7 @@ static void ui_layout_split(const bContext *C, uiLayout *layout, uiBlock *block, for(a=0; a<split->number; a++) { sublayout= split->sublayout[a]; - splitw= ui_item_fit(1, x, split->number, w, (split->number-1)*COLUMN_SPACE, a == split->number-1, UI_FIT_EXPAND); + splitw= ui_item_fit(1, x, split->number, w, (split->number-1)*layout->column_space, a == split->number-1, UI_FIT_EXPAND); sublayout->x= layout->x + x; sublayout->w= splitw; sublayout->y= layout->y; @@ -849,7 +1189,7 @@ static void ui_layout_split(const bContext *C, uiLayout *layout, uiBlock *block, ui_layout_end(C, block, sublayout, NULL, &y); miny= MIN2(y, miny); - x += splitw + COLUMN_SPACE; + x += splitw + layout->column_space; } layout->y= miny; @@ -865,9 +1205,9 @@ static void ui_layout_box(const bContext *C, uiLayout *layout, uiBlock *block, u starty= layout->y; /* some extra padding */ - box->sublayout->x= layout->x + BOX_SPACE; - box->sublayout->w= w - 2*BOX_SPACE; - box->sublayout->y= layout->y - BOX_SPACE; + box->sublayout->x= layout->x + layout->box_space; + box->sublayout->w= w - 2*layout->box_space; + box->sublayout->y= layout->y - layout->box_space; box->sublayout->h= h; box->sublayout->emw= layout->emw; @@ -888,15 +1228,15 @@ static void ui_layout_header_buttons(uiLayout *layout, uiBlock *block, uiTemplat uiBlockBeginAlign(block); for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh); - ui_item_buts(block, item, layout->x, layout->y, itemw, itemh); + ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_X); + ui_item_buts(layout, block, item, layout->x, layout->y, itemw, itemh); layout->x += itemw; } uiBlockEndAlign(block); } -static void ui_layout_header_menus(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) +static void ui_layout_header(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) { ScrArea *sa= CTX_wm_area(C); @@ -910,16 +1250,127 @@ static void ui_layout_header_menus(const bContext *C, uiLayout *layout, uiBlock uiBlockSetEmboss(block, UI_EMBOSS); } +static void header_id_cb(bContext *C, void *arg_template, void *arg_event) +{ + uiTemplateHeadID *idtemplate= (uiTemplateHeadID*)arg_template; + PointerRNA idptr= RNA_property_pointer_get(&idtemplate->ptr, idtemplate->prop); + ID *idtest, *id= idptr.data; + ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT); // XXX + int nr, event= GET_INT_FROM_POINTER(arg_event); + + if(event == UI_ID_BROWSE && idtemplate->browse == 32767) + event= UI_ID_ADD_NEW; + else if(event == UI_ID_BROWSE && idtemplate->browse == 32766) + event= UI_ID_OPEN; + + switch(event) { + case UI_ID_BROWSE: { + if(id==0) id= lb->first; + if(id==0) return; + + if(idtemplate->browse== -2) { + /* XXX implement or find a replacement + * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &idtemplate->browse, do_global_buttons); */ + return; + } + if(idtemplate->browse < 0) + return; + + for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) { + if(nr==idtemplate->browse) { + if(id == idtest) + return; + + id= idtest; + RNA_id_pointer_create(id, &idptr); + RNA_property_pointer_set(&idtemplate->ptr, idtemplate->prop, idptr); + RNA_property_update(C, &idtemplate->ptr, idtemplate->prop); + /* XXX */ + + break; + } + } + break; + } +#if 0 + case UI_ID_DELETE: + id= NULL; + break; + case UI_ID_FAKE_USER: + if(id) { + if(id->flag & LIB_FAKEUSER) id->us++; + else id->us--; + } + else return; + break; +#endif + case UI_ID_PIN: + break; + case UI_ID_ADD_NEW: + WM_operator_name_call(C, idtemplate->newop, WM_OP_INVOKE_REGION_WIN, NULL); + break; + case UI_ID_OPEN: + WM_operator_name_call(C, idtemplate->openop, WM_OP_INVOKE_REGION_WIN, NULL); + break; +#if 0 + case UI_ID_ALONE: + if(!id || id->us < 1) + return; + break; + case UI_ID_LOCAL: + if(!id || id->us < 1) + return; + break; + case UI_ID_AUTO_NAME: + break; +#endif + } +} + static void ui_layout_header_id(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) { - uiTemplateHeadID *idtemplate= (uiTemplateHeadID*)template; - PointerRNA idptr; + uiTemplateHeadID *duptemplate, *idtemplate= (uiTemplateHeadID*)template; + uiBut *but; + PointerRNA idptr= RNA_property_pointer_get(&idtemplate->ptr, idtemplate->prop); + ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT); // XXX + + if(idtemplate->flag & UI_ID_BROWSE) { + char *extrastr, *str; + + if((idtemplate->flag & UI_ID_ADD_NEW) && (idtemplate->flag && UI_ID_OPEN)) + extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767"; + else if(idtemplate->flag & UI_ID_ADD_NEW) + extrastr= "ADD NEW %x 32767"; + else if(idtemplate->flag & UI_ID_OPEN) + extrastr= "OPEN NEW %x 32766"; + else + extrastr= NULL; - idptr= RNA_pointer_get(&idtemplate->ptr, idtemplate->propname); + duptemplate= MEM_dupallocN(idtemplate); + IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse); - layout->x= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)idptr.data, ID_TXT, NULL, - layout->x, layout->y, idtemplate->func, - UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE); + but= uiDefButS(block, MENU, 0, str, layout->x, layout->y, EM_UNIT_X, EM_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new"); + uiButSetNFunc(but, header_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE)); + layout->x+= EM_UNIT_X; + + MEM_freeN(str); + } + + /* text button with name */ + if(idptr.data) { + char name[64]; + + text_idbutton(idptr.data, name); + but= uiDefButR(block, TEX, 0, name, layout->x, layout->y, EM_UNIT_X*6, EM_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL); + uiButSetNFunc(but, header_id_cb, MEM_dupallocN(idtemplate), SET_INT_IN_POINTER(UI_ID_RENAME)); + layout->x += EM_UNIT_X*6; + + /* delete button */ + if(idtemplate->flag & UI_ID_DELETE) { + but= uiDefIconButO(block, BUT, idtemplate->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, layout->x, layout->y, EM_UNIT_X, EM_UNIT_Y, NULL); + layout->x += EM_UNIT_X; + } + } } void ui_template_free(uiTemplate *template) @@ -982,7 +1433,7 @@ uiLayout *uiLayoutBox(uiLayout *layout) box= MEM_callocN(sizeof(uiTemplateBx), "uiTemplateBx"); box->template.type= TEMPLATE_BOX; - box->sublayout= uiLayoutBegin(layout->dir, 0, 0, 0, 0); + box->sublayout= uiLayoutBegin(layout->dir, layout->type, 0, 0, 0, 0); BLI_addtail(&layout->templates, box); return box->sublayout; @@ -1000,7 +1451,7 @@ void uiLayoutSplit(uiLayout *layout, int number, int lr) split->sublayout= MEM_callocN(sizeof(uiLayout*)*number, "uiTemplateSpltSub"); for(a=0; a<number; a++) - split->sublayout[a]= uiLayoutBegin(layout->dir, 0, 0, 0, 0); + split->sublayout[a]= uiLayoutBegin(layout->dir, layout->type, 0, 0, 0, 0); BLI_addtail(&layout->templates, split); } @@ -1026,46 +1477,51 @@ uiLayout *uiLayoutSub(uiLayout *layout, int n) return NULL; } -void uiTemplateHeaderMenus(uiLayout *layout) +void uiTemplateHeader(uiLayout *layout) { uiTemplate *template; template= MEM_callocN(sizeof(uiTemplate), "uiTemplate"); - template->type= TEMPLATE_HEADER_MENUS; + template->type= TEMPLATE_HEADER; BLI_addtail(&layout->templates, template); } -void uiTemplateHeaderButtons(uiLayout *layout) +void uiTemplateHeaderID(uiLayout *layout, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop) { - uiTemplate *template; + uiTemplateHeadID *idtemplate; + PropertyRNA *prop; - template= MEM_callocN(sizeof(uiTemplate), "uiTemplate"); - template->type= TEMPLATE_HEADER_BUTTONS; + if(!ptr->data) + return; - BLI_addtail(&layout->templates, template); -} + prop= RNA_struct_find_property(ptr, propname); -void uiTemplateHeaderID(uiLayout *layout, PointerRNA *ptr, char *propname, int flag, uiIDPoinFunc func) -{ - uiTemplateHeadID *idtemplate; + if(!prop) { + printf("uiTemplateHeaderID: property not found: %s\n", propname); + return; + } idtemplate= MEM_callocN(sizeof(uiTemplateHeadID), "uiTemplateHeadID"); idtemplate->template.type= TEMPLATE_HEADER_ID; idtemplate->ptr= *ptr; - idtemplate->propname= propname; - idtemplate->flag= flag; - idtemplate->func= func; + idtemplate->prop= prop; + idtemplate->flag= UI_ID_BROWSE|UI_ID_RENAME; - BLI_addtail(&layout->templates, idtemplate); -} - -void uiTemplateSetColor(uiLayout *layout, int color) -{ - uiTemplate *template= layout->templates.last; + if(newop) { + idtemplate->flag |= UI_ID_ADD_NEW; + idtemplate->newop= newop; + } + if(openop) { + idtemplate->flag |= UI_ID_OPEN; + idtemplate->openop= openop; + } + if(unlinkop) { + idtemplate->flag |= UI_ID_DELETE; + idtemplate->unlinkop= unlinkop; + } - if(template) - template->color= color; + BLI_addtail(&layout->templates, idtemplate); } void uiTemplateSlot(uiLayout *layout, int slot) @@ -1078,35 +1534,88 @@ void uiTemplateSlot(uiLayout *layout, int slot) /********************** Layout *******************/ +static void ui_layout_init_items(const bContext *C, uiLayout *layout) +{ + ARegion *ar= CTX_wm_region(C); + MenuType *mt; + uiTemplate *template; + uiItem *item; + uiItemMenu *menuitem; + uiItemRNA *rnaitem; + uiItemOp *opitem; + PropertyType type; + + for(template=layout->templates.first; template; template=template->next) { + for(item=template->items.first; item; item=item->next) { + /* initialize buttons names */ + if(item->type == ITEM_MENU) { + menuitem= (uiItemMenu*)item; + + if(menuitem->menuname) { + for(mt=ar->type->menutypes.first; mt; mt=mt->next) { + if(strcmp(menuitem->menuname, mt->idname) == 0) { + menuitem->arg= mt; + ui_item_name(item, mt->label); + break; + } + } + } + } + else if(item->type == ITEM_RNA_PROPERTY) { + rnaitem= (uiItemRNA*)item; + ui_item_name(item, (char*)RNA_property_ui_name(rnaitem->prop)); + } + else if(item->type == ITEM_OPERATOR) { + opitem= (uiItemOp*)item; + ui_item_name(item, opitem->ot->name); + } + + ui_item_name(item, ""); + + /* initialize icons */ + if(layout->type == UI_LAYOUT_MENU) { + if(item->type == ITEM_RNA_PROPERTY) { + rnaitem= (uiItemRNA*)item; + type= RNA_property_type(rnaitem->prop); + + if(type == PROP_BOOLEAN) + item->icon= (RNA_property_boolean_get(&rnaitem->ptr, rnaitem->prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + else if(type == PROP_ENUM && rnaitem->index == RNA_ENUM_VALUE) + item->icon= (RNA_property_enum_get(&rnaitem->ptr, rnaitem->prop) == rnaitem->value)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + } + + if(!item->icon) + item->icon= ICON_BLANK1; + } + } + } +} + static void ui_layout_templates(const bContext *C, uiBlock *block, uiLayout *layout) { uiTemplate *template; + ui_layout_init_items(C, layout); + if(layout->dir == UI_LAYOUT_HORIZONTAL) { for(template=layout->templates.first; template; template=template->next) { switch(template->type) { - case TEMPLATE_HEADER_MENUS: - ui_layout_header_menus(C, layout, block, template); + case TEMPLATE_HEADER: + ui_layout_header(C, layout, block, template); break; case TEMPLATE_HEADER_ID: ui_layout_header_id(C, layout, block, template); break; - case TEMPLATE_HEADER_BUTTONS: default: ui_layout_header_buttons(layout, block, template); break; } - } - layout->x += TEMPLATE_SPACE; + layout->x += layout->template_space; + } } else { for(template=layout->templates.first; template; template=template->next) { - if(template->color) { - // XXX oldcolor= uiBlockGetCol(block); - // XXX uiBlockSetCol(block, template->color); - } - switch(template->type) { case TEMPLATE_ROW: ui_layout_row(layout, block, template); @@ -1126,16 +1635,16 @@ static void ui_layout_templates(const bContext *C, uiBlock *block, uiLayout *lay break; } - // XXX if(template->color) - // XXX uiBlockSetCol(block, oldcolor); - - layout->y -= TEMPLATE_SPACE; + layout->y -= layout->template_space; } } } void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) { + if(layout->handlefunc) + uiBlockSetButmFunc(block, layout->handlefunc, layout->argv); + ui_layout_templates(C, block, layout); if(x) *x= layout->x; @@ -1154,16 +1663,23 @@ void ui_layout_free(uiLayout *layout) MEM_freeN(layout); } -uiLayout *uiLayoutBegin(int dir, int x, int y, int size, int em) +uiLayout *uiLayoutBegin(int dir, int type, int x, int y, int size, int em) { uiLayout *layout; layout= MEM_callocN(sizeof(uiLayout), "uiLayout"); layout->opcontext= WM_OP_INVOKE_REGION_WIN; layout->dir= dir; + layout->type= type; layout->x= x; layout->y= y; + layout->column_space= 5; + layout->template_space= 5; + layout->box_space= 5; + layout->button_space_x= 5; + layout->button_space_y= 2; + if(dir == UI_LAYOUT_HORIZONTAL) { layout->h= size; layout->emh= em*EM_UNIT_Y; @@ -1181,6 +1697,12 @@ void uiLayoutContext(uiLayout *layout, int opcontext) layout->opcontext= opcontext; } +void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) +{ + layout->handlefunc= handlefunc; + layout->argv= argv; +} + void uiLayoutEnd(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) { ui_layout_end(C, block, layout, x, y); @@ -1229,7 +1751,7 @@ void uiRegionPanelLayout(const bContext *C, ARegion *ar, int vertical, char *con } panel->type= pt; - panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, PNL_SAFETY, 0, w-2*PNL_SAFETY, em); + panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, PNL_SAFETY, 0, w-2*PNL_SAFETY, em); pt->draw(C, panel); @@ -1286,7 +1808,7 @@ void uiRegionHeaderLayout(const bContext *C, ARegion *ar) /* draw all headers types */ for(ht= ar->type->headertypes.first; ht; ht= ht->next) { block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS); - layout= uiLayoutBegin(UI_LAYOUT_HORIZONTAL, xco, yco, 24, 1); + layout= uiLayoutBegin(UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, 24, 1); if(ht->draw) { header.type= ht; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 181513b58bc..7bc7e2e3c19 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1643,30 +1643,14 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle, #define MENU_ITEM_LEVEL_OPNAME_ENUM 31 #define MENU_ITEM_LEVEL_RNA_ENUM 32 -struct uiMenuItem { - struct uiMenuItem *next, *prev; - - int type; +struct uiPopupMenu { + uiLayout *layout; int icon; char name[MAX_MENU_STR]; - - char *opname; /* static string */ - char *propname; /* static string */ - - int retval, enumval, boolval, intval; - float fltval; - char *strval; - int opcontext; - uiMenuHandleFunc eventfunc; - void *argv; - uiMenuCreateFunc newlevel; - PointerRNA rnapoin; - - ListBase items; }; typedef struct uiMenuInfo { - uiMenuItem *head; + uiPopupMenu *pup; int mx, my, popup, slideout; int startx, starty; } uiMenuInfo; @@ -1707,201 +1691,49 @@ typedef struct MenuItemLevel { PointerRNA rnapoin; } MenuItemLevel; -/* make a menu level from enum properties */ -static void menu_item_enum_opname_menu(bContext *C, uiMenuItem *head, void *arg) -{ - MenuItemLevel *lvl= (MenuItemLevel*)(((uiBut*)arg)->func_argN); - - head->opcontext= lvl->opcontext; - uiMenuItemsEnumO(head, lvl->opname, lvl->propname); -} - -static void menu_item_enum_rna_menu(bContext *C, uiMenuItem *head, void *arg) -{ - MenuItemLevel *lvl= (MenuItemLevel*)(((uiBut*)arg)->func_argN); - - head->opcontext= lvl->opcontext; - uiMenuItemsEnumR(head, &lvl->rnapoin, lvl->propname); -} - static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle, void *arg_info) { uiBlock *block; uiBut *but; uiMenuInfo *info= arg_info; - uiMenuItem *head, *item; - MenuItemLevel *lvl; + uiPopupMenu *pup; ScrArea *sa; ARegion *ar; static int counter= 0; - int width, height, icon; - int startx, starty, x1, y1; char str[16]; - head= info->head; - height= 0; + pup= info->pup; /* block stuff first, need to know the font */ sprintf(str, "tb %d", counter++); block= uiBeginBlock(C, handle->region, str, UI_EMBOSSP); - uiBlockSetButmFunc(block, head->eventfunc, head->argv); block->direction= UI_DOWN; - width= 50; // fixed with, uiMenuPopupBoundsBlock will compute actual width - - for(item= head->items.first; item; item= item->next) { - if(0) height+= PUP_LABELH; // XXX sepr line - else height+= MENU_BUTTON_HEIGHT; - } - - startx= 0; - starty= 0; - /* here we go! */ - if(head->name[0]) { + if(pup->name[0]) { char titlestr[256]; - if(head->icon) { - width+= 20; - sprintf(titlestr, " %s", head->name); - uiDefIconTextBut(block, LABEL, 0, head->icon, titlestr, startx, (short)(starty+height), width, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, ""); + if(pup->icon) { + sprintf(titlestr, " %s", pup->name); + uiDefIconTextBut(block, LABEL, 0, pup->icon, titlestr, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, ""); } else { - but= uiDefBut(block, LABEL, 0, head->name, startx, (short)(starty+height), width, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, ""); + but= uiDefBut(block, LABEL, 0, pup->name, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, ""); but->flag= UI_TEXT_LEFT; } //uiDefBut(block, SEPR, 0, "", startx, (short)(starty+height)-MENU_SEPR_HEIGHT, width, MENU_SEPR_HEIGHT, NULL, 0.0, 0.0, 0, 0, ""); } - x1= startx; - y1= starty + height - MENU_BUTTON_HEIGHT; // - MENU_SEPR_HEIGHT; - - for(item= head->items.first; item; item= item->next) { - - if(item->type==MENU_ITEM_LEVEL) { - uiDefIconTextMenuBut(block, item->newlevel, NULL, ICON_RIGHTARROW_THIN, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL); - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_LEVEL_OPNAME_ENUM) { - but= uiDefIconTextMenuBut(block, menu_item_enum_opname_menu, NULL, ICON_RIGHTARROW_THIN, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL); - - /* XXX warning, abuse of func_arg! */ - lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); - lvl->opname= item->opname; - lvl->propname= item->propname; - lvl->opcontext= item->opcontext; - - but->poin= (char*)but; - but->func_argN= lvl; - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_LEVEL_RNA_ENUM) { - but= uiDefIconTextMenuBut(block, menu_item_enum_rna_menu, NULL, ICON_RIGHTARROW_THIN, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL); - - /* XXX warning, abuse of func_arg! */ - lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); - lvl->rnapoin= item->rnapoin; - lvl->propname= item->propname; - lvl->opcontext= item->opcontext; - - but->poin= (char*)but; - but->func_argN= lvl; - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_OPNAME_BOOL) { - but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, ""); - RNA_boolean_set(uiButGetOperatorPtrRNA(but), item->propname, item->boolval); - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_OPNAME_ENUM) { - const char *name; - char bname[64]; - - /* If no name is given, use the enum name */ - if (item->name[0] == '\0') - name= ui_menu_enumpropname(item->opname, item->propname, item->enumval); - else - name= item->name; - - BLI_strncpy(bname, name, sizeof(bname)); - - but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, bname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, ""); - RNA_enum_set(uiButGetOperatorPtrRNA(but), item->propname, item->enumval); - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_OPNAME_INT) { - but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, ""); - RNA_int_set(uiButGetOperatorPtrRNA(but), item->propname, item->intval); - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_OPNAME_FLOAT) { - but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, ""); - RNA_float_set(uiButGetOperatorPtrRNA(but), item->propname, item->fltval); - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_OPNAME_STRING) { - but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, ""); - RNA_string_set(uiButGetOperatorPtrRNA(but), item->propname, item->strval); - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_OPNAME) { - uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL); - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_RNA_BOOL) { - PropertyRNA *prop= RNA_struct_find_property(&item->rnapoin, item->propname); - - if(prop && RNA_property_type(prop) == PROP_BOOLEAN) { - icon= (RNA_property_boolean_get(&item->rnapoin, prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; - uiDefIconTextButR(block, TOG, 0, icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, &item->rnapoin, item->propname, 0, 0, 0, 0, 0, NULL); - } - else { - uiBlockSetButLock(block, 1, ""); - uiDefIconTextBut(block, BUT, 0, ICON_BLANK1, item->propname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL, 0.0, 0.0, 0, 0, ""); - uiBlockClearButLock(block); - } - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type==MENU_ITEM_RNA_ENUM) { - PropertyRNA *prop= RNA_struct_find_property(&item->rnapoin, item->propname); - - if(prop && RNA_property_type(prop) == PROP_ENUM) { - icon= (RNA_property_enum_get(&item->rnapoin, prop) == item->enumval)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; - uiDefIconTextButR(block, ROW, 0, icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, &item->rnapoin, item->propname, 0, 0, item->enumval, 0, 0, NULL); - } - else { - uiBlockSetButLock(block, 1, ""); - uiDefIconTextBut(block, BUT, 0, ICON_BLANK1, item->propname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL, 0.0, 0.0, 0, 0, ""); - uiBlockClearButLock(block); - } - - y1 -= MENU_BUTTON_HEIGHT; - } - else if(item->type == MENU_ITEM_ITEM) { - uiDefIconTextButF(block, BUTM, B_NOP, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, &handle->retvalue, 0.0, 0.0, 0, item->retval, ""); - y1 -= MENU_BUTTON_HEIGHT; - } - else { - uiDefBut(block, SEPR, 0, "", x1, y1, width+16, MENU_SEPR_HEIGHT-1, NULL, 0.0, 0.0, 0, 0, ""); - y1 -= MENU_SEPR_HEIGHT; - } - } + block->handle= handle; + uiLayoutEnd(C, block, pup->layout, NULL, NULL); if(info->popup) { uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1); uiBlockSetDirection(block, UI_DOWN); /* here we set an offset for the mouse position */ - uiMenuPopupBoundsBlock(block, 1, 0, -height+MENU_BUTTON_HEIGHT/2); + uiMenuPopupBoundsBlock(block, 1, 0, MENU_BUTTON_HEIGHT/2); } else { /* for a header menu we set the direction automatic */ @@ -1932,262 +1764,51 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle, uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg) { uiPopupBlockHandle *handle; - uiMenuItem *head; + uiPopupMenu *pup; uiMenuInfo info; - head= MEM_callocN(sizeof(uiMenuItem), "menu dummy"); - head->opcontext= WM_OP_INVOKE_REGION_WIN; + pup= MEM_callocN(sizeof(uiPopupMenu), "menu dummy"); + pup->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0); + uiLayoutContext(pup->layout, WM_OP_INVOKE_REGION_WIN); + uiLayoutColumn(pup->layout); - menu_func(C, head, arg); + menu_func(C, pup->layout, arg); memset(&info, 0, sizeof(info)); - info.head= head; + info.pup= pup; info.slideout= (but && (but->block->flag & UI_BLOCK_LOOP)); handle= ui_popup_block_create(C, butregion, but, NULL, ui_block_func_MENU_ITEM, &info); - BLI_freelistN(&head->items); - MEM_freeN(head); + MEM_freeN(pup); return handle; } /*************************** Menu Creating API **************************/ -/* internal add func */ -static uiMenuItem *ui_menu_add_item(uiMenuItem *head, const char *name, int icon, int argval) -{ - uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu item"); - - BLI_strncpy(item->name, name, MAX_MENU_STR); - if(icon) - item->icon= icon; - else - item->icon= ICON_BLANK1; - item->retval= argval; - - item->opcontext= head->opcontext; - - BLI_addtail(&head->items, item); - - return item; -} - -/* set callback for regular items */ -void uiMenuFunc(uiMenuItem *head, void (*eventfunc)(bContext *, void *, int), void *argv) -{ - head->eventfunc= eventfunc; - head->argv= argv; -} - -/* optionally set different context for all items in one level */ -void uiMenuContext(uiMenuItem *head, int opcontext) -{ - head->opcontext= opcontext; -} - - -/* regular item, with retval */ -void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval) -{ - uiMenuItem *item= ui_menu_add_item(head, name, icon, argval); - - item->type = MENU_ITEM_ITEM; -} - -/* regular operator item */ -void uiMenuItemO(uiMenuItem *head, int icon, char *opname) -{ - uiMenuItem *item= ui_menu_add_item(head, "", icon, 0); - - item->opname= opname; // static! - item->type = MENU_ITEM_OPNAME; -} - -/* single operator item with property */ -void uiMenuItemEnumO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value) -{ - uiMenuItem *item= ui_menu_add_item(head, name, icon, 0); - - item->opname= opname; // static! - item->propname= propname; // static! - item->enumval= value; - item->type = MENU_ITEM_OPNAME_ENUM; -} - -/* single operator item with property */ -void uiMenuItemIntO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value) -{ - uiMenuItem *item= ui_menu_add_item(head, name, icon, 0); - - item->opname= opname; // static! - item->propname= propname; // static! - item->intval= value; - item->type = MENU_ITEM_OPNAME_INT; -} - -/* single operator item with property */ -void uiMenuItemFloatO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, float value) -{ - uiMenuItem *item= ui_menu_add_item(head, name, icon, 0); - - item->opname= opname; // static! - item->propname= propname; // static! - item->fltval= value; - item->type = MENU_ITEM_OPNAME_FLOAT; -} - -/* single operator item with property */ -void uiMenuItemBooleanO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value) -{ - uiMenuItem *item= ui_menu_add_item(head, name, icon, 0); - - item->opname= opname; // static! - item->propname= propname; // static! - item->boolval= value; - item->type = MENU_ITEM_OPNAME_BOOL; -} - -/* single operator item with property */ -void uiMenuItemStringO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, char *value) -{ - uiMenuItem *item= ui_menu_add_item(head, name, icon, 0); - - item->opname= opname; // static! - item->propname= propname; // static! - item->strval= value; - item->type = MENU_ITEM_OPNAME_STRING; -} - -/* add all operator items with property */ -void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname) -{ - wmOperatorType *ot= WM_operatortype_find(opname); - PointerRNA ptr; - PropertyRNA *prop; - - if(!ot || !ot->srna) - return; - - RNA_pointer_create(NULL, ot->srna, NULL, &ptr); - prop= RNA_struct_find_property(&ptr, propname); - - if(prop && RNA_property_type(prop) == PROP_ENUM) { - const EnumPropertyItem *item; - int totitem, i; - - RNA_property_enum_items(&ptr, prop, &item, &totitem); - - for (i=0; i<totitem; i++) - uiMenuItemEnumO(head, "", 0, opname, propname, item[i].value); - } -} - -/* rna property toggle */ -void uiMenuItemBooleanR(uiMenuItem *head, PointerRNA *ptr, char *propname) -{ - uiMenuItem *item= ui_menu_add_item(head, "", 0, 0); - - item->propname= propname; // static! - item->rnapoin= *ptr; - item->type = MENU_ITEM_RNA_BOOL; -} - -void uiMenuItemEnumR(uiMenuItem *head, PointerRNA *ptr, char *propname, int value) -{ - uiMenuItem *item= ui_menu_add_item(head, "", 0, 0); - - item->propname= propname; // static! - item->rnapoin= *ptr; - item->enumval= value; - item->type = MENU_ITEM_RNA_ENUM; -} - -/* add all rna items with property */ -void uiMenuItemsEnumR(uiMenuItem *head, PointerRNA *ptr, char *propname) -{ - PropertyRNA *prop; - - prop= RNA_struct_find_property(ptr, propname); - - if(prop && RNA_property_type(prop) == PROP_ENUM) { - const EnumPropertyItem *item; - int totitem, i; - - RNA_property_enum_items(ptr, prop, &item, &totitem); - - for (i=0; i<totitem; i++) - uiMenuItemEnumR(head, ptr, propname, item[i].value); - } -} - -/* generic new menu level */ -void uiMenuLevel(uiMenuItem *head, const char *name, uiMenuCreateFunc newlevel) -{ - uiMenuItem *item= ui_menu_add_item(head, name, 0, 0); - - item->type = MENU_ITEM_LEVEL; - item->newlevel= newlevel; -} - -/* make a new level from enum properties */ -void uiMenuLevelEnumO(uiMenuItem *head, char *opname, char *propname) -{ - uiMenuItem *item= ui_menu_add_item(head, "", 0, 0); - wmOperatorType *ot; - - item->type = MENU_ITEM_LEVEL_OPNAME_ENUM; - ot= WM_operatortype_find(opname); - if(ot) - BLI_strncpy(item->name, ot->name, MAX_MENU_STR); - - item->opname= opname; // static! - item->propname= propname; // static! -} - -/* make a new level from enum properties */ -void uiMenuLevelEnumR(uiMenuItem *head, PointerRNA *ptr, char *propname) -{ - uiMenuItem *item= ui_menu_add_item(head, "", 0, 0); - PropertyRNA *prop; - - item->type = MENU_ITEM_LEVEL_RNA_ENUM; - prop= RNA_struct_find_property(ptr, propname); - if(prop) - BLI_strncpy(item->name, RNA_property_ui_name(prop), MAX_MENU_STR); - - item->rnapoin= *ptr; - item->propname= propname; // static! -} - -/* separator */ -void uiMenuSeparator(uiMenuItem *head) -{ - uiMenuItem *item= ui_menu_add_item(head, "", 0, 0); - - item->type = MENU_ITEM_SEPARATOR; -} /*************************** Popup Menu API **************************/ /* only return handler, and set optional title */ -uiMenuItem *uiPupMenuBegin(const char *title, int icon) +uiPopupMenu *uiPupMenuBegin(const char *title, int icon) { - uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu start"); + uiPopupMenu *pup= MEM_callocN(sizeof(uiPopupMenu), "menu start"); - item->type = MENU_ITEM_TITLE; - item->opcontext= WM_OP_EXEC_REGION_WIN; - item->icon= icon; + pup->icon= icon; + pup->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0); + uiLayoutContext(pup->layout, WM_OP_EXEC_REGION_WIN); + uiLayoutColumn(pup->layout); /* NULL is no title */ if(title) - BLI_strncpy(item->name, title, MAX_MENU_STR); + BLI_strncpy(pup->name, title, MAX_MENU_STR); - return item; + return pup; } /* set the whole structure to work */ -void uiPupMenuEnd(bContext *C, uiMenuItem *head) +void uiPupMenuEnd(bContext *C, uiPopupMenu *pup) { wmWindow *window= CTX_wm_window(C); uiMenuInfo info; @@ -2197,7 +1818,7 @@ void uiPupMenuEnd(bContext *C, uiMenuItem *head) info.popup= 1; info.mx= window->eventstate->x; info.my= window->eventstate->y; - info.head= head; + info.pup= pup; menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_MENU_ITEM, &info); menu->popup= 1; @@ -2205,8 +1826,12 @@ void uiPupMenuEnd(bContext *C, uiMenuItem *head) UI_add_popup_handlers(C, &window->handlers, menu); WM_event_add_mousemove(C); - BLI_freelistN(&head->items); - MEM_freeN(head); + MEM_freeN(pup); +} + +uiLayout *uiPupMenuLayout(uiPopupMenu *pup) +{ + return pup->layout; } /* ************** standard pupmenus *************** */ diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 5ef1e68bd59..3bb7581b16c 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -297,7 +297,7 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) char *name; int x= 0, y= 0; - layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, DEF_BUT_WIDTH*2, 20); + layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, DEF_BUT_WIDTH*2, 20); uiLayoutColumn(layout); uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0); @@ -317,7 +317,7 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) uiLayoutColumn(uiLayoutSub(layout, 0)); uiItemL(uiLayoutSub(layout, 0), name, 0); uiLayoutColumn(uiLayoutSub(layout, 1)); - uiItemFullR(uiLayoutSub(layout, 1), "", 0, ptr, prop, -1, 0); + uiItemFullR(uiLayoutSub(layout, 1), "", 0, ptr, prop, -1, 0, 0); } RNA_property_collection_end(&iter); @@ -506,18 +506,7 @@ int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID *id, int id_code, uiBlockSetButLock(block, id->lib!=0, "Can't edit external libdata"); /* name button */ - if(GS(id->name)==ID_SCE) - strcpy(str1, "SCE:"); - else if(GS(id->name)==ID_SCE) - strcpy(str1, "SCR:"); - else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes) - strcpy(str1, "NT:"); - else { - str1[0]= id->name[0]; - str1[1]= id->name[1]; - str1[2]= ':'; - str1[3]= 0; - } + text_idbutton(id, str1); if(GS(id->name)==ID_IP) len= 110; else if((y) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib) |