diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-08-27 17:48:43 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-08-27 17:56:08 +0300 |
commit | ddff9d0ea68b4c92be2fc515a4ec6a17b3696aa0 (patch) | |
tree | 0bf133537dac8f69339905ee364db47fa992a3e1 | |
parent | ca9801bd427ce2e76a992b62d476859efcc14547 (diff) |
Manipulator: support operator per-part
A single manipulator could only assign a single operator to each part.
Now each part can have it's own.
Also modify 2D selection callback, 2D started at 1, 3D at 0.
Now use -1 for unset value, start both at 0.
14 files changed, 88 insertions, 55 deletions
diff --git a/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c index 67583d28668..c789e6a13b0 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c @@ -173,16 +173,20 @@ static int manipulator_arrow2d_test_select( const float lambda_1 = line_point_factor_v2(isect_1, line_ext[0], line_ext[1]); if (isect == 1) { - return IN_RANGE_INCL(lambda_1, 0.0f, 1.0f); + if (IN_RANGE_INCL(lambda_1, 0.0f, 1.0f)) { + return 0; + } } else { BLI_assert(isect == 2); const float lambda_2 = line_point_factor_v2(isect_2, line_ext[0], line_ext[1]); - return IN_RANGE_INCL(lambda_1, 0.0f, 1.0f) && IN_RANGE_INCL(lambda_2, 0.0f, 1.0f); + if (IN_RANGE_INCL(lambda_1, 0.0f, 1.0f) && IN_RANGE_INCL(lambda_2, 0.0f, 1.0f)) { + return 0; + } } } - return 0; + return -1; } /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c index 311c8acde9e..c6638511033 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c @@ -63,11 +63,11 @@ /* wmManipulator->highlight_part */ enum { - ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE = 1, - ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT = 2, - ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT = 3, - ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP = 4, - ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN = 5, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE = 0, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT = 1, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT = 2, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP = 3, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN = 4, }; #define MANIPULATOR_RECT_MIN_WIDTH 15.0f @@ -367,7 +367,7 @@ static int manipulator_rect_transform_test_select( if (manipulator_window_project_2d( C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) { - return 0; + return -1; } const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); @@ -438,7 +438,7 @@ static int manipulator_rect_transform_test_select( return ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP; } - return 0; + return -1; } typedef struct RectTransformInteraction { diff --git a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c index a5deb47a753..37ad31db642 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c @@ -316,14 +316,14 @@ static int manipulator_grab_test_select( if (manipulator_window_project_2d( C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) { - return 0; + return -1; } if (len_squared_v2(point_local) < SQUARE(mpr->scale_final)) { - return true; + return 0; } - return 0; + return -1; } static void manipulator_grab_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop) diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c index a1646325e45..5d0940493ee 100644 --- a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c +++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c @@ -267,7 +267,7 @@ static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmManipulat RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL | ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW); - WM_manipulator_set_operator(mpr, ot, NULL); + WM_manipulator_operator_set(mpr, 0, ot, NULL); } static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 84892ee7641..9a4be46855f 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -1232,7 +1232,7 @@ static void WIDGETGROUP_manipulator_setup(const bContext *UNUSED(C), wmManipulat if (ot_store.translate == NULL) { ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true); } - ptr = WM_manipulator_set_operator(axis, ot_store.translate, NULL); + ptr = WM_manipulator_operator_set(axis, 0, ot_store.translate, NULL); break; case MAN_AXES_ROTATE: { @@ -1249,7 +1249,7 @@ static void WIDGETGROUP_manipulator_setup(const bContext *UNUSED(C), wmManipulat } ot_rotate = ot_store.rotate; } - ptr = WM_manipulator_set_operator(axis, ot_rotate, NULL); + ptr = WM_manipulator_operator_set(axis, 0, ot_rotate, NULL); break; } case MAN_AXES_SCALE: @@ -1257,7 +1257,7 @@ static void WIDGETGROUP_manipulator_setup(const bContext *UNUSED(C), wmManipulat if (ot_store.resize == NULL) { ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true); } - ptr = WM_manipulator_set_operator(axis, ot_store.resize, NULL); + ptr = WM_manipulator_operator_set(axis, 0, ot_store.resize, NULL); break; } } diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c index 96c87039fbf..9538b4c1846 100644 --- a/source/blender/editors/transform/transform_manipulator2d.c +++ b/source/blender/editors/transform/transform_manipulator2d.c @@ -208,7 +208,7 @@ void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulator WM_manipulator_set_color_highlight(axis, color_hi); /* assign operator */ - PointerRNA *ptr = WM_manipulator_set_operator(axis, ot_translate, NULL); + PointerRNA *ptr = WM_manipulator_operator_set(axis, 0, ot_translate, NULL); int constraint[3] = {0.0f}; constraint[(axis_idx + 1) % 2] = 1; if (RNA_struct_find_property(ptr, "constraint_axis")) diff --git a/source/blender/makesrna/intern/rna_wm_manipulator_api.c b/source/blender/makesrna/intern/rna_wm_manipulator_api.c index a0d474968d0..27d292ddfa2 100644 --- a/source/blender/makesrna/intern/rna_wm_manipulator_api.c +++ b/source/blender/makesrna/intern/rna_wm_manipulator_api.c @@ -140,7 +140,7 @@ static void rna_manipulator_target_set_prop( } static PointerRNA rna_manipulator_target_set_operator( - wmManipulator *mpr, ReportList *reports, const char *opname) + wmManipulator *mpr, ReportList *reports, const char *opname, int part_index) { wmOperatorType *ot; @@ -157,9 +157,7 @@ static PointerRNA rna_manipulator_target_set_operator( properties = IDP_New(IDP_GROUP, &val, "wmManipulatorProperties"); } - WM_manipulator_set_operator(mpr, ot, properties); - - return mpr->op_data.ptr; + return *WM_manipulator_operator_set(mpr, part_index, ot, properties); } /** \} */ @@ -264,6 +262,8 @@ void RNA_api_manipulator(StructRNA *srna) "(overrides property targets)"); parm = RNA_def_string(func, "operator", NULL, 0, "", "Target operator"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + RNA_def_int(func, "index", 0, 0, 255, "Part index", "", 0, 255); + /* similar to UILayout.operator */ parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR); diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index 84e93c2ca29..726e560a061 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -73,8 +73,11 @@ void WM_manipulator_name_set(struct wmManipulatorGroup *mgroup, struct wmManipul bool WM_manipulator_select_unlink(struct wmManipulatorMap *mmap, struct wmManipulator *mpr); bool WM_manipulator_select_set(struct wmManipulatorMap *mmap, struct wmManipulator *mpr, bool select); -struct PointerRNA *WM_manipulator_set_operator( - struct wmManipulator *, struct wmOperatorType *ot, struct IDProperty *properties); +struct wmManipulatorOpElem *WM_manipulator_operator_get( + struct wmManipulator *mpr, int part_index); +struct PointerRNA *WM_manipulator_operator_set( + struct wmManipulator *mpr, int part_index, + struct wmOperatorType *ot, struct IDProperty *properties); /* callbacks */ void WM_manipulator_set_fn_custom_modal(struct wmManipulator *mpr, wmManipulatorFnModal fn); diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index 23c0fa305a9..df4dd9668d4 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -138,6 +138,13 @@ typedef enum { #include "wm_manipulator_fn.h" +typedef struct wmManipulatorOpElem { + struct wmOperatorType *type; + /* operator properties if manipulator spawns and controls an operator, + * or owner pointer if manipulator spawns and controls a property */ + PointerRNA ptr; +} wmManipulatorOpElem; + /* manipulators are set per region by registering them on manipulator-maps */ struct wmManipulator { struct wmManipulator *next, *prev; @@ -162,7 +169,8 @@ struct wmManipulator { /* state flags (active, highlighted, selected) */ eWM_ManipulatorState state; - /* Optional ID for highlighting different parts of this manipulator. */ + /* Optional ID for highlighting different parts of this manipulator. + * -1 when unset, otherwise a valid index. (Used as index to 'op_data'). */ int highlight_part; /* Transformation of the manipulator in 2d or 3d space. @@ -192,13 +200,10 @@ struct wmManipulator { /* data used during interaction */ void *interaction_data; - /* name of operator to spawn when activating the manipulator */ - struct { - struct wmOperatorType *type; - /* operator properties if manipulator spawns and controls an operator, - * or owner pointer if manipulator spawns and controls a property */ - PointerRNA ptr; - } op_data; + /* Operator to spawn when activating the manipulator (overrides property editing), + * an array of items (aligned with #wmManipulator.highlight_part). */ + wmManipulatorOpElem *op_data; + int op_data_len; struct IDProperty *properties; @@ -267,7 +272,8 @@ typedef struct wmManipulatorType { /* determines 3d intersection by rendering the manipulator in a selection routine. */ wmManipulatorFnDrawSelect draw_select; - /* determine if the mouse intersects with the manipulator. The calculation should be done in the callback itself */ + /* Determine if the mouse intersects with the manipulator. + * The calculation should be done in the callback itself, -1 for no seleciton. */ wmManipulatorFnTestSelect test_select; /* handler used by the manipulator. Usually handles interaction tied to a manipulator type */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c index 316254202fa..ee7c10aa50b 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c @@ -172,8 +172,11 @@ void WM_manipulator_free(wmManipulator *mpr) } #endif - if (mpr->op_data.ptr.data) { - WM_operator_properties_free(&mpr->op_data.ptr); + if (mpr->op_data) { + for (int i = 0; i < mpr->op_data_len; i++) { + WM_operator_properties_free(&mpr->op_data[i].ptr); + } + MEM_freeN(mpr->op_data); } if (mpr->ptr != NULL) { @@ -228,22 +231,38 @@ void WM_manipulator_unlink(ListBase *manipulatorlist, wmManipulatorMap *mmap, wm * * \{ */ +struct wmManipulatorOpElem *WM_manipulator_operator_get( + wmManipulator *mpr, int part_index) +{ + if (mpr->op_data && ((part_index >= 0) && (part_index < mpr->op_data_len))) { + return &mpr->op_data[part_index]; + } + return NULL; +} -PointerRNA *WM_manipulator_set_operator( - wmManipulator *mpr, wmOperatorType *ot, IDProperty *properties) +PointerRNA *WM_manipulator_operator_set( + wmManipulator *mpr, int part_index, + wmOperatorType *ot, IDProperty *properties) { - mpr->op_data.type = ot; + BLI_assert(part_index < 255); + /* We could pre-allocate these but using multiple is such a rare thing. */ + if (part_index >= mpr->op_data_len) { + mpr->op_data_len = part_index + 1; + mpr->op_data = MEM_recallocN(mpr->op_data, sizeof(*mpr->op_data) * mpr->op_data_len); + } + wmManipulatorOpElem *mpop = &mpr->op_data[part_index]; + mpop->type = ot; - if (mpr->op_data.ptr.data) { - WM_operator_properties_free(&mpr->op_data.ptr); + if (mpop->ptr.data) { + WM_operator_properties_free(&mpop->ptr); } - WM_operator_properties_create_ptr(&mpr->op_data.ptr, ot); + WM_operator_properties_create_ptr(&mpop->ptr, ot); if (properties) { - mpr->op_data.ptr.data = properties; + mpop->ptr.data = properties; } - return &mpr->op_data.ptr; + return &mpop->ptr; } static void wm_manipulator_set_matrix_rotation_from_z_axis__internal( diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c index 94064c84701..bc09fa30931 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c @@ -146,7 +146,7 @@ wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator( { for (wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) { if (mpr->type->test_select && (mpr->flag & WM_MANIPULATOR_HIDDEN) == 0) { - if ((*r_part = mpr->type->test_select(C, mpr, event))) { + if ((*r_part = mpr->type->test_select(C, mpr, event)) != -1) { return mpr; } } @@ -385,8 +385,9 @@ static int manipulator_tweak_invoke(bContext *C, wmOperator *op, const wmEvent * /* XXX temporary workaround for modal manipulator operator * conflicting with modal operator attached to manipulator */ - if (mpr->op_data.type) { - if (mpr->op_data.type->modal) { + wmManipulatorOpElem *mpop = WM_manipulator_operator_get(mpr, mpr->highlight_part); + if (mpop && mpop->type) { + if (mpop->type->modal) { return OPERATOR_FINISHED; } } diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index 51ad133daed..e0c803067d6 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -643,9 +643,8 @@ void wm_manipulatormaps_handled_modal_update( /* regular update for running operator */ if (modal_running) { - if (mpr && (mpr->op_data.type != NULL) && - (mpr->op_data.type == handler->op->type)) - { + wmManipulatorOpElem *mpop = mpr ? WM_manipulator_operator_get(mpr, mpr->highlight_part) : NULL; + if (mpr && mpop && (mpop->type != NULL) && (mpop->type == handler->op->type)) { wmManipulatorFnModal modal_fn = mpr->custom_modal ? mpr->custom_modal : mpr->type->modal; if (modal_fn != NULL) { int retval = modal_fn(C, mpr, event, 0); @@ -813,7 +812,7 @@ void wm_manipulatormap_highlight_set( { if (mmap->mmap_context.highlight) { mmap->mmap_context.highlight->state &= ~WM_MANIPULATOR_STATE_HIGHLIGHT; - mmap->mmap_context.highlight->highlight_part = 0; + mmap->mmap_context.highlight->highlight_part = -1; } mmap->mmap_context.highlight = mpr; @@ -873,8 +872,9 @@ void wm_manipulatormap_modal_set( mpr->state |= WM_MANIPULATOR_STATE_MODAL; mmap->mmap_context.modal = mpr; - if (mpr->op_data.type) { - WM_operator_name_call_ptr(C, mpr->op_data.type, WM_OP_INVOKE_DEFAULT, &mpr->op_data.ptr); + struct wmManipulatorOpElem *mpop = WM_manipulator_operator_get(mpr, mpr->highlight_part); + if (mpop && mpop->type) { + WM_operator_name_call_ptr(C, mpop->type, WM_OP_INVOKE_DEFAULT, &mpop->ptr); /* we failed to hook the manipulator to the operator handler or operator was cancelled, return */ if (!mmap->mmap_context.modal) { diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c index 50e1d82a0fc..9ef3590de96 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c @@ -87,7 +87,7 @@ void WM_manipulator_target_property_def_rna_ptr( wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type); /* if manipulator evokes an operator we cannot use it for property manipulation */ - mpr->op_data.type = NULL; + BLI_assert(mpr->op_data == NULL); mpr_prop->type = mpr_prop_type; @@ -116,7 +116,7 @@ void WM_manipulator_target_property_def_func_ptr( wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type); /* if manipulator evokes an operator we cannot use it for property manipulation */ - mpr->op_data.type = NULL; + BLI_assert(mpr->op_data == NULL); mpr_prop->type = mpr_prop_type; diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 86497f2e914..80257096cb6 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -365,7 +365,7 @@ void WM_report(ReportType type, const char *message) RET_NONE void BPY_RNA_manipulatorgroup_wrapper(struct wmManipulatorGroupType *wgt, void *userdata) RET_NONE void BPY_RNA_manipulator_wrapper(struct wmManipulatorType *wgt, void *userdata) RET_NONE -PointerRNA *WM_manipulator_set_operator(struct wmManipulator *mpr, struct wmOperatorType *ot, struct IDProperty *properties) RET_NULL +PointerRNA *WM_manipulator_operator_set(struct wmManipulator *mpr, struct wmOperatorType *ot, struct IDProperty *properties) RET_NULL const struct wmManipulatorPropertyType *WM_manipulatortype_target_property_find(const struct wmManipulatorType *wt, const char *idname) RET_NULL const struct wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet) RET_NULL struct wmManipulator *WM_manipulator_new_ptr(const struct wmManipulatorType *wt, struct wmManipulatorGroup *mgroup, struct PointerRNA *properties) RET_NULL |