diff options
Diffstat (limited to 'source/blender')
40 files changed, 1668 insertions, 1401 deletions
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index fb85099bf58..6d0c15ab724 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -998,7 +998,7 @@ static int insert_key_menu_invoke (bContext *C, wmOperator *op, wmEvent *event) uiLayout *layout; int i = 0; - pup= uiPupMenuBegin("Insert Keyframe", 0); + pup= uiPupMenuBegin(C, "Insert Keyframe", 0); layout= uiPupMenuLayout(pup); /* active Keying Set */ diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 98f51a4015d..1c113c25720 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -3461,7 +3461,7 @@ static int armature_subdivs_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("Subdivision Type", 0); + pup= uiPupMenuBegin(C, "Subdivision Type", 0); layout= uiPupMenuLayout(pup); uiItemsEnumO(layout, "ARMATURE_OT_subdivs", "type"); uiPupMenuEnd(C, pup); @@ -3744,7 +3744,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) static int armature_parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event) { EditBone *actbone = CTX_data_active_bone(C); - uiPopupMenu *pup= uiPupMenuBegin("Make Parent ", 0); + uiPopupMenu *pup= uiPupMenuBegin(C, "Make Parent ", 0); uiLayout *layout= uiPupMenuLayout(pup); int allchildbones = 0; diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 43590346299..dec4847f125 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -326,7 +326,7 @@ static int poselib_add_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) return OPERATOR_CANCELLED; /* start building */ - pup= uiPupMenuBegin(op->type->name, 0); + pup= uiPupMenuBegin(C, op->type->name, 0); layout= uiPupMenuLayout(pup); uiLayoutContext(layout, WM_OP_EXEC_DEFAULT); @@ -460,7 +460,7 @@ static int poselib_stored_pose_menu_invoke (bContext *C, wmOperator *op, wmEvent return OPERATOR_CANCELLED; /* start building */ - pup= uiPupMenuBegin(op->type->name, 0); + pup= uiPupMenuBegin(C, op->type->name, 0); layout= uiPupMenuLayout(pup); uiLayoutContext(layout, WM_OP_EXEC_DEFAULT); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 49d86d08db2..5292d86d3c9 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -70,7 +70,7 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("Specials", 0); + pup= uiPupMenuBegin(C, "Specials", 0); layout= uiPupMenuLayout(pup); uiItemO(layout, NULL, 0, "CURVE_OT_subdivide"); uiItemO(layout, NULL, 0, "CURVE_OT_switch_direction"); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index c60007680ba..45b9a589bd5 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3567,7 +3567,7 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, wmEvent *event) for(nu= editnurb->first; nu; nu= nu->next) { if(nu->pntsu>1 || nu->pntsv>1) { if(nu->type==CU_NURBS) { - pup= uiPupMenuBegin("Direction", 0); + pup= uiPupMenuBegin(C, "Direction", 0); layout= uiPupMenuLayout(pup); uiItemsEnumO(layout, op->type->idname, "direction"); uiPupMenuEnd(C, pup); @@ -4511,14 +4511,14 @@ static int delete_invoke(bContext *C, wmOperator *op, wmEvent *event) uiLayout *layout; if(obedit->type==OB_SURF) { - pup= uiPupMenuBegin("Delete", 0); + pup= uiPupMenuBegin(C, "Delete", 0); layout= uiPupMenuLayout(pup); uiItemEnumO(layout, NULL, 0, op->type->idname, "type", 0); uiItemEnumO(layout, NULL, 0, op->type->idname, "type", 2); uiPupMenuEnd(C, pup); } else { - pup= uiPupMenuBegin("Delete", 0); + pup= uiPupMenuBegin(C, "Delete", 0); layout= uiPupMenuLayout(pup); uiItemsEnumO(layout, op->type->idname, "type"); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 847120a5804..bfa0c680bd6 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -53,6 +53,8 @@ void ED_region_pixelspace(struct ARegion *ar); void ED_region_init(struct bContext *C, struct ARegion *ar); void ED_region_tag_redraw(struct ARegion *ar); void ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct); +void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, char *context); +void ED_region_header(const struct bContext *C, struct ARegion *ar); /* spaces */ void ED_spacetypes_init(void); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 0e34b3702ed..475d77d90f3 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -131,6 +131,8 @@ typedef struct uiLayout uiLayout; #define UI_BUT_ANIMATED_KEY (1<<21) #define UI_BUT_DRIVEN (1<<22) +#define UI_PANEL_WIDTH 340 +#define UI_COMPACT_PANEL_WIDTH 160 /* Button types, bits stored in 1 value... and a short even! - bits 0-4: bitnr (0-31) @@ -215,7 +217,7 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event); typedef struct uiPopupMenu uiPopupMenu; -uiPopupMenu *uiPupMenuBegin(const char *title, int icon); +uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon); void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head); struct uiLayout *uiPupMenuLayout(uiPopupMenu *head); @@ -260,6 +262,8 @@ void uiFreeBlock(const struct bContext *C, uiBlock *block); void uiFreeBlocks(const struct bContext *C, struct ListBase *lb); void uiFreeInactiveBlocks(const struct bContext *C, struct ListBase *lb); +void uiBlockSetRegion(uiBlock *block, struct ARegion *region); + void uiBlockSetButLock(uiBlock *block, int val, char *lockstr); void uiBlockClearButLock(uiBlock *block); @@ -523,7 +527,8 @@ uiBut *uiDefMenuTogR(uiBlock *block, struct PointerRNA *ptr, char *propname, cha * - Template: predefined layouts for buttons with a number of slots, each * slot can contain multiple items. * - Item: item to put in a template slot, being either an RNA property, - * operator, label or menu currently. */ + * operator, label or menu. Also regular buttons can be used when setting + * uiBlockCurLayout. */ /* layout */ #define UI_LAYOUT_HORIZONTAL 0 @@ -533,23 +538,29 @@ uiBut *uiDefMenuTogR(uiBlock *block, struct PointerRNA *ptr, char *propname, cha #define UI_LAYOUT_HEADER 1 #define UI_LAYOUT_MENU 2 -uiLayout *uiLayoutBegin(int dir, int type, int x, int y, int size, int em, struct uiStyle *style); -void uiLayoutEnd(const struct bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y); +#define UI_UNIT_X 20 +#define UI_UNIT_Y 20 + +uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style); +void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout); +void uiBlockLayoutResolve(const struct bContext *C, uiBlock *block, int *x, int *y); +float uiBlockAspect(uiBlock *block); /* temporary */ void uiLayoutContext(uiLayout *layout, int opcontext); void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv); +uiBlock *uiLayoutBlock(uiLayout *layout); /* layout specifiers */ -void uiLayoutRow(uiLayout *layout); -void uiLayoutColumn(uiLayout *layout); -void uiLayoutColumnFlow(uiLayout *layout, int number); -void uiLayoutSplit(uiLayout *layout, int number, int lr); +uiLayout *uiLayoutRow(uiLayout *layout, int align); +uiLayout *uiLayoutColumn(uiLayout *layout, int align); +uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align); uiLayout *uiLayoutBox(uiLayout *layout); -uiLayout *uiLayoutSub(uiLayout *layout, int n); +uiLayout *uiLayoutFree(uiLayout *layout, int align); +uiLayout *uiLayoutSplit(uiLayout *layout); /* templates */ -void uiTemplateHeader(uiLayout *layout); -void uiTemplateHeaderID(uiLayout *layout, struct PointerRNA *ptr, char *propname, +void uiTemplateHeader(uiLayout *layout, struct bContext *C); +void uiTemplateHeaderID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop); /* items */ @@ -568,7 +579,7 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname); void uiItemL(uiLayout *layout, char *name, int icon); /* label */ -void uiItemM(uiLayout *layout, char *name, int icon, char *menuname); /* menu */ +void uiItemM(uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname); /* menu */ void uiItemV(uiLayout *layout, char *name, int icon, int argval); /* value */ void uiItemS(uiLayout *layout); /* separator */ @@ -576,21 +587,10 @@ void uiItemMenuF(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func); void uiItemMenuEnumO(uiLayout *layout, char *name, int icon, char *opname, char *propname); void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname); -/* utilities */ -#define UI_PANEL_WIDTH 340 -#define UI_COMPACT_PANEL_WIDTH 160 - -typedef void (*uiHeaderCreateFunc)(const struct bContext *C, uiLayout *layout); -typedef void (*uiPanelCreateFunc)(const struct bContext *C, uiLayout *layout); - -void uiRegionPanelLayout(const struct bContext *C, struct ARegion *ar, int vertical, char *context); -void uiRegionHeaderLayout(const struct bContext *C, struct ARegion *ar); - /* Animation */ void uiAnimContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index); - /* Styled text draw */ void uiStyleFontSet(struct uiFontStyle *fs); void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, char *str); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index fd082c34238..57f45059865 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -502,10 +502,10 @@ void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) return; for(but=block->buttons.first; but; but=but->next) { - if(but->opname) { + if(but->optype) { prop= (but->opptr)? but->opptr->data: NULL; - if(WM_key_event_operator_string(C, but->opname, but->opcontext, prop, buf, sizeof(buf))) { + if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) { butstr= MEM_mallocN(strlen(but->str)+strlen(buf)+2, "menu_block_set_keymaps"); strcpy(butstr, but->str); strcat(butstr, "|"); @@ -535,8 +535,8 @@ void uiEndBlock(const bContext *C, uiBlock *block) ui_check_but(but); /* temp? Proper check for greying out */ - if(but->opname) { - wmOperatorType *ot= WM_operatortype_find(but->opname); + if(but->optype) { + wmOperatorType *ot= but->optype; if(ot==NULL || (ot->poll && ot->poll((bContext *)C)==0)) { but->flag |= UI_BUT_DISABLED; but->lock = 1; @@ -559,6 +559,8 @@ void uiEndBlock(const bContext *C, uiBlock *block) } /* handle pending stuff */ + if(block->layout) uiBlockLayoutResolve(C, block, NULL, NULL); + ui_block_do_align(block); if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block); /* after keymaps! */ @@ -598,7 +600,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u getsizex= ar->winx; getsizey= ar->winy; - + gx= (but?but->x1:block->minx) + (block->panel?block->panel->ofsx:0.0f); gy= (but?but->y1:block->miny) + (block->panel?block->panel->ofsy:0.0f); @@ -1716,21 +1718,18 @@ void uiFreeInactiveBlocks(const bContext *C, ListBase *lb) } } -uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, short dt) +void uiBlockSetRegion(uiBlock *block, ARegion *region) { ListBase *lb; - uiBlock *block, *oldblock= NULL; - wmWindow *window; - int getsizex, getsizey; + uiBlock *oldblock= NULL; - window= CTX_wm_window(C); lb= ®ion->uiblocks; /* each listbase only has one block with this name, free block * if is already there so it can be rebuilt from scratch */ if(lb) { for (oldblock= lb->first; oldblock; oldblock= oldblock->next) - if (BLI_streq(oldblock->name, name)) + if (BLI_streq(oldblock->name, block->name)) break; if (oldblock) { @@ -1738,20 +1737,32 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor oldblock->panel= NULL; } } - - block= MEM_callocN(sizeof(uiBlock), "uiBlock"); + block->oldblock= oldblock; - block->active= 1; - block->dt= dt; /* at the beginning of the list! for dynamical menus/blocks */ if(lb) BLI_addhead(lb, block); +} + +uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, short dt) +{ + uiBlock *block; + wmWindow *window; + int getsizex, getsizey; + window= CTX_wm_window(C); + + block= MEM_callocN(sizeof(uiBlock), "uiBlock"); + block->active= 1; + block->dt= dt; BLI_strncpy(block->name, name, sizeof(block->name)); + if(region) + uiBlockSetRegion(block, region); + /* window matrix and aspect */ - if(region->swinid) { + if(region && region->swinid) { wm_subwindow_getmatrix(window, region->swinid, block->winmat); wm_subwindow_getsize(window, region->swinid, &getsizex, &getsizey); @@ -1952,7 +1963,9 @@ void uiBlockBeginAlign(uiBlock *block) if(block->flag & UI_BUT_ALIGN) uiBlockEndAlign(block); block->flag |= UI_BUT_ALIGN_DOWN; - /* buttons declared after this call will this align flag */ + block->alignnr++; + + /* buttons declared after this call will get this align nr */ // XXX flag? } static int buts_are_horiz(uiBut *but1, uiBut *but2) @@ -1968,36 +1981,33 @@ static int buts_are_horiz(uiBut *but1, uiBut *but2) void uiBlockEndAlign(uiBlock *block) { + block->flag &= ~UI_BUT_ALIGN; // all 4 flags +} + +static void ui_block_do_align_but(uiBlock *block, uiBut *first, int nr) +{ uiBut *prev, *but=NULL, *next; int flag= 0, cols=0, rows=0; - /* auto align: - - go back to first button of align start (ALIGN_DOWN) - - compare triples, and define flags - */ - prev= block->buttons.last; - while(prev) { - if( (prev->flag & UI_BUT_ALIGN_DOWN)) but= prev; - else break; - - if(but && but->next) { + /* auto align */ + + for(but=first; but && but->alignnr == nr; but=but->next) { + if(but->next && but->next->alignnr == nr) { if(buts_are_horiz(but, but->next)) cols++; else rows++; } - - prev= prev->prev; } - if(but==NULL) return; - + /* rows==0: 1 row, cols==0: 1 collumn */ /* note; how it uses 'flag' in loop below (either set it, or OR it) is confusing */ - prev= NULL; - while(but) { + for(but=first, prev=NULL; but && but->alignnr == nr; prev=but, but=but->next) { next= but->next; - + if(next && next->alignnr != nr) + next= NULL; + /* clear old flag */ - but->flag &= ~UI_BUT_ALIGN_DOWN; + but->flag &= ~UI_BUT_ALIGN; if(flag==0) { /* first case */ if(next) { @@ -2030,11 +2040,11 @@ void uiBlockEndAlign(uiBlock *block) /* exception case: bottom row */ if(rows>0) { uiBut *bt= but; - while(bt) { - if(bt->next && buts_are_horiz(bt, bt->next)==0 ) break; + while(bt && bt->alignnr == nr) { + if(bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next)==0 ) break; bt= bt->next; } - if(bt==0) flag= UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT; + if(bt==0 || bt->alignnr != nr) flag= UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT; } } else flag |= UI_BUT_ALIGN_LEFT; @@ -2086,35 +2096,30 @@ void uiBlockEndAlign(uiBlock *block) } } } - - prev= but; - but= next; } - - block->flag &= ~UI_BUT_ALIGN; // all 4 flags } -#if 0 -static void uiBlockEndAligno(uiBlock *block) +void ui_block_do_align(uiBlock *block) { uiBut *but; - - /* correct last defined button */ - but= block->buttons.last; - if(but) { - /* vertical align case */ - if( (block->flag & UI_BUT_ALIGN) == (UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_DOWN) ) { - but->flag &= ~UI_BUT_ALIGN_DOWN; - } - /* horizontal align case */ - if( (block->flag & UI_BUT_ALIGN) == (UI_BUT_ALIGN_LEFT|UI_BUT_ALIGN_RIGHT) ) { - but->flag &= ~UI_BUT_ALIGN_RIGHT; + int nr; + + /* align buttons with same align nr */ + for(but=block->buttons.first; but;) { + if(but->alignnr) { + nr= but->alignnr; + ui_block_do_align_but(block, but, nr); + + /* skip with same number */ + for(; but && but->alignnr == nr; but=but->next); + + if(!but) + break; } - /* else do nothing, manually provided flags */ + else + but= but->next; } - block->flag &= ~UI_BUT_ALIGN; // all 4 flags } -#endif /* ui_def_but is the function that draws many button types @@ -2171,6 +2176,9 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short but->aspect= 1.0f; //XXX block->aspect; but->block= block; // pointer back, used for frontbuffer status, and picker + if(block->flag & UI_BUT_ALIGN) + but->alignnr= block->alignnr; + but->func= block->func; but->func_arg1= block->func_arg1; but->func_arg2= block->func_arg2; @@ -2217,6 +2225,9 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short } else BLI_addtail(&block->buttons, but); + + if(block->curlayout) + ui_layout_add_but(block->curlayout, but); return but; } @@ -2374,7 +2385,7 @@ uiBut *ui_def_but_operator(uiBlock *block, int type, char *opname, int opcontext } but= ui_def_but(block, type, -1, str, x1, y1, x2, y2, NULL, 0, 0, 0, 0, tip); - but->opname= opname; + but->optype= ot; but->opcontext= opcontext; if(!ot) { @@ -2894,9 +2905,9 @@ int uiButGetRetVal(uiBut *but) PointerRNA *uiButGetOperatorPtrRNA(uiBut *but) { - if(but->opname && !but->opptr) { + if(but->optype && !but->opptr) { but->opptr= MEM_callocN(sizeof(PointerRNA), "uiButOpPtr"); - WM_operator_properties_create(but->opptr, but->opname); + WM_operator_properties_create(but->opptr, but->optype->idname); } return but->opptr; diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index ac6f5d970eb..4a26db29160 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -119,7 +119,7 @@ void ui_but_anim_menu(bContext *C, uiBut *but) int length; if(but->rnapoin.data && but->rnaprop) { - pup= uiPupMenuBegin(RNA_property_ui_name(but->rnaprop), 0); + pup= uiPupMenuBegin(C, RNA_property_ui_name(but->rnaprop), 0); layout= uiPupMenuLayout(pup); length= RNA_property_array_length(but->rnaprop); diff --git a/source/blender/editors/interface/interface_api.c b/source/blender/editors/interface/interface_api.c index 1cd804851b5..873406de7aa 100644 --- a/source/blender/editors/interface/interface_api.c +++ b/source/blender/editors/interface/interface_api.c @@ -56,9 +56,20 @@ void RNA_api_ui_layout(StructRNA *srna) /* simple layout specifiers */ func= RNA_def_function(srna, "row", "uiLayoutRow"); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); + func= RNA_def_function(srna, "column", "uiLayoutColumn"); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); + func= RNA_def_function(srna, "column_flow", "uiLayoutColumnFlow"); parm= RNA_def_int(func, "columns", 0, 0, INT_MAX, "", "Number of columns, 0 is automatic.", 0, INT_MAX); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); /* box layout */ func= RNA_def_function(srna, "box", "uiLayoutBox"); @@ -67,13 +78,6 @@ void RNA_api_ui_layout(StructRNA *srna) /* split layout */ func= RNA_def_function(srna, "split", "uiLayoutSplit"); - parm= RNA_def_int(func, "number", 2, 0, INT_MAX, "", "Number of splits.", 0, INT_MAX); - parm= RNA_def_boolean(func, "lr", 0, "", "LR."); - - /* sub layout */ - func= RNA_def_function(srna, "sub", "uiLayoutSub"); - parm= RNA_def_int(func, "n", 0, 0, INT_MAX, "", "Index of sub-layout.", 0, INT_MAX); - RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); RNA_def_function_return(func, parm); @@ -161,6 +165,8 @@ void RNA_api_ui_layout(StructRNA *srna) api_ui_item_common(func); func= RNA_def_function(srna, "itemM", "uiItemM"); + parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); + RNA_def_property_flag(parm, PROP_REQUIRED); api_ui_item_common(func); parm= RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu."); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -169,8 +175,12 @@ void RNA_api_ui_layout(StructRNA *srna) /* templates */ func= RNA_def_function(srna, "template_header", "uiTemplateHeader"); + parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); + RNA_def_property_flag(parm, PROP_REQUIRED); func= RNA_def_function(srna, "template_header_ID", "uiTemplateHeaderID"); + parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); + RNA_def_property_flag(parm, PROP_REQUIRED); 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."); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 5aa2cded642..02c803963eb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -151,7 +151,7 @@ typedef struct uiAfterFunc { void *butm_func_arg; int a2; - const char *opname; + wmOperatorType *optype; int opcontext; PointerRNA *opptr; @@ -222,7 +222,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) * handling is done, i.e. menus are closed, in order to avoid conflicts * with these functions removing the buttons we are working with */ - if(but->func || but->funcN || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) { + if(but->func || but->funcN || block->handle_func || (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) { after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc"); after->func= but->func; @@ -242,14 +242,14 @@ static void ui_apply_but_func(bContext *C, uiBut *but) after->a2= but->a2; } - after->opname= but->opname; + after->optype= but->optype; after->opcontext= but->opcontext; after->opptr= but->opptr; after->rnapoin= but->rnapoin; after->rnaprop= but->rnaprop; - but->opname= NULL; + but->optype= NULL; but->opcontext= 0; but->opptr= NULL; @@ -280,8 +280,8 @@ static void ui_apply_but_funcs_after(bContext *C) if(after.butm_func) after.butm_func(C, after.butm_func_arg, after.a2); - if(after.opname) - WM_operator_name_call(C, after.opname, after.opcontext, after.opptr); + if(after.optype) + WM_operator_name_call(C, after.optype->idname, after.opcontext, after.opptr); if(after.opptr) { WM_operator_properties_free(after.opptr); MEM_freeN(after.opptr); @@ -3780,8 +3780,8 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata) if(temp.menuretval == UI_RETURN_OK) { if(temp.popup_func) temp.popup_func(C, temp.popup_arg, temp.retvalue); - if(temp.opname) - WM_operator_name_call(C, temp.opname, temp.opcontext, NULL); + if(temp.optype) + WM_operator_name_call(C, temp.optype->idname, temp.opcontext, NULL); } else if(temp.cancel_func) temp.cancel_func(temp.popup_arg); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 0edcc95f7af..b96726a5ead 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -38,9 +38,11 @@ struct bContext; struct IDProperty; struct uiHandleButtonData; struct wmEvent; +struct wmOperatorType; struct wmWindow; struct uiStyle; struct uiWidgetColors; +struct uiLayout; /* ****************** general defines ************** */ @@ -99,8 +101,6 @@ typedef enum { /* internal panel drawing defines */ #define PNL_GRID 4 -#define PNL_DIST 4 -#define PNL_SAFETY 8 #define PNL_HEADER 20 /* panel->flag */ @@ -145,6 +145,7 @@ typedef struct { struct uiBut { struct uiBut *next, *prev; short type, pointype, bit, bitnr, retval, strwidth, ofs, pos, selsta, selend; + short alignnr; int flag; char *str; @@ -196,7 +197,7 @@ struct uiBut { int rnaindex; /* Operator data */ - const char *opname; + struct wmOperatorType *optype; int opcontext; struct IDProperty *opproperties; struct PointerRNA *opptr; @@ -216,10 +217,13 @@ struct uiBut { struct uiBlock { uiBlock *next, *prev; - + ListBase buttons; Panel *panel; uiBlock *oldblock; + + struct uiLayout *layout; + struct uiLayout *curlayout; char name[UI_MAX_NAME_STR]; @@ -228,6 +232,8 @@ struct uiBlock { float minx, miny, maxx, maxy; float aspect; + short alignnr; + uiButHandleFunc func; void *func_arg1; void *func_arg2; @@ -302,6 +308,7 @@ extern void ui_update_block_buts_hsv(uiBlock *block, float *hsv); extern void ui_bounds_block(uiBlock *block); extern void ui_block_translate(uiBlock *block, int x, int y); +extern void ui_block_do_align(uiBlock *block); /* interface_regions.c */ @@ -318,7 +325,7 @@ struct uiPopupBlockHandle { void *popup_arg; /* for operator popups */ - const char *opname; + struct wmOperatorType *optype; int opcontext; ScrArea *ctx_area; ARegion *ctx_region; @@ -389,6 +396,8 @@ void ui_theme_init_userdef(void); void ui_resources_init(void); void ui_resources_free(void); +/* interface_layout.c */ +void ui_layout_add_but(struct uiLayout *layout, uiBut *but); /* interface_anim.c */ void ui_but_anim_flag(uiBut *but, float cfra); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 6a02e992390..ab2bb57a25f 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1,3 +1,26 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Blender Foundation 2009. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include <limits.h> #include <math.h> @@ -44,163 +67,112 @@ #define RNA_NO_INDEX -1 #define RNA_ENUM_VALUE -2 -#define EM_UNIT_X XIC -#define EM_UNIT_Y YIC - #define EM_SEPR_X 6 #define EM_SEPR_Y 6 -/* Item */ - -typedef enum uiItemType { - ITEM_OPERATOR, - ITEM_RNA_PROPERTY, - ITEM_MENU, - ITEM_LABEL, - ITEM_VALUE, - ITEM_SEPARATOR -} uiItemType; - -enum uiItemFlag { - ITEM_ICON, - ITEM_TEXT -}; - -typedef struct uiItem { - struct uiItem *next, *prev; - uiItemType type; - int slot; - - char *name; - char namestr[UI_MAX_NAME_STR]; - int icon; - int disabled; -} uiItem; - -typedef struct uiItemRNA { - uiItem item; - - PointerRNA ptr; - PropertyRNA *prop; - int index, value; - int expand; -} uiItemRNA; +/* uiLayoutCommon */ -typedef struct uiItemOp { - uiItem item; +typedef struct uiLayoutCommon { + int type; + int opcontext; - wmOperatorType *ot; - IDProperty *properties; - int context; -} uiItemOp; + int emw, emh; -typedef struct uiItemMenu { - uiItem item; + uiMenuHandleFunc handlefunc; + void *argv; - char *menuname; - uiMenuCreateFunc func; - void *arg, *argN; -} uiItemMenu; + uiStyle *style; + uiBlock *block; +} uiLayoutCommon; -typedef struct uiItemValue { - uiItem item; +/* Item */ - int argval; -} uiItemValue; +typedef enum uiItemType { + ITEM_BUTTON, -/* Template */ + ITEM_LAYOUT_ROW, + ITEM_LAYOUT_COLUMN, + ITEM_LAYOUT_COLUMN_FLOW, + ITEM_LAYOUT_ROW_FLOW, + ITEM_LAYOUT_BOX, + ITEM_LAYOUT_FREE, + ITEM_LAYOUT_SPLIT, -typedef enum uiTemplateType { - TEMPLATE_ROW, - TEMPLATE_COLUMN, + ITEM_LAYOUT_ROOT +#if 0 TEMPLATE_COLUMN_FLOW, TEMPLATE_SPLIT, TEMPLATE_BOX, TEMPLATE_HEADER, TEMPLATE_HEADER_ID -} uiTemplateType; +#endif +} uiItemType; + +typedef struct uiItem { + void *next, *prev; + uiItemType type; +} uiItem; -typedef struct uiTemplate { - struct uiTemplate *next, *prev; - uiTemplateType type; +typedef struct uiButtonItem { + uiItem item; + uiBut *but; +} uiButtonItem; + +struct uiLayout { + uiItem item; + uiLayoutCommon *common; ListBase items; - int slot; -} uiTemplate; -typedef struct uiTemplateFlow { - uiTemplate template; + int x, y, w, h; + int space; + int align; +}; + +typedef struct uiLayoutItemFlow { + uiLayout litem; int number; -} uiTemplateFlow; + int totcol; +} uiLayoutItemFlow; -typedef struct uiTemplateSplt { - uiTemplate template; +typedef struct uiLayoutItemSplt { + uiLayout litem; int number; int lr; - uiLayout **sublayout; -} uiTemplateSplt; - -typedef struct uiTemplateBx { - uiTemplate template; - uiLayout *sublayout; -} uiTemplateBx; - -typedef struct uiTemplateHeadID { - uiTemplate template; - - PointerRNA ptr; - PropertyRNA *prop; - - int flag; - short browse; - char *newop; - char *openop; - char *unlinkop; -} uiTemplateHeadID; - -/* Layout */ - -struct uiLayout { - ListBase templates; - int opcontext; - int dir, type; - int x, y, w, h; - int emw, emh; +} uiLayoutItemSplt; - uiMenuHandleFunc handlefunc; - void *argv; +typedef struct uiLayoutItemBx { + uiLayout litem; +} uiLayoutItemBx; - uiStyle *style; -}; - -void ui_layout_free(uiLayout *layout); -void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y); +typedef struct uiLayoutItemRoot { + uiLayout litem; +} uiLayoutItemRoot; /************************** 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; - } -} -static void ui_item_name_add_colon(uiItem *item) +static char *ui_item_name_add_colon(char *name, char namestr[UI_MAX_NAME_STR]) { - int len= strlen(item->namestr); + int len= strlen(name); - if(len != 0 && len+1 < sizeof(item->namestr)) { - item->namestr[len]= ':'; - item->namestr[len+1]= '\0'; + if(len != 0 && len+1 < UI_MAX_NAME_STR) { + BLI_strncpy(namestr, name, UI_MAX_NAME_STR); + namestr[len]= ':'; + namestr[len+1]= '\0'; + return namestr; } + + return name; } #define UI_FIT_EXPAND 1 static int ui_item_fit(int item, int pos, int all, int available, int spacing, int last, int flag) { - if(all > available-spacing) { + /* available == 0 is unlimited */ + + if(available != 0 && all > available-spacing) { /* contents is bigger than available space */ if(last) return available-pos; @@ -209,7 +181,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i } else { /* contents is smaller or equal to available space */ - if(flag & UI_FIT_EXPAND) { + if(available != 0 && (flag & UI_FIT_EXPAND)) { if(last) return available-pos; else @@ -220,54 +192,162 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i } } +/* variable button size in which direction? */ +#define UI_ITEM_VARY_X 1 +#define UI_ITEM_VARY_Y 2 + +static int ui_layout_vary_direction(uiLayout *layout) +{ + return (layout->common->type == UI_LAYOUT_HEADER)? UI_ITEM_VARY_X: UI_ITEM_VARY_Y; +} + +/* estimated size of text + icon */ +static int ui_text_icon_width(uiLayout *layout, char *name, int icon) +{ + int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X; + + if(icon && strcmp(name, "") == 0) + return UI_UNIT_X; /* icon only */ + else if(icon) + return (variable)? UI_GetStringWidth(name) + UI_UNIT_X: 10*UI_UNIT_X; /* icon + text */ + else + return (variable)? UI_GetStringWidth(name) + UI_UNIT_X: 10*UI_UNIT_X; /* text only */ +} + +static void ui_item_size(uiItem *item, int *r_w, int *r_h) +{ + if(item->type == ITEM_BUTTON) { + uiButtonItem *bitem= (uiButtonItem*)item; + + if(r_w) *r_w= bitem->but->x2 - bitem->but->x1; + if(r_h) *r_h= bitem->but->y2 - bitem->but->y1; + } + else { + uiLayout *litem= (uiLayout*)item; + + if(r_w) *r_w= litem->w; + if(r_h) *r_h= litem->h; + } +} + +static void ui_item_offset(uiItem *item, int *r_x, int *r_y) +{ + if(item->type == ITEM_BUTTON) { + uiButtonItem *bitem= (uiButtonItem*)item; + + if(r_x) *r_x= bitem->but->x1; + if(r_y) *r_y= bitem->but->y1; + } + else { + if(r_x) *r_x= 0; + if(r_y) *r_y= 0; + } +} + +static void ui_item_position(uiItem *item, int x, int y, int w, int h) +{ + if(item->type == ITEM_BUTTON) { + uiButtonItem *bitem= (uiButtonItem*)item; + + bitem->but->x1= x; + bitem->but->y1= y; + bitem->but->x2= x+w; + bitem->but->y2= y+h; + } + else { + uiLayout *litem= (uiLayout*)item; + + litem->x= x; + litem->y= y+h; + litem->w= w; + litem->h= h; + } +} + +/******************** Special RNA Items *********************/ + +static int ui_layout_local_dir(uiLayout *layout) +{ + switch(layout->item.type) { + case ITEM_LAYOUT_ROW: + case ITEM_LAYOUT_ROOT: + return UI_LAYOUT_HORIZONTAL; + case ITEM_LAYOUT_COLUMN: + case ITEM_LAYOUT_COLUMN_FLOW: + case ITEM_LAYOUT_SPLIT: + case ITEM_LAYOUT_FREE: + case ITEM_LAYOUT_BOX: + default: + return UI_LAYOUT_VERTICAL; + } +} + +static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, int align) +{ + uiLayout *sub; + + if(ui_layout_local_dir(test) == UI_LAYOUT_HORIZONTAL) + sub= uiLayoutRow(layout, align); + else + sub= uiLayoutColumn(layout, align); + + sub->space= 0; + return sub; +} + /* create buttons for an item with an RNA array */ -static void ui_item_array(uiLayout *layout, uiBlock *block, uiItemRNA *rnaitem, int len, int x, int y, int w, int h) +static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int h, int expand) { - uiStyle *style= layout->style; + uiStyle *style= layout->common->style; PropertyType type; PropertySubType subtype; + uiLayout *sub; int a; /* retrieve type and subtype */ - type= RNA_property_type(rnaitem->prop); - subtype= RNA_property_subtype(rnaitem->prop); + type= RNA_property_type(prop); + subtype= RNA_property_subtype(prop); + + sub= ui_item_local_sublayout(layout, layout, 0); + uiBlockSetCurLayout(block, sub); /* create label */ - 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, ""); + if(strcmp(name, "") != 0) + uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* create buttons */ - uiBlockBeginAlign(block); - if(type == PROP_BOOLEAN && len == 20) { /* special check for layer layout */ - int butw, buth; + int butw, buth, unit; - butw= ui_item_fit(EM_UNIT_X, 0, EM_UNIT_X*10 + style->buttonspacex, w, 0, 0, UI_FIT_EXPAND); - buth= MIN2(EM_UNIT_Y, butw); + uiBlockSetCurLayout(block, uiLayoutFree(layout, 0)); - y += 2*(EM_UNIT_Y - buth); + unit= UI_UNIT_X*0.75; + butw= unit; + buth= unit; uiBlockBeginAlign(block); for(a=0; a<5; a++) - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth); + uiDefAutoButR(block, ptr, prop, a, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth); for(a=0; a<5; a++) - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth); + uiDefAutoButR(block, ptr, prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth); uiBlockEndAlign(block); x += 5*butw + style->buttonspacex; uiBlockBeginAlign(block); for(a=0; a<5; a++) - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+5, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth); + uiDefAutoButR(block, ptr, prop, a+5, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth); for(a=0; a<5; a++) - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+15, "", ICON_BLANK1, x + butw*a, y, butw, buth); + uiDefAutoButR(block, ptr, prop, a+15, "", ICON_BLANK1, x + butw*a, y, butw, buth); uiBlockEndAlign(block); } else if(subtype == PROP_MATRIX) { /* matrix layout */ int row, col; + uiBlockSetCurLayout(block, uiLayoutFree(layout, 1)); + len= ceil(sqrt(len)); h /= len; @@ -278,315 +358,156 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, uiItemRNA *rnaitem, col= a%len; row= a/len; - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", 0, x + w*col, y+(row-a-1)*EM_UNIT_Y, w, EM_UNIT_Y); + uiDefAutoButR(block, ptr, prop, a, "", 0, x + w*col, y+(row-a-1)*UI_UNIT_Y, w, UI_UNIT_Y); } } else if(len <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) { - /* layout for known array subtypes */ - static char vectoritem[4]= {'X', 'Y', 'Z', 'W'}; - static char quatitem[4]= {'W', 'X', 'Y', 'Z'}; - static char coloritem[4]= {'R', 'G', 'B', 'A'}; - char str[3]; - - for(a=0; a<len; a++) { - if(len == 4 && subtype == PROP_ROTATION) - str[0]= quatitem[a]; - else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION) - str[0]= vectoritem[a]; - else - str[0]= coloritem[a]; + uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, sub, 1)); + + if(subtype == PROP_COLOR) + uiDefAutoButR(block, ptr, prop, -1, "", 0, 0, 0, w, UI_UNIT_Y); + + if(subtype != PROP_COLOR || expand) { + /* layout for known array subtypes */ + static char vectoritem[4]= {'X', 'Y', 'Z', 'W'}; + static char quatitem[4]= {'W', 'X', 'Y', 'Z'}; + static char coloritem[4]= {'R', 'G', 'B', 'A'}; + char str[3]; + + for(a=0; a<len; a++) { + if(len == 4 && subtype == PROP_ROTATION) + str[0]= quatitem[a]; + else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION) + str[0]= vectoritem[a]; + else + str[0]= coloritem[a]; + + if(type == PROP_BOOLEAN) { + str[1]= '\0'; + } + else { + str[1]= ':'; + str[2]= '\0'; + } - if(type == PROP_BOOLEAN) { - str[1]= '\0'; - } - else { - str[1]= ':'; - str[2]= '\0'; + uiDefAutoButR(block, ptr, prop, a, str, 0, 0, 0, w, UI_UNIT_Y); } - - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, str, 0, x, y+(len-a-1)*EM_UNIT_Y, w, EM_UNIT_Y); } + else if(subtype == PROP_COLOR && len == 4) + uiDefAutoButR(block, ptr, prop, 3, "A:", 0, 0, 0, w, UI_UNIT_Y); } else { /* default array layout */ + uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, sub, 1)); + for(a=0; a<len; a++) - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", 0, x, y+(len-a-1)*EM_UNIT_Y, w, EM_UNIT_Y); + uiDefAutoButR(block, ptr, prop, a, "", 0, 0, 0, w, UI_UNIT_Y); } - uiBlockEndAlign(block); + uiBlockSetCurLayout(block, layout); } -static void ui_item_enum_row(uiBlock *block, uiItemRNA *rnaitem, int x, int y, int w, int h) +static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int x, int y, int w, int h) { const EnumPropertyItem *item; - int a, totitem, pos, itemw; + int a, totitem, itemw; const char *propname; - - propname= RNA_property_identifier(rnaitem->prop); - RNA_property_enum_items(&rnaitem->ptr, rnaitem->prop, &item, &totitem); - uiBlockBeginAlign(block); - pos= 0; + propname= RNA_property_identifier(prop); + RNA_property_enum_items(ptr, prop, &item, &totitem); + + uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1)); for(a=0; a<totitem; a++) { - itemw= ui_item_fit(1, pos, totitem, w, 0, a == totitem-1, UI_FIT_EXPAND); - uiDefButR(block, ROW, 0, NULL, x+pos, y, itemw, h, &rnaitem->ptr, propname, -1, 0, item[a].value, -1, -1, NULL); - pos += itemw; + 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); } - uiBlockEndAlign(block); + uiBlockSetCurLayout(block, layout); } /* create label + button for RNA property */ -static void ui_item_with_label(uiBlock *block, uiItemRNA *rnaitem, int x, int y, int w, int h) +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) { - if(strcmp(rnaitem->item.name, "") != 0) { - w= w/2; - uiDefBut(block, LABEL, 0, rnaitem->item.name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); - x += w; - } + uiLayout *sub; + PropertySubType subtype; - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, rnaitem->index, "", rnaitem->item.icon, x, y, w, h); -} - -/* create buttons for an arbitrary item */ -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 */ - uiItemRNA *rnaitem= (uiItemRNA*)item; - PropertyType type; - int len; - - /* retrieve info */ - type= RNA_property_type(rnaitem->prop); - len= RNA_property_array_length(rnaitem->prop); - - /* array property */ - if(rnaitem->index == RNA_NO_INDEX && len > 0) - 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); - /* property with separate label */ - else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) - ui_item_with_label(block, rnaitem, x, y, w, h); - /* single button */ - else - uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, rnaitem->index, (char*)item->name, item->icon, x, y, w, h); - } - else if(item->type == ITEM_OPERATOR) { - /* operator */ - uiItemOp *opitem= (uiItemOp*)item; - uiBut *but; - - 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); - /* text only */ - else - but= uiDefButO(block, BUT, opitem->ot->idname, opitem->context, (char*)item->name, x, y, w, h, NULL); + sub= uiLayoutRow(layout, 0); + uiBlockSetCurLayout(block, sub); - if(but && opitem->properties) { - /* assign properties */ - PointerRNA *opptr= uiButGetOperatorPtrRNA(but); - opptr->data= opitem->properties; - opitem->properties= NULL; - } + if(strcmp(name, "") != 0) { + w= w/2; + uiDefBut(block, LABEL, 0, name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); } - else if(item->type == ITEM_MENU) { - /* menu */ - uiBut *but; - uiItemMenu *menuitem= (uiItemMenu*)item; - - 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 && 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) - 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, ""); + subtype= RNA_property_subtype(prop); - 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 */ - uiDefBut(block, SEPR, 0, "", x, y, w, h, NULL, 0.0, 0.0, 0, 0, ""); + 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 */ } -} - -/* estimated size of text + icon */ -static int ui_text_icon_width(char *name, int icon, int variable) -{ - if(icon && strcmp(name, "") == 0) - return EM_UNIT_X; /* icon only */ - else if(icon) - return (variable)? UI_GetStringWidth(name) + EM_UNIT_X: 10*EM_UNIT_X; /* icon + text */ else - return (variable)? UI_GetStringWidth(name) + EM_UNIT_X: 10*EM_UNIT_X; /* text only */ -} - -/* estimated size of an item */ -#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; + uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h); - if(item->type == ITEM_RNA_PROPERTY) { - /* RNA property */ - uiItemRNA *rnaitem= (uiItemRNA*)item; - PropertyType type; - PropertySubType subtype; - int len; - - w= ui_text_icon_width(item->name, item->icon, flag & UI_ITEM_VARY_X); - h= EM_UNIT_Y; - - /* arbitrary extended width by type */ - type= RNA_property_type(rnaitem->prop); - subtype= RNA_property_subtype(rnaitem->prop); - len= RNA_property_array_length(rnaitem->prop); - - if(type == PROP_STRING) - w += 10*EM_UNIT_X; - - /* increase height for arrays */ - if(rnaitem->index == RNA_NO_INDEX && len > 0) { - if(strcmp(item->name, "") == 0 && item->icon == 0) - h= 0; - - if(type == PROP_BOOLEAN && len == 20) - h += 2*EM_UNIT_Y; - else if(subtype == PROP_MATRIX) - h += ceil(sqrt(len))*EM_UNIT_Y; - 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 */ - if(item->type == ITEM_SEPARATOR) { - w= EM_SEPR_X; - h= EM_SEPR_Y; - } - else { - w= ui_text_icon_width(item->name, item->icon, flag & UI_ITEM_VARY_X); - h= EM_UNIT_Y; - } - } - - if(r_w) *r_w= w; - if(r_h) *r_h= h; + uiBlockSetCurLayout(block, layout); } -static void ui_item_free(uiItem *item) -{ - if(item->type == ITEM_OPERATOR) { - uiItemOp *opitem= (uiItemOp*)item; - - if(opitem->properties) { - IDP_FreeProperty(opitem->properties); - MEM_freeN(opitem->properties); - } - } -} +/********************* Button Items *************************/ /* disabled item */ static void ui_item_disabled(uiLayout *layout, char *name) { - uiTemplate *template= layout->templates.last; - uiItem *item; - - if(!template) - return; + uiBlock *block= layout->common->block; + uiBut *but; + int w; + + uiBlockSetCurLayout(block, layout); - item= MEM_callocN(sizeof(uiItem), "uiItem"); + if(!name) + name= ""; - ui_item_name(item, name); - item->disabled= 1; - item->type= ITEM_LABEL; - item->slot= template->slot; + w= ui_text_icon_width(layout, name, 0); - BLI_addtail(&template->items, item); + but= uiDefBut(block, LABEL, 0, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but->flag |= UI_BUT_DISABLED; + but->lock = 1; + but->lockstr = ""; } /* operator items */ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context) { - uiTemplate *template= layout->templates.last; + uiBlock *block= layout->common->block; wmOperatorType *ot= WM_operatortype_find(idname); - uiItemOp *opitem; + uiBut *but; + int w; - if(!template) - return; if(!ot) { ui_item_disabled(layout, idname); return; } - opitem= MEM_callocN(sizeof(uiItemOp), "uiItemOp"); + if(!name) + name= ot->name; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; - ui_item_name(&opitem->item, name); - opitem->item.icon= icon; - opitem->item.type= ITEM_OPERATOR; - opitem->item.slot= template->slot; + /* create button */ + uiBlockSetCurLayout(block, layout); - opitem->ot= ot; - opitem->properties= properties; - opitem->context= context; + w= ui_text_icon_width(layout, name, icon); + + if(icon && strcmp(name, "") != 0) + but= uiDefIconTextButO(block, BUT, ot->idname, context, icon, (char*)name, 0, 0, w, UI_UNIT_Y, NULL); + else if(icon) + but= uiDefIconButO(block, BUT, ot->idname, context, icon, 0, 0, w, UI_UNIT_Y, NULL); + else + but= uiDefButO(block, BUT, ot->idname, context, (char*)name, 0, 0, w, UI_UNIT_Y, NULL); - BLI_addtail(&template->items, opitem); + /* assign properties */ + if(properties) { + PointerRNA *opptr= uiButGetOperatorPtrRNA(but); + opptr->data= properties; + } } static char *ui_menu_enumpropname(char *opname, char *propname, int retval) @@ -597,16 +518,16 @@ static char *ui_menu_enumpropname(char *opname, char *propname, int retval) 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; @@ -626,7 +547,7 @@ void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *pro if(!name) name= ui_menu_enumpropname(opname, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); } void uiItemsEnumO(uiLayout *layout, char *opname, char *propname) @@ -661,7 +582,7 @@ void uiItemBooleanO(uiLayout *layout, char *name, int icon, char *opname, char * WM_operator_properties_create(&ptr, opname); RNA_boolean_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); } void uiItemIntO(uiLayout *layout, char *name, int icon, char *opname, char *propname, int value) @@ -671,7 +592,7 @@ void uiItemIntO(uiLayout *layout, char *name, int icon, char *opname, char *prop WM_operator_properties_create(&ptr, opname); RNA_int_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); } void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *propname, float value) @@ -681,7 +602,7 @@ void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *pr WM_operator_properties_create(&ptr, opname); RNA_float_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); } void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value) @@ -691,39 +612,112 @@ void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *p WM_operator_properties_create(&ptr, opname); RNA_string_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); } void uiItemO(uiLayout *layout, char *name, int icon, char *opname) { - uiItemFullO(layout, name, icon, opname, NULL, layout->opcontext); + uiItemFullO(layout, name, icon, opname, NULL, layout->common->opcontext); } /* RNA property items */ + +static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA *prop, int index, int *r_w, int *r_h) +{ + PropertyType type; + PropertySubType subtype; + int len, w, h; + + w= ui_text_icon_width(layout, name, icon); + h= UI_UNIT_Y; + + /* arbitrary extended width by type */ + type= RNA_property_type(prop); + subtype= RNA_property_subtype(prop); + len= RNA_property_array_length(prop); + + if(type == PROP_STRING) + w += 10*UI_UNIT_X; + + /* increase height for arrays */ + if(index == RNA_NO_INDEX && len > 0) { + if(strcmp(name, "") == 0 && icon == 0) + h= 0; + + if(type == PROP_BOOLEAN && len == 20) + h += 2*UI_UNIT_Y; + else if(subtype == PROP_MATRIX) + h += ceil(sqrt(len))*UI_UNIT_Y; + else + h += len*UI_UNIT_Y; + } + else if(ui_layout_vary_direction(layout) == UI_ITEM_VARY_X) { + if(type == PROP_BOOLEAN && strcmp(name, "") != 0) + w += UI_UNIT_X; + } + + *r_w= w; + *r_h= h; +} + 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; + uiBlock *block= layout->common->block; + PropertyType type; + char namestr[UI_MAX_NAME_STR]; + int len, w, h; if(!ptr->data || !prop) return; - if(!template) - return; - rnaitem= MEM_callocN(sizeof(uiItemRNA), "uiItemRNA"); + uiBlockSetCurLayout(block, layout); + + /* retrieve info */ + type= RNA_property_type(prop); + len= RNA_property_array_length(prop); - ui_item_name(&rnaitem->item, name); - rnaitem->item.icon= icon; - rnaitem->item.type= ITEM_RNA_PROPERTY; - rnaitem->item.slot= template->slot; + /* set name and icon */ + if(!name) + name= (char*)RNA_property_ui_name(prop); + + if(ELEM5(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_ENUM, PROP_POINTER)) + name= ui_item_name_add_colon(name, namestr); + if(type == PROP_BOOLEAN && len) + name= ui_item_name_add_colon(name, namestr); + + if(layout->common->type == UI_LAYOUT_MENU) { + if(type == PROP_BOOLEAN) + icon= (RNA_property_boolean_get(ptr, prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) + icon= (RNA_property_enum_get(ptr, prop) == value)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + } - rnaitem->ptr= *ptr; - rnaitem->prop= prop; - rnaitem->index= index; - rnaitem->value= value; - rnaitem->expand= expand; + /* get size */ + ui_item_rna_size(layout, name, icon, prop, index, &w, &h); - BLI_addtail(&template->items, rnaitem); + /* array property */ + if(index == RNA_NO_INDEX && len > 0) + ui_item_array(layout, block, name, icon, ptr, prop, len, 0, 0, w, h, expand); + /* enum item */ + else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) { + char *identifier= (char*)RNA_property_identifier(prop); + + if(icon && strcmp(name, "") != 0) + uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + else if(icon) + uiDefIconButR(block, ROW, 0, icon, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + else + uiDefButR(block, ROW, 0, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + } + /* expanded enum */ + else if(type == PROP_ENUM && expand) + ui_item_enum_row(layout, block, ptr, prop, 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); + /* single button */ + else + uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h); } void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand) @@ -740,7 +734,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop printf("uiItemR: property not found: %s\n", propname); return; } - + uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand); } @@ -758,7 +752,7 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, printf("uiItemEnumR: property not found: %s\n", propname); return; } - + uiItemFullR(layout, name, icon, ptr, prop, RNA_ENUM_VALUE, value, 0); } @@ -795,106 +789,127 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) mt->draw(C, &menu); } -void uiItemM(uiLayout *layout, char *name, int icon, char *menuname) +static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN) { - uiTemplate *template= layout->templates.last; - uiItemMenu *menuitem; - - if(!template) - return; - if(!menuname) - return; + uiBlock *block= layout->common->block; + uiBut *but; + int w, h; + + uiBlockSetCurLayout(block, layout); + + if(layout->common->type == UI_LAYOUT_HEADER) + uiBlockSetEmboss(block, UI_EMBOSSP); + + if(!name) + name= ""; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; + + w= ui_text_icon_width(layout, name, icon); + h= UI_UNIT_Y; + + if(layout->common->type == UI_LAYOUT_HEADER) /* ugly .. */ + w -= 3; + + if(icon) + but= uiDefIconTextMenuBut(block, func, arg, icon, (char*)name, 0, 0, w, h, ""); + else + but= uiDefMenuBut(block, func, arg, (char*)name, 0, 0, w, h, ""); - menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu"); + if(argN) { /* ugly .. */ + but->poin= (char*)but; + but->func_argN= argN; + } - ui_item_name(&menuitem->item, name); - menuitem->item.icon= icon; - menuitem->item.type= ITEM_MENU; - menuitem->item.slot= template->slot; + if(layout->common->type == UI_LAYOUT_HEADER) + uiBlockSetEmboss(block, UI_EMBOSS); +} - menuitem->func= ui_item_menutype_func; - menuitem->menuname= menuname; +void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname) +{ + ARegion *ar= CTX_wm_region(C); + MenuType *mt; + + if(!menuname) + return; - BLI_addtail(&template->items, menuitem); + for(mt=ar->type->menutypes.first; mt; mt=mt->next) { + if(strcmp(menuname, mt->idname) == 0) { + if(!name) + name= mt->label; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; + ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL); + break; + } + } } /* label item */ void uiItemL(uiLayout *layout, char *name, int icon) { - uiTemplate *template= layout->templates.last; - uiItem *item; - - if(!template) - return; + uiBlock *block= layout->common->block; + uiBut *but; + int w; - item= MEM_callocN(sizeof(uiItem), "uiItem"); + uiBlockSetCurLayout(block, layout); + + if(!name) + name= ""; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; - ui_item_name(item, name); - item->icon= icon; - item->type= ITEM_LABEL; - item->slot= template->slot; + w= ui_text_icon_width(layout, name, icon); - BLI_addtail(&template->items, item); + if(icon && strcmp(name, "") != 0) + but= uiDefIconTextBut(block, LABEL, 0, icon, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + else if(icon) + but= uiDefIconBut(block, LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + else + but= uiDefBut(block, LABEL, 0, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } /* value item */ void uiItemV(uiLayout *layout, char *name, int icon, int argval) { - uiTemplate *template= layout->templates.last; - uiItemValue *vitem; - - if(!template) - return; + /* label */ + uiBlock *block= layout->common->block; + float *retvalue= (block->handle)? &block->handle->retvalue: NULL; + int w; - vitem= MEM_callocN(sizeof(uiItemValue), "uiItemValue"); + uiBlockSetCurLayout(block, layout); - vitem->item.name= name; - vitem->item.icon= icon; - vitem->item.type= ITEM_VALUE; - vitem->item.slot= template->slot; - vitem->argval= argval; + if(!name) + name= ""; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; - BLI_addtail(&template->items, vitem); + w= ui_text_icon_width(layout, name, icon); + + if(icon && strcmp(name, "") != 0) + uiDefIconTextButF(block, BUTM, 0, icon, (char*)name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, ""); + else if(icon) + uiDefIconButF(block, BUTM, 0, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, ""); + else + uiDefButF(block, BUTM, 0, (char*)name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, ""); } /* separator item */ void uiItemS(uiLayout *layout) { - uiTemplate *template= layout->templates.last; - uiItem *item; - - if(!template) - return; - - item= MEM_callocN(sizeof(uiItem), "uiItem"); + uiBlock *block= layout->common->block; - item->type= ITEM_SEPARATOR; - item->slot= template->slot; - - BLI_addtail(&template->items, item); + uiBlockSetCurLayout(block, layout); + uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, ""); } /* level items */ void uiItemMenuF(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"); - - 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); + ui_item_menu(layout, name, icon, func, NULL, NULL); } typedef struct MenuItemLevel { @@ -915,36 +930,24 @@ 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); - 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(!name) name= ot->name; - - ui_item_name(&menuitem->item, name); - menuitem->item.icon= icon; - menuitem->item.type= ITEM_MENU; - menuitem->item.slot= template->slot; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); lvl->opname= opname; lvl->propname= propname; - lvl->opcontext= layout->opcontext; + lvl->opcontext= layout->common->opcontext; - menuitem->func= menu_item_enum_opname_menu; - menuitem->argN= lvl; - - BLI_addtail(&template->items, menuitem); + ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl); } static void menu_item_enum_rna_menu(bContext *C, uiLayout *layout, void *arg) @@ -957,13 +960,8 @@ static void menu_item_enum_rna_menu(bContext *C, uiLayout *layout, void *arg) void uiItemMenuEnumR(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) { @@ -971,118 +969,210 @@ void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA * return; } - menuitem= MEM_callocN(sizeof(uiItemMenu), "uiItemMenu"); - 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; + if(layout->common->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; 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; + lvl->opcontext= layout->common->opcontext; - BLI_addtail(&template->items, menuitem); + ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl); } -/**************************** Template ***************************/ +/**************************** Layout Items ***************************/ -/* single row layout */ -static void ui_layout_row(uiLayout *layout, uiBlock *block, uiTemplate *template) +/* single-row layout */ +static void ui_litem_estimate_row(uiLayout *litem) { - uiStyle *style= layout->style; uiItem *item; - int tot=0, totw= 0, maxh= 0, itemw, itemh, x, w; + int itemw, itemh; + + litem->w= 0; + litem->h= 0; + + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); + + litem->w += itemw; + litem->h= MAX2(itemh, litem->h); + + if(item->next) + litem->w += litem->space; + } +} + +static void ui_litem_layout_row(uiLayout *litem) +{ + uiItem *item; + int neww, itemw, itemh, x, y, w, tot= 0, totw= 0, extra=0, available=0; + + x= litem->x; + y= litem->y; + w= litem->w; - /* estimate total width of buttons */ - for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); totw += itemw; - maxh= MAX2(maxh, itemh); tot++; } if(totw == 0) return; - /* create buttons starting from left */ - x= 0; - w= layout->w; + /* two step to enforce minimum button with .. could be better */ + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); + + itemw= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND); + x += itemw; + + if(itemw < UI_UNIT_X) + extra += UI_UNIT_X - itemw; + else + available += itemw - UI_UNIT_X; + + if(item->next) + x += litem->space; + } + + x= litem->x; - for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); - itemw= ui_item_fit(itemw, x, totw, w, (tot-1)*style->buttonspacex, !item->next, UI_FIT_EXPAND); + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); - ui_item_buts(layout, block, item, layout->x+x, layout->y-itemh, itemw, itemh); - x += itemw+style->buttonspacex; + neww= ui_item_fit(itemw, x-litem->x, totw, w, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND); + if(neww < UI_UNIT_X) { + if(item->next) + itemw= UI_UNIT_X; + else + itemw= litem->w - (x-litem->x); + } + else + itemw= ui_item_fit(itemw, x-litem->x, totw, w-extra, (tot-1)*litem->space, !item->next, UI_FIT_EXPAND); + + ui_item_position(item, x, y-itemh, itemw, itemh); + x += itemw; + + if(item->next) + x += litem->space; } - layout->y -= maxh; + litem->w= x - litem->x; + litem->h= litem->y - y; + litem->x= x; + litem->y= y; } -/* multi-column layout */ -static void ui_layout_column(uiLayout *layout, uiBlock *block, uiTemplate *template) +/* single-column layout */ +static void ui_litem_estimate_column(uiLayout *litem) { - uiStyle *style= layout->style; uiItem *item; - int col, totcol= 0, x, y, miny, itemw, itemh, w; + int itemw, itemh; - /* compute number of columns */ - for(item=template->items.first; item; item=item->next) - totcol= MAX2(item->slot+1, totcol); - - if(totcol == 0) - return; - - x= 0; - miny= 0; - w= layout->w; + litem->w= 0; + litem->h= 0; - /* create column per column */ - for(col=0; col<totcol; col++) { - y= 0; + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); - itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*style->columnspace, col == totcol-1, UI_FIT_EXPAND); + litem->w= MAX2(litem->w, itemw); + litem->h += itemh; - for(item=template->items.first; item; item=item->next) { - if(item->slot != col) - continue; + if(item->next) + litem->h += litem->space; + } +} - ui_item_size(item, NULL, &itemh, UI_ITEM_VARY_Y); +static void ui_litem_layout_column(uiLayout *litem) +{ + uiItem *item; + int itemh, x, y; - y -= itemh; - ui_item_buts(layout, block, item, layout->x+x, layout->y+y, itemw, itemh); - y -= style->buttonspacey; - } + x= litem->x; + y= litem->y; - x += itemw + style->columnspace; - miny= MIN2(miny, y); + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, NULL, &itemh); + + y -= itemh; + ui_item_position(item, x, y, litem->w, itemh); + + if(item->next) + y -= litem->space; } - layout->y += miny; + litem->h= litem->y - y; + litem->x= x; + litem->y= y; +} + +/* root layout */ +static void ui_litem_estimate_root(uiLayout *litem) +{ + /* nothing to do */ +} + +static void ui_litem_layout_root(uiLayout *litem) +{ + if(litem->common->type == UI_LAYOUT_HEADER) + ui_litem_layout_row(litem); + else + ui_litem_layout_column(litem); +} + +/* box layout */ +static void ui_litem_estimate_box(uiLayout *litem) +{ + uiStyle *style= litem->common->style; + + ui_litem_estimate_column(litem); + litem->w += 2*style->boxspace; + litem->h += 2*style->boxspace; +} + +static void ui_litem_layout_box(uiLayout *litem) +{ + uiStyle *style= litem->common->style; + int w, h; + + w= litem->w; + h= litem->h; + + litem->x += style->boxspace; + litem->y -= style->boxspace; + + if(w != 0) litem->w -= 2*style->boxspace; + if(h != 0) litem->h -= 2*style->boxspace; + + ui_litem_layout_column(litem); + + litem->x -= style->boxspace; + litem->y -= style->boxspace; + + if(w != 0) litem->w += 2*style->boxspace; + if(h != 0) litem->h += 2*style->boxspace; + + /* roundbox around the sublayout */ + uiDefBut(litem->common->block, ROUNDBOX, 0, "", litem->x, litem->y, litem->w, litem->h, NULL, 7.0, 0.0, 3, 20, ""); } /* multi-column layout, automatically flowing to the next */ -static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate *template) +static void ui_litem_estimate_column_flow(uiLayout *litem) { - uiStyle *style= layout->style; - uiTemplateFlow *flow= (uiTemplateFlow*)template; + uiStyle *style= litem->common->style; + uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem; uiItem *item; - int col, x, y, w, emh, emy, miny, itemw, itemh, maxw=0; - int toth, totcol, totitem; + int col, x, y, emh, emy, miny, itemw, itemh, maxw=0; + int toth, totitem; /* compute max needed width and total height */ toth= 0; totitem= 0; - for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); maxw= MAX2(maxw, itemw); toth += itemh; totitem++; @@ -1090,14 +1180,16 @@ static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate * if(flow->number <= 0) { /* auto compute number of columns, not very good */ - if(maxw == 0) + if(maxw == 0) { + flow->totcol= 1; return; + } - totcol= MAX2(layout->emw/maxw, 1); - totcol= MIN2(totcol, totitem); + flow->totcol= MAX2(litem->common->emw/maxw, 1); + flow->totcol= MIN2(flow->totcol, totitem); } else - totcol= flow->number; + flow->totcol= flow->number; /* compute sizes */ x= 0; @@ -1105,742 +1197,512 @@ static void ui_layout_column_flow(uiLayout *layout, uiBlock *block, uiTemplate * emy= 0; miny= 0; - w= layout->w; - emh= toth/totcol; + maxw= 0; + emh= toth/flow->totcol; /* create column per column */ col= 0; - for(item=template->items.first; item; item=item->next) { - ui_item_size(item, NULL, &itemh, UI_ITEM_VARY_Y); - itemw= ui_item_fit(1, x, totcol, w, (totcol-1)*style->columnspace, col == totcol-1, UI_FIT_EXPAND); - - y -= itemh; - emy -= itemh; - ui_item_buts(layout, block, item, layout->x+x, layout->y+y, itemw, itemh); - y -= style->buttonspacey; + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); + + y -= itemh + style->buttonspacey; miny= MIN2(miny, y); + emy -= itemh; + maxw= MAX2(itemw, maxw); /* decide to go to next one */ - if(col < totcol-1 && emy <= -emh) { - x += itemw + style->columnspace; + if(col < flow->totcol-1 && emy <= -emh) { + x += maxw + litem->space; + maxw= 0; y= 0; col++; } } - layout->y += miny; + litem->h= litem->y - miny; } -#if 0 -/* left-right layout, with buttons aligned on both sides */ -static void ui_layout_split(uiLayout *layout, uiBlock *block, uiTemplate *template) +static void ui_litem_layout_column_flow(uiLayout *litem) { + uiStyle *style= litem->common->style; + uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem; uiItem *item; - int tot=0, totw= 0, maxh= 0, itemw, itemh, lx, rx, w; + int col, x, y, w, emh, emy, miny, itemw, itemh; + int toth, totitem; - /* estimate total width of buttons */ - for(item=template->items.first; item; item=item->next) { - ui_item_size(item, &itemw, &itemh, UI_ITEM_VARY_Y); - totw += itemw; - maxh= MAX2(maxh, itemh); - tot++; + /* compute max needed width and total height */ + toth= 0; + totitem= 0; + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, &itemw, &itemh); + toth += itemh; + totitem++; } - if(totw == 0) - return; + /* compute sizes */ + x= litem->x; + y= litem->y; + emy= 0; + miny= 0; + + w= litem->w; + emh= toth/flow->totcol; + + /* create column per column */ + col= 0; + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, NULL, &itemh); + itemw= ui_item_fit(1, x-litem->x, flow->totcol, w, (flow->totcol-1)*style->columnspace, col == flow->totcol-1, UI_FIT_EXPAND); - /* create buttons starting from left and right */ - lx= 0; - rx= 0; - w= layout->w - style->buttonspacex*(tot-1) + style->buttonspacex; - - for(item=template->items.first; item; item=item->next) { - 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(layout, block, item, layout->x+lx, layout->y-itemh, itemw, itemh); - lx += itemw + style->buttonspacex; - } - else { - itemw= ui_item_fit(itemw, totw + rx, totw, w, 0, 0); - rx -= itemw + style->buttonspacex; - ui_item_buts(layout, block, item, layout->x+layout->w+rx, layout->y-itemh, itemw, itemh); + y -= itemh; + emy -= itemh; + ui_item_position(item, x, y, itemw, itemh); + y -= style->buttonspacey; + miny= MIN2(miny, y); + + /* decide to go to next one */ + if(col < flow->totcol-1 && emy <= -emh) { + x += itemw + style->columnspace; + y= litem->y; + col++; } } - layout->y -= maxh; + litem->h= litem->y - miny; + litem->x= x; + litem->y= miny; } -#endif -/* split in columns */ -static void ui_layout_split(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) +/* free layout */ +static void ui_litem_estimate_free(uiLayout *litem) { - uiStyle *style= layout->style; - uiTemplateSplt *split= (uiTemplateSplt*)template; - uiLayout *sublayout; - int a, x, y, miny, w= layout->w, h= layout->h, splitw; - - x= 0; - y= 0; - miny= layout->y; - - for(a=0; a<split->number; a++) { - sublayout= split->sublayout[a]; + uiItem *item; + int itemx, itemy, itemw, itemh, minx, miny; - splitw= ui_item_fit(1, x, split->number, w, (split->number-1)*style->columnspace, a == split->number-1, UI_FIT_EXPAND); - sublayout->x= layout->x + x; - sublayout->w= splitw; - sublayout->y= layout->y; - sublayout->h= h; + minx= 1e6; + miny= 1e6; + litem->w= 0; + litem->h= 0; - sublayout->emw= layout->emw/split->number; - sublayout->emh= layout->emh; + for(item=litem->items.first; item; item=item->next) { + ui_item_offset(item, &itemx, &itemy); + ui_item_size(item, &itemw, &itemh); - /* do layout for elements in sublayout */ - ui_layout_end(C, block, sublayout, NULL, &y); - miny= MIN2(y, miny); + minx= MIN2(minx, itemx); + miny= MIN2(miny, itemy); - x += splitw + style->columnspace; + litem->w= MAX2(litem->w, itemx+itemw); + litem->h= MAX2(litem->h, itemy+itemh); } - layout->y= miny; + litem->w -= minx; + litem->h -= miny; } -/* element in a box layout */ -static void ui_layout_box(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) +static void ui_litem_layout_free(uiLayout *litem) { - uiStyle *style= layout->style; - uiTemplateBx *box= (uiTemplateBx*)template; - int starty, startx, w= layout->w, h= layout->h; + uiItem *item; + float scalex=1.0f, scaley=1.0f; + int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth; - startx= layout->x; - starty= layout->y; + minx= 1e6; + miny= 1e6; + totw= 0; + toth= 0; - /* some extra padding */ - box->sublayout->x= layout->x + style->boxspace; - box->sublayout->w= w - 2*style->boxspace; - box->sublayout->y= layout->y - style->boxspace; - box->sublayout->h= h; + for(item=litem->items.first; item; item=item->next) { + ui_item_offset(item, &itemx, &itemy); + ui_item_size(item, &itemw, &itemh); - box->sublayout->emw= layout->emw; - box->sublayout->emh= layout->emh; + minx= MIN2(minx, itemx); + miny= MIN2(miny, itemy); - /* do layout for elements in sublayout */ - ui_layout_end(C, block, box->sublayout, NULL, &layout->y); + totw= MAX2(totw, itemx+itemw); + toth= MAX2(toth, itemy+itemh); + } - /* roundbox around the sublayout */ - uiDefBut(block, ROUNDBOX, 0, "", startx, layout->y, w, starty - layout->y, NULL, 7.0, 0.0, 3, 20, ""); -} + totw -= minx; + toth -= miny; -static void ui_layout_header_buttons(uiLayout *layout, uiBlock *block, uiTemplate *template) -{ - uiItem *item; - int itemw, itemh; + if(litem->w && totw > litem->w) + scalex= (float)litem->w/(float)totw; + if(litem->h && toth > litem->h) + scaley= (float)litem->h/(float)toth; - uiBlockBeginAlign(block); + x= litem->x; + y= litem->y - scalex*toth; - for(item=template->items.first; item; item=item->next) { - 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; - } + for(item=litem->items.first; item; item=item->next) { + ui_item_offset(item, &itemx, &itemy); + ui_item_size(item, &itemw, &itemh); - uiBlockEndAlign(block); -} - -static void ui_layout_header(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) -{ - ScrArea *sa= CTX_wm_area(C); + if(scalex != 1.0f) { + newx= itemx*scalex; + itemw= (itemx + itemw)*scalex - newx; + itemx= newx; + } - layout->x= ED_area_header_standardbuttons(C, block, layout->y); + if(scaley != 1.0f) { + newy= itemy*scaley; + itemh= (itemy + itemh)*scaley - newy; + itemy= newy; + } - if((sa->flag & HEADER_NO_PULLDOWN)==0) { - uiBlockSetEmboss(block, UI_EMBOSSP); - ui_layout_header_buttons(layout, block, template); + ui_item_position(item, x+itemx-minx, y+itemy-miny, itemw, itemh); } - uiBlockSetEmboss(block, UI_EMBOSS); + litem->w= scalex*totw; + litem->h= litem->y - y; + litem->x= x + litem->w; + litem->y= y; } -static void header_id_cb(bContext *C, void *arg_template, void *arg_event) +/* split layout */ +static void ui_litem_estimate_split(uiLayout *litem) { - 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 - } + ui_litem_estimate_row(litem); } -static void ui_layout_header_id(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template) +static void ui_litem_layout_split(uiLayout *litem) { - 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; + uiItem *item; + int itemh, x, y, w, tot=0, colw=0; - duptemplate= MEM_dupallocN(idtemplate); - IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse); + x= litem->x; + y= litem->y; + w= litem->w; - 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; + for(item=litem->items.first; item; item=item->next) + tot++; - MEM_freeN(str); - } + if(tot == 0) + return; + + colw= (litem->w - (tot-1)*litem->space)/tot; + colw= MAX2(colw, 0); - /* text button with name */ - if(idptr.data) { - char name[64]; + for(item=litem->items.first; item; item=item->next) { + ui_item_size(item, NULL, &itemh); - 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; + ui_item_position(item, x, y-itemh, colw, itemh); + x += colw; - /* 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; - } + if(item->next) + x += litem->space; } + + litem->w= x - litem->x; + litem->h= litem->y - y; + litem->x= x; + litem->y= y; } -void ui_template_free(uiTemplate *template) +/* layout create functions */ +uiLayout *uiLayoutRow(uiLayout *layout, int align) { - uiItem *item; - int a; - - if(template->type == TEMPLATE_BOX) { - uiTemplateBx *box= (uiTemplateBx*)template; - ui_layout_free(box->sublayout); - } - if(template->type == TEMPLATE_SPLIT) { - uiTemplateSplt *split= (uiTemplateSplt*)template; - - for(a=0; a<split->number; a++) - ui_layout_free(split->sublayout[a]); - MEM_freeN(split->sublayout); - } + uiLayout *litem; - for(item=template->items.first; item; item=item->next) - ui_item_free(item); + litem= MEM_callocN(sizeof(uiLayout), "uiLayoutRow"); + litem->item.type= ITEM_LAYOUT_ROW; + litem->common= layout->common; + litem->align= align; + litem->space= (align)? 0: layout->common->style->buttonspacex; + BLI_addtail(&layout->items, litem); - BLI_freelistN(&template->items); + return litem; } -/* template create functions */ -void uiLayoutRow(uiLayout *layout) +uiLayout *uiLayoutColumn(uiLayout *layout, int align) { - uiTemplate *template; + uiLayout *litem; - template= MEM_callocN(sizeof(uiTemplate), "uiTemplate"); - template->type= TEMPLATE_ROW; + litem= MEM_callocN(sizeof(uiLayout), "uiLayoutColumn"); + litem->item.type= ITEM_LAYOUT_COLUMN; + litem->common= layout->common; + litem->align= align; + litem->space= (litem->align)? 0: layout->common->style->buttonspacey; + BLI_addtail(&layout->items, litem); - BLI_addtail(&layout->templates, template); + return litem; } -void uiLayoutColumn(uiLayout *layout) +uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align) { - uiTemplate *template; + uiLayoutItemFlow *flow; - template= MEM_callocN(sizeof(uiTemplate), "uiTemplate"); - template->type= TEMPLATE_COLUMN; + flow= MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow"); + flow->litem.item.type= ITEM_LAYOUT_COLUMN_FLOW; + flow->litem.common= layout->common; + flow->litem.align= align; + flow->litem.space= (flow->litem.align)? 0: layout->common->style->columnspace; + flow->number= number; + BLI_addtail(&layout->items, flow); - BLI_addtail(&layout->templates, template); + return &flow->litem; } -void uiLayoutColumnFlow(uiLayout *layout, int number) +uiLayout *uiLayoutBox(uiLayout *layout) { - uiTemplateFlow *flow; + uiLayoutItemBx *box; - flow= MEM_callocN(sizeof(uiTemplateFlow), "uiTemplateFlow"); - flow->template.type= TEMPLATE_COLUMN_FLOW; - flow->number= number; - BLI_addtail(&layout->templates, flow); + box= MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx"); + box->litem.item.type= ITEM_LAYOUT_BOX; + box->litem.common= layout->common; + box->litem.space= layout->common->style->columnspace; + BLI_addtail(&layout->items, box); + + return &box->litem; } -uiLayout *uiLayoutBox(uiLayout *layout) +uiLayout *uiLayoutFree(uiLayout *layout, int align) { - uiTemplateBx *box; + uiLayout *litem; - box= MEM_callocN(sizeof(uiTemplateBx), "uiTemplateBx"); - box->template.type= TEMPLATE_BOX; - box->sublayout= uiLayoutBegin(layout->dir, layout->type, 0, 0, 0, 0, layout->style); - BLI_addtail(&layout->templates, box); + litem= MEM_callocN(sizeof(uiLayout), "uiLayoutFree"); + litem->item.type= ITEM_LAYOUT_FREE; + litem->common= layout->common; + litem->align= align; + BLI_addtail(&layout->items, litem); - return box->sublayout; + return litem; } -void uiLayoutSplit(uiLayout *layout, int number, int lr) +uiLayout *uiLayoutSplit(uiLayout *layout) { - uiTemplateSplt *split; - int a; + uiLayout *litem; - split= MEM_callocN(sizeof(uiTemplateSplt), "uiTemplateSplt"); - split->template.type= TEMPLATE_SPLIT; - split->number= number; - split->lr= lr; - split->sublayout= MEM_callocN(sizeof(uiLayout*)*number, "uiTemplateSpltSub"); + litem= uiLayoutRow(layout, 0); + litem->item.type = ITEM_LAYOUT_SPLIT; + litem->common= layout->common; + litem->space= layout->common->style->columnspace; - for(a=0; a<number; a++) - split->sublayout[a]= uiLayoutBegin(layout->dir, layout->type, 0, 0, 0, 0, layout->style); - - BLI_addtail(&layout->templates, split); + return litem; } -uiLayout *uiLayoutSub(uiLayout *layout, int n) +/********************** Layout *******************/ + +static void ui_item_estimate(uiItem *item) { - uiTemplate *template= layout->templates.last; + uiItem *subitem; + + if(item->type != ITEM_BUTTON) { + uiLayout *litem= (uiLayout*)item; + + for(subitem=litem->items.first; subitem; subitem=subitem->next) + ui_item_estimate(subitem); - if(template) { - switch(template->type) { - case TEMPLATE_SPLIT: - if(n >= 0 && n < ((uiTemplateSplt*)template)->number) - return ((uiTemplateSplt*)template)->sublayout[n]; + switch(litem->item.type) { + case ITEM_LAYOUT_COLUMN: + ui_litem_estimate_column(litem); + break; + case ITEM_LAYOUT_COLUMN_FLOW: + ui_litem_estimate_column_flow(litem); + break; + case ITEM_LAYOUT_ROW: + ui_litem_estimate_row(litem); + break; + case ITEM_LAYOUT_BOX: + ui_litem_estimate_box(litem); + break; + case ITEM_LAYOUT_ROOT: + ui_litem_estimate_root(litem); break; - case TEMPLATE_BOX: - return ((uiTemplateBx*)template)->sublayout; + case ITEM_LAYOUT_FREE: + ui_litem_estimate_free(litem); + break; + case ITEM_LAYOUT_SPLIT: + ui_litem_estimate_split(litem); break; default: break; } } - - return NULL; } -void uiTemplateHeader(uiLayout *layout) +static void ui_item_align(uiLayout *litem, int nr) { - uiTemplate *template; - - template= MEM_callocN(sizeof(uiTemplate), "uiTemplate"); - template->type= TEMPLATE_HEADER; + uiItem *item; - BLI_addtail(&layout->templates, template); + for(item=litem->items.first; item; item=item->next) { + if(item->type == ITEM_BUTTON) + ((uiButtonItem*)item)->but->alignnr= nr; + else + ui_item_align((uiLayout*)item, nr); + } } -void uiTemplateHeaderID(uiLayout *layout, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop) +static void ui_item_layout(uiItem *item, int align) { - uiTemplateHeadID *idtemplate; - PropertyRNA *prop; - - if(!ptr->data) - return; + uiItem *subitem; - prop= RNA_struct_find_property(ptr, propname); + if(item->type != ITEM_BUTTON) { + uiLayout *litem= (uiLayout*)item; - if(!prop) { - printf("uiTemplateHeaderID: property not found: %s\n", propname); - return; - } + if(litem->align && !align) + ui_item_align(litem, ++litem->common->block->alignnr); - idtemplate= MEM_callocN(sizeof(uiTemplateHeadID), "uiTemplateHeadID"); - idtemplate->template.type= TEMPLATE_HEADER_ID; - idtemplate->ptr= *ptr; - idtemplate->prop= prop; - idtemplate->flag= UI_ID_BROWSE|UI_ID_RENAME; + switch(litem->item.type) { + case ITEM_LAYOUT_COLUMN: + ui_litem_layout_column(litem); + break; + case ITEM_LAYOUT_COLUMN_FLOW: + ui_litem_layout_column_flow(litem); + break; + case ITEM_LAYOUT_ROW: + ui_litem_layout_row(litem); + break; + case ITEM_LAYOUT_BOX: + ui_litem_layout_box(litem); + break; + case ITEM_LAYOUT_ROOT: + ui_litem_layout_root(litem); + break; + case ITEM_LAYOUT_FREE: + ui_litem_layout_free(litem); + break; + case ITEM_LAYOUT_SPLIT: + ui_litem_layout_split(litem); + break; + default: + break; + } - if(newop) { - idtemplate->flag |= UI_ID_ADD_NEW; - idtemplate->newop= newop; + for(subitem=litem->items.first; subitem; subitem=subitem->next) + ui_item_layout(subitem, litem->align || align); } - if(openop) { - idtemplate->flag |= UI_ID_OPEN; - idtemplate->openop= openop; - } - if(unlinkop) { - idtemplate->flag |= UI_ID_DELETE; - idtemplate->unlinkop= unlinkop; - } - - BLI_addtail(&layout->templates, idtemplate); } -void uiTemplateSlot(uiLayout *layout, int slot) +static void ui_layout_items(const bContext *C, uiBlock *block, uiLayout *layout) { - uiTemplate *template= layout->templates.last; - - if(template) - template->slot= slot; + ui_item_estimate(&layout->item); + ui_item_layout(&layout->item, 0); } -/********************** Layout *******************/ - -static void ui_layout_init_items(const bContext *C, uiLayout *layout) +static void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) { - 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; - type= RNA_property_type(rnaitem->prop); + if(layout->common->handlefunc) + uiBlockSetButmFunc(block, layout->common->handlefunc, layout->common->argv); - ui_item_name(item, (char*)RNA_property_ui_name(rnaitem->prop)); + ui_layout_items(C, block, layout); - if(ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_ENUM)) - ui_item_name_add_colon(item); - } - else if(item->type == ITEM_OPERATOR) { - opitem= (uiItemOp*)item; - ui_item_name(item, opitem->ot->name); - } - - ui_item_name(item, ""); + if(x) *x= layout->x; + if(y) *y= layout->y; +} - /* initialize icons */ - if(layout->type == UI_LAYOUT_MENU) { - if(item->type == ITEM_RNA_PROPERTY) { - rnaitem= (uiItemRNA*)item; - type= RNA_property_type(rnaitem->prop); +static void ui_layout_free(uiLayout *layout) +{ + uiItem *item, *next; - 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; - } + for(item=layout->items.first; item; item=next) { + next= item->next; - if(!item->icon) - item->icon= ICON_BLANK1; - } - } + if(item->type == ITEM_BUTTON) + MEM_freeN(item); + else + ui_layout_free((uiLayout*)item); } + + MEM_freeN(layout); } -static void ui_layout_templates(const bContext *C, uiBlock *block, uiLayout *layout) +uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, uiStyle *style) { - uiStyle *style= layout->style; - uiTemplate *template; + uiLayout *layout; + uiLayoutCommon *common; - ui_layout_init_items(C, layout); + if(!block->layout) { + common= MEM_callocN(sizeof(uiLayoutCommon), "uiLayoutCommon"); + common->type= type; + common->style= style; + common->block= block; + common->opcontext= WM_OP_INVOKE_REGION_WIN; - if(layout->dir == UI_LAYOUT_HORIZONTAL) { - for(template=layout->templates.first; template; template=template->next) { - switch(template->type) { - case TEMPLATE_HEADER: - ui_layout_header(C, layout, block, template); - break; - case TEMPLATE_HEADER_ID: - ui_layout_header_id(C, layout, block, template); - break; - default: - ui_layout_header_buttons(layout, block, template); - break; - } + layout= MEM_callocN(sizeof(uiLayout), "uiLayout"); + layout->item.type= ITEM_LAYOUT_ROOT; - layout->x += style->templatespace; - } - } - else { - for(template=layout->templates.first; template; template=template->next) { - switch(template->type) { - case TEMPLATE_ROW: - ui_layout_row(layout, block, template); - break; - case TEMPLATE_COLUMN_FLOW: - ui_layout_column_flow(layout, block, template); - break; - case TEMPLATE_SPLIT: - ui_layout_split(C, layout, block, template); - break; - case TEMPLATE_BOX: - ui_layout_box(C, layout, block, template); - break; - case TEMPLATE_COLUMN: - default: - ui_layout_column(layout, block, template); - break; - } + layout->x= x; + layout->y= y; + layout->common= common; + layout->space= style->templatespace; + + if(type == UI_LAYOUT_MENU) + layout->space= 0; - layout->y -= style->templatespace; + if(dir == UI_LAYOUT_HORIZONTAL) { + layout->h= size; + layout->common->emh= em*UI_UNIT_Y; } + else { + layout->w= size; + layout->common->emw= em*UI_UNIT_X; + } + + block->curlayout= layout; + block->layout= layout; } + + return block->layout; } -void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) +uiBlock *uiLayoutBlock(uiLayout *layout) { - if(layout->handlefunc) - uiBlockSetButmFunc(block, layout->handlefunc, layout->argv); - - ui_layout_templates(C, block, layout); - - if(x) *x= layout->x; - if(y) *y= layout->y; - + return layout->common->block; } -void ui_layout_free(uiLayout *layout) +void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout) { - uiTemplate *template; - - for(template=layout->templates.first; template; template=template->next) - ui_template_free(template); - - BLI_freelistN(&layout->templates); - MEM_freeN(layout); + block->curlayout= layout; } -uiLayout *uiLayoutBegin(int dir, int type, int x, int y, int size, int em, uiStyle *style) +void ui_layout_add_but(uiLayout *layout, uiBut *but) { - 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->style= style; - - if(dir == UI_LAYOUT_HORIZONTAL) { - layout->h= size; - layout->emh= em*EM_UNIT_Y; - } - else { - layout->w= size; - layout->emw= em*EM_UNIT_X; - } - - return layout; + uiButtonItem *bitem; + + bitem= MEM_callocN(sizeof(uiButtonItem), "uiButtonItem"); + bitem->item.type= ITEM_BUTTON; + bitem->but= but; + BLI_addtail(&layout->items, bitem); } void uiLayoutContext(uiLayout *layout, int opcontext) { - layout->opcontext= opcontext; + layout->common->opcontext= opcontext; } void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) { - layout->handlefunc= handlefunc; - layout->argv= argv; + layout->common->handlefunc= handlefunc; + layout->common->argv= argv; } -void uiLayoutEnd(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) +void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y) { - ui_layout_end(C, block, layout, x, y); - ui_layout_free(layout); -} + uiLayout *layout= block->layout; -/************************ Utilities ************************/ + if(layout) { + /* NULL in advance so we don't interfere when adding button */ + block->layout= NULL; + block->curlayout= NULL; -void uiRegionPanelLayout(const bContext *C, ARegion *ar, int vertical, char *context) -{ - uiStyle *style= U.uistyles.first; - uiBlock *block; - PanelType *pt; - Panel *panel; - float col[3]; - int xco, yco, x=PNL_DIST, y=-PNL_HEADER-PNL_DIST, w, em; - - // XXX this only hides cruft - - /* clear */ - UI_GetThemeColor3fv(TH_BACK, col); - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - uiBeginPanels(C, ar); - - for(pt= ar->type->paneltypes.first; pt; pt= pt->next) { - if(context) - if(!pt->context || strcmp(context, pt->context) != 0) - continue; - - if(pt->draw && (!pt->poll || pt->poll(C, pt))) { - block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); - panel= uiBeginPanel(ar, block, pt); - - if(panel) { - if(vertical) { - w= (ar->type->minsizex)? ar->type->minsizex-12: block->aspect*ar->winx-12; - em= (ar->type->minsizex)? 10: 20; - } - else { - w= (ar->type->minsizex)? ar->type->minsizex-12: UI_PANEL_WIDTH-12; - em= (ar->type->minsizex)? 10: 20; - } - - panel->type= pt; - panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, PNL_SAFETY, 0, w-2*PNL_SAFETY, em, style); - - pt->draw(C, panel); - - uiLayoutEnd(C, block, panel->layout, &xco, &yco); - panel->layout= NULL; - uiEndPanel(block, w, -yco + 12); - } - else { - w= PNL_HEADER; - yco= PNL_HEADER; - } - - uiEndBlock(C, block); - - if(vertical) - y += yco+PNL_DIST; - else - x += w+PNL_DIST; - } + ui_layout_end(C, block, layout, x, y); + MEM_freeN(layout->common); + ui_layout_free(layout); + } + else { + if(x) *x= 0; + if(y) *y= 0; } - uiEndPanels(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + /* XXX silly trick, interface_templates.c doesn't get linked + * because it's not used by other files in this module? */ + { + void ui_template_fix_linking(); + ui_template_fix_linking(); + } } -void uiRegionHeaderLayout(const bContext *C, ARegion *ar) +float uiBlockAspect(uiBlock *block) { - uiStyle *style= U.uistyles.first; - uiBlock *block; - uiLayout *layout; - HeaderType *ht; - Header header = {0}; - float col[3]; - int xco, yco; - - // XXX this only hides cruft - - /* clear */ - if(ED_screen_area_active(C)) - UI_GetThemeColor3fv(TH_HEADER, col); - else - UI_GetThemeColor3fv(TH_HEADERDESEL, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - xco= 8; - yco= 3; - - /* 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, UI_LAYOUT_HEADER, xco, yco, 24, 1, style); - - if(ht->draw) { - header.type= ht; - header.layout= layout; - ht->draw(C, &header); - } - - uiLayoutEnd(C, block, layout, &xco, &yco); - uiEndBlock(C, block); - uiDrawBlock(C, block); - } - - /* always as last */ - UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + return block->aspect; /* temporary */ } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 730f22e3390..36c794ab098 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -157,6 +157,7 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar) Panel *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt) { + uiStyle *style= U.uistyles.first; Panel *pa, *patab, *palast, *panext; char *panelname= pt->label; char *tabname= pt->label; @@ -181,8 +182,8 @@ Panel *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt) BLI_strncpy(pa->panelname, panelname, UI_MAX_NAME_STR); BLI_strncpy(pa->tabname, tabname, UI_MAX_NAME_STR); - pa->ofsx= PNL_DIST; - pa->ofsy= PNL_DIST; + pa->ofsx= style->panelouter; + pa->ofsy= style->panelouter; pa->sizex= 0; pa->sizey= 0; @@ -377,31 +378,32 @@ static int panel_has_tabs(ARegion *ar, Panel *panel) static void ui_scale_panel_block(uiBlock *block) { + uiStyle *style= U.uistyles.first; uiBut *but; float facx= 1.0, facy= 1.0; - int centerx= 0, topy=0, tabsy=0; + int centerx= 0, topy=0, tabsy=0, space= style->panelspace; if(block->panel==NULL) return; /* buttons min/max centered, offset calculated */ ui_bounds_block(block); - if((!block->panel->type) && block->maxx-block->minx > block->panel->sizex - 2*PNL_SAFETY) - facx= (block->panel->sizex - (2*PNL_SAFETY))/(block->maxx-block->minx); + if((!block->panel->type) && block->maxx-block->minx > block->panel->sizex - 2*space) + facx= (block->panel->sizex - (2*space))/(block->maxx-block->minx); else - centerx= (block->panel->sizex-(block->maxx-block->minx) - 2*PNL_SAFETY)/2; + centerx= (block->panel->sizex-(block->maxx-block->minx) - 2*space)/2; // tabsy= PNL_HEADER*panel_has_tabs(block->panel); - if((!block->panel->type) && (block->maxy-block->miny) > block->panel->sizey - 2*PNL_SAFETY - tabsy) - facy= (block->panel->sizey - (2*PNL_SAFETY) - tabsy)/(block->maxy-block->miny); + if((!block->panel->type) && (block->maxy-block->miny) > block->panel->sizey - 2*space - tabsy) + facy= (block->panel->sizey - (2*space) - tabsy)/(block->maxy-block->miny); else - topy= (block->panel->sizey- 2*PNL_SAFETY - tabsy) - (block->maxy-block->miny) ; + topy= (block->panel->sizey- 2*space - tabsy) - (block->maxy-block->miny) ; for(but= block->buttons.first; but; but=but->next) { - but->x1= PNL_SAFETY+centerx+ facx*(but->x1-block->minx); - but->y1= PNL_SAFETY+topy + facy*(but->y1-block->miny); - but->x2= PNL_SAFETY+centerx+ facx*(but->x2-block->minx); - but->y2= PNL_SAFETY+topy + facy*(but->y2-block->miny); + but->x1= space+centerx+ facx*(but->x1-block->minx); + but->y1= space+topy + facy*(but->y1-block->miny); + but->x2= space+centerx+ facx*(but->x2-block->minx); + but->y2= space+topy + facy*(but->y2-block->miny); if(facx!=1.0) ui_check_but(but); /* for strlen */ } @@ -413,6 +415,7 @@ static void ui_scale_panel_block(uiBlock *block) // for 'home' key void uiPanelsHome(ARegion *ar) { + uiStyle *style= U.uistyles.first; Panel *pa; uiBlock *block; View2D *v2d; @@ -432,10 +435,10 @@ void uiPanelsHome(ARegion *ar) } if(done) { - v2d->tot.xmin= minx-PNL_DIST; - v2d->tot.xmax= maxx+PNL_DIST; - v2d->tot.ymin= miny-PNL_DIST; - v2d->tot.ymax= maxy+PNL_DIST; + v2d->tot.xmin= minx-style->panelouter; + v2d->tot.xmax= maxx+style->panelouter; + v2d->tot.ymin= miny-style->panelouter; + v2d->tot.ymax= maxy+style->panelouter; } else { v2d->tot.xmin= 0; @@ -890,6 +893,7 @@ static int compare_panel(const void *a1, const void *a2) /* returns 1 when it did something */ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac, int drag) { + uiStyle *style= U.uistyles.first; Panel *pa; PanelSort *ps, *panelsort, *psnext; int a, tot=0, done; @@ -940,18 +944,18 @@ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac, int drag) /* no smart other default start loc! this keeps switching f5/f6/etc compatible */ ps= panelsort; - ps->pa->ofsx= PNL_DIST; - ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-PNL_DIST; + ps->pa->ofsx= style->panelouter; + ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-style->panelouter; for(a=0; a<tot-1; a++, ps++) { psnext= ps+1; if(align==BUT_VERTICAL) { psnext->pa->ofsx= ps->pa->ofsx; - psnext->pa->ofsy= get_panel_real_ofsy(ps->pa) - psnext->pa->sizey-PNL_HEADER-PNL_DIST; + psnext->pa->ofsy= get_panel_real_ofsy(ps->pa) - psnext->pa->sizey-PNL_HEADER-style->panelouter; } else { - psnext->pa->ofsx= get_panel_real_ofsx(ps->pa)+PNL_DIST; + psnext->pa->ofsx= get_panel_real_ofsx(ps->pa)+style->panelouter; psnext->pa->ofsy= ps->pa->ofsy + ps->pa->sizey - psnext->pa->sizey; } } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 59725cc4954..57644e5decc 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -624,6 +624,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut /* create area region */ ar= ui_add_temporary_region(CTX_wm_screen(C)); + handle->region= ar; memset(&type, 0, sizeof(ARegionType)); type.draw= ui_block_region_draw; @@ -631,15 +632,21 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut UI_add_region_handlers(&ar->handlers); - handle->region= ar; - ar->regiondata= handle; - /* create ui block */ if(create_func) block= create_func(C, handle->region, arg); else block= handle_create_func(C, handle, arg); - block->handle= handle; + + if(block->handle) { + memcpy(block->handle, handle, sizeof(uiPopupBlockHandle)); + MEM_freeN(handle); + handle= block->handle; + } + else + block->handle= handle; + + ar->regiondata= handle; if(!block->endblock) uiEndBlock(C, block); @@ -1625,28 +1632,9 @@ uiBlock *ui_block_func_PUPMENUCOL(bContext *C, uiPopupBlockHandle *handle, void /* prototype */ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle, void *arg_info); -#define MAX_MENU_STR 64 - -/* type, internal */ -#define MENU_ITEM_TITLE 0 -#define MENU_ITEM_ITEM 1 -#define MENU_ITEM_SEPARATOR 2 -#define MENU_ITEM_OPNAME 10 -#define MENU_ITEM_OPNAME_BOOL 11 -#define MENU_ITEM_OPNAME_ENUM 12 -#define MENU_ITEM_OPNAME_INT 13 -#define MENU_ITEM_OPNAME_FLOAT 14 -#define MENU_ITEM_OPNAME_STRING 15 -#define MENU_ITEM_RNA_BOOL 20 -#define MENU_ITEM_RNA_ENUM 21 -#define MENU_ITEM_LEVEL 30 -#define MENU_ITEM_LEVEL_OPNAME_ENUM 31 -#define MENU_ITEM_LEVEL_RNA_ENUM 32 - struct uiPopupMenu { + uiBlock *block; uiLayout *layout; - int icon; - char name[MAX_MENU_STR]; }; typedef struct uiMenuInfo { @@ -1694,46 +1682,26 @@ typedef struct MenuItemLevel { static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle, void *arg_info) { uiBlock *block; - uiBut *but; uiMenuInfo *info= arg_info; uiPopupMenu *pup; ScrArea *sa; ARegion *ar; - static int counter= 0; - char str[16]; pup= info->pup; + block= pup->block; /* block stuff first, need to know the font */ - sprintf(str, "tb %d", counter++); - block= uiBeginBlock(C, handle->region, str, UI_EMBOSSP); + uiBlockSetRegion(block, handle->region); block->direction= UI_DOWN; - /* here we go! */ - if(pup->name[0]) { - char titlestr[256]; - - 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, 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, ""); - } - - block->handle= handle; - uiLayoutEnd(C, block, pup->layout, NULL, NULL); + uiBlockLayoutResolve(C, block, 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, MENU_BUTTON_HEIGHT/2); + uiMenuPopupBoundsBlock(block, 1, 0, 1.5*MENU_BUTTON_HEIGHT); } else { /* for a header menu we set the direction automatic */ @@ -1769,9 +1737,12 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut uiMenuInfo info; pup= MEM_callocN(sizeof(uiPopupMenu), "menu dummy"); - pup->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style); + pup->block= uiBeginBlock(C, NULL, "ui_popup_menu_create", UI_EMBOSSP); + pup->layout= uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style); uiLayoutContext(pup->layout, WM_OP_INVOKE_REGION_WIN); - uiLayoutColumn(pup->layout); + + /* create in advance so we can let buttons point to retval already */ + pup->block->handle= MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle"); menu_func(C, pup->layout, arg); @@ -1792,20 +1763,35 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut /*************************** Popup Menu API **************************/ /* only return handler, and set optional title */ -uiPopupMenu *uiPupMenuBegin(const char *title, int icon) +uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) { uiStyle *style= U.uistyles.first; uiPopupMenu *pup= MEM_callocN(sizeof(uiPopupMenu), "menu start"); + uiBut *but; - pup->icon= icon; - pup->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style); + pup->block= uiBeginBlock(C, NULL, "uiPupMenuBegin", UI_EMBOSSP); + pup->layout= uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style); uiLayoutContext(pup->layout, WM_OP_EXEC_REGION_WIN); - uiLayoutColumn(pup->layout); - - /* NULL is no title */ - if(title) - BLI_strncpy(pup->name, title, MAX_MENU_STR); + + /* create in advance so we can let buttons point to retval already */ + pup->block->handle= MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle"); + /* create title button */ + if(title && title[0]) { + char titlestr[256]; + + if(icon) { + sprintf(titlestr, " %s", title); + uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, ""); + } + else { + but= uiDefBut(pup->block, LABEL, 0, (char*)title, 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, ""); + } + return pup; } @@ -2002,7 +1988,7 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, i handle= ui_popup_block_create(C, NULL, NULL, func, NULL, arg); handle->popup= 1; - handle->opname= opname; + handle->optype= (opname)? WM_operatortype_find(opname): NULL; handle->opcontext= opcontext; UI_add_popup_handlers(C, &window->handlers, handle); diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index d0361174e70..f789f81e0d3 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -121,6 +121,8 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name) style->boxspace= 5; style->buttonspacex= 5; style->buttonspacey= 2; + style->panelspace= 8; + style->panelouter= 4; return style; } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c new file mode 100644 index 00000000000..5244c9983cf --- /dev/null +++ b/source/blender/editors/interface/interface_templates.c @@ -0,0 +1,248 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Blender Foundation 2009. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_string.h" + +#include "BKE_context.h" +#include "BKE_library.h" +#include "BKE_utildefines.h" + +#include "ED_screen.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +static uiBlock *block_free_layout(uiLayout *layout) +{ + uiBlock *block; + + block= uiLayoutBlock(layout); + uiBlockSetCurLayout(block, uiLayoutFree(layout, 0)); + + return block; +} + +void ui_template_fix_linking() +{ +} + +/********************** Header Template *************************/ + +void uiTemplateHeader(uiLayout *layout, bContext *C) +{ + uiBlock *block; + + block= block_free_layout(layout); + ED_area_header_standardbuttons(C, block, 0); +} + +/******************* Header ID Template ************************/ + +typedef struct TemplateHeaderID { + PointerRNA ptr; + PropertyRNA *prop; + + int flag; + short browse; + + char newop[256]; + char openop[256]; + char unlinkop[256]; +} TemplateHeaderID; + +static void template_header_id_cb(bContext *C, void *arg_litem, void *arg_event) +{ + TemplateHeaderID *template= (TemplateHeaderID*)arg_litem; + PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop); + ID *idtest, *id= idptr.data; + ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT); + int nr, event= GET_INT_FROM_POINTER(arg_event); + + if(event == UI_ID_BROWSE && template->browse == 32767) + event= UI_ID_ADD_NEW; + else if(event == UI_ID_BROWSE && template->browse == 32766) + event= UI_ID_OPEN; + + switch(event) { + case UI_ID_BROWSE: { + if(template->browse== -2) { + /* XXX implement or find a replacement + * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &template->browse, do_global_buttons); */ + return; + } + if(template->browse < 0) + return; + + for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) { + if(nr==template->browse) { + if(id == idtest) + return; + + id= idtest; + RNA_id_pointer_create(id, &idptr); + RNA_property_pointer_set(&template->ptr, template->prop, idptr); + RNA_property_update(C, &template->ptr, template->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, template->newop, WM_OP_INVOKE_REGION_WIN, NULL); + break; + case UI_ID_OPEN: + WM_operator_name_call(C, template->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 template_header_ID(bContext *C, uiBlock *block, TemplateHeaderID *template) +{ + uiBut *but; + TemplateHeaderID *duptemplate; + PointerRNA idptr; + ListBase *lb; + int x= 0, y= 0; + + idptr= RNA_property_pointer_get(&template->ptr, template->prop); + lb= wich_libbase(CTX_data_main(C), ID_TXT); + + uiBlockBeginAlign(block); + if(template->flag & UI_ID_BROWSE) { + char *extrastr, *str; + + if((template->flag & UI_ID_ADD_NEW) && (template->flag && UI_ID_OPEN)) + extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767"; + else if(template->flag & UI_ID_ADD_NEW) + extrastr= "ADD NEW %x 32767"; + else if(template->flag & UI_ID_OPEN) + extrastr= "OPEN NEW %x 32766"; + else + extrastr= NULL; + + duptemplate= MEM_dupallocN(template); + IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse); + + but= uiDefButS(block, MENU, 0, str, x, y, UI_UNIT_X, UI_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new"); + uiButSetNFunc(but, template_header_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE)); + x+= UI_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, x, y, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL); + uiButSetNFunc(but, template_header_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME)); + x += UI_UNIT_X*6; + + /* delete button */ + if(template->flag & UI_ID_DELETE) { + but= uiDefIconButO(block, BUT, template->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, x, y, UI_UNIT_X, UI_UNIT_Y, NULL); + x += UI_UNIT_X; + } + } + uiBlockEndAlign(block); +} + +void uiTemplateHeaderID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop) +{ + TemplateHeaderID *template; + uiBlock *block; + PropertyRNA *prop; + + if(!ptr->data) + return; + + prop= RNA_struct_find_property(ptr, propname); + + if(!prop) { + printf("uiTemplateHeaderID: property not found: %s\n", propname); + return; + } + + template= MEM_callocN(sizeof(TemplateHeaderID), "TemplateHeaderID"); + template->ptr= *ptr; + template->prop= prop; + template->flag= UI_ID_BROWSE|UI_ID_RENAME; + + if(newop) { + template->flag |= UI_ID_ADD_NEW; + BLI_strncpy(template->newop, newop, sizeof(template->newop)); + } + if(openop) { + template->flag |= UI_ID_OPEN; + BLI_strncpy(template->openop, openop, sizeof(template->openop)); + } + if(unlinkop) { + template->flag |= UI_ID_DELETE; + BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop)); + } + + block= block_free_layout(layout); + template_header_ID(C, block, template); + + MEM_freeN(template); +} + diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index dc346be7af2..e3f986efde9 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -320,13 +320,12 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) uiStyle *style= U.uistyles.first; CollectionPropertyIterator iter; PropertyRNA *iterprop, *prop; - uiLayout *layout; + uiLayout *layout, *split; char *name; int x= 0, y= 0; - layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, DEF_BUT_WIDTH*2, 20, style); + layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, DEF_BUT_WIDTH*2, 20, style); - uiLayoutColumn(layout); uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0); iterprop= RNA_struct_iterator_property(ptr->type); @@ -338,17 +337,16 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) if(strcmp(RNA_property_identifier(prop), "rna_type") == 0) continue; - uiLayoutSplit(layout, 2, 0); + split = uiLayoutSplit(layout); name= (char*)RNA_property_ui_name(prop); - uiLayoutColumn(uiLayoutSub(layout, 0)); - uiItemL(uiLayoutSub(layout, 0), name, 0); - uiLayoutColumn(uiLayoutSub(layout, 1)); - uiItemFullR(uiLayoutSub(layout, 1), "", 0, ptr, prop, -1, 0, 0); + + uiItemL(uiLayoutColumn(split, 0), name, 0); + uiItemFullR(uiLayoutColumn(split, 0), "", 0, ptr, prop, -1, 0, 0); } RNA_property_collection_end(&iter); - uiLayoutEnd(C, block, layout, &x, &y); + uiBlockLayoutResolve(C, block, &x, &y); return -y; } @@ -363,9 +361,8 @@ int uiDefAutoButsRNA_single(const bContext *C, uiBlock *block, PointerRNA *ptr) char *name; int x= 0, y= 0; - layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, block->panel->sizex, 20, style); + layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, block->panel->sizex, 20, style); - uiLayoutColumn(layout); uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0); iterprop= RNA_struct_iterator_property(ptr->type); @@ -377,17 +374,13 @@ int uiDefAutoButsRNA_single(const bContext *C, uiBlock *block, PointerRNA *ptr) if(strcmp(RNA_property_identifier(prop), "rna_type") == 0) continue; - uiLayoutSplit(layout, 1, 0); - uiLayoutColumn(uiLayoutSub(layout, 0)); - name= (char*)RNA_property_ui_name(prop); - uiItemL(uiLayoutSub(layout, 0), name, 0); - - uiItemFullR(uiLayoutSub(layout, 0), "", 0, ptr, prop, -1, 0, 0); + uiItemL(layout, name, 0); + uiItemFullR(layout, "", 0, ptr, prop, -1, 0, 0); } RNA_property_collection_end(&iter); - uiLayoutEnd(C, block, layout, &x, &y); + uiBlockLayoutResolve(C, block, &x, &y); return -y; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index b6e679468e0..3035ff6d3a6 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -6588,7 +6588,7 @@ static int subdivs_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("Subdivision Type", 0); + pup= uiPupMenuBegin(C, "Subdivision Type", 0); layout= uiPupMenuLayout(pup); uiItemsEnumO(layout, "MESH_OT_subdivs", "type"); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 68a2cf04692..cf61c16fbe4 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -463,7 +463,7 @@ static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin(op->type->name, 0); + pup= uiPupMenuBegin(C, op->type->name, 0); layout= uiPupMenuLayout(pup); if(!obedit || obedit->type == OB_CURVE) uiItemsEnumO(layout, op->type->idname, "type"); @@ -632,7 +632,7 @@ void OBJECT_OT_armature_add(wmOperatorType *ot) static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event) { - uiPopupMenu *pup= uiPupMenuBegin("Add Object", 0); + uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0); uiLayout *layout= uiPupMenuLayout(pup); uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type"); @@ -2623,7 +2623,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event) { Object *ob= CTX_data_active_object(C); - uiPopupMenu *pup= uiPupMenuBegin("Set Parent To", 0); + uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", 0); uiLayout *layout= uiPupMenuLayout(pup); uiLayoutContext(layout, WM_OP_EXEC_DEFAULT); diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 0d58a0bfdcd..1c2b3c6b309 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -3842,7 +3842,7 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("Specials", 0); + pup= uiPupMenuBegin(C, "Specials", 0); layout= uiPupMenuLayout(pup); uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 6b7b7a914f4..e344a177517 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -31,6 +31,9 @@ #include "MEM_guardedalloc.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" + #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_rand.h" @@ -955,3 +958,128 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) return xco; } +/************************ standard UI regions ************************/ + +void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *context) +{ + uiStyle *style= U.uistyles.first; + uiBlock *block; + PanelType *pt; + Panel *panel; + float col[3]; + int xco, yco, x, y, w, em, header; + + header= 20; // XXX + x= style->panelouter; + y= -(header + style->panelouter); + + /* clear */ + UI_GetThemeColor3fv(TH_BACK, col); + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* set view2d view matrix for scrolling (without scrollers) */ + UI_view2d_view_ortho(C, &ar->v2d); + + /* create panels */ + uiBeginPanels(C, ar); + + for(pt= ar->type->paneltypes.first; pt; pt= pt->next) { + /* verify context */ + if(context) + if(!pt->context || strcmp(context, pt->context) != 0) + continue; + + /* draw panel */ + if(pt->draw && (!pt->poll || pt->poll(C, pt))) { + block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); + panel= uiBeginPanel(ar, block, pt); + + if(panel) { + if(vertical) { + w= (ar->type->minsizex)? ar->type->minsizex-12: uiBlockAspect(block)*ar->winx-12; + em= (ar->type->minsizex)? 10: 20; + } + else { + w= (ar->type->minsizex)? ar->type->minsizex-12: UI_PANEL_WIDTH-12; + em= (ar->type->minsizex)? 10: 20; + } + + panel->type= pt; + panel->layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, + style->panelspace, 0, w-2*style->panelspace, em, style); + + pt->draw(C, panel); + + uiBlockLayoutResolve(C, block, &xco, &yco); + uiEndPanel(block, w, -yco + 12); + panel->layout= NULL; + } + else { + w= header; + yco= header; + } + + uiEndBlock(C, block); + + if(vertical) + y += yco+style->panelouter; + else + x += w+style->panelouter; + } + } + + uiEndPanels(C, ar); + + /* restore view matrix? */ + UI_view2d_view_restore(C); +} + +void ED_region_header(const bContext *C, ARegion *ar) +{ + uiStyle *style= U.uistyles.first; + uiBlock *block; + uiLayout *layout; + HeaderType *ht; + Header header = {0}; + float col[3]; + int xco, yco; + + /* clear */ + if(ED_screen_area_active(C)) + UI_GetThemeColor3fv(TH_HEADER, col); + else + UI_GetThemeColor3fv(TH_HEADERDESEL, col); + + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* set view2d view matrix for scrolling (without scrollers) */ + UI_view2d_view_ortho(C, &ar->v2d); + + xco= 8; + yco= HEADERY-3; + + /* draw all headers types */ + for(ht= ar->type->headertypes.first; ht; ht= ht->next) { + block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS); + layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, HEADERY-6, 1, style); + + if(ht->draw) { + header.type= ht; + header.layout= layout; + ht->draw(C, &header); + } + + uiBlockLayoutResolve(C, block, &xco, &yco); + uiEndBlock(C, block); + uiDrawBlock(C, block); + } + + /* always as last */ + UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin); + + /* restore view matrix? */ + UI_view2d_view_restore(C); +} + diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index e441a93fe23..10139f9851f 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1581,7 +1581,7 @@ static int repeat_history_invoke(bContext *C, wmOperator *op, wmEvent *event) if(items==0) return OPERATOR_CANCELLED; - pup= uiPupMenuBegin(op->type->name, 0); + pup= uiPupMenuBegin(C, op->type->name, 0); layout= uiPupMenuLayout(pup); for (i=items-1, lastop= wm->operators.last; lastop; lastop= lastop->prev, i--) @@ -1827,7 +1827,7 @@ static void newlevel1(bContext *C, uiLayout *layout, void *arg) static int testing123(bContext *C, wmOperator *op, wmEvent *event) { - uiPopupMenu *pup= uiPupMenuBegin("Hello world", 0); + uiPopupMenu *pup= uiPupMenuBegin(C, "Hello world", 0); uiLayout *layout= uiPupMenuLayout(pup); uiLayoutContext(layout, WM_OP_EXEC_DEFAULT); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 2013c3d72a9..893ef139bad 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -170,21 +170,21 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar) int vertical= (sbuts->align == BUT_VERTICAL); if(sbuts->mainb == BCONTEXT_SCENE) - uiRegionPanelLayout(C, ar, vertical, "scene"); + ED_region_panels(C, ar, vertical, "scene"); else if(sbuts->mainb == BCONTEXT_WORLD) - uiRegionPanelLayout(C, ar, vertical, "world"); + ED_region_panels(C, ar, vertical, "world"); else if(sbuts->mainb == BCONTEXT_OBJECT) - uiRegionPanelLayout(C, ar, vertical, "object"); + ED_region_panels(C, ar, vertical, "object"); else if(sbuts->mainb == BCONTEXT_DATA) - uiRegionPanelLayout(C, ar, vertical, "data"); + ED_region_panels(C, ar, vertical, "data"); else if(sbuts->mainb == BCONTEXT_MATERIAL) - uiRegionPanelLayout(C, ar, vertical, "material"); + ED_region_panels(C, ar, vertical, "material"); else if(sbuts->mainb == BCONTEXT_TEXTURE) - uiRegionPanelLayout(C, ar, vertical, "texture"); + ED_region_panels(C, ar, vertical, "texture"); else if(sbuts->mainb == BCONTEXT_PARTICLE) - uiRegionPanelLayout(C, ar, vertical, "particle"); + ED_region_panels(C, ar, vertical, "particle"); else if(sbuts->mainb == BCONTEXT_PHYSICS) - uiRegionPanelLayout(C, ar, vertical, "physics"); + ED_region_panels(C, ar, vertical, "physics"); sbuts->re_align= 0; sbuts->mainbo= sbuts->mainb; diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c index 457d322f565..a584993005a 100644 --- a/source/blender/editors/space_image/image_header.c +++ b/source/blender/editors/space_image/image_header.c @@ -945,7 +945,7 @@ static int toolbox_invoke(bContext *C, wmOperator *op, wmEvent *event) show_uvedit= ED_space_image_show_uvedit(sima, obedit); - pup= uiPupMenuBegin("Toolbox", 0); + pup= uiPupMenuBegin(C, "Toolbox", 0); layout= uiPupMenuLayout(pup); uiItemMenuF(layout, "View", 0, image_viewmenu); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 908b24bd84d..6efd508c335 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1133,7 +1133,7 @@ static int pack_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; if(!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) { - pup= uiPupMenuBegin("OK", ICON_HELP); + pup= uiPupMenuBegin(C, "OK", ICON_HELP); layout= uiPupMenuLayout(pup); uiItemBooleanO(layout, "Can't pack edited image from disk. Pack as internal PNG?", 0, op->idname, "as_png", 1); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 577dae433c1..33fa85dbb5d 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -354,7 +354,7 @@ static void text_header_area_init(wmWindowManager *wm, ARegion *ar) static void text_header_area_draw(const bContext *C, ARegion *ar) { - uiRegionHeaderLayout(C, ar); + ED_region_header(C, ar); } /****************** properties region ******************/ @@ -367,7 +367,7 @@ static void text_properties_area_init(wmWindowManager *wm, ARegion *ar) static void text_properties_area_draw(const bContext *C, ARegion *ar) { - uiRegionPanelLayout(C, ar, 1, NULL); + ED_region_panels(C, ar, 1, NULL); } /********************* registration ********************/ diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c index 83c144d88c5..fe00b86e19f 100644 --- a/source/blender/editors/space_text/text_header.c +++ b/source/blender/editors/space_text/text_header.c @@ -323,7 +323,7 @@ void TEXT_OT_properties(wmOperatorType *ot) uiPopupMenu *pup; if(text) { - pup= uiPupMenuBegin("Text", 0); + pup= uiPupMenuBegin(C, "Text", 0); if(txt_has_sel(text)) { uiItemO(layout, NULL, 0, "TEXT_OT_cut"); uiItemO(layout, NULL, 0, "TEXT_OT_copy"); @@ -337,7 +337,7 @@ void TEXT_OT_properties(wmOperatorType *ot) uiPupMenuEnd(C, pup); } else { - pup= uiPupMenuBegin("File", 0); + pup= uiPupMenuBegin(C, "File", 0); uiItemO(layout, NULL, 0, "TEXT_OT_new"); uiItemO(layout, NULL, 0, "TEXT_OT_open"); uiPupMenuEnd(C, pup); @@ -349,7 +349,7 @@ void TEXT_OT_properties(wmOperatorType *ot) uiPopupMenu *pup; - pup= uiPupMenuBegin("Edit", 0); + pup= uiPupMenuBegin(C, "Edit", 0); uiItemO(layout, NULL, 0, "TEXT_OT_cut"); uiItemO(layout, NULL, 0, "TEXT_OT_copy"); uiItemO(layout, NULL, 0, "TEXT_OT_paste"); @@ -362,7 +362,7 @@ void TEXT_OT_properties(wmOperatorType *ot) uiPopupMenu *pup; if(text) { - pup= uiPupMenuBegin("Text", 0); + pup= uiPupMenuBegin(C, "Text", 0); uiItemO(layout, NULL, 0, "TEXT_OT_new"); uiItemO(layout, NULL, 0, "TEXT_OT_open"); uiItemO(layout, NULL, 0, "TEXT_OT_save"); @@ -371,7 +371,7 @@ void TEXT_OT_properties(wmOperatorType *ot) uiPupMenuEnd(C, pup); } else { - pup= uiPupMenuBegin("File", 0); + pup= uiPupMenuBegin(C, "File", 0); uiItemO(layout, NULL, 0, "TEXT_OT_new"); uiItemO(layout, NULL, 0, "TEXT_OT_open"); uiPupMenuEnd(C, pup); @@ -383,7 +383,7 @@ void TEXT_OT_properties(wmOperatorType *ot) uiPopupMenu *pup; - pup= uiPupMenuBegin("Text", 0); + pup= uiPupMenuBegin(C, "Text", 0); uiItemEnumO(layout, "Top of File", 0, "TEXT_OT_move", "type", FILE_TOP); uiItemEnumO(layout, "Bottom of File", 0, "TEXT_OT_move", "type", FILE_BOTTOM); uiItemEnumO(layout, "Page Up", 0, "TEXT_OT_move", "type", PREV_PAGE); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 913bd307ab2..5f974e7bcbb 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -2540,7 +2540,7 @@ static int resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *event) case 1: if(text->flags & TXT_ISDIRTY) { /* modified locally and externally, ahhh. offer more possibilites. */ - pup= uiPupMenuBegin("File Modified Outside and Inside Blender", 0); + pup= uiPupMenuBegin(C, "File Modified Outside and Inside Blender", 0); layout= uiPupMenuLayout(pup); uiItemEnumO(layout, "Reload from disk (ignore local changes)", 0, op->type->idname, "resolution", RESOLVE_RELOAD); uiItemEnumO(layout, "Save to disk (ignore outside changes)", 0, op->type->idname, "resolution", RESOLVE_SAVE); @@ -2548,7 +2548,7 @@ static int resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPupMenuEnd(C, pup); } else { - pup= uiPupMenuBegin("File Modified Outside Blender", 0); + pup= uiPupMenuBegin(C, "File Modified Outside Blender", 0); layout= uiPupMenuLayout(pup); uiItemEnumO(layout, "Reload from disk", 0, op->type->idname, "resolution", RESOLVE_RELOAD); uiItemEnumO(layout, "Make text internal (separate copy)", 0, op->type->idname, "resolution", RESOLVE_MAKE_INTERNAL); @@ -2557,7 +2557,7 @@ static int resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *event) } break; case 2: - pup= uiPupMenuBegin("File Deleted Outside Blender", 0); + pup= uiPupMenuBegin(C, "File Deleted Outside Blender", 0); layout= uiPupMenuLayout(pup); uiItemEnumO(layout, "Make text internal", 0, op->type->idname, "resolution", RESOLVE_MAKE_INTERNAL); uiItemEnumO(layout, "Recreate file", 0, op->type->idname, "resolution", RESOLVE_SAVE); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 24d211d81ab..9c0cffb547a 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -5554,7 +5554,7 @@ static int editmesh_face_toolbox_invoke(bContext *C, wmOperator *op, wmEvent *ev uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("Edit Faces", 0); + pup= uiPupMenuBegin(C, "Edit Faces", 0); layout= uiPupMenuLayout(pup); uiItemO(layout, NULL, 0, "MESH_OT_fill"); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 7b417c94a73..fba8d13c6a5 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -1113,7 +1113,7 @@ int minmax_verts(Object *obedit, float *min, float *max) static int snap_menu_invoke(bContext *C, wmOperator *unused, wmEvent *event) { - uiPopupMenu *pup= uiPupMenuBegin("Snap", 0); + uiPopupMenu *pup= uiPupMenuBegin(C, "Snap", 0); uiLayout *layout= uiPupMenuLayout(pup); uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_grid"); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 46a6f121990..769001b30a8 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -122,7 +122,7 @@ static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("Orientation", 0); + pup= uiPupMenuBegin(C, "Orientation", 0); layout= uiPupMenuLayout(pup); BIF_menuTransformOrientation(C, layout, NULL); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index be571c132ab..27d0c68ec36 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1287,7 +1287,7 @@ static int mapping_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("UV Mapping", 0); + pup= uiPupMenuBegin(C, "UV Mapping", 0); layout= uiPupMenuLayout(pup); uiItemO(layout, NULL, 0, "UV_OT_unwrap"); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index ab2b7ba498a..c7a74fe5358 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -100,8 +100,10 @@ typedef struct uiStyle { short boxspace; short buttonspacex; short buttonspacey; + short panelspace; + short panelouter; - short pad; + short pad[3]; } uiStyle; typedef struct uiWidgetColors { diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index ece5b6cc1f9..e45319a42a6 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -97,6 +97,7 @@ void RNA_def_context(BlenderRNA *brna) srna= RNA_def_struct(brna, "Context", NULL); RNA_def_struct_ui_text(srna, "Context", "Current windowmanager and data context."); + RNA_def_struct_sdna(srna, "bContext"); /* WM */ prop= RNA_def_property(srna, "manager", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 34a7ea7d1e9..b5f4ee98dfe 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -600,7 +600,7 @@ static void rna_def_material_sss(BlenderRNA *brna) RNA_def_struct_nested(brna, srna, "Material"); RNA_def_struct_ui_text(srna, "Material Subsurface Scattering", "Diffuse subsurface scattering settings for a Material datablock."); - prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_COLOR); + prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sss_radius"); RNA_def_property_range(prop, 0.001, FLT_MAX); RNA_def_property_ui_range(prop, 0.001, 10000, 1, 3); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 2f732138643..e387dd680f3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -502,6 +502,10 @@ void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Back Buffer", "Render backbuffer image"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + prop= RNA_def_property(srna, "output_path", PROP_STRING, PROP_DIRPATH); + RNA_def_property_string_sdna(prop, NULL, "pic"); + RNA_def_property_ui_text(prop, "Output Path", "Directory/name to save animations, # characters defines the position and length of frame numbers."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); } void RNA_def_scene(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 034fd603367..e8b766ff2ea 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -67,6 +67,10 @@ static void rna_def_scrarea(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "regionbase", NULL); RNA_def_property_struct_type(prop, "Region"); RNA_def_property_ui_text(prop, "Regions", "Regions this area is subdivided in."); + + prop= RNA_def_property(srna, "show_menus", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", HEADER_NO_PULLDOWN); + RNA_def_property_ui_text(prop, "Show Menus", "Show menus in the header."); } static void rna_def_region(BlenderRNA *brna) diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index b795409c1c9..471263d9d63 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -43,12 +43,13 @@ static PyObject *Method_pupMenuBegin( PyObject * self, PyObject * args ) { + PyObject *py_context; char *title; int icon; - if( !PyArg_ParseTuple( args, "si:pupMenuBegin", &title, &icon)) + if( !PyArg_ParseTuple( args, "O!si:pupMenuBegin", &PyCObject_Type, &py_context, &title, &icon)) return NULL; - return PyCObject_FromVoidPtr( uiPupMenuBegin(title, icon), NULL ); + return PyCObject_FromVoidPtr( uiPupMenuBegin(PyCObject_AsVoidPtr(py_context), title, icon), NULL ); } static PyObject *Method_pupMenuEnd( PyObject * self, PyObject * args ) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5a10aa4490e..7084bb799c0 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -211,7 +211,7 @@ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) printf("WM_menu_invoke: %s \"type\" is not an enum property\n", op->type->idname); } else { - pup= uiPupMenuBegin(op->type->name, 0); + pup= uiPupMenuBegin(C, op->type->name, 0); layout= uiPupMenuLayout(pup); uiItemsEnumO(layout, op->type->idname, "type"); uiPupMenuEnd(C, pup); @@ -226,7 +226,7 @@ int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event) uiPopupMenu *pup; uiLayout *layout; - pup= uiPupMenuBegin("OK?", ICON_HELP); + pup= uiPupMenuBegin(C, "OK?", ICON_HELP); layout= uiPupMenuLayout(pup); uiItemO(layout, NULL, 0, op->type->idname); uiPupMenuEnd(C, pup); @@ -378,7 +378,7 @@ static int wm_recentfile_invoke(bContext *C, wmOperator *op, wmEvent *event) uiLayout *layout; int i, ofs= 0; - pup= uiPupMenuBegin("Open Recent", 0); + pup= uiPupMenuBegin(C, "Open Recent", 0); layout= uiPupMenuLayout(pup); if(G.sce[0]) { |