diff options
5 files changed, 52 insertions, 2 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index a711ffb9df8..37457892033 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5134,6 +5134,7 @@ def km_gesture_straight_line(_params): ("BEGIN", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("SELECT", {"type": 'LEFTMOUSE', "value": 'RELEASE', "any": True}, None), ("MOVE", {"type": 'SPACE', "value": 'ANY', "repeat": False, "any": True}, None), + ("SNAP", {"type": 'LEFT_CTRL', "value": 'ANY', "any": True, "repeat": False}, None), ]) return keymap diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 05a35e030ff..b23446e0dce 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -500,6 +500,9 @@ typedef struct wmGesture { uint wait_for_input : 1; /** Use for gestures that can be moved, like box selection */ uint move : 1; + /** For gestures that support snapping, stores if snapping is enabled using the modal keymap + * toggle. */ + uint use_snap : 1; /** * customdata diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c index faafd6c8235..669cf48a4f2 100644 --- a/source/blender/windowmanager/intern/wm_gesture_ops.c +++ b/source/blender/windowmanager/intern/wm_gesture_ops.c @@ -884,6 +884,32 @@ int WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, cons return OPERATOR_RUNNING_MODAL; } +#define STRAIGHTLINE_SNAP_DEG 15.0f +static void wm_gesture_straightline_do_angle_snap(rcti *rect) +{ + const float line_start[2] = {rect->xmin, rect->ymin}; + const float line_end[2] = {rect->xmax, rect->ymax}; + const float x_axis[2] = {1.0f, 0.0f}; + + float line_direction[2]; + sub_v2_v2v2(line_direction, line_end, line_start); + const float line_length = normalize_v2(line_direction); + + const float angle = angle_signed_v2v2(x_axis, line_direction); + const float angle_deg = RAD2DEG(angle) + (STRAIGHTLINE_SNAP_DEG / 2.0f); + const float angle_snapped_deg = -floorf(angle_deg / STRAIGHTLINE_SNAP_DEG) * + STRAIGHTLINE_SNAP_DEG; + const float angle_snapped = DEG2RAD(angle_snapped_deg); + + float line_snapped_end[2]; + rotate_v2_v2fl(line_snapped_end, x_axis, angle_snapped); + mul_v2_fl(line_snapped_end, line_length); + add_v2_v2(line_snapped_end, line_start); + + rect->xmax = (int)line_snapped_end[0]; + rect->ymax = (int)line_snapped_end[1]; +} + /** * This modal callback calls exec once per mouse move event while the gesture is active with the * updated line start and end values, so it can be used for tools that have a real time preview @@ -912,6 +938,10 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev gesture_straightline_apply(C, op); } + if (gesture->use_snap) { + wm_gesture_straightline_do_angle_snap(rect); + } + wm_gesture_tag_redraw(win); } else if (event->type == EVT_MODAL_MAP) { @@ -925,6 +955,10 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev wm_gesture_tag_redraw(win); } break; + case GESTURE_MODAL_SNAP: + /* Toggle snapping on/off. */ + gesture->use_snap = !gesture->use_snap; + break; case GESTURE_MODAL_SELECT: if (gesture_straightline_apply(C, op)) { gesture_modal_end(C, op); @@ -971,6 +1005,10 @@ int WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmE rect->ymax = event->y - gesture->winrct.ymin; } + if (gesture->use_snap) { + wm_gesture_straightline_do_angle_snap(rect); + } + wm_gesture_tag_redraw(win); } else if (event->type == EVT_MODAL_MAP) { @@ -984,6 +1022,10 @@ int WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmE wm_gesture_tag_redraw(win); } break; + case GESTURE_MODAL_SNAP: + /* Toggle snapping on/off. */ + gesture->use_snap = !gesture->use_snap; + break; case GESTURE_MODAL_SELECT: case GESTURE_MODAL_DESELECT: case GESTURE_MODAL_IN: diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index bbe2ff4b81a..5e4a45ea3be 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3806,6 +3806,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, {GESTURE_MODAL_MOVE, "MOVE", 0, "Move", ""}, + {GESTURE_MODAL_SNAP, "SNAP", 0, "Snap", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -3822,6 +3823,8 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line"); WM_modalkeymap_assign(keymap, "PAINT_OT_weight_gradient"); WM_modalkeymap_assign(keymap, "MESH_OT_bisect"); + WM_modalkeymap_assign(keymap, "PAINT_OT_mask_line_gesture"); + WM_modalkeymap_assign(keymap, "SCULPT_OT_project_line_gesture"); } /* box_select-like modal operators */ @@ -3870,8 +3873,6 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "PAINT_OT_mask_box_gesture"); WM_modalkeymap_assign(keymap, "SCULPT_OT_face_set_box_gesture"); WM_modalkeymap_assign(keymap, "SCULPT_OT_trim_box_gesture"); - WM_modalkeymap_assign(keymap, "PAINT_OT_mask_line_gesture"); - WM_modalkeymap_assign(keymap, "SCULPT_OT_project_line_gesture"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index de8ca0dc68a..21662a4e83a 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -493,6 +493,9 @@ enum { /** Move selection area. */ GESTURE_MODAL_MOVE = 12, + + /** Toggle to activate snapping (angle snapping for straight line). */ + GESTURE_MODAL_SNAP = 13, }; #ifdef __cplusplus |