diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index fc68dd0223..e577c05144 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -317,6 +317,9 @@ If [code]true[/code], the Create dialog (Create New Node/Create New Resource) will start with all its sections expanded. Otherwise, sections will be collapsed until the user starts searching (which will automatically expand sections as needed). + + Delay time for automatic resampling in the 2D editor (in seconds). + The "start" stop of the color gradient to use for bones in the 2D skeleton editor. diff --git a/editor/scene/canvas_item_editor_plugin.cpp b/editor/scene/canvas_item_editor_plugin.cpp index f678d71b13..cdb1f02bf3 100644 --- a/editor/scene/canvas_item_editor_plugin.cpp +++ b/editor/scene/canvas_item_editor_plugin.cpp @@ -65,6 +65,7 @@ #include "scene/gui/subviewport_container.h" #include "scene/gui/view_panner.h" #include "scene/main/canvas_layer.h" +#include "scene/main/timer.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "scene/resources/style_box_texture.h" @@ -4351,6 +4352,9 @@ void CanvasItemEditor::_update_editor_settings() { ruler_width_scaled = MAX(ruler_width_unscaled * EDSCALE, ruler_font_size * 2.0); grab_distance = EDITOR_GET("editors/polygon_editor/point_grab_radius"); + + resample_delay = EDITOR_GET("editors/2d/auto_resample_delay"); + resample_timer->set_wait_time(resample_delay); } void CanvasItemEditor::_project_settings_changed() { @@ -4613,12 +4617,19 @@ void CanvasItemEditor::_zoom_on_position(real_t p_zoom, Point2 p_position) { zoom_widget->set_zoom(zoom); update_viewport(); + if (auto_resampling_enabled) { + resample_timer->start(); + } } void CanvasItemEditor::_update_zoom(real_t p_zoom) { _zoom_on_position(p_zoom, viewport_scrollable->get_size() / 2.0); } +void CanvasItemEditor::_update_oversampling() { + EditorNode::get_singleton()->get_scene_root()->set_oversampling_override(auto_resampling_enabled ? zoom : 0.0); +} + void CanvasItemEditor::_shortcut_zoom_set(real_t p_zoom) { _zoom_on_position(p_zoom * MAX(1, EDSCALE), viewport->get_local_mouse_position()); } @@ -5130,6 +5141,16 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->commit_action(); } break; + case AUTO_RESAMPLE_CANVAS_ITEMS: { + auto_resampling_enabled = !auto_resampling_enabled; + int idx = view_menu->get_popup()->get_item_index(AUTO_RESAMPLE_CANVAS_ITEMS); + view_menu->get_popup()->set_item_checked(idx, auto_resampling_enabled); + if (!resample_timer->is_stopped()) { + resample_timer->stop(); + } + _update_oversampling(); + EditorSettings::get_singleton()->set_project_metadata("2d_editor", "auto_resampling_enabled", auto_resampling_enabled); + } break; } } @@ -5184,6 +5205,9 @@ void CanvasItemEditor::_focus_selection(int p_op) { zoom_widget->set_zoom(zoom); viewport->queue_redraw(); // Redraw to update the global canvas transform after zoom changes. callable_mp(this, &CanvasItemEditor::center_at).call_deferred(rect.get_center()); // Defer because the updated transform is needed. + if (auto_resampling_enabled) { + resample_timer->start(); + } } else { center_at(rect.get_center()); } @@ -5252,6 +5276,9 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { // and the zoom level will still be the same (relative to the editor scale). zoom = real_t(p_state["zoom"]) * MAX(1, EDSCALE); zoom_widget->set_zoom(zoom); + if (auto_resampling_enabled) { + resample_timer->start(); + } } if (state.has("ofs")) { @@ -5445,6 +5472,14 @@ void CanvasItemEditor::clear() { snap_rotation_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_rotation_step", Math::deg_to_rad(15.0)); snap_rotation_offset = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_rotation_offset", 0.0); snap_scale_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_scale_step", 0.1); + + if (auto_resampling_enabled) { + if (resample_timer->is_inside_tree()) { + resample_timer->start(); + } else { + _update_oversampling(); + } + } } void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) { @@ -5906,7 +5941,11 @@ CanvasItemEditor::CanvasItemEditor() { p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTRC("Center Selection"), Key::F), VIEW_CENTER_TO_SELECTION); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTRC("Frame Selection"), KeyModifierMask::SHIFT | Key::F), VIEW_FRAME_TO_SELECTION); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/clear_guides", TTRC("Clear Guides")), CLEAR_GUIDES); + p->add_separator(); + auto_resampling_enabled = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "auto_resampling_enabled", true); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/auto_resample_canvas_items", TTRC("Auto Resample CanvasItems")), AUTO_RESAMPLE_CANVAS_ITEMS); + p->set_item_checked(p->get_item_index(AUTO_RESAMPLE_CANVAS_ITEMS), auto_resampling_enabled); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTRC("Preview Canvas Scale")), PREVIEW_CANVAS_SCALE); theme_menu = memnew(PopupMenu); @@ -6016,6 +6055,12 @@ CanvasItemEditor::CanvasItemEditor() { add_child(add_node_menu); add_node_menu->connect(SceneStringName(id_pressed), callable_mp(this, &CanvasItemEditor::_add_node_pressed)); + resample_timer = memnew(Timer); + resample_timer->set_wait_time(resample_delay); + resample_timer->set_one_shot(true); + add_child(resample_timer); + resample_timer->connect("timeout", callable_mp(this, &CanvasItemEditor::_update_oversampling)); + multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTRC("Multiply grid step by 2"), Key::KP_MULTIPLY); divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTRC("Divide grid step by 2"), Key::KP_DIVIDE); reset_transform_position_shortcut = ED_SHORTCUT("canvas_item_editor/reset_transform_position", TTRC("Reset Position"), KeyModifierMask::ALT + Key::W); diff --git a/editor/scene/canvas_item_editor_plugin.h b/editor/scene/canvas_item_editor_plugin.h index 3c5baebfda..2726b47f41 100644 --- a/editor/scene/canvas_item_editor_plugin.h +++ b/editor/scene/canvas_item_editor_plugin.h @@ -46,6 +46,7 @@ class HSplitContainer; class MenuButton; class PanelContainer; class StyleBoxTexture; +class Timer; class ViewPanner; class VScrollBar; class VSeparator; @@ -145,7 +146,8 @@ private: VIEW_FRAME_TO_SELECTION, PREVIEW_CANVAS_SCALE, SKELETON_MAKE_BONES, - SKELETON_SHOW_BONES + SKELETON_SHOW_BONES, + AUTO_RESAMPLE_CANVAS_ITEMS, }; enum DragType { @@ -227,6 +229,10 @@ private: Point2 view_offset; Point2 previous_update_view_offset; + Timer *resample_timer = nullptr; + bool auto_resampling_enabled = true; + real_t resample_delay = 0.3; + bool selected_from_canvas = false; // Defaults are defined in clear(). @@ -432,6 +438,7 @@ private: void _prepare_grid_menu(); void _on_grid_menu_id_pressed(int p_id); void _reset_transform(TransformType p_type); + void _update_oversampling(); public: enum ThemePreviewMode { diff --git a/editor/settings/editor_settings.cpp b/editor/settings/editor_settings.cpp index 2cea19a518..158df9dd9a 100644 --- a/editor/settings/editor_settings.cpp +++ b/editor/settings/editor_settings.cpp @@ -981,6 +981,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { _initial_set("editors/2d/use_integer_zoom_by_default", false, true); EDITOR_SETTING_BASIC(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/2d/zoom_speed_factor", 1.1, "1.01,2,0.01") EDITOR_SETTING_BASIC(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/2d/ruler_width", 16.0, "12.0,30.0,1.0") + EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/2d/auto_resample_delay", 0.3, "0.1,2,0.1") // Bone mapper (BoneMapEditorPlugin) _initial_set("editors/bone_mapper/handle_colors/unset", Color(0.3, 0.3, 0.3));