Merge pull request #105625 from zmn-hamid/zoom_drag_2d
Add drag zoom feature with CTRL+MiddleMouseButton
This commit is contained in:
@ -582,6 +582,9 @@
|
||||
<member name="editors/panning/warped_mouse_panning" type="bool" setter="" getter="">
|
||||
If [code]true[/code], warps the mouse around the 2D viewport while panning in the 2D editor. This makes it possible to pan over a large area without having to exit panning and adjust the mouse cursor.
|
||||
</member>
|
||||
<member name="editors/panning/zoom_style" type="int" setter="" getter="">
|
||||
The mouse cursor movement direction to use when drag-zooming in any editor (except 3D scene editor) by moving the mouse. This does not affect zooming with the mouse wheel.
|
||||
</member>
|
||||
<member name="editors/polygon_editor/auto_bake_delay" type="float" setter="" getter="">
|
||||
The delay in seconds until more complex and performance costly polygon editors commit their outlines, e.g. the 2D navigation polygon editor rebakes the navigation mesh polygons. A negative value stops the auto bake.
|
||||
</member>
|
||||
|
||||
@ -920,6 +920,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||
_initial_set("editors/panning/simple_panning", false);
|
||||
_initial_set("editors/panning/warped_mouse_panning", true);
|
||||
_initial_set("editors/panning/2d_editor_pan_speed", 20, true);
|
||||
EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "editors/panning/zoom_style", 0, "Vertical,Horizontal");
|
||||
|
||||
// Tiles editor
|
||||
_initial_set("editors/tiles_editor/display_grid", true);
|
||||
|
||||
@ -4129,6 +4129,7 @@ void CanvasItemEditor::_update_editor_settings() {
|
||||
panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning")));
|
||||
panner->set_scroll_speed(EDITOR_GET("editors/panning/2d_editor_pan_speed"));
|
||||
panner->setup_warped_panning(get_viewport(), EDITOR_GET("editors/panning/warped_mouse_panning"));
|
||||
panner->set_zoom_style((ViewPanner::ZoomStyle)EDITOR_GET("editors/panning/zoom_style").operator int());
|
||||
}
|
||||
|
||||
void CanvasItemEditor::_project_settings_changed() {
|
||||
|
||||
@ -52,7 +52,7 @@ void TileAtlasView::_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event)
|
||||
|
||||
void TileAtlasView::_zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event) {
|
||||
zoom_widget->set_zoom(zoom_widget->get_zoom() * p_zoom_factor);
|
||||
_update_zoom_and_panning(true);
|
||||
_update_zoom_and_panning(true, p_origin);
|
||||
emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) {
|
||||
void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos, const Vector2 &p_mouse_pos) {
|
||||
if (tile_set_atlas_source.is_null()) {
|
||||
return;
|
||||
}
|
||||
@ -132,8 +132,7 @@ void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) {
|
||||
|
||||
// Zoom on the position.
|
||||
if (p_zoom_on_mouse_pos) {
|
||||
// Offset the panning relative to the center of panel.
|
||||
Vector2 relative_mpos = get_local_mouse_position() - get_size() / 2;
|
||||
Vector2 relative_mpos = p_mouse_pos - get_size() / 2;
|
||||
panning = (panning - relative_mpos) * zoom / previous_zoom + relative_mpos;
|
||||
} else {
|
||||
// Center of panel.
|
||||
|
||||
@ -58,7 +58,7 @@ private:
|
||||
Button *button_center_view = nullptr;
|
||||
CenterContainer *center_container = nullptr;
|
||||
Vector2 panning;
|
||||
void _update_zoom_and_panning(bool p_zoom_on_mouse_pos = false);
|
||||
void _update_zoom_and_panning(bool p_zoom_on_mouse_pos = false, const Vector2 &p_mouse_pos = Vector2());
|
||||
void _zoom_widget_changed();
|
||||
void _center_view();
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
@ -92,16 +92,26 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_drag_event = mb->get_button_index() == MouseButton::MIDDLE ||
|
||||
drag_type = DragType::DRAG_TYPE_NONE;
|
||||
|
||||
bool is_drag_zoom_event = mb->get_button_index() == MouseButton::MIDDLE && mb->is_ctrl_pressed();
|
||||
|
||||
if (is_drag_zoom_event) {
|
||||
if (mb->is_pressed()) {
|
||||
drag_type = DragType::DRAG_TYPE_ZOOM;
|
||||
drag_zoom_position = mb->get_position();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_drag_pan_event = mb->get_button_index() == MouseButton::MIDDLE ||
|
||||
(enable_rmb && mb->get_button_index() == MouseButton::RIGHT) ||
|
||||
(!simple_panning_enabled && mb->get_button_index() == MouseButton::LEFT && is_panning()) ||
|
||||
(force_drag && mb->get_button_index() == MouseButton::LEFT);
|
||||
|
||||
if (is_drag_event) {
|
||||
if (is_drag_pan_event) {
|
||||
if (mb->is_pressed()) {
|
||||
is_dragging = true;
|
||||
} else {
|
||||
is_dragging = false;
|
||||
drag_type = DragType::DRAG_TYPE_PAN;
|
||||
}
|
||||
return mb->get_button_index() != MouseButton::LEFT || mb->is_pressed(); // Don't consume LMB release events (it fixes some selection problems).
|
||||
}
|
||||
@ -109,13 +119,23 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
|
||||
|
||||
Ref<InputEventMouseMotion> mm = p_event;
|
||||
if (mm.is_valid()) {
|
||||
if (is_dragging) {
|
||||
if (drag_type == DragType::DRAG_TYPE_PAN) {
|
||||
if (warped_panning_viewport && p_canvas_rect.has_area()) {
|
||||
pan_callback.call(warped_panning_viewport->wrap_mouse_in_rect(mm->get_relative(), p_canvas_rect), p_event);
|
||||
} else {
|
||||
pan_callback.call(mm->get_relative(), p_event);
|
||||
}
|
||||
return true;
|
||||
} else if (drag_type == DragType::DRAG_TYPE_ZOOM) {
|
||||
float drag_zoom_distance = 0.0;
|
||||
if (zoom_style == ZoomStyle::ZOOM_VERTICAL) {
|
||||
drag_zoom_distance = mm->get_relative().y;
|
||||
} else if (zoom_style == ZoomStyle::ZOOM_HORIZONTAL) {
|
||||
drag_zoom_distance = mm->get_relative().x * -1.0; // Needs to be flipped to match the 3D horizontal zoom style.
|
||||
}
|
||||
float drag_zoom_factor = 1.0 + (drag_zoom_distance * scroll_zoom_factor * drag_zoom_sensitivity_factor);
|
||||
zoom_callback.call(drag_zoom_factor, drag_zoom_position, p_event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +177,11 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
|
||||
if (pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(k)) {
|
||||
pan_key_pressed = k->is_pressed();
|
||||
if (simple_panning_enabled || Input::get_singleton()->get_mouse_button_mask().has_flag(MouseButtonMask::LEFT)) {
|
||||
is_dragging = pan_key_pressed;
|
||||
if (pan_key_pressed) {
|
||||
drag_type = DragType::DRAG_TYPE_PAN;
|
||||
} else if (drag_type == DragType::DRAG_TYPE_PAN) {
|
||||
drag_type = DragType::DRAG_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -168,7 +192,9 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
|
||||
|
||||
void ViewPanner::release_pan_key() {
|
||||
pan_key_pressed = false;
|
||||
is_dragging = false;
|
||||
if (drag_type == DragType::DRAG_TYPE_PAN) {
|
||||
drag_type = DragType::DRAG_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void ViewPanner::set_callbacks(Callable p_pan_callback, Callable p_zoom_callback) {
|
||||
@ -207,6 +233,10 @@ void ViewPanner::set_pan_axis(PanAxis p_pan_axis) {
|
||||
pan_axis = p_pan_axis;
|
||||
}
|
||||
|
||||
void ViewPanner::set_zoom_style(ZoomStyle p_zoom_style) {
|
||||
zoom_style = p_zoom_style;
|
||||
}
|
||||
|
||||
void ViewPanner::setup(ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning) {
|
||||
set_control_scheme(p_scheme);
|
||||
set_pan_shortcut(p_shortcut);
|
||||
@ -218,7 +248,7 @@ void ViewPanner::setup_warped_panning(Viewport *p_viewport, bool p_allowed) {
|
||||
}
|
||||
|
||||
bool ViewPanner::is_panning() const {
|
||||
return is_dragging || pan_key_pressed;
|
||||
return (drag_type == DragType::DRAG_TYPE_PAN) || pan_key_pressed;
|
||||
}
|
||||
|
||||
void ViewPanner::set_force_drag(bool p_force) {
|
||||
|
||||
@ -51,15 +51,32 @@ public:
|
||||
PAN_AXIS_VERTICAL,
|
||||
};
|
||||
|
||||
enum DragType {
|
||||
DRAG_TYPE_NONE,
|
||||
DRAG_TYPE_PAN,
|
||||
DRAG_TYPE_ZOOM,
|
||||
};
|
||||
|
||||
enum ZoomStyle {
|
||||
ZOOM_VERTICAL,
|
||||
ZOOM_HORIZONTAL,
|
||||
};
|
||||
|
||||
private:
|
||||
int scroll_speed = 32;
|
||||
float scroll_zoom_factor = 1.1;
|
||||
PanAxis pan_axis = PAN_AXIS_BOTH;
|
||||
|
||||
bool is_dragging = false;
|
||||
bool pan_key_pressed = false;
|
||||
bool force_drag = false;
|
||||
|
||||
DragType drag_type = DragType::DRAG_TYPE_NONE;
|
||||
|
||||
ZoomStyle zoom_style = ZoomStyle::ZOOM_VERTICAL;
|
||||
|
||||
Vector2 drag_zoom_position;
|
||||
float drag_zoom_sensitivity_factor = -0.01f;
|
||||
|
||||
bool enable_rmb = false;
|
||||
bool simple_panning_enabled = false;
|
||||
|
||||
@ -80,6 +97,7 @@ public:
|
||||
void set_scroll_speed(int p_scroll_speed);
|
||||
void set_scroll_zoom_factor(float p_scroll_zoom_factor);
|
||||
void set_pan_axis(PanAxis p_pan_axis);
|
||||
void set_zoom_style(ZoomStyle p_zoom_style);
|
||||
|
||||
void setup(ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning);
|
||||
void setup_warped_panning(Viewport *p_viewport, bool p_allowed);
|
||||
|
||||
Reference in New Issue
Block a user