diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 55f7319b2f0..290241dc620 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -44,6 +44,8 @@ /* The same as in `draw_cache.c` */ #define CIRCLE_RESOL 32 +static int gizmo_cage2d_transform_flag_get(const wmGizmo *gz); + static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2]) { float matrix_final_no_offset[4][4]; @@ -616,7 +618,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, RNA_float_get_array(gz->ptr, "dimensions", dims); float matrix_final[4][4]; - const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + const int transform_flag = gizmo_cage2d_transform_flag_get(gz); const int draw_style = RNA_enum_get(gz->ptr, "draw_style"); const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); @@ -831,7 +833,7 @@ static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2]) /* Expand for hots-pot. */ const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2}; - const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + const int transform_flag = gizmo_cage2d_transform_flag_get(gz); const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) { @@ -934,8 +936,21 @@ typedef struct RectTransformInteraction { float orig_matrix_offset[4][4]; float orig_matrix_final_no_offset[4][4]; Dial *dial; + bool use_temp_uniform; } RectTransformInteraction; +static int gizmo_cage2d_transform_flag_get(const wmGizmo *gz) +{ + RectTransformInteraction *data = gz->interaction_data; + int transform_flag = RNA_enum_get(gz->ptr, "transform"); + if (data) { + if (data->use_temp_uniform) { + transform_flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM; + } + } + return transform_flag; +} + static void gizmo_cage2d_setup(wmGizmo *gz) { gz->flag |= WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_NO_SCALE; @@ -1015,9 +1030,7 @@ static int gizmo_cage2d_modal(bContext *C, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag)) { - if (event->type != MOUSEMOVE) { - return OPERATOR_RUNNING_MODAL; - } + /* For transform logic to be manageable we operate in -0.5..0.5 2D space, * no matter the size of the rectangle, mouse coords are scaled to unit space. * The mouse coords have been projected into the matrix @@ -1027,6 +1040,25 @@ static int gizmo_cage2d_modal(bContext *C, * - Matrix translation is also multiplied by 'dims'. */ RectTransformInteraction *data = gz->interaction_data; + int transform_flag = RNA_enum_get(gz->ptr, "transform"); + if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) == 0) { + /* WARNING: Checking the events modifier only makes sense as long as `tweak_flag` + * remains unused (this controls #WM_GIZMO_TWEAK_PRECISE by default). */ + const bool use_temp_uniform = (event->modifier & KM_SHIFT) != 0; + const bool changed = data->use_temp_uniform != use_temp_uniform; + data->use_temp_uniform = data->use_temp_uniform; + if (use_temp_uniform) { + transform_flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM; + } + + if (changed) { + /* Always refresh. */ + } + else if (event->type != MOUSEMOVE) { + return OPERATOR_RUNNING_MODAL; + } + } + float point_local[2]; float dims[2]; @@ -1045,7 +1077,6 @@ static int gizmo_cage2d_modal(bContext *C, } } - const int transform_flag = RNA_enum_get(gz->ptr, "transform"); wmGizmoProperty *gz_prop; gz_prop = WM_gizmo_target_property_find(gz, "matrix");