Centralized operator UI drawing into a new function uiLayoutOperatorButs(),
Operator drawing calls were duplicated in file selector panel, redo panels, redo & dialog popups. note, uiDefAutoButsRNA's column's argument was misleading, renamed to label_align.
This commit is contained in:
@@ -496,7 +496,7 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
|
||||
void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
|
||||
|
||||
uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2);
|
||||
void uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int columns);
|
||||
int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int (*check_prop)(struct PropertyRNA *), const char label_align);
|
||||
|
||||
/* Links
|
||||
*
|
||||
@@ -633,6 +633,10 @@ void UI_exit(void);
|
||||
#define UI_ITEM_R_NO_BG 128
|
||||
#define UI_ITEM_R_IMMEDIATE 256
|
||||
|
||||
/* uiLayoutOperatorButs flags */
|
||||
#define UI_LAYOUT_OP_SHOW_TITLE 1
|
||||
#define UI_LAYOUT_OP_SHOW_EMPTY 2
|
||||
|
||||
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(uiBlock *block, int *x, int *y);
|
||||
@@ -642,6 +646,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout);
|
||||
void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv);
|
||||
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr);
|
||||
const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing
|
||||
void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op, int (*check_prop)(struct PropertyRNA *), const char label_align, const short flag);
|
||||
|
||||
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext);
|
||||
void uiLayoutSetActive(uiLayout *layout, int active);
|
||||
|
||||
@@ -2664,3 +2664,45 @@ const char *uiLayoutIntrospect(uiLayout *layout)
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* this function does not initialize the layout, functions can be called on the layout before and after */
|
||||
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,int (*check_prop)(struct PropertyRNA *), const char label_align, const short flag)
|
||||
{
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
if(flag & UI_LAYOUT_OP_SHOW_TITLE) {
|
||||
uiItemL(layout, op->type->name, 0);
|
||||
}
|
||||
|
||||
/* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
|
||||
* just fails silently */
|
||||
if(!WM_operator_repeat_check(C, op)) {
|
||||
uiBlockSetButLock(uiLayoutGetBlock(layout), TRUE, "Operator cannot redo");
|
||||
uiItemL(layout, "* Redo Unsupported *", 0); // XXX, could give some nicer feedback or not show redo panel at all?
|
||||
}
|
||||
|
||||
if(op->type->ui) {
|
||||
op->layout= layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
op->layout= NULL;
|
||||
|
||||
/* UI_LAYOUT_OP_SHOW_EMPTY ignored */
|
||||
}
|
||||
else {
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
PointerRNA ptr;
|
||||
int empty;
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
|
||||
/* main draw call */
|
||||
empty= uiDefAutoButsRNA(layout, &ptr, check_prop, label_align) == 0;
|
||||
|
||||
if(empty && (flag & UI_LAYOUT_OP_SHOW_EMPTY)) {
|
||||
uiItemL(layout, "No Properties.", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
@@ -131,35 +132,50 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
|
||||
return but;
|
||||
}
|
||||
|
||||
void uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int columns)
|
||||
int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PropertyRNA *), const char label_align)
|
||||
{
|
||||
uiLayout *split, *col;
|
||||
int flag;
|
||||
char *name;
|
||||
const char *name;
|
||||
int tot= 0;
|
||||
|
||||
assert(ELEM3(label_align, '\0', 'H', 'V'));
|
||||
|
||||
RNA_STRUCT_BEGIN(ptr, prop) {
|
||||
flag= RNA_property_flag(prop);
|
||||
if(flag & PROP_HIDDEN)
|
||||
if(flag & PROP_HIDDEN || (check_prop && check_prop(prop)==FALSE))
|
||||
continue;
|
||||
|
||||
name= (char*)RNA_property_ui_name(prop);
|
||||
if(label_align != '\0') {
|
||||
name= RNA_property_ui_name(prop);
|
||||
|
||||
if(columns == 1) {
|
||||
col= uiLayoutColumn(layout, 1);
|
||||
uiItemL(col, name, 0);
|
||||
if(label_align=='V') {
|
||||
col= uiLayoutColumn(layout, 1);
|
||||
uiItemL(col, name, 0);
|
||||
}
|
||||
else if(label_align=='H') {
|
||||
split = uiLayoutSplit(layout, 0.5f, 0);
|
||||
|
||||
uiItemL(uiLayoutColumn(split, 0), name, 0);
|
||||
col= uiLayoutColumn(split, 0);
|
||||
}
|
||||
else {
|
||||
col= NULL;
|
||||
}
|
||||
|
||||
name= ""; /* name is shown above, empty name for button below */
|
||||
}
|
||||
else if(columns == 2) {
|
||||
split = uiLayoutSplit(layout, 0.5f, 0);
|
||||
|
||||
uiItemL(uiLayoutColumn(split, 0), name, 0);
|
||||
col= uiLayoutColumn(split, 0);
|
||||
else {
|
||||
col= layout;
|
||||
name= NULL; /* no smart label alignment, show default name with button */
|
||||
}
|
||||
else
|
||||
col= NULL;
|
||||
|
||||
uiItemFullR(col, ptr, prop, -1, 0, 0, "", 0);
|
||||
uiItemFullR(col, ptr, prop, -1, 0, 0, name, 0);
|
||||
tot++;
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/***************************** ID Utilities *******************************/
|
||||
|
||||
@@ -171,41 +171,25 @@ static void file_panel_operator_header(const bContext *C, Panel *pa)
|
||||
BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
|
||||
}
|
||||
|
||||
static int file_panel_check_prop(PropertyRNA *prop)
|
||||
{
|
||||
const char *prop_id= RNA_property_identifier(prop);
|
||||
return !( strcmp(prop_id, "filepath") == 0 ||
|
||||
strcmp(prop_id, "directory") == 0 ||
|
||||
strcmp(prop_id, "filename") == 0
|
||||
);
|
||||
}
|
||||
|
||||
static void file_panel_operator(const bContext *C, Panel *pa)
|
||||
{
|
||||
SpaceFile *sfile= CTX_wm_space_file(C);
|
||||
wmOperator *op= sfile->op;
|
||||
int empty= 1, flag;
|
||||
// int empty= 1, flag;
|
||||
|
||||
uiBlockSetFunc(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
|
||||
|
||||
if(op->type->ui) {
|
||||
op->layout= pa->layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
op->layout= NULL;
|
||||
}
|
||||
else {
|
||||
RNA_STRUCT_BEGIN(op->ptr, prop) {
|
||||
flag= RNA_property_flag(prop);
|
||||
|
||||
if(flag & PROP_HIDDEN)
|
||||
continue;
|
||||
if(strcmp(RNA_property_identifier(prop), "filepath") == 0)
|
||||
continue;
|
||||
if(strcmp(RNA_property_identifier(prop), "directory") == 0)
|
||||
continue;
|
||||
if(strcmp(RNA_property_identifier(prop), "filename") == 0)
|
||||
continue;
|
||||
uiLayoutOperatorButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_LAYOUT_OP_SHOW_EMPTY);
|
||||
|
||||
uiItemFullR(pa->layout, op->ptr, prop, -1, 0, 0, NULL, 0);
|
||||
empty= 0;
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
|
||||
if(empty)
|
||||
uiItemL(pa->layout, "No properties.", 0);
|
||||
}
|
||||
|
||||
uiBlockSetFunc(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1392,33 +1392,6 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
wmOperator *op;
|
||||
PointerRNA ptr;
|
||||
uiBlock *block;
|
||||
|
||||
block= uiLayoutGetBlock(pa->layout);
|
||||
|
||||
/* only for operators that are registered and did an undo push */
|
||||
for(op= wm->operators.last; op; op= op->prev)
|
||||
if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
|
||||
break;
|
||||
|
||||
if(op==NULL)
|
||||
return;
|
||||
|
||||
uiBlockSetFunc(block, ED_undo_operator_repeat_cb, op, NULL);
|
||||
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
uiDefAutoButsRNA(pa->layout, &ptr, 2);
|
||||
}
|
||||
#endif // XXX not used
|
||||
|
||||
void view3d_buttons_register(ARegionType *art)
|
||||
|
||||
@@ -78,29 +78,7 @@ static wmOperator *view3d_last_operator(const bContext *C)
|
||||
|
||||
static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
PointerRNA ptr;
|
||||
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
/* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
|
||||
* just fails silently */
|
||||
if(!WM_operator_repeat_check(C, op)) {
|
||||
uiBlockSetButLock(uiLayoutGetBlock(pa->layout), TRUE, "Operator cannot redo");
|
||||
uiItemL(pa->layout, "* Redo Unsupported *", 0); // XXX, could give some nicer feedback or not show redo panel at all?
|
||||
}
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
if(op->type->ui) {
|
||||
op->layout= pa->layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
op->layout= NULL;
|
||||
}
|
||||
else
|
||||
uiDefAutoButsRNA(pa->layout, &ptr, 1);
|
||||
uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0);
|
||||
}
|
||||
|
||||
static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)
|
||||
|
||||
@@ -871,13 +871,11 @@ int WM_operator_winactive(bContext *C)
|
||||
|
||||
static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
||||
{
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
wmOperator *op= arg_op;
|
||||
PointerRNA ptr;
|
||||
uiBlock *block;
|
||||
uiLayout *layout;
|
||||
uiStyle *style= U.uistyles.first;
|
||||
int columns= 2, width= 300;
|
||||
int width= 300;
|
||||
|
||||
|
||||
block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS);
|
||||
@@ -889,30 +887,9 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
||||
assert(op->type->flag & OPTYPE_REGISTER);
|
||||
|
||||
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op);
|
||||
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, 20, style);
|
||||
uiItemL(layout, op->type->name, 0);
|
||||
|
||||
/* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
|
||||
* just fails silently */
|
||||
if(!WM_operator_repeat_check(C, op)) {
|
||||
uiBlockSetButLock(uiLayoutGetBlock(layout), TRUE, "Operator cannot redo");
|
||||
uiItemL(layout, "* Redo Unsupported *", 0); // XXX, could give some nicer feedback or not show redo panel at all?
|
||||
}
|
||||
|
||||
if(op->type->ui) {
|
||||
op->layout= layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
op->layout= NULL;
|
||||
}
|
||||
else
|
||||
uiDefAutoButsRNA(layout, &ptr, columns);
|
||||
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
|
||||
|
||||
uiPopupBoundsBlock(block, 4.0f, 0, 0);
|
||||
uiEndBlock(C, block);
|
||||
@@ -945,38 +922,23 @@ void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
|
||||
static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
|
||||
{
|
||||
struct { wmOperator *op; int width; int height; } * data = userData;
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
wmOperator *op= data->op;
|
||||
PointerRNA ptr;
|
||||
uiBlock *block;
|
||||
uiLayout *layout;
|
||||
uiBut *btn;
|
||||
uiStyle *style= U.uistyles.first;
|
||||
int columns= 2;
|
||||
|
||||
block = uiBeginBlock(C, ar, "operator dialog", UI_EMBOSS);
|
||||
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
||||
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
|
||||
if (!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, style);
|
||||
uiItemL(layout, op->type->name, 0);
|
||||
|
||||
uiBlockSetFunc(block, dialog_check_cb, op, NULL);
|
||||
|
||||
if (op->type->ui) {
|
||||
op->layout= layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
op->layout= NULL;
|
||||
}
|
||||
else
|
||||
uiDefAutoButsRNA(layout, &ptr, columns);
|
||||
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
|
||||
|
||||
/* clear so the OK button is left alone */
|
||||
uiBlockSetFunc(block, NULL, NULL, NULL);
|
||||
|
||||
/* Create OK button, the callback of which will execute op */
|
||||
@@ -993,9 +955,7 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
|
||||
static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
|
||||
{
|
||||
struct { wmOperator *op; int width; int height; } * data = userData;
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
wmOperator *op= data->op;
|
||||
PointerRNA ptr;
|
||||
uiBlock *block;
|
||||
uiLayout *layout;
|
||||
uiStyle *style= U.uistyles.first;
|
||||
@@ -1004,19 +964,10 @@ static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
|
||||
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
||||
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
|
||||
|
||||
if(!op->properties) {
|
||||
IDPropertyTemplate val = {0};
|
||||
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
|
||||
}
|
||||
|
||||
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
||||
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, style);
|
||||
|
||||
if(op->type->ui) {
|
||||
op->layout= layout;
|
||||
op->type->ui((bContext*)C, op);
|
||||
op->layout= NULL;
|
||||
}
|
||||
/* since ui is defined the auto-layout args are not used */
|
||||
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
|
||||
|
||||
uiPopupBoundsBlock(block, 4.0f, 0, 0);
|
||||
uiEndBlock(C, block);
|
||||
@@ -1103,7 +1054,7 @@ static uiBlock *wm_block_create_menu(bContext *C, ARegion *ar, void *arg_op)
|
||||
op->layout= NULL;
|
||||
}
|
||||
else
|
||||
uiDefAutoButsRNA(layout, op->ptr, 2);
|
||||
uiDefAutoButsRNA(layout, op->ptr, NULL, 'H');
|
||||
|
||||
uiPopupBoundsBlock(block, 4.0f, 0, 0);
|
||||
uiEndBlock(C, block);
|
||||
|
||||
Reference in New Issue
Block a user