@@ -92,30 +92,50 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
9292 return false ;
9393 }
9494
95- bool is_drag_event = mb->get_button_index () == MouseButton::MIDDLE ||
95+ drag_type = DragType::DRAG_TYPE_NONE;
96+
97+ bool is_drag_zoom_event = mb->get_button_index () == MouseButton::MIDDLE && mb->is_ctrl_pressed ();
98+
99+ if (is_drag_zoom_event) {
100+ if (mb->is_pressed ()) {
101+ drag_type = DragType::DRAG_TYPE_ZOOM;
102+ drag_zoom_position = mb->get_position ();
103+ }
104+ return true ;
105+ }
106+
107+ bool is_drag_pan_event = mb->get_button_index () == MouseButton::MIDDLE ||
96108 (enable_rmb && mb->get_button_index () == MouseButton::RIGHT) ||
97109 (!simple_panning_enabled && mb->get_button_index () == MouseButton::LEFT && is_panning ()) ||
98110 (force_drag && mb->get_button_index () == MouseButton::LEFT);
99111
100- if (is_drag_event ) {
112+ if (is_drag_pan_event ) {
101113 if (mb->is_pressed ()) {
102- is_dragging = true ;
103- } else {
104- is_dragging = false ;
114+ drag_type = DragType::DRAG_TYPE_PAN;
105115 }
106116 return mb->get_button_index () != MouseButton::LEFT || mb->is_pressed (); // Don't consume LMB release events (it fixes some selection problems).
107117 }
108118 }
109119
110120 Ref<InputEventMouseMotion> mm = p_event;
111121 if (mm.is_valid ()) {
112- if (is_dragging ) {
122+ if (drag_type == DragType::DRAG_TYPE_PAN ) {
113123 if (warped_panning_viewport && p_canvas_rect.has_area ()) {
114124 pan_callback.call (warped_panning_viewport->wrap_mouse_in_rect (mm->get_relative (), p_canvas_rect), p_event);
115125 } else {
116126 pan_callback.call (mm->get_relative (), p_event);
117127 }
118128 return true ;
129+ } else if (drag_type == DragType::DRAG_TYPE_ZOOM) {
130+ float drag_zoom_distance = 0.0 ;
131+ if (zoom_style == ZoomStyle::ZOOM_VERTICAL) {
132+ drag_zoom_distance = mm->get_relative ().y ;
133+ } else if (zoom_style == ZoomStyle::ZOOM_HORIZONTAL) {
134+ drag_zoom_distance = mm->get_relative ().x * -1.0 ; // Needs to be flipped to match the 3D horizontal zoom style.
135+ }
136+ float drag_zoom_factor = 1.0 + (drag_zoom_distance * scroll_zoom_factor * drag_zoom_sensitivity_factor);
137+ zoom_callback.call (drag_zoom_factor, drag_zoom_position, p_event);
138+ return true ;
119139 }
120140 }
121141
@@ -157,7 +177,11 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
157177 if (pan_view_shortcut.is_valid () && pan_view_shortcut->matches_event (k)) {
158178 pan_key_pressed = k->is_pressed ();
159179 if (simple_panning_enabled || Input::get_singleton ()->get_mouse_button_mask ().has_flag (MouseButtonMask::LEFT)) {
160- is_dragging = pan_key_pressed;
180+ if (pan_key_pressed) {
181+ drag_type = DragType::DRAG_TYPE_PAN;
182+ } else if (drag_type == DragType::DRAG_TYPE_PAN) {
183+ drag_type = DragType::DRAG_TYPE_NONE;
184+ }
161185 }
162186 return true ;
163187 }
@@ -168,7 +192,9 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
168192
169193void ViewPanner::release_pan_key () {
170194 pan_key_pressed = false ;
171- is_dragging = false ;
195+ if (drag_type == DragType::DRAG_TYPE_PAN) {
196+ drag_type = DragType::DRAG_TYPE_NONE;
197+ }
172198}
173199
174200void ViewPanner::set_callbacks (Callable p_pan_callback, Callable p_zoom_callback) {
@@ -207,6 +233,10 @@ void ViewPanner::set_pan_axis(PanAxis p_pan_axis) {
207233 pan_axis = p_pan_axis;
208234}
209235
236+ void ViewPanner::set_zoom_style (ZoomStyle p_zoom_style) {
237+ zoom_style = p_zoom_style;
238+ }
239+
210240void ViewPanner::setup (ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning) {
211241 set_control_scheme (p_scheme);
212242 set_pan_shortcut (p_shortcut);
@@ -218,7 +248,7 @@ void ViewPanner::setup_warped_panning(Viewport *p_viewport, bool p_allowed) {
218248}
219249
220250bool ViewPanner::is_panning () const {
221- return is_dragging || pan_key_pressed;
251+ return (drag_type == DragType::DRAG_TYPE_PAN) || pan_key_pressed;
222252}
223253
224254void ViewPanner::set_force_drag (bool p_force) {
0 commit comments