Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-05-15 15:19:59 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-05-15 15:19:59 +0400
commitb4d46e5dedfa88951558a4f941d987a171594a0a (patch)
tree4de559356ab0ac6135f5a1abbbdb60eb1134ffca /source
parent2df94626c483c9b522e347ecc792c634fdec420a (diff)
UI: Layout Engine
* Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/animation/keyframing.c2
-rw-r--r--source/blender/editors/armature/editarmature.c4
-rw-r--r--source/blender/editors/armature/poselib.c4
-rw-r--r--source/blender/editors/curve/curve_ops.c2
-rw-r--r--source/blender/editors/curve/editcurve.c6
-rw-r--r--source/blender/editors/include/ED_screen.h2
-rw-r--r--source/blender/editors/include/UI_interface.h46
-rw-r--r--source/blender/editors/interface/interface.c135
-rw-r--r--source/blender/editors/interface/interface_anim.c2
-rw-r--r--source/blender/editors/interface/interface_api.c24
-rw-r--r--source/blender/editors/interface/interface_handlers.c16
-rw-r--r--source/blender/editors/interface/interface_intern.h19
-rw-r--r--source/blender/editors/interface/interface_layout.c2160
-rw-r--r--source/blender/editors/interface/interface_panel.c46
-rw-r--r--source/blender/editors/interface/interface_regions.c104
-rw-r--r--source/blender/editors/interface/interface_style.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c248
-rw-r--r--source/blender/editors/interface/interface_utils.c29
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c2
-rw-r--r--source/blender/editors/object/object_edit.c6
-rw-r--r--source/blender/editors/physics/editparticle.c2
-rw-r--r--source/blender/editors/screen/area.c128
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c16
-rw-r--r--source/blender/editors/space_image/image_header.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_text/space_text.c4
-rw-r--r--source/blender/editors/space_text/text_header.c12
-rw-r--r--source/blender/editors/space_text/text_ops.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c2
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_context.c1
-rw-r--r--source/blender/makesrna/intern/rna_material.c2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c4
-rw-r--r--source/blender/makesrna/intern/rna_screen.c4
-rw-r--r--source/blender/python/intern/bpy_ui.c5
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c6
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= &region->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]) {