WM: Add operator property poll callback
authorCampbell Barton <ideasman42@gmail.com>
Wed, 25 Jul 2018 23:59:56 +0000 (09:59 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 26 Jul 2018 01:53:53 +0000 (11:53 +1000)
This allows operators to filter out properties from the
auto-generated draw functions.

Some custom draw functions can move to using this.

15 files changed:
source/blender/editors/gpencil/gpencil_convert.c
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_utils.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/object/object_data_transfer.c
source/blender/editors/object/object_relations.c
source/blender/editors/screen/screendump.c
source/blender/editors/space_clip/clip_toolbar.c
source/blender/editors/space_file/file_panels.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_operators.c

index 0c148710e3e28c58ac05fb03dde38b6c01171b2f..d6cb36d7fcd3f8c764e544c1926d757668ae5317 100644 (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)
index eefbeee6336b8e93befbc01400d2d9f552a7fb39..f2aad249df3dfe450de0451bfd5d74e5c6437f64 100644 (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);
index daee0d3af3f337ee1f6f6883eea592d225df4ecc..9d05819dd6a003f0f6eb829cec1a70430a774665 100644 (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);
index 1aa6f045266b6630b831f64629da31d780cc41a9..2059fc1c849ba1bd5c78d0a266dae8d5fe212751 100644 (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);
index a478fee1f82fa4ccf7baed49b4ea09a9160c4783..c5c670b77ea44549c1443f04c889d36ca456a2b0 100644 (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)
index 384bea3701f9e65e1c06c81879a085346881884a..44cca58fc5c5206f05a788dcd9756ab60cc6a166 100644 (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 */
index 286a7e095817711ea937efd457e5d956505d05c7..77b5d35db0341c8e07b05cf9f2beee583d8e1e4b 100644 (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)
index dda75877f50a8401a5d3883e92a157d78c918341..3ec2078a4d19de87f2851f83dd0bd973703bf72e 100644 (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)
index fbd73ee43152bb936e2bd82d8ea0c4df433c4b43..7d4aa0083f1b4012dd5d760ced77349d0fc5ba7f 100644 (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)
index c02320de89ebc6ad62dbee0ec3ae2d7a830f111f..c5350750af4fc5400c48c18bdad14d1046a60c4d 100644 (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);
 }
index d9f66ef175adf911b14e43498e3c97f2969a35f6..2a015177dacf0e93dd60e28993aed80c3655240f 100644 (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)
index 5c3329250113af396c0387f00597e949324bb70b..b3e1d3be42a2d9d530824a7a8bdb27572cb92c61 100644 (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);
index 02634d1b0d1eb09e2e04f430f12f4f3c13c43f6a..02136af958bbb7ed4a842499520ea01ea0fafce1 100644 (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)
index 3d4080eb60026014053832639c4cf8f7dfc610f5..918188117ebf46b018b43186714e3838d2102166 100644 (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 *);
 
index ffa6b0fc371c84b473a1b488b4047438aa728d4d..454d7dc57f06a33a63bda1935ee401474b278500 100644 (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);