summaryrefslogtreecommitdiffstats
path: root/editor/plugins
diff options
context:
space:
mode:
authorSpartan322 <Megacake1234@gmail.com>2024-11-15 14:24:07 -0500
committerSpartan322 <Megacake1234@gmail.com>2024-11-15 14:24:07 -0500
commit4a5836e5462554a738b502aa8bbde5e4a051eb56 (patch)
treed58eaa8daad3e30c8b84a50e70a21f93b05525c5 /editor/plugins
parentac1a49725fc038ae11ef9060fecb2b0f9c6333b2 (diff)
parent6c05ec3d6732cac44cf85c91db7d3fd1075bcb23 (diff)
downloadredot-engine-4a5836e5462554a738b502aa8bbde5e4a051eb56.tar.gz
Merge commit godotengine/godot@6c05ec3d6732cac44cf85c91db7d3fd1075bcb23
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp298
-rw-r--r--editor/plugins/script_editor_plugin.cpp16
-rw-r--r--editor/plugins/script_text_editor.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp110
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h12
5 files changed, 301 insertions, 137 deletions
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 0d439c4311..51679cca9a 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1932,37 +1932,50 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
// Drag resize handles
if (drag_type == DRAG_NONE) {
- if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && ((b->is_alt_pressed() && b->is_command_or_control_pressed()) || tool == TOOL_SCALE)) {
+ if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() &&
+ ((tool == TOOL_SELECT && b->is_alt_pressed() && b->is_command_or_control_pressed()) || tool == TOOL_SCALE)) {
bool has_locked_items = false;
List<CanvasItem *> selection = _get_edited_canvas_items(false, true, &has_locked_items);
- if (selection.size() == 1) {
+
+ // Remove non-movable nodes.
+ for (CanvasItem *ci : selection) {
+ if (!_is_node_movable(ci, true)) {
+ selection.erase(ci);
+ }
+ }
+
+ if (!selection.is_empty()) {
CanvasItem *ci = selection.front()->get();
- if (_is_node_movable(ci)) {
- Transform2D xform = transform * ci->get_global_transform_with_canvas();
- Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized();
- Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+ Transform2D edit_transform;
+ if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) {
+ edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot);
+ } else {
+ edit_transform = ci->_edit_get_transform();
+ }
- drag_type = DRAG_SCALE_BOTH;
+ Transform2D xform = transform * ci->get_global_transform_with_canvas();
+ Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * edit_transform).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
- if (show_transformation_gizmos) {
- Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
- Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
- if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) {
- drag_type = DRAG_SCALE_X;
- }
- Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
- if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) {
- drag_type = DRAG_SCALE_Y;
- }
- }
+ drag_type = DRAG_SCALE_BOTH;
- drag_from = transform.affine_inverse().xform(b->get_position());
- drag_selection = List<CanvasItem *>();
- drag_selection.push_back(ci);
- _save_canvas_item_state(drag_selection);
- return true;
+ if (show_transformation_gizmos) {
+ Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
+ Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) {
+ drag_type = DRAG_SCALE_X;
+ }
+ Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) {
+ drag_type = DRAG_SCALE_Y;
+ }
}
+
+ drag_from = transform.affine_inverse().xform(b->get_position());
+ drag_selection = selection;
+ _save_canvas_item_state(drag_selection);
+ return true;
} else {
if (has_locked_items) {
EditorToaster::get_singleton()->popup_str(TTR(locked_transform_warning), EditorToaster::SEVERITY_WARNING);
@@ -1970,66 +1983,87 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
return has_locked_items;
}
}
- }
-
- if (drag_type == DRAG_SCALE_BOTH || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) {
+ } else if (drag_type == DRAG_SCALE_BOTH || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) {
// Resize the node
if (m.is_valid()) {
_restore_canvas_item_state(drag_selection);
- CanvasItem *ci = drag_selection.front()->get();
drag_to = transform.affine_inverse().xform(m->get_position());
- Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse();
- Transform2D unscaled_transform = (transform * parent_xform * ci->_edit_get_transform()).orthonormalized();
- Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
-
- bool uniform = m->is_shift_pressed();
- bool is_ctrl = m->is_command_or_control_pressed();
-
- Point2 drag_from_local = simple_xform.xform(drag_from);
- Point2 drag_to_local = simple_xform.xform(drag_to);
- Point2 offset = drag_to_local - drag_from_local;
+ Size2 scale_max;
+ if (drag_type != DRAG_SCALE_BOTH) {
+ for (CanvasItem *ci : drag_selection) {
+ scale_max = scale_max.max(ci->_edit_get_scale());
+ }
+ }
- Size2 scale = ci->_edit_get_scale();
- Size2 original_scale = scale;
- real_t ratio = scale.y / scale.x;
- if (drag_type == DRAG_SCALE_BOTH) {
- Size2 scale_factor = drag_to_local / drag_from_local;
- if (uniform) {
- scale *= (scale_factor.x + scale_factor.y) / 2.0;
+ for (CanvasItem *ci : drag_selection) {
+ Transform2D edit_transform;
+ bool using_temp_pivot = !Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y);
+ if (using_temp_pivot) {
+ edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot);
} else {
- scale *= scale_factor;
+ edit_transform = ci->_edit_get_transform();
}
- } else {
- Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE;
- Size2 parent_scale = parent_xform.get_scale();
- scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y);
- if (drag_type == DRAG_SCALE_X) {
- scale.x += scale_factor.x;
+ Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse();
+ Transform2D unscaled_transform = (transform * parent_xform * edit_transform).orthonormalized();
+ Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
+
+ bool uniform = m->is_shift_pressed();
+ bool is_ctrl = m->is_command_or_control_pressed();
+
+ Point2 drag_from_local = simple_xform.xform(drag_from);
+ Point2 drag_to_local = simple_xform.xform(drag_to);
+ Point2 offset = drag_to_local - drag_from_local;
+
+ Size2 scale = ci->_edit_get_scale();
+ Size2 original_scale = scale;
+ real_t ratio = scale.y / scale.x;
+ if (drag_type == DRAG_SCALE_BOTH) {
+ Size2 scale_factor = drag_to_local / drag_from_local;
if (uniform) {
- scale.y = scale.x * ratio;
+ scale *= (scale_factor.x + scale_factor.y) / 2.0;
+ } else {
+ scale *= scale_factor;
}
- } else if (drag_type == DRAG_SCALE_Y) {
- scale.y -= scale_factor.y;
- if (uniform) {
- scale.x = scale.y / ratio;
+ } else {
+ Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE;
+ Size2 parent_scale = parent_xform.get_scale();
+ // Take into account the biggest scale, so all nodes are scaled uniformly.
+ scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y) / (scale_max / original_scale);
+
+ if (drag_type == DRAG_SCALE_X) {
+ scale.x += scale_factor.x;
+ if (uniform) {
+ scale.y = scale.x * ratio;
+ }
+ } else if (drag_type == DRAG_SCALE_Y) {
+ scale.y -= scale_factor.y;
+ if (uniform) {
+ scale.x = scale.y / ratio;
+ }
}
}
- }
- if (snap_scale && !is_ctrl) {
- if (snap_relative) {
- scale.x = original_scale.x * (roundf((scale.x / original_scale.x) / snap_scale_step) * snap_scale_step);
- scale.y = original_scale.y * (roundf((scale.y / original_scale.y) / snap_scale_step) * snap_scale_step);
- } else {
- scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step;
- scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step;
+ if (snap_scale && !is_ctrl) {
+ if (snap_relative) {
+ scale.x = original_scale.x * (Math::round((scale.x / original_scale.x) / snap_scale_step) * snap_scale_step);
+ scale.y = original_scale.y * (Math::round((scale.y / original_scale.y) / snap_scale_step) * snap_scale_step);
+ } else {
+ scale.x = Math::round(scale.x / snap_scale_step) * snap_scale_step;
+ scale.y = Math::round(scale.y / snap_scale_step) * snap_scale_step;
+ }
+ }
+
+ ci->_edit_set_scale(scale);
+
+ if (using_temp_pivot) {
+ Point2 ci_origin = ci->_edit_get_transform().get_origin();
+ ci->_edit_set_position(ci_origin + (ci_origin - temp_pivot) * ((scale - original_scale) / original_scale));
}
}
- ci->_edit_set_scale(scale);
return true;
}
@@ -2077,7 +2111,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
if (drag_type == DRAG_NONE) {
//Start moving the nodes
if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed()) {
- if ((b->is_alt_pressed() && !b->is_command_or_control_pressed()) || tool == TOOL_MOVE) {
+ if ((tool == TOOL_SELECT && b->is_alt_pressed() && !b->is_command_or_control_pressed()) || tool == TOOL_MOVE) {
bool has_locked_items = false;
List<CanvasItem *> selection = _get_edited_canvas_items(false, true, &has_locked_items);
@@ -2137,7 +2171,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
}
Point2 drag_delta = drag_to - drag_from;
- if (drag_selection.size() == 1 && (drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y)) {
+ if (drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y) {
const CanvasItem *selected = drag_selection.front()->get();
Transform2D parent_xform = selected->get_global_transform_with_canvas() * selected->get_transform().affine_inverse();
Transform2D unscaled_transform = (transform * parent_xform * selected->_edit_get_transform()).orthonormalized();
@@ -3470,16 +3504,14 @@ void CanvasItemEditor::_draw_selection() {
Ref<Texture2D> previous_position_icon = get_editor_theme_icon(SNAME("EditorPositionPrevious"));
RID vp_ci = viewport->get_canvas_item();
-
List<CanvasItem *> selection = _get_edited_canvas_items(true, false);
-
bool single = selection.size() == 1;
+ bool transform_tool = tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT;
+
for (CanvasItem *E : selection) {
CanvasItem *ci = Object::cast_to<CanvasItem>(E);
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci);
- bool item_locked = ci->has_meta("_edit_lock_");
-
// Draw the previous position if we are dragging the node
if (show_helpers &&
(drag_type == DRAG_MOVE || drag_type == DRAG_ROTATE ||
@@ -3504,6 +3536,7 @@ void CanvasItemEditor::_draw_selection() {
}
}
+ bool item_locked = ci->has_meta("_edit_lock_");
Transform2D xform = transform * ci->get_global_transform_with_canvas();
// Draw the selected items position / surrounding boxes
@@ -3533,7 +3566,7 @@ void CanvasItemEditor::_draw_selection() {
viewport->draw_set_transform_matrix(viewport->get_transform());
}
- if (single && !item_locked && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
+ if (single && !item_locked && transform_tool) {
// Draw the pivot
if (ci->_edit_use_pivot()) {
// Draw the node's pivot
@@ -3576,73 +3609,88 @@ void CanvasItemEditor::_draw_selection() {
select_handle->draw(vp_ci, (ofs - (select_handle->get_size() / 2)).floor());
}
}
+ }
+ }
- // Draw the move handles
- bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL);
- bool is_alt = Input::get_singleton()->is_key_pressed(Key::ALT);
- if (tool == TOOL_MOVE && show_transformation_gizmos) {
- if (_is_node_movable(ci)) {
- Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized();
- Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+ // Remove non-movable nodes.
+ for (CanvasItem *ci : selection) {
+ if (!_is_node_movable(ci, true)) {
+ selection.erase(ci);
+ }
+ }
- Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE);
- viewport->draw_set_transform_matrix(simple_xform);
+ if (!selection.is_empty() && transform_tool && show_transformation_gizmos) {
+ CanvasItem *ci = selection.front()->get();
- Vector<Point2> points = {
- Vector2(move_factor.x * EDSCALE, 5 * EDSCALE),
- Vector2(move_factor.x * EDSCALE, -5 * EDSCALE),
- Vector2((move_factor.x + 10) * EDSCALE, 0)
- };
+ Transform2D xform = transform * ci->get_global_transform_with_canvas();
+ bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL);
+ bool is_alt = Input::get_singleton()->is_key_pressed(Key::ALT);
- viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
- viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE));
+ // Draw the move handles.
+ if ((tool == TOOL_SELECT && is_alt && !is_ctrl) || tool == TOOL_MOVE) {
+ Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
- points.clear();
- points.push_back(Vector2(5 * EDSCALE, move_factor.y * EDSCALE));
- points.push_back(Vector2(-5 * EDSCALE, move_factor.y * EDSCALE));
- points.push_back(Vector2(0, (move_factor.y + 10) * EDSCALE));
+ Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE);
+ viewport->draw_set_transform_matrix(simple_xform);
- viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
- viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE));
+ Vector<Point2> points = {
+ Vector2(move_factor.x * EDSCALE, 5 * EDSCALE),
+ Vector2(move_factor.x * EDSCALE, -5 * EDSCALE),
+ Vector2((move_factor.x + 10) * EDSCALE, 0)
+ };
- viewport->draw_set_transform_matrix(viewport->get_transform());
- }
- }
+ viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE));
- // Draw the rescale handles
- if (show_transformation_gizmos && ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y)) {
- if (_is_node_movable(ci)) {
- Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized();
- Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+ points.clear();
+ points.push_back(Vector2(5 * EDSCALE, move_factor.y * EDSCALE));
+ points.push_back(Vector2(-5 * EDSCALE, move_factor.y * EDSCALE));
+ points.push_back(Vector2(0, (move_factor.y + 10) * EDSCALE));
- Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
- bool uniform = Input::get_singleton()->is_key_pressed(Key::SHIFT);
- Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom;
+ viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE));
- if (drag_type == DRAG_SCALE_X) {
- scale_factor.x += offset.x;
- if (uniform) {
- scale_factor.y += offset.x;
- }
- } else if (drag_type == DRAG_SCALE_Y) {
- scale_factor.y += offset.y;
- if (uniform) {
- scale_factor.x += offset.y;
- }
- }
+ viewport->draw_set_transform_matrix(viewport->get_transform());
+ }
- viewport->draw_set_transform_matrix(simple_xform);
- Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
- viewport->draw_rect(x_handle_rect, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
- viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE));
+ // Draw the rescale handles.
+ if ((tool == TOOL_SELECT && is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) {
+ Transform2D edit_transform;
+ if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) {
+ edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot);
+ } else {
+ edit_transform = ci->_edit_get_transform();
+ }
+ Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * edit_transform).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
- Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
- viewport->draw_rect(y_handle_rect, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
- viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE));
+ Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
+ bool uniform = Input::get_singleton()->is_key_pressed(Key::SHIFT);
+ Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom;
- viewport->draw_set_transform_matrix(viewport->get_transform());
+ if (drag_type == DRAG_SCALE_X) {
+ scale_factor.x += offset.x;
+ if (uniform) {
+ scale_factor.y += offset.x;
+ }
+ } else if (drag_type == DRAG_SCALE_Y) {
+ scale_factor.y += offset.y;
+ if (uniform) {
+ scale_factor.x += offset.y;
}
}
+
+ viewport->draw_set_transform_matrix(simple_xform);
+ Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ viewport->draw_rect(x_handle_rect, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE));
+
+ Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ viewport->draw_rect(y_handle_rect, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE));
+
+ viewport->draw_set_transform_matrix(viewport->get_transform());
}
}
@@ -5358,7 +5406,7 @@ CanvasItemEditor::CanvasItemEditor() {
main_menu_hbox->add_child(pivot_button);
pivot_button->set_toggle_mode(true);
pivot_button->connect(SceneStringName(pressed), callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_EDIT_PIVOT));
- pivot_button->set_tooltip_text(TTR("Click to change object's rotation pivot.") + "\n" + TTR("Shift: Set temporary rotation pivot.") + "\n" + TTR("Click this button while holding Shift to put the temporary rotation pivot in the center of the selected nodes."));
+ pivot_button->set_tooltip_text(TTR("Click to change object's pivot.") + "\n" + TTR("Shift: Set temporary pivot.") + "\n" + TTR("Click this button while holding Shift to put the temporary pivot in the center of the selected nodes."));
pan_button = memnew(Button);
pan_button->set_theme_type_variation("FlatButton");
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index f7d52306c5..d2098de99a 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -4393,28 +4393,28 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
disk_changed = memnew(ConfirmationDialog);
{
- disk_changed->set_title(TTR("Files have been modified on disk"));
+ disk_changed->set_title(TTR("Files have been modified outside Godot"));
VBoxContainer *vbc = memnew(VBoxContainer);
disk_changed->add_child(vbc);
Label *files_are_newer_label = memnew(Label);
- files_are_newer_label->set_text(TTR("The following files are newer on disk."));
+ files_are_newer_label->set_text(TTR("The following files are newer on disk:"));
vbc->add_child(files_are_newer_label);
- Label *what_action_label = memnew(Label);
- what_action_label->set_text(TTR("What action should be taken?:"));
- vbc->add_child(what_action_label);
-
disk_changed_list = memnew(Tree);
vbc->add_child(disk_changed_list);
disk_changed_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL);
+ Label *what_action_label = memnew(Label);
+ what_action_label->set_text(TTR("What action should be taken?"));
+ vbc->add_child(what_action_label);
+
disk_changed->connect(SceneStringName(confirmed), callable_mp(this, &ScriptEditor::reload_scripts).bind(false));
- disk_changed->set_ok_button_text(TTR("Discard local changes and reload"));
+ disk_changed->set_ok_button_text(TTR("Reload from disk"));
- disk_changed->add_button(TTR("Keep local changes and overwrite"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
+ disk_changed->add_button(TTR("Ignore external changes"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
disk_changed->connect("custom_action", callable_mp(this, &ScriptEditor::_resave_scripts));
}
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 94c54b69d7..32ea811c3a 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -953,7 +953,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
} else if (p_symbol.is_resource_file() || p_symbol.begins_with("uid://")) {
String symbol = p_symbol;
if (symbol.begins_with("uid://")) {
- symbol = ResourceUID::get_singleton()->get_id_path(ResourceUID::get_singleton()->text_to_id(symbol));
+ symbol = ResourceUID::uid_to_path(symbol);
}
List<String> scene_extensions;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 649c2d849d..e714e9b4cc 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -1987,6 +1987,67 @@ bool VisualShaderEditor::_update_preview_parameter_tree() {
return found;
}
+void VisualShaderEditor::_preview_tools_menu_option(int p_idx) {
+ ShaderMaterial *src_mat = nullptr;
+
+ if (p_idx == COPY_PARAMS_FROM_MATERIAL || p_idx == PASTE_PARAMS_TO_MATERIAL) {
+ for (int i = EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() - 1; i >= 0; i--) {
+ Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(i));
+ ShaderMaterial *src_mat2;
+ if (!object) {
+ continue;
+ }
+ if (object->has_method("get_material_override")) { // Trying to get material from MeshInstance.
+ src_mat2 = Object::cast_to<ShaderMaterial>(object->call("get_material_override"));
+ } else if (object->has_method("get_material")) { // From CanvasItem/Node2D.
+ src_mat2 = Object::cast_to<ShaderMaterial>(object->call("get_material"));
+ } else {
+ src_mat2 = Object::cast_to<ShaderMaterial>(object);
+ }
+
+ if (src_mat2 && src_mat2->get_shader().is_valid() && src_mat2->get_shader() == visual_shader) {
+ src_mat = src_mat2;
+ break;
+ }
+ }
+ }
+
+ switch (p_idx) {
+ case COPY_PARAMS_FROM_MATERIAL:
+ if (src_mat) {
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Copy Preview Shader Parameters From Material"));
+
+ List<PropertyInfo> params;
+ preview_material->get_shader()->get_shader_uniform_list(&params);
+ for (const PropertyInfo &E : params) {
+ undo_redo->add_do_method(visual_shader.ptr(), "_set_preview_shader_parameter", E.name, src_mat->get_shader_parameter(E.name));
+ undo_redo->add_undo_method(visual_shader.ptr(), "_set_preview_shader_parameter", E.name, preview_material->get_shader_parameter(E.name));
+ }
+
+ undo_redo->commit_action();
+ }
+ break;
+ case PASTE_PARAMS_TO_MATERIAL:
+ if (src_mat) {
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Paste Preview Shader Parameters To Material"));
+
+ List<PropertyInfo> params;
+ preview_material->get_shader()->get_shader_uniform_list(&params);
+ for (const PropertyInfo &E : params) {
+ undo_redo->add_do_method(src_mat, "set_shader_parameter", E.name, preview_material->get_shader_parameter(E.name));
+ undo_redo->add_undo_method(src_mat, "set_shader_parameter", E.name, src_mat->get_shader_parameter(E.name));
+ }
+
+ undo_redo->commit_action();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
void VisualShaderEditor::_clear_preview_param() {
selected_param_id = "";
current_prop = nullptr;
@@ -4066,6 +4127,7 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
int from = p_from.to_int();
int to = p_to.to_int();
+ bool swap = last_to_node != -1 && Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL);
if (!visual_shader->can_connect_nodes(type, from, p_from_index, to, p_to_index)) {
return;
@@ -4083,6 +4145,14 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+
+ if (swap) {
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port);
+ }
+ break;
}
}
@@ -4096,6 +4166,9 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, to);
undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", (int)type, to);
undo_redo->commit_action();
+
+ last_to_node = -1;
+ last_to_port = -1;
}
void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
@@ -4106,6 +4179,11 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from
int from = p_from.to_int();
int to = p_to.to_int();
+ last_to_node = to;
+ last_to_port = p_to_index;
+
+ info_label->show();
+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Nodes Disconnected"));
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
@@ -4117,6 +4195,10 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from
undo_redo->commit_action();
}
+void VisualShaderEditor::_connection_drag_ended() {
+ info_label->hide();
+}
+
void VisualShaderEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) {
from_node = p_from.to_int();
from_slot = p_from_slot;
@@ -5021,8 +5103,11 @@ void VisualShaderEditor::_param_property_changed(const String &p_property, const
void VisualShaderEditor::_update_current_param() {
if (current_prop != nullptr) {
String name = current_prop->get_meta("id");
- preview_material->set("shader_parameter/" + name, visual_shader->_get_preview_shader_parameter(name));
-
+ if (visual_shader->_has_preview_shader_parameter(name)) {
+ preview_material->set("shader_parameter/" + name, visual_shader->_get_preview_shader_parameter(name));
+ } else {
+ preview_material->set("shader_parameter/" + name, Variant());
+ }
current_prop->update_property();
current_prop->update_editor_property_status();
current_prop->update_cache();
@@ -5161,6 +5246,7 @@ void VisualShaderEditor::_notification(int p_what) {
}
tools->set_button_icon(get_editor_theme_icon(SNAME("Tools")));
+ preview_tools->set_button_icon(get_editor_theme_icon(SNAME("Tools")));
if (is_visible_in_tree()) {
_update_graph();
@@ -6307,6 +6393,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect(SceneStringName(gui_input), callable_mp(this, &VisualShaderEditor::_graph_gui_input));
graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty));
graph->connect("connection_from_empty", callable_mp(this, &VisualShaderEditor::_connection_from_empty));
+ graph->connect("connection_drag_ended", callable_mp(this, &VisualShaderEditor::_connection_drag_ended));
graph->connect(SceneStringName(visibility_changed), callable_mp(this, &VisualShaderEditor::_visibility_changed));
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT);
@@ -6367,6 +6454,13 @@ VisualShaderEditor::VisualShaderEditor() {
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SAMPLER, VisualShaderNode::PORT_TYPE_SAMPLER);
+ info_label = memnew(Label);
+ info_label->set_text(vformat(TTR("Hold %s Key To Swap Connections"), keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL)));
+ info_label->set_anchors_and_offsets_preset(Control::PRESET_BOTTOM_WIDE, PRESET_MODE_MINSIZE, 20);
+ info_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ info_label->hide();
+ graph->get_top_layer()->add_child(info_label);
+
PanelContainer *toolbar_panel = static_cast<PanelContainer *>(graph->get_menu_hbox()->get_parent());
toolbar_panel->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE, PRESET_MODE_MINSIZE, 10);
toolbar_panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
@@ -6557,11 +6651,21 @@ VisualShaderEditor::VisualShaderEditor() {
VBoxContainer *params_vbox = memnew(VBoxContainer);
preview_split->add_child(params_vbox);
+ HBoxContainer *filter_hbox = memnew(HBoxContainer);
+ params_vbox->add_child(filter_hbox);
+
param_filter = memnew(LineEdit);
+ filter_hbox->add_child(param_filter);
param_filter->connect(SceneStringName(text_changed), callable_mp(this, &VisualShaderEditor::_param_filter_changed));
param_filter->set_h_size_flags(SIZE_EXPAND_FILL);
param_filter->set_placeholder(TTR("Filter Parameters"));
- params_vbox->add_child(param_filter);
+
+ preview_tools = memnew(MenuButton);
+ filter_hbox->add_child(preview_tools);
+ preview_tools->set_tooltip_text(TTR("Options"));
+ preview_tools->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &VisualShaderEditor::_preview_tools_menu_option));
+ preview_tools->get_popup()->add_item(TTR("Copy Parameters From Material"), COPY_PARAMS_FROM_MATERIAL);
+ preview_tools->get_popup()->add_item(TTR("Paste Parameters To Material"), PASTE_PARAMS_TO_MATERIAL);
ScrollContainer *sc = memnew(ScrollContainer);
sc->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 1877bd094e..51cab987cb 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -223,6 +223,10 @@ class VisualShaderEditor : public ShaderEditor {
Button *code_preview_button = nullptr;
Button *shader_preview_button = nullptr;
+ int last_to_node = -1;
+ int last_to_port = -1;
+ Label *info_label = nullptr;
+
OptionButton *edit_type = nullptr;
OptionButton *edit_type_standard = nullptr;
OptionButton *edit_type_particles = nullptr;
@@ -278,6 +282,7 @@ class VisualShaderEditor : public ShaderEditor {
bool shader_preview_showed = true;
LineEdit *param_filter = nullptr;
+ MenuButton *preview_tools = nullptr;
String selected_param_id;
Tree *parameters = nullptr;
HashMap<String, PropertyInfo> parameter_props;
@@ -320,6 +325,11 @@ class VisualShaderEditor : public ShaderEditor {
COLLAPSE_ALL
};
+ enum PreviewToolsMenuOptions {
+ COPY_PARAMS_FROM_MATERIAL,
+ PASTE_PARAMS_TO_MATERIAL,
+ };
+
#ifdef MINGW_ENABLED
#undef DELETE
#endif
@@ -369,6 +379,7 @@ class VisualShaderEditor : public ShaderEditor {
void _show_add_varying_dialog();
void _show_remove_varying_dialog();
+ void _preview_tools_menu_option(int p_idx);
void _clear_preview_param();
void _update_preview_parameter_list();
bool _update_preview_parameter_tree();
@@ -497,6 +508,7 @@ class VisualShaderEditor : public ShaderEditor {
void _unlink_node_from_parent_frame(int p_node_id);
+ void _connection_drag_ended();
void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position);
void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position);
bool _check_node_drop_on_connection(const Vector2 &p_position, Ref<GraphEdit::Connection> *r_closest_connection, int *r_node_id = nullptr, int *r_to_port = nullptr);