patch #21680 from Richard Olsson

wm.invoke_props_dialog()

This is so python scripts can have popups which do not redo all the time.
This commit is contained in:
2010-03-20 18:03:59 +00:00
parent 11b260ee06
commit 66ccd94e3f
3 changed files with 93 additions and 11 deletions

View File

@@ -158,7 +158,11 @@ static int rna_event_add_modal_handler(struct bContext *C, struct wmOperator *op
#else
static void rna_generic_op_invoke(FunctionRNA *func, int use_event, int use_ret)
#define WM_GEN_INVOKE_EVENT (1<<0)
#define WM_GEN_INVOKE_SIZE (1<<1)
#define WM_GEN_INVOKE_RETURN (1<<2)
static void rna_generic_op_invoke(FunctionRNA *func, int flag)
{
PropertyRNA *parm;
@@ -166,12 +170,17 @@ static void rna_generic_op_invoke(FunctionRNA *func, int use_event, int use_ret)
parm= RNA_def_pointer(func, "operator", "Operator", "", "Operator to call.");
RNA_def_property_flag(parm, PROP_REQUIRED);
if(use_event) {
if(flag & WM_GEN_INVOKE_EVENT) {
parm= RNA_def_pointer(func, "event", "Event", "", "Event.");
RNA_def_property_flag(parm, PROP_REQUIRED);
}
if(use_ret) {
if(flag & WM_GEN_INVOKE_SIZE) {
parm= RNA_def_int(func, "width", 300, 0, INT_MAX, "", "Width of the popup.", 0, INT_MAX);
parm= RNA_def_int(func, "height", 20, 0, INT_MAX, "", "Height of the popup.", 0, INT_MAX);
}
if(flag & WM_GEN_INVOKE_RETURN) {
parm= RNA_def_enum(func, "result", operator_return_items, 0, "result", "");
RNA_def_property_flag(parm, PROP_ENUM_FLAG);
RNA_def_function_return(func, parm);
@@ -185,7 +194,7 @@ void RNA_api_wm(StructRNA *srna)
func= RNA_def_function(srna, "add_fileselect", "WM_event_add_fileselect");
RNA_def_function_ui_description(func, "Show up the file selector.");
rna_generic_op_invoke(func, 0, 0);
rna_generic_op_invoke(func, 0);
func= RNA_def_function(srna, "add_keyconfig", "WM_keyconfig_add_user");
parm= RNA_def_string(func, "name", "", 0, "Name", "");
@@ -206,18 +215,21 @@ void RNA_api_wm(StructRNA *srna)
/* invoke functions, for use with python */
func= RNA_def_function(srna, "invoke_props_popup", "WM_operator_props_popup");
RNA_def_function_ui_description(func, "Operator popup invoke.");
rna_generic_op_invoke(func, 1, 1);
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT|WM_GEN_INVOKE_RETURN);
/* invoked dialog opens popup with OK button, does not auto-exec operator. */
func= RNA_def_function(srna, "invoke_props_dialog", "WM_operator_props_dialog_popup");
RNA_def_function_ui_description(func, "Operator dialog (non-autoexec popup) invoke.");
rna_generic_op_invoke(func, WM_GEN_INVOKE_SIZE|WM_GEN_INVOKE_RETURN);
/* invoke enum */
func= RNA_def_function(srna, "invoke_search_popup", "rna_Operator_enum_search_invoke");
rna_generic_op_invoke(func, 0, 0);
rna_generic_op_invoke(func, 0);
/* invoke functions, for use with python */
func= RNA_def_function(srna, "invoke_popup", "WM_operator_ui_popup");
RNA_def_function_ui_description(func, "Operator popup invoke.");
rna_generic_op_invoke(func, 0, 0);
parm= RNA_def_int(func, "width", 300, 0, INT_MAX, "", "Width of the popup.", 0, INT_MAX);
parm= RNA_def_int(func, "height", 20, 0, INT_MAX, "", "Height of the popup.", 0, INT_MAX);
rna_generic_op_invoke(func, WM_GEN_INVOKE_SIZE|WM_GEN_INVOKE_RETURN);
}
void RNA_api_operator(StructRNA *srna)

View File

@@ -190,8 +190,9 @@ int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wm
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_operator_props_dialog_popup (struct bContext *C, struct wmOperator *op, int width, int height);
int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op);
void WM_operator_ui_popup (struct bContext *C, struct wmOperator *op, int width, int height);
int WM_operator_ui_popup (struct bContext *C, struct wmOperator *op, int width, int height);
int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, char *message);

View File

@@ -910,6 +910,60 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
return block;
}
/* Only invoked by OK button in popups created with wm_block_create_dialog() */
static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
{
wmOperator *op= arg1;
uiBlock *block= arg2;
WM_operator_call(C, op);
uiPupBlockClose(C, block);
}
/* Dialogs are popups that require user verification (click OK) before exec */
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);
if (op->type->ui) {
op->layout= layout;
op->type->ui((bContext*)C, op);
op->layout= NULL;
}
else
uiDefAutoButsRNA(C, layout, &ptr, columns);
/* Create OK button, the callback of which will execute op */
btn= uiDefBut(block, BUT, 0, "OK", 0, 0, 0, 20, NULL, 0, 0, 0, 0, "");
uiButSetFunc(btn, dialog_exec_cb, op, block);
uiPopupBoundsBlock(block, 4.0f, 0, 0);
uiEndBlock(C, block);
return block;
}
static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
{
@@ -958,13 +1012,28 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *event)
return retval;
}
void WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
{
struct { wmOperator *op; int width; int height; } data;
data.op= op;
data.width= width;
data.height= height;
/* op is not executed until popup OK but is clicked */
uiPupBlock(C, wm_block_create_dialog, &data);
return OPERATOR_RUNNING_MODAL;
}
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
{
struct { wmOperator *op; int width; int height; } data;
data.op = op;
data.width = width;
data.height = height;
uiPupBlock(C, wm_operator_create_ui, &data);
return OPERATOR_RUNNING_MODAL;
}
int WM_operator_redo_popup(bContext *C, wmOperator *op)