diff options
Diffstat (limited to 'source/blender/editors/transform/transform_manipulator2d.c')
-rw-r--r-- | source/blender/editors/transform/transform_manipulator2d.c | 147 |
1 files changed, 128 insertions, 19 deletions
diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c index 104675cb1a8..94f425eb9f0 100644 --- a/source/blender/editors/transform/transform_manipulator2d.c +++ b/source/blender/editors/transform/transform_manipulator2d.c @@ -73,8 +73,13 @@ typedef struct ManipulatorGroup2D { wmManipulator *translate_x, *translate_y; + wmManipulator *cage; + /* Current origin in view space, used to update widget origin for possible view changes */ float origin[2]; + float min[2]; + float max[2]; + } ManipulatorGroup2D; @@ -131,11 +136,18 @@ static void manipulator2d_get_axis_color(const int axis_idx, float *r_col, float static ManipulatorGroup2D *manipulatorgroup2d_init(wmManipulatorGroup *mgroup) { const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_2d", true); + const wmManipulatorType *wt_cage = WM_manipulatortype_find("MANIPULATOR_WT_cage_2d", true); ManipulatorGroup2D *man = MEM_callocN(sizeof(ManipulatorGroup2D), __func__); - man->translate_x = WM_manipulator_new_ptr(wt_arrow, mgroup, "translate_x", NULL); - man->translate_y = WM_manipulator_new_ptr(wt_arrow, mgroup, "translate_y", NULL); + man->translate_x = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + man->translate_y = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + man->cage = WM_manipulator_new_ptr(wt_cage, mgroup, NULL); + + RNA_enum_set(man->cage->ptr, "transform", + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE | + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE); return man; } @@ -143,17 +155,24 @@ static ManipulatorGroup2D *manipulatorgroup2d_init(wmManipulatorGroup *mgroup) /** * Calculates origin in view space, use with #manipulator2d_origin_to_region. */ -static void manipulator2d_calc_origin(const bContext *C, float *r_origin) +static void manipulator2d_calc_bounds(const bContext *C, float *r_center, float *r_min, float *r_max) { SpaceImage *sima = CTX_wm_space_image(C); Image *ima = ED_space_image(sima); - if (sima->around == V3D_AROUND_CURSOR) { - copy_v2_v2(r_origin, sima->cursor); + float min_buf[2], max_buf[2]; + if (r_min == NULL) { + r_min = min_buf; } - else { - ED_uvedit_center(CTX_data_scene(C), ima, CTX_data_edit_object(C), r_origin, sima->around); + if (r_max == NULL) { + r_max = max_buf; + } + + if (!ED_uvedit_minmax(CTX_data_scene(C), ima, CTX_data_edit_object(C), r_min, r_max)) { + zero_v2(r_min); + zero_v2(r_max); } + mid_v2_v2v2(r_center, r_min, r_max); } /** @@ -167,17 +186,20 @@ BLI_INLINE void manipulator2d_origin_to_region(ARegion *ar, float *r_origin) /** * Custom handler for manipulator widgets */ -static void manipulator2d_modal( - bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), const int UNUSED(flag)) +static int manipulator2d_modal( + bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), + eWM_ManipulatorTweak UNUSED(tweak_flag)) { ARegion *ar = CTX_wm_region(C); float origin[3]; - manipulator2d_calc_origin(C, origin); + manipulator2d_calc_bounds(C, origin, NULL, NULL); manipulator2d_origin_to_region(ar, origin); WM_manipulator_set_matrix_location(widget, origin); ED_region_tag_redraw(ar); + + return OPERATOR_RUNNING_MODAL; } void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) @@ -190,8 +212,8 @@ void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulator { const float offset[3] = {0.0f, 0.2f}; - float col[4], col_hi[4]; - manipulator2d_get_axis_color(axis_idx, col, col_hi); + float color[4], color_hi[4]; + manipulator2d_get_axis_color(axis_idx, color, color_hi); /* custom handler! */ WM_manipulator_set_fn_custom_modal(axis, manipulator2d_modal); @@ -201,41 +223,128 @@ void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulator WM_manipulator_set_matrix_offset_location(axis, offset); WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH); WM_manipulator_set_scale(axis, U.manipulator_size); - WM_manipulator_set_color(axis, col); - WM_manipulator_set_color_highlight(axis, col_hi); + WM_manipulator_set_color(axis, color); + WM_manipulator_set_color_highlight(axis, color_hi); /* assign operator */ - PointerRNA *ptr = WM_manipulator_set_operator(axis, ot_translate, NULL); - int constraint[3] = {0.0f}; + PointerRNA *ptr = WM_manipulator_operator_set(axis, 0, ot_translate, NULL); + int constraint[3] = {0}; constraint[(axis_idx + 1) % 2] = 1; if (RNA_struct_find_property(ptr, "constraint_axis")) RNA_boolean_set_array(ptr, "constraint_axis", constraint); RNA_boolean_set(ptr, "release_confirm", 1); } MAN2D_ITER_AXES_END; + + { + wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true); + wmOperatorType *ot_rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true); + PointerRNA *ptr; + + /* assign operator */ + ptr = WM_manipulator_operator_set(man->cage, 0, ot_translate, NULL); + RNA_boolean_set(ptr, "release_confirm", 1); + + int constraint_x[3] = {1, 0, 0}; + int constraint_y[3] = {0, 1, 0}; + + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X, ot_resize, NULL); + PropertyRNA *prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); + PropertyRNA *prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis"); + RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_x); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X, ot_resize, NULL); + RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_x); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y, ot_resize, NULL); + RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_y); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y, ot_resize, NULL); + RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_y); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y, ot_resize, NULL); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y, ot_resize, NULL); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y, ot_resize, NULL); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y, ot_resize, NULL); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + ptr = WM_manipulator_operator_set(man->cage, ED_MANIPULATOR_CAGE2D_PART_ROTATE, ot_rotate, NULL); + RNA_property_boolean_set(ptr, prop_release_confirm, true); + } } void ED_widgetgroup_manipulator2d_refresh(const bContext *C, wmManipulatorGroup *mgroup) { ManipulatorGroup2D *man = mgroup->customdata; float origin[3]; - - manipulator2d_calc_origin(C, origin); + manipulator2d_calc_bounds(C, origin, man->min, man->max); copy_v2_v2(man->origin, origin); + bool show_cage = !equals_v2v2(man->min, man->max); + + if (show_cage) { + man->cage->flag &= ~WM_MANIPULATOR_HIDDEN; + man->translate_x->flag |= WM_MANIPULATOR_HIDDEN; + man->translate_y->flag |= WM_MANIPULATOR_HIDDEN; + } + else { + man->cage->flag |= WM_MANIPULATOR_HIDDEN; + man->translate_x->flag &= ~WM_MANIPULATOR_HIDDEN; + man->translate_y->flag &= ~WM_MANIPULATOR_HIDDEN; + } + + if (show_cage) { + wmManipulatorOpElem *mpop; + float mid[2]; + const float *min = man->min; + const float *max = man->max; + mid_v2_v2v2(mid, min, max); + + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X); + PropertyRNA *prop_center_override = RNA_struct_find_property(&mpop->ptr, "center_override"); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){max[0], mid[1], 0.0f}); + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){min[0], mid[1], 0.0f}); + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_Y); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){mid[0], max[1], 0.0f}); + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_Y); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){mid[0], min[1], 0.0f}); + + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MIN_Y); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){max[0], max[1], 0.0f}); + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MIN_X_MAX_Y); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){max[0], min[1], 0.0f}); + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MIN_Y); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){min[0], max[1], 0.0f}); + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_SCALE_MAX_X_MAX_Y); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){min[0], min[1], 0.0f}); + + mpop = WM_manipulator_operator_get(man->cage, ED_MANIPULATOR_CAGE2D_PART_ROTATE); + RNA_property_float_set_array(&mpop->ptr, prop_center_override, (float[3]){mid[0], mid[1], 0.0f}); + } } void ED_widgetgroup_manipulator2d_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) { + ARegion *ar = CTX_wm_region(C); ManipulatorGroup2D *man = mgroup->customdata; float origin[3] = {UNPACK2(man->origin), 0.0f}; + float origin_aa[3] = {UNPACK2(man->origin), 0.0f}; - manipulator2d_origin_to_region(CTX_wm_region(C), origin); + manipulator2d_origin_to_region(ar, origin); MAN2D_ITER_AXES_BEGIN(axis, axis_idx) { WM_manipulator_set_matrix_location(axis, origin); } MAN2D_ITER_AXES_END; + + UI_view2d_view_to_region_m4(&ar->v2d, man->cage->matrix_space); + WM_manipulator_set_matrix_offset_location(man->cage, origin_aa); + man->cage->matrix_offset[0][0] = (man->max[0] - man->min[0]); + man->cage->matrix_offset[1][1] = (man->max[1] - man->min[1]); } /* TODO (Julian) |