diff --git a/material_maker/globals.gd b/material_maker/globals.gd index 50021a02c..26031117f 100644 --- a/material_maker/globals.gd +++ b/material_maker/globals.gd @@ -7,6 +7,8 @@ extends Node # warning-ignore:unused_class_variable var main_window +static var _is_drag_zoom_warping : int = 0 + var config : ConfigFile = ConfigFile.new() const DEFAULT_CONFIG : Dictionary = { locale = "", @@ -32,6 +34,7 @@ const DEFAULT_CONFIG : Dictionary = { auto_size_comment = true, graph_line_curvature = 0.5, graph_line_style = 1, + ui_warp_mouse_gestures = true, } @@ -148,6 +151,32 @@ func parse_paste_data(data : String): # Misc. UI functions +static func do_warp_mouse(position : Vector2, node : Node): + if mm_globals.get_config("ui_warp_mouse_gestures"): + Input.mouse_mode = Input.MOUSE_MODE_HIDDEN + node.warp_mouse(position) + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + +static func handle_warped_drag_zoom(node : Control, zoom_func : Callable, + from_rect_y : float, to_rect_y : float, mouse_pos : Vector2, + should_accept_event : bool = true, ignore_after_warp : int = 2) -> void: + if should_accept_event: + node.accept_event() + + _is_drag_zoom_warping -= 1 if _is_drag_zoom_warping else 0 + if DisplayServer.get_name() != "X11" or not mm_globals.get_config("ui_warp_mouse_gestures"): + _is_drag_zoom_warping = 0 + + if not _is_drag_zoom_warping: + zoom_func.call() + + if mouse_pos.y > to_rect_y: + _is_drag_zoom_warping = ignore_after_warp + do_warp_mouse(Vector2(mouse_pos.x, from_rect_y), node) + elif mouse_pos.y < from_rect_y: + _is_drag_zoom_warping = ignore_after_warp + do_warp_mouse(Vector2(mouse_pos.x, to_rect_y), node) + static func popup_menu(menu : PopupMenu, parent : Control): var zoom_fac = 1.0 if parent is GraphNode: diff --git a/material_maker/panels/graph_edit/graph_edit.gd b/material_maker/panels/graph_edit/graph_edit.gd index 28043abf6..7fd104c0b 100644 --- a/material_maker/panels/graph_edit/graph_edit.gd +++ b/material_maker/panels/graph_edit/graph_edit.gd @@ -219,6 +219,15 @@ func _gui_input(event) -> void: if rect.has_point(get_global_mouse_position()): mm_globals.set_tip_text("Space/#RMB: Nodes menu, Arrow keys: Pan, Mouse wheel: Zoom", 3) + if (event.button_mask & MOUSE_BUTTON_MASK_MIDDLE) != 0 and ( + event.ctrl_pressed or event.meta_pressed): + mm_globals.handle_warped_drag_zoom(self, + (func() -> void: + #force connection lines to redraw + set_connection_lines_curvature(connection_lines_curvature) + zoom -= event.relative.y * 0.002 + ),get_viewport_rect().position.y,get_rect().size.y, get_local_mouse_position()) + func get_padded_node_rect(graph_node:GraphNode) -> Rect2: var rect : Rect2 = graph_node.get_global_rect() var padding := 8 * graph_node.get_global_transform().get_scale().x @@ -1388,7 +1397,7 @@ func _get_connection_line(from: Vector2, to: Vector2) -> PackedVector2Array: curve.set_point_out(0, Vector2(cp_offset, 0)) curve.add_point(to) curve.set_point_in(1, Vector2(-cp_offset, 0)) - + if connection_lines_curvature > 0: return curve.tessellate(5, 2.0) else: @@ -1428,7 +1437,7 @@ func _get_connection_line(from: Vector2, to: Vector2) -> PackedVector2Array: var r = min(min(abs(to.y - from.y) * 0.25, abs(from.x - to.x) * 0.25), max_radius) - + if from.x < to.x: for i in range(pts): var x = lerp(mid.x - r, mid.x, i/pts) diff --git a/material_maker/panels/preview_2d/preview_2d_panel.gd b/material_maker/panels/preview_2d/preview_2d_panel.gd index 6ab5102c9..3d467ed62 100644 --- a/material_maker/panels/preview_2d/preview_2d_panel.gd +++ b/material_maker/panels/preview_2d/preview_2d_panel.gd @@ -223,6 +223,7 @@ func on_resized() -> void: var dragging : bool = false var zooming : bool = false +var drag_zooming : bool = false func _input(event): if event.is_pressed(): @@ -252,17 +253,28 @@ func _on_gui_input(event): else: dragging = false zooming = false + drag_zooming = false elif event is InputEventMouseMotion: - if dragging: - new_center = center-event.relative*view_scale/multiplier - elif zooming: - new_scale = clamp(new_scale*(1.0+0.01*event.relative.y), 0.005, 5.0) + if (event.button_mask & MOUSE_BUTTON_MASK_MIDDLE) != 0 and ( + event.ctrl_pressed or event.meta_pressed): + drag_zooming = true + var sca : Array[float] = [new_scale] + mm_globals.handle_warped_drag_zoom(self, + (func(): sca[0] *= 1.0 + 0.005 *event.relative.y),0, + get_rect().size.y, get_local_mouse_position()) + new_scale = clamp(sca[0], 0.005, 5.0) + else: + if dragging: + new_center = center-event.relative*view_scale/multiplier + elif zooming: + new_scale = clamp(new_scale*(1.0+0.01*event.relative.y), 0.005, 5.0) elif event is InputEventPanGesture: new_center = center-event.delta*10.0*view_scale/multiplier elif event is InputEventMagnifyGesture: new_scale = clamp(new_scale/event.factor, 0.005, 5.0) if new_scale != view_scale: - new_center = center+offset_from_center*(view_scale-new_scale)/multiplier + if not drag_zooming: + new_center = center+offset_from_center*(view_scale-new_scale)/multiplier view_scale = new_scale need_update = true if new_center != center: diff --git a/material_maker/panels/reference/reference_panel.gd b/material_maker/panels/reference/reference_panel.gd index 4b891ccac..70df0a175 100644 --- a/material_maker/panels/reference/reference_panel.gd +++ b/material_maker/panels/reference/reference_panel.gd @@ -12,6 +12,7 @@ var current_image_index := 0 var is_picking := false var is_dragging := false var is_zooming := false +var is_drag_zooming := false var selected_slot: Button = null @@ -188,7 +189,7 @@ func handle_movement(event: InputEvent) -> void: is_dragging = event.pressed and event.shift_pressed is_zooming = event.pressed and event.is_command_or_control_pressed() and not is_dragging - + is_drag_zooming = false MOUSE_BUTTON_WHEEL_DOWN: new_scale = min(new_scale+0.05, 3) @@ -196,15 +197,25 @@ func handle_movement(event: InputEvent) -> void: new_scale = max(new_scale-0.05, 0.05) elif event is InputEventMouseMotion: - if is_dragging: - new_center = m.get_shader_parameter("center")-event.relative*image_scale/multiplier + if (event.button_mask & MOUSE_BUTTON_MASK_MIDDLE) != 0 and ( + event.ctrl_pressed or event.meta_pressed): + is_drag_zooming = true + var sca : Array[float] = [new_scale] + mm_globals.handle_warped_drag_zoom(self, + (func(): sca[0] *= 1.0 + 0.005 *event.relative.y),0, + get_rect().size.y, get_local_mouse_position()) + new_scale = clamp(sca[0], 0.005, 3.0) + else: + if is_dragging: + new_center = m.get_shader_parameter("center")-event.relative*image_scale/multiplier - elif is_zooming: - new_scale = clamp(new_scale*(1.0+0.01*event.relative.y), 0.005, 3) + elif is_zooming: + new_scale = clamp(new_scale*(1.0+0.01*event.relative.y), 0.005, 3) if new_scale != image_scale: m.set_shader_parameter("scale", new_scale) - new_center = center+offset_from_center*(image_scale-new_scale)/multiplier + if not is_drag_zooming: + new_center = center+offset_from_center*(image_scale-new_scale)/multiplier opened_images[current_image_index].scale = new_scale if new_center != center: diff --git a/material_maker/projects_panel.tscn b/material_maker/projects_panel.tscn index 0540690b6..487fd7d5e 100644 --- a/material_maker/projects_panel.tscn +++ b/material_maker/projects_panel.tscn @@ -442,7 +442,7 @@ layout_mode = 2 size_flags_vertical = 4 tooltip_text = "Middle-Mouse click and drag to turn the 3D preview. -Scroll to zoom the 3D Preview." +Scroll/Ctrl+MMB drag to zoom the 3D Preview." [connection signal="resized" from="." to="." method="_on_projects_panel_resized"] [connection signal="no_more_tabs" from="Projects" to="." method="_on_projects_no_more_tabs"] diff --git a/material_maker/windows/environment_editor/camera_controller.gd b/material_maker/windows/environment_editor/camera_controller.gd index 163fba334..bc2663f4c 100644 --- a/material_maker/windows/environment_editor/camera_controller.gd +++ b/material_maker/windows/environment_editor/camera_controller.gd @@ -25,6 +25,17 @@ func process_event(event : InputEvent, viewport : Viewport = null) -> bool: var factor = 0.0025*camera_position.position.z camera_target_position.translate(-factor*event.relative.x*camera_position.global_transform.basis.x) camera_target_position.translate(factor*event.relative.y*camera_position.global_transform.basis.y) + elif event.ctrl_pressed or event.meta_pressed: + if get_parent().name == "Preview3d": + var preview_3d : SubViewportContainer = get_parent().owner + + mm_globals.handle_warped_drag_zoom(preview_3d, + (func() -> void: + var amount : float = 1.0 + event.relative.y * 0.002 + camera_position.position.z = clamp( + camera_position.position.z * amount, + preview_3d.CAMERA_DISTANCE_MIN, preview_3d.CAMERA_DISTANCE_MAX) + ), 0, preview_3d.get_rect().size.y, preview_3d.get_local_mouse_position()) else: camera_rotation2.rotate_x(-0.01*event.relative.y) camera_rotation1.rotate_y(-0.01*event.relative.x) diff --git a/material_maker/windows/preferences/preferences.tscn b/material_maker/windows/preferences/preferences.tscn index a4e7bd87a..2cb06e490 100644 --- a/material_maker/windows/preferences/preferences.tscn +++ b/material_maker/windows/preferences/preferences.tscn @@ -89,6 +89,17 @@ max_value = 2.0 step = 0.01 float_only = true +[node name="GuiWarpMouseGestures" parent="VBoxContainer/TabContainer/General" instance=ExtResource("1")] +layout_mode = 2 +tooltip_text = "Warps mouse around panel for supported gestures +(i.e. drag zoom via Ctrl/Command+MMB) + +This makes it possible to move over a large area without +exiting and having to adjust mouse position, but may cause +issues with pen inputs on some opearating systems." +text = "Warp mouse gestures" +config_variable = "ui_warp_mouse_gestures" + [node name="Gui3DPreviewResolution" type="HBoxContainer" parent="VBoxContainer/TabContainer/General"] layout_mode = 2