Merge pull request #102888 from Shaderd00d/clear_transform

Add shortcuts to reset position, rotation and scale in Spatial and Canvas Item Editor
This commit is contained in:
Thaddeus Crews 2025-10-14 10:31:27 -05:00
commit 9659dc13bd
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
4 changed files with 122 additions and 0 deletions

View file

@ -1573,6 +1573,37 @@ Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const
} }
} }
void Node3DEditorViewport::_reset_transform(TransformType p_type) {
List<Node *> selection = editor_selection->get_full_selected_node_list();
if (selection.is_empty()) {
return;
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Reset Transform"));
for (Node *node : selection) {
Node3D *sp = Object::cast_to<Node3D>(node);
if (!sp) {
continue;
}
switch (p_type) {
case TransformType::POSITION:
undo_redo->add_undo_method(sp, "set_position", sp->get_position());
undo_redo->add_do_method(sp, "set_position", Vector3());
break;
case TransformType::ROTATION:
undo_redo->add_undo_method(sp, "set_rotation", sp->get_rotation());
undo_redo->add_do_method(sp, "set_rotation", Vector3());
break;
case TransformType::SCALE:
undo_redo->add_undo_method(sp, "set_scale", sp->get_scale());
undo_redo->add_do_method(sp, "set_scale", Vector3(1, 1, 1));
break;
}
}
undo_redo->commit_action();
}
void Node3DEditorViewport::_surface_mouse_enter() { void Node3DEditorViewport::_surface_mouse_enter() {
if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) { if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
return; return;
@ -2573,6 +2604,15 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
cancel_transform(); cancel_transform();
} }
if (!is_freelook_active() && !k->is_echo()) { if (!is_freelook_active() && !k->is_echo()) {
if (ED_IS_SHORTCUT("spatial_editor/reset_transform_position", p_event)) {
_reset_transform(TransformType::POSITION);
}
if (ED_IS_SHORTCUT("spatial_editor/reset_transform_rotation", p_event)) {
_reset_transform(TransformType::ROTATION);
}
if (ED_IS_SHORTCUT("spatial_editor/reset_transform_scale", p_event)) {
_reset_transform(TransformType::SCALE);
}
if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event) && (_edit.mode != TRANSFORM_TRANSLATE || collision_reposition)) { if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event) && (_edit.mode != TRANSFORM_TRANSLATE || collision_reposition)) {
if (_edit.mode == TRANSFORM_NONE) { if (_edit.mode == TRANSFORM_NONE) {
begin_transform(TRANSFORM_TRANSLATE, true); begin_transform(TRANSFORM_TRANSLATE, true);
@ -6041,6 +6081,9 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
ED_SHORTCUT("spatial_editor/instant_rotate", TTRC("Begin Rotate Transformation")); ED_SHORTCUT("spatial_editor/instant_rotate", TTRC("Begin Rotate Transformation"));
ED_SHORTCUT("spatial_editor/instant_scale", TTRC("Begin Scale Transformation")); ED_SHORTCUT("spatial_editor/instant_scale", TTRC("Begin Scale Transformation"));
ED_SHORTCUT("spatial_editor/collision_reposition", TTRC("Reposition Using Collisions"), KeyModifierMask::SHIFT | Key::G); ED_SHORTCUT("spatial_editor/collision_reposition", TTRC("Reposition Using Collisions"), KeyModifierMask::SHIFT | Key::G);
ED_SHORTCUT("spatial_editor/reset_transform_position", TTRC("Reset Position"), KeyModifierMask::ALT + Key::W);
ED_SHORTCUT("spatial_editor/reset_transform_rotation", TTRC("Reset Rotation"), KeyModifierMask::ALT + Key::E);
ED_SHORTCUT("spatial_editor/reset_transform_scale", TTRC("Reset Scale"), KeyModifierMask::ALT + Key::R);
translation_preview_button = memnew(EditorTranslationPreviewButton); translation_preview_button = memnew(EditorTranslationPreviewButton);
hbox->add_child(translation_preview_button); hbox->add_child(translation_preview_button);

View file

@ -365,6 +365,11 @@ private:
TRANSFORM_XZ, TRANSFORM_XZ,
TRANSFORM_XY, TRANSFORM_XY,
}; };
enum TransformType {
POSITION,
ROTATION,
SCALE,
};
struct EditData { struct EditData {
TransformMode mode; TransformMode mode;
@ -524,6 +529,8 @@ private:
Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal); Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal);
void _reset_transform(TransformType p_type);
void begin_transform(TransformMode p_mode, bool instant); void begin_transform(TransformMode p_mode, bool instant);
void commit_transform(); void commit_transform();
void apply_transform(Vector3 p_motion, double p_snap); void apply_transform(Vector3 p_motion, double p_snap);

View file

@ -530,6 +530,18 @@ void CanvasItemEditor::shortcut_input(const Ref<InputEvent> &p_ev) {
viewport->queue_redraw(); viewport->queue_redraw();
} }
} }
if (k->is_pressed() && !k->is_echo()) {
if (reset_transform_position_shortcut.is_valid() && reset_transform_position_shortcut->matches_event(p_ev)) {
_reset_transform(TransformType::POSITION);
}
if (reset_transform_rotation_shortcut.is_valid() && reset_transform_rotation_shortcut->matches_event(p_ev)) {
_reset_transform(TransformType::ROTATION);
}
if (reset_transform_scale_shortcut.is_valid() && reset_transform_scale_shortcut->matches_event(p_ev)) {
_reset_transform(TransformType::SCALE);
}
}
} }
} }
@ -1094,6 +1106,53 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) {
viewport->queue_redraw(); viewport->queue_redraw();
} }
void CanvasItemEditor::_reset_transform(TransformType p_type) {
List<Node *> selection = editor_selection->get_full_selected_node_list();
if (selection.is_empty()) {
return;
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Reset Transform"));
for (Node *node : selection) {
Node2D *res_node = Object::cast_to<Node2D>(node);
if (res_node) {
switch (p_type) {
case TransformType::POSITION:
undo_redo->add_undo_method(res_node, "set_position", res_node->get_position());
undo_redo->add_do_method(res_node, "set_position", Vector2());
break;
case TransformType::ROTATION:
undo_redo->add_undo_method(res_node, "set_rotation", res_node->get_rotation());
undo_redo->add_do_method(res_node, "set_rotation", 0);
break;
case TransformType::SCALE:
undo_redo->add_undo_method(res_node, "set_scale", res_node->get_scale());
undo_redo->add_do_method(res_node, "set_scale", Size2(1, 1));
break;
}
continue;
}
Control *res_control = Object::cast_to<Control>(node);
if (res_control) {
switch (p_type) {
case TransformType::POSITION:
undo_redo->add_undo_method(res_control, "set_position", res_control->get_position());
undo_redo->add_do_method(res_control, "set_position", Vector2());
break;
case TransformType::ROTATION:
undo_redo->add_undo_method(res_control, "set_rotation", res_control->get_rotation());
undo_redo->add_do_method(res_control, "set_rotation", 0);
break;
case TransformType::SCALE:
undo_redo->add_undo_method(res_control, "set_scale", res_control->get_scale());
undo_redo->add_do_method(res_control, "set_scale", Size2(1, 1));
break;
}
}
}
undo_redo->commit_action();
}
void CanvasItemEditor::_switch_theme_preview(int p_mode) { void CanvasItemEditor::_switch_theme_preview(int p_mode) {
view_menu->get_popup()->hide(); view_menu->get_popup()->hide();
@ -5803,6 +5862,9 @@ CanvasItemEditor::CanvasItemEditor() {
multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTRC("Multiply grid step by 2"), Key::KP_MULTIPLY); 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); 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);
reset_transform_rotation_shortcut = ED_SHORTCUT("canvas_item_editor/reset_transform_rotation", TTRC("Reset Rotation"), KeyModifierMask::ALT + Key::E);
reset_transform_scale_shortcut = ED_SHORTCUT("canvas_item_editor/reset_transform_scale", TTRC("Reset Scale"), KeyModifierMask::ALT + Key::R);
skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true); skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true);

View file

@ -186,6 +186,12 @@ private:
GRID_VISIBILITY_HIDE, GRID_VISIBILITY_HIDE,
}; };
enum TransformType {
POSITION,
ROTATION,
SCALE,
};
const String locked_transform_warning = TTRC("All selected CanvasItems are either invisible or locked in some way and can't be transformed."); const String locked_transform_warning = TTRC("All selected CanvasItems are either invisible or locked in some way and can't be transformed.");
bool selection_menu_additive_selection = false; bool selection_menu_additive_selection = false;
@ -381,6 +387,9 @@ private:
Ref<Shortcut> set_pivot_shortcut; Ref<Shortcut> set_pivot_shortcut;
Ref<Shortcut> multiply_grid_step_shortcut; Ref<Shortcut> multiply_grid_step_shortcut;
Ref<Shortcut> divide_grid_step_shortcut; Ref<Shortcut> divide_grid_step_shortcut;
Ref<Shortcut> reset_transform_position_shortcut;
Ref<Shortcut> reset_transform_rotation_shortcut;
Ref<Shortcut> reset_transform_scale_shortcut;
Ref<ViewPanner> panner; Ref<ViewPanner> panner;
void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event); void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);
@ -420,6 +429,7 @@ private:
bool _is_grid_visible() const; bool _is_grid_visible() const;
void _prepare_grid_menu(); void _prepare_grid_menu();
void _on_grid_menu_id_pressed(int p_id); void _on_grid_menu_id_pressed(int p_id);
void _reset_transform(TransformType p_type);
public: public:
enum ThemePreviewMode { enum ThemePreviewMode {