WM: Add operator property poll callback

This allows operators to filter out properties from the
auto-generated draw functions.

Some custom draw functions can move to using this.
This commit is contained in:
Campbell Barton 2018-07-26 09:59:56 +10:00
parent 2df27fa6cf
commit dbd79c097c
Notes: blender-bot 2024-03-25 05:51:17 +01:00
Referenced by issue #119854, File handlers: hidden properties are shown in the properties dialog if the file selector was called before
15 changed files with 68 additions and 39 deletions

View File

@ -1371,7 +1371,7 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
const bool link_strokes = RNA_boolean_get(ptr, "use_link_strokes");
@ -1444,7 +1444,7 @@ static void gp_convert_ui(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* Main auto-draw call */
uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, NULL, '\0');
}
void GPENCIL_OT_convert(wmOperatorType *ot)

View File

@ -703,7 +703,11 @@ uiBut *uiDefSearchButO_ptr(
short width, short height, float a1, float a2, const char *tip);
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);
int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align);
int uiDefAutoButsRNA(
uiLayout *layout, struct PointerRNA *ptr,
bool (*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data,
const char label_align);
/* Links
*
@ -988,7 +992,6 @@ void UI_but_func_operator_search(uiBut *but);
void uiTemplateOperatorSearch(uiLayout *layout);
void uiTemplateOperatorPropertyButs(
const struct bContext *C, uiLayout *layout, struct wmOperator *op,
bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const char label_align, const short flag);
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C);

View File

@ -3549,13 +3549,24 @@ static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt,
}
#endif
struct uiTemplateOperatorPropertyPollParam {
const bContext *C;
wmOperator *op;
};
static bool ui_layout_operator_buts_poll_property(
struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data)
{
struct uiTemplateOperatorPropertyPollParam *params = user_data;
return params->op->type->poll_property(params->C, params->op, prop);
}
/**
* Draw Operator property buttons for redoing execution with different settings.
* This function does not initialize the layout, functions can be called on the layout before and after.
*/
void uiTemplateOperatorPropertyButs(
const bContext *C, uiLayout *layout, wmOperator *op,
bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const char label_align, const short flag)
{
if (!op->properties) {
@ -3611,11 +3622,16 @@ void uiTemplateOperatorPropertyButs(
wmWindowManager *wm = CTX_wm_manager(C);
PointerRNA ptr;
int empty;
struct uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op};
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* main draw call */
empty = uiDefAutoButsRNA(layout, &ptr, check_prop, label_align) == 0;
empty = uiDefAutoButsRNA(
layout, &ptr,
op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL,
op->type->poll_property ? &user_data : NULL,
label_align) == 0;
if (empty && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
uiItemL(layout, IFACE_("No Properties"), ICON_NONE);

View File

@ -159,7 +159,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
*/
int uiDefAutoButsRNA(
uiLayout *layout, PointerRNA *ptr,
bool (*check_prop)(PointerRNA *, PropertyRNA *),
bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data,
const char label_align)
{
uiLayout *split, *col;
@ -172,8 +172,9 @@ int uiDefAutoButsRNA(
RNA_STRUCT_BEGIN (ptr, prop)
{
flag = RNA_property_flag(prop);
if (flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop) == 0))
if (flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop, user_data) == 0)) {
continue;
}
if (label_align != '\0') {
PropertyType type = RNA_property_type(prop);

View File

@ -5373,7 +5373,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
const int action = RNA_enum_get(ptr, "type");
@ -5406,7 +5406,7 @@ static void edbm_sort_elements_ui(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* Main auto-draw call. */
uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, NULL, '\0');
}
void MESH_OT_sort_elements(wmOperatorType *ot)

View File

@ -453,7 +453,7 @@ static bool data_transfer_poll(bContext *C)
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
PropertyRNA *prop_other;
@ -525,7 +525,7 @@ static void data_transfer_ui(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* Main auto-draw call */
uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, NULL, '\0');
}
/* transfers weight from active to selected */

View File

@ -938,7 +938,7 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
return OPERATOR_INTERFACE;
}
static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
const int type = RNA_enum_get(ptr, "type");
@ -963,7 +963,7 @@ static void parent_set_ui(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* Main auto-draw call. */
uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, NULL, '\0');
}
void OBJECT_OT_parent_set(wmOperatorType *ot)

View File

@ -247,7 +247,7 @@ static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
screenshot_data_free(op);
}
static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@ -266,7 +266,7 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, '\0');
}
static bool screenshot_poll(bContext *C)

View File

@ -193,7 +193,7 @@ void CLIP_OT_tools(wmOperatorType *ot)
static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
{
uiTemplateOperatorPropertyButs(C, pa->layout, op, NULL, 'V', 0);
uiTemplateOperatorPropertyButs(C, pa->layout, op, 'V', 0);
}
static void clip_panel_operator_redo_header(const bContext *C, Panel *pa)

View File

@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "ED_fileselect.h"
@ -71,24 +72,26 @@ static void file_panel_operator_header(const bContext *C, Panel *pa)
BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
}
static bool file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
return !(STREQ(prop_id, "filepath") ||
STREQ(prop_id, "directory") ||
STREQ(prop_id, "filename")
);
}
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;
UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
uiTemplateOperatorPropertyButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
/* Hack: temporary hide.*/
const char *hide[3] = {"filepath", "directory", "filename"};
for (int i = 0; i < ARRAY_SIZE(hide); i++) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
uiTemplateOperatorPropertyButs(C, pa->layout, op, '\0', UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
for (int i = 0; i < ARRAY_SIZE(hide); i++) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
RNA_def_property_clear_flag(prop, PROP_HIDDEN);
}
UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
}

View File

@ -1406,7 +1406,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
return OPERATOR_RUNNING_MODAL;
}
static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@ -1425,7 +1425,7 @@ static void image_open_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, NULL, '\0');
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
@ -2120,7 +2120,7 @@ static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op)
image_save_as_free(op);
}
static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@ -2145,7 +2145,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, NULL, '\0');
/* multiview template */
if (is_multiview)

View File

@ -627,7 +627,7 @@ static void sequencer_add_cancel(bContext *UNUSED(C), wmOperator *op)
op->customdata = NULL;
}
static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@ -693,7 +693,7 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, '\0');
uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, NULL, '\0');
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);

View File

@ -67,7 +67,7 @@
static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
{
uiTemplateOperatorPropertyButs(C, pa->layout, op, NULL, 'V', 0);
uiTemplateOperatorPropertyButs(C, pa->layout, op, 'V', 0);
}
static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)

View File

@ -571,6 +571,12 @@ typedef struct wmOperatorType {
* that the operator might still fail to execute even if this return true */
bool (*poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT;
/* Use to check of properties should be displayed in auto-generated UI.
* Use 'check' callback to enforce refreshing. */
bool (*poll_property)(
const struct bContext *C, struct wmOperator *op,
const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT;
/* optional panel for redo and repeat, autogenerated if not set */
void (*ui)(struct bContext *, struct wmOperator *);

View File

@ -996,13 +996,13 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
if (op->type->flag & OPTYPE_MACRO) {
for (op = op->macro.first; op; op = op->next) {
uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
uiTemplateOperatorPropertyButs(C, layout, op, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
if (op->next)
uiItemS(layout);
}
}
else {
uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
uiTemplateOperatorPropertyButs(C, layout, op, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
}
UI_block_bounds_set_popup(block, 4, 0, 0);
@ -1071,7 +1071,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
uiTemplateOperatorPropertyButs(C, layout, op, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
/* clear so the OK button is left alone */
UI_block_func_set(block, NULL, NULL, NULL);
@ -1110,7 +1110,7 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
/* since ui is defined the auto-layout args are not used */
uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'V', 0);
uiTemplateOperatorPropertyButs(C, layout, op, 'V', 0);
UI_block_func_set(block, NULL, NULL, NULL);