diff options
Diffstat (limited to 'editor/plugins')
130 files changed, 2385 insertions, 1063 deletions
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 281b1d79af..80d0a7db60 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -264,7 +264,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position()))); if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) { - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { if (mb->get_control() || mb->get_shift() || mb->get_alt()) { return false; @@ -326,7 +326,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) return true; } } - } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && !edited_point.valid()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed() && !edited_point.valid()) { const PosVertex closest = closest_point(gpoint); if (closest.valid()) { @@ -335,7 +335,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) } } } else if (mode == MODE_DELETE) { - if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) { const PosVertex closest = closest_point(gpoint); if (closest.valid()) { @@ -346,7 +346,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) } if (mode == MODE_CREATE) { - if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) { if (_is_line()) { // for lines, we don't have a wip mode, and we can undo each single add point. Vector<Vector2> vertices = _get_polygon(0); @@ -384,7 +384,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) return true; } } - } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed() && wip_active) { _wip_cancel(); } } @@ -395,7 +395,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) if (mm.is_valid()) { Vector2 gpoint = mm->get_position(); - if (edited_point.valid() && (wip_active || (mm->get_button_mask() & BUTTON_MASK_LEFT))) { + if (edited_point.valid() && (wip_active || (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT))) { Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint))); //Move the point in a single axis. Should only work when editing a polygon and while holding shift. @@ -585,11 +585,11 @@ void AbstractPolygon2DEditor::edit(Node *p_polygon) { edited_point = PosVertex(); hover_point = Vertex(); selected_point = Vertex(); - - canvas_item_editor->update_viewport(); } else { _set_node(nullptr); } + + canvas_item_editor->update_viewport(); } void AbstractPolygon2DEditor::_bind_methods() { diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 527803150d..4f9adfff25 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 223484044a..025fcaf818 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -51,7 +51,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (mb->get_button_index() == BUTTON_LEFT && tool_create->is_pressed()))) { + if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && tool_create->is_pressed()))) { menu->clear(); animations_menu->clear(); animations_to_add.clear(); @@ -106,11 +106,11 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven add_point_pos += blend_space->get_min_space(); if (snap->is_pressed()) { - add_point_pos = Math::stepify(add_point_pos, blend_space->get_snap()); + add_point_pos = Math::snapped(add_point_pos, blend_space->get_snap()); } } - if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { blend_space_draw->update(); // why not // try to see if a point can be selected @@ -132,14 +132,14 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven } } - if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (dragging_selected) { // move float point = blend_space->get_blend_point_position(selected_point); point += drag_ofs.x; if (snap->is_pressed()) { - point = Math::stepify(point, blend_space->get_snap()); + point = Math::snapped(point, blend_space->get_snap()); } updating = true; @@ -161,7 +161,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven } // *set* the blend - if (mb.is_valid() && !mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && !mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { float blend_pos = mb->get_position().x / blend_space_draw->get_size().x; blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos += blend_space->get_min_space(); @@ -184,7 +184,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven _update_edited_point_pos(); } - if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { float blend_pos = mm->get_position().x / blend_space_draw->get_size().x; blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos += blend_space->get_min_space(); @@ -253,7 +253,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() { if (dragging_selected && selected_point == i) { point += drag_ofs.x; if (snap->is_pressed()) { - point = Math::stepify(point, blend_space->get_snap()); + point = Math::snapped(point, blend_space->get_snap()); } } @@ -454,7 +454,7 @@ void AnimationNodeBlendSpace1DEditor::_update_edited_point_pos() { pos += drag_ofs.x; if (snap->is_pressed()) { - pos = Math::stepify(pos, blend_space->get_snap()); + pos = Math::snapped(pos, blend_space->get_snap()); } } diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index 5ff5da47c0..24c950fdee 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 94785a5422..af9c391174 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -79,7 +79,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (mb->get_button_index() == BUTTON_LEFT && tool_create->is_pressed()))) { + if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && tool_create->is_pressed()))) { menu->clear(); animations_menu->clear(); animations_to_add.clear(); @@ -129,12 +129,12 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven add_point_pos += blend_space->get_min_space(); if (snap->is_pressed()) { - add_point_pos.x = Math::stepify(add_point_pos.x, blend_space->get_snap().x); - add_point_pos.y = Math::stepify(add_point_pos.y, blend_space->get_snap().y); + add_point_pos.x = Math::snapped(add_point_pos.x, blend_space->get_snap().x); + add_point_pos.y = Math::snapped(add_point_pos.y, blend_space->get_snap().y); } } - if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { blend_space_draw->update(); //update anyway //try to see if a point can be selected selected_point = -1; @@ -174,7 +174,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven } } - if (mb.is_valid() && mb->is_pressed() && tool_triangle->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && tool_triangle->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { blend_space_draw->update(); //update anyway //try to see if a point can be selected selected_point = -1; @@ -209,14 +209,14 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven } } - if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (dragging_selected) { //move Vector2 point = blend_space->get_blend_point_position(selected_point); point += drag_ofs; if (snap->is_pressed()) { - point.x = Math::stepify(point.x, blend_space->get_snap().x); - point.y = Math::stepify(point.y, blend_space->get_snap().y); + point.x = Math::snapped(point.x, blend_space->get_snap().x); + point.y = Math::snapped(point.y, blend_space->get_snap().y); } updating = true; @@ -236,7 +236,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven blend_space_draw->update(); } - if (mb.is_valid() && mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { Vector2 blend_pos = (mb->get_position() / blend_space_draw->get_size()); blend_pos.y = 1.0 - blend_pos.y; blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); @@ -270,7 +270,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven blend_space_draw->update(); } - if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { Vector2 blend_pos = (mm->get_position() / blend_space_draw->get_size()); blend_pos.y = 1.0 - blend_pos.y; blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); @@ -467,8 +467,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { if (dragging_selected && selected_point == point_idx) { point += drag_ofs; if (snap->is_pressed()) { - point.x = Math::stepify(point.x, blend_space->get_snap().x); - point.y = Math::stepify(point.y, blend_space->get_snap().y); + point.x = Math::snapped(point.x, blend_space->get_snap().x); + point.y = Math::snapped(point.y, blend_space->get_snap().y); } } point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); @@ -503,8 +503,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { if (dragging_selected && selected_point == i) { point += drag_ofs; if (snap->is_pressed()) { - point.x = Math::stepify(point.x, blend_space->get_snap().x); - point.y = Math::stepify(point.y, blend_space->get_snap().y); + point.x = Math::snapped(point.x, blend_space->get_snap().x); + point.y = Math::snapped(point.y, blend_space->get_snap().y); } } point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); @@ -702,8 +702,8 @@ void AnimationNodeBlendSpace2DEditor::_update_edited_point_pos() { if (dragging_selected) { pos += drag_ofs; if (snap->is_pressed()) { - pos.x = Math::stepify(pos.x, blend_space->get_snap().x); - pos.y = Math::stepify(pos.y, blend_space->get_snap().y); + pos.x = Math::snapped(pos.x, blend_space->get_snap().x); + pos.y = Math::snapped(pos.y, blend_space->get_snap().y); } } updating = true; diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h index 64885aeaca..3b8b78b2b5 100644 --- a/editor/plugins/animation_blend_space_2d_editor.h +++ b/editor/plugins/animation_blend_space_2d_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index a20bbd2b62..fdbbe5184b 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -139,7 +139,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { name->set_expand_to_text_length(true); node->add_child(name); node->set_slot(0, false, 0, Color(), true, 0, get_theme_color("font_color", "Label")); - name->connect("text_entered", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed), varray(agnode)); + name->connect("text_entered", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed), varray(agnode), CONNECT_DEFERRED); name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out), varray(name, agnode), CONNECT_DEFERRED); base = 1; node->set_show_close_button(true); @@ -255,6 +255,9 @@ void AnimationNodeBlendTreeEditor::_update_graph() { graph->connect_node(from, 0, to, to_idx); } + + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); } void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) { @@ -416,7 +419,7 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request() { } } - if (to_erase.empty()) { + if (to_erase.is_empty()) { return; } @@ -537,7 +540,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano default: { } break; } - if (!track_type_name.empty()) { + if (!track_type_name.is_empty()) { types[track_path].insert(track_type_name); } } @@ -888,6 +891,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed)); graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request)); graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request)); + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); VSeparator *vs = memnew(VSeparator); graph->get_zoom_hbox()->add_child(vs); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index 3ebf623eef..9f09069719 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 4b97dacbc1..7c623505b5 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -78,7 +78,6 @@ void AnimationPlayerEditor::_notification(int p_what) { } frame->set_value(player->get_current_animation_position()); track_editor->set_anim_pos(player->get_current_animation_position()); - EditorNode::get_singleton()->get_inspector()->refresh(); } else if (!player->is_valid()) { // Reset timeline when the player has been stopped externally @@ -680,7 +679,7 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) { if (p_state.has("animation")) { String anim = p_state["animation"]; - if (!anim.empty() && player->has_animation(anim)) { + if (!anim.is_empty() && player->has_animation(anim)) { _select_anim_by_name(anim); _animation_edit(); } @@ -1013,7 +1012,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) { float pos = CLAMP(anim->get_length() * (p_value / frame->get_max()), 0, anim->get_length()); if (track_editor->is_snap_enabled()) { - pos = Math::stepify(pos, _get_editor_step()); + pos = Math::snapped(pos, _get_editor_step()); } if (player->is_valid() && !p_set) { @@ -1069,11 +1068,9 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) } updating = true; - frame->set_value(Math::stepify(p_pos, _get_editor_step())); + frame->set_value(Math::snapped(p_pos, _get_editor_step())); updating = false; _seek_value_changed(p_pos, !p_drag); - - EditorNode::get_singleton()->get_inspector()->refresh(); } void AnimationPlayerEditor::_animation_tool_menu(int p_option) { @@ -1400,7 +1397,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() { // Render every past/future step with the capture shader. RS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid()); - onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/default_clear_color")); + onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color")); onion.capture.material->set_shader_param("differences_only", onion.differences_only); onion.capture.material->set_shader_param("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID()); diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index ab3feb115f..2f6bf55e4c 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 6fa1792c67..a9709bbb16 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -76,7 +76,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv Ref<InputEventMouseButton> mb = p_event; //Add new node - if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == BUTTON_LEFT))) { + if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT))) { menu->clear(); animations_menu->clear(); animations_to_add.clear(); @@ -124,7 +124,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } // select node or push a field inside - if (mb.is_valid() && !mb->get_shift() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && !mb->get_shift() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { selected_transition_from = StringName(); selected_transition_to = StringName(); selected_node = StringName(); @@ -216,7 +216,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } //end moving node - if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { + if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == MOUSE_BUTTON_LEFT && !mb->is_pressed()) { if (dragging_selected) { Ref<AnimationNode> an = state_machine->get_node(selected_node); updating = true; @@ -237,7 +237,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } //connect nodes - if (mb.is_valid() && ((tool_select->is_pressed() && mb->get_shift()) || tool_connect->is_pressed()) && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { + if (mb.is_valid() && ((tool_select->is_pressed() && mb->get_shift()) || tool_connect->is_pressed()) && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected connecting = true; @@ -250,7 +250,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } //end connecting nodes - if (mb.is_valid() && connecting && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { + if (mb.is_valid() && connecting && mb->get_button_index() == MOUSE_BUTTON_LEFT && !mb->is_pressed()) { if (connecting_to_node != StringName()) { if (state_machine->has_transition(connecting_from, connecting_to_node)) { EditorNode::get_singleton()->show_warning(TTR("Transition exists!")); @@ -284,7 +284,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv Ref<InputEventMouseMotion> mm = p_event; //pan window - if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_MIDDLE) { + if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } @@ -520,7 +520,7 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co Transform2D xf; xf.elements[0] = (p_to - p_from).normalized(); - xf.elements[1] = xf.elements[0].tangent(); + xf.elements[1] = xf.elements[0].orthogonal(); xf.elements[2] = (p_from + p_to) * 0.5 - xf.elements[1] * icon->get_height() * 0.5 - xf.elements[0] * icon->get_height() * 0.5; state_machine_draw->draw_set_transform_matrix(xf); @@ -690,7 +690,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { tl.width = tr_bidi_offset; if (state_machine->has_transition(tl.to_node, tl.from_node)) { //offset if same exists - Vector2 offset = -(tl.from - tl.to).normalized().tangent() * tr_bidi_offset; + Vector2 offset = -(tl.from - tl.to).normalized().orthogonal() * tr_bidi_offset; tl.from += offset; tl.to += offset; } diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index 119feb417d..a969ddd26b 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 800df12199..c33b06ff32 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h index fd3a449487..de3d89ae17 100644 --- a/editor/plugins/animation_tree_editor_plugin.h +++ b/editor/plugins/animation_tree_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index bd70e649e6..b7484aa748 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -350,7 +350,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int if (sha256 != download_sha256) { error_text = TTR("Bad download hash, assuming file has been tampered with.") + "\n"; error_text += TTR("Expected:") + " " + sha256 + "\n" + TTR("Got:") + " " + download_sha256; - status->set_text(TTR("Failed sha256 hash check")); + status->set_text(TTR("Failed SHA-256 hash check")); } } } break; @@ -359,6 +359,8 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int if (error_text != String()) { download_error->set_text(TTR("Asset Download Error:") + "\n" + error_text); download_error->popup_centered(); + // Let the user retry the download. + retry->show(); return; } @@ -459,6 +461,9 @@ void EditorAssetLibraryItemDownload::_install() { } void EditorAssetLibraryItemDownload::_make_request() { + // Hide the Retry button if we've just pressed it. + retry->hide(); + download->cancel_request(); download->set_download_file(EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); @@ -516,6 +521,8 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() { retry = memnew(Button); retry->set_text(TTR("Retry")); retry->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_make_request)); + // Only show the Retry button in case of a failure. + retry->hide(); hb2->add_child(retry); hb2->add_child(install); @@ -577,6 +584,24 @@ void EditorAssetLibrary::_notification(int p_what) { filter->set_right_icon(get_theme_icon("Search", "EditorIcons")); filter->set_clear_button_enabled(true); } break; + + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + _update_repository_options(); + } break; + } +} + +void EditorAssetLibrary::_update_repository_options() { + Dictionary default_urls; + default_urls["godotengine.org"] = "https://godotengine.org/asset-library/api"; + default_urls["localhost"] = "http://127.0.0.1/asset-library/api"; + Dictionary available_urls = _EDITOR_DEF("asset_library/available_urls", default_urls, true); + repository->clear(); + Array keys = available_urls.keys(); + for (int i = 0; i < available_urls.size(); i++) { + String key = keys[i]; + repository->add_item(key); + repository->set_item_metadata(i, available_urls[key]); } } @@ -702,7 +727,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PackedB } } - if (!image->empty()) { + if (!image->is_empty()) { switch (image_queue[p_queue_id].image_type) { case IMAGE_QUEUE_ICON: @@ -900,7 +925,7 @@ void EditorAssetLibrary::_search(int p_page) { } if (filter->get_text() != String()) { - args += "&filter=" + filter->get_text().http_escape(); + args += "&filter=" + filter->get_text().uri_encode(); } if (p_page > 0) { @@ -962,14 +987,16 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int for (int i = from; i < to; i++) { if (i == p_page) { Button *current = memnew(Button); - current->set_text(itos(i + 1)); + // Keep the extended padding for the currently active page (see below). + current->set_text(vformat(" %d ", i + 1)); current->set_disabled(true); current->set_focus_mode(Control::FOCUS_NONE); hbc->add_child(current); } else { Button *current = memnew(Button); - current->set_text(itos(i + 1)); + // Add padding to make page number buttons easier to click. + current->set_text(vformat(" %d ", i + 1)); current->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(i)); hbc->add_child(current); @@ -1151,7 +1178,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const asset_bottom_page = _make_pages(page, pages, page_len, total_items, result.size()); library_vb->add_child(asset_bottom_page); - if (result.empty()) { + if (result.is_empty()) { if (filter->get_text() != String()) { library_error->set_text( vformat(TTR("No results for \"%s\"."), filter->get_text())); @@ -1188,7 +1215,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const } } - if (!result.empty()) { + if (!result.is_empty()) { library_scroll->set_v_scroll(0); } } break; @@ -1364,10 +1391,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { search_hb2->add_child(memnew(Label(TTR("Site:") + " "))); repository = memnew(OptionButton); - repository->add_item("godotengine.org"); - repository->set_item_metadata(0, "https://godotengine.org/asset-library/api"); - repository->add_item("localhost"); - repository->set_item_metadata(1, "http://127.0.0.1/asset-library/api"); + _update_repository_options(); repository->connect("item_selected", callable_mp(this, &EditorAssetLibrary::_repository_changed)); @@ -1379,6 +1403,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { support = memnew(MenuButton); search_hb2->add_child(support); support->set_text(TTR("Support")); + support->get_popup()->set_hide_on_checkable_item_selection(false); support->get_popup()->add_check_item(TTR("Official"), SUPPORT_OFFICIAL); support->get_popup()->add_check_item(TTR("Community"), SUPPORT_COMMUNITY); support->get_popup()->add_check_item(TTR("Testing"), SUPPORT_TESTING); @@ -1492,7 +1517,7 @@ AssetLibraryEditorPlugin::AssetLibraryEditorPlugin(EditorNode *p_node) { editor = p_node; addon_library = memnew(EditorAssetLibrary); addon_library->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor->get_viewport()->add_child(addon_library); + editor->get_main_control()->add_child(addon_library); addon_library->set_anchors_and_offsets_preset(Control::PRESET_WIDE); addon_library->hide(); } diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index b69dfc208e..11eae9e041 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -176,6 +176,7 @@ class EditorAssetLibrary : public PanelContainer { void _asset_open(); void _asset_file_selected(const String &p_file); + void _update_repository_options(); PanelContainer *library_scroll_bg; ScrollContainer *library_scroll; diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 5041cf9f32..3553450672 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -96,7 +96,7 @@ void AudioStreamEditor::_preview_changed(ObjectID p_which) { } } -void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void AudioStreamEditor::_audio_changed() { if (!is_visible()) { return; } @@ -105,6 +105,8 @@ void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) void AudioStreamEditor::_play() { if (_player->is_playing()) { + // '_pausing' variable indicates that we want to pause the audio player, not stop it. See '_on_finished()'. + _pausing = true; _player->stop(); _play_button->set_icon(get_theme_icon("MainPlay", "EditorIcons")); set_process(false); @@ -125,10 +127,13 @@ void AudioStreamEditor::_stop() { void AudioStreamEditor::_on_finished() { _play_button->set_icon(get_theme_icon("MainPlay", "EditorIcons")); - if (_current == _player->get_stream()->get_length()) { + if (!_pausing) { _current = 0; _indicator->update(); + } else { + _pausing = false; } + set_process(false); } void AudioStreamEditor::_draw_indicator() { @@ -172,7 +177,7 @@ void AudioStreamEditor::_seek_to(real_t p_x) { void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { if (!stream.is_null()) { - stream->remove_change_receptor(this); + stream->disconnect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); } stream = p_stream; @@ -182,7 +187,7 @@ void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { _duration_label->set_text(text); if (!stream.is_null()) { - stream->add_change_receptor(this); + stream->connect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); update(); } else { hide(); @@ -194,8 +199,6 @@ void AudioStreamEditor::_bind_methods() { AudioStreamEditor::AudioStreamEditor() { set_custom_minimum_size(Size2(1, 100) * EDSCALE); - _current = 0; - _dragging = false; _player = memnew(AudioStreamPlayer); _player->connect("finished", callable_mp(this, &AudioStreamEditor::_on_finished)); diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h index 5936b91fa1..14e829d025 100644 --- a/editor/plugins/audio_stream_editor_plugin.h +++ b/editor/plugins/audio_stream_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,17 +41,20 @@ class AudioStreamEditor : public ColorRect { GDCLASS(AudioStreamEditor, ColorRect); Ref<AudioStream> stream; - AudioStreamPlayer *_player; - ColorRect *_preview; - Control *_indicator; - Label *_current_label; - Label *_duration_label; + AudioStreamPlayer *_player = nullptr; + ColorRect *_preview = nullptr; + Control *_indicator = nullptr; + Label *_current_label = nullptr; + Label *_duration_label = nullptr; - Button *_play_button; - Button *_stop_button; + Button *_play_button = nullptr; + Button *_stop_button = nullptr; - float _current; - bool _dragging; + float _current = 0; + bool _dragging = false; + bool _pausing = false; + + void _audio_changed(); protected: void _notification(int p_what); @@ -63,7 +66,6 @@ protected: void _draw_indicator(); void _on_input_indicator(Ref<InputEvent> p_event); void _seek_to(real_t p_x); - void _changed_callback(Object *p_changed, const char *p_prop) override; static void _bind_methods(); public: diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp index e5d4e4a761..470b61bf40 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.cpp +++ b/editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h index b4c7c07562..d291c377d9 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.h +++ b/editor/plugins/baked_lightmap_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/camera_3d_editor_plugin.cpp b/editor/plugins/camera_3d_editor_plugin.cpp index 9a5cfd35cd..8583e95b25 100644 --- a/editor/plugins/camera_3d_editor_plugin.cpp +++ b/editor/plugins/camera_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -98,7 +98,7 @@ void Camera3DEditorPlugin::make_visible(bool p_visible) { Camera3DEditorPlugin::Camera3DEditorPlugin(EditorNode *p_node) { editor = p_node; /* camera_editor = memnew( CameraEditor ); - editor->get_viewport()->add_child(camera_editor); + editor->get_main_control()->add_child(camera_editor); camera_editor->set_anchor(SIDE_LEFT,Control::ANCHOR_END); camera_editor->set_anchor(SIDE_RIGHT,Control::ANCHOR_END); diff --git a/editor/plugins/camera_3d_editor_plugin.h b/editor/plugins/camera_3d_editor_plugin.h index 023f1866df..e087dd22a8 100644 --- a/editor/plugins/camera_3d_editor_plugin.h +++ b/editor/plugins/camera_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 5073cbd0b9..d4e06aa9ca 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -216,8 +216,8 @@ public: grid_step_x->set_value(p_grid_step.x); grid_step_y->set_value(p_grid_step.y); primary_grid_steps->set_value(p_primary_grid_steps); - rotation_offset->set_value(p_rotation_offset * (180 / Math_PI)); - rotation_step->set_value(p_rotation_step * (180 / Math_PI)); + rotation_offset->set_value(Math::rad2deg(p_rotation_offset)); + rotation_step->set_value(Math::rad2deg(p_rotation_step)); scale_step->set_value(p_scale_step); } @@ -225,8 +225,8 @@ public: p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value()); p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value()); p_primary_grid_steps = int(primary_grid_steps->get_value()); - p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI); - p_rotation_step = rotation_step->get_value() / (180 / Math_PI); + p_rotation_offset = Math::deg2rad(rotation_offset->get_value()); + p_rotation_step = Math::deg2rad(rotation_step->get_value()); p_scale_step = scale_step->get_value(); } }; @@ -444,8 +444,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig } } Point2 grid_output; - grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x; - grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y; + grid_output.x = Math::snapped(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x; + grid_output.y = Math::snapped(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y; _snap_if_closer_point(p_target, output, snap_target, grid_output, SNAP_TARGET_GRID, 0.0, -1.0); } @@ -462,9 +462,9 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig float CanvasItemEditor::snap_angle(float p_target, float p_start) const { if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) { if (snap_relative) { - return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step); + return Math::snapped(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step); } else { - return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset; + return Math::snapped(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset; } } else { return p_target; @@ -518,7 +518,7 @@ void CanvasItemEditor::_keying_changed() { } Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_list) { - ERR_FAIL_COND_V(p_list.empty(), Rect2()); + ERR_FAIL_COND_V(p_list.is_empty(), Rect2()); // Handles the first element CanvasItem *canvas_item = p_list.front()->get(); @@ -629,9 +629,9 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel Node *node = r_items[i].item; // Make sure the selected node is in the current scene, or editable - while (node && node != get_tree()->get_edited_scene_root() && node->get_owner() != scene && !scene->is_editable_instance(node->get_owner())) { - node = node->get_parent(); - }; + if (node && node != get_tree()->get_edited_scene_root()) { + node = scene->get_deepest_editable_node(node); + } CanvasItem *canvas_item = Object::cast_to<CanvasItem>(node); if (!p_allow_locked) { @@ -727,7 +727,7 @@ bool CanvasItemEditor::_get_bone_shape(Vector<Vector2> *shape, Vector<Vector2> * } Vector2 rel = to - from; - Vector2 relt = rel.tangent().normalized() * bone_width; + Vector2 relt = rel.orthogonal().normalized() * bone_width; Vector2 reln = rel.normalized(); Vector2 reltn = relt.normalized(); @@ -762,7 +762,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); Node *scene = editor->get_edited_scene(); - bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner()); + bool editable = p_node == scene || p_node->get_owner() == scene || p_node == scene->get_deepest_editable_node(p_node); bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); bool locked = _is_node_locked(p_node); @@ -955,25 +955,44 @@ void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_it for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - canvas_item->_edit_set_state(se->undo_state); - if (restore_bones) { - _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state)); + if (se) { + canvas_item->_edit_set_state(se->undo_state); + if (restore_bones) { + _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state)); + } } } } void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones) { - undo_redo->create_action(action_name); + List<CanvasItem *> modified_canvas_items; for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); + Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item)->undo_state; + Dictionary new_state = canvas_item->_edit_get_state(); + + if (old_state.hash() != new_state.hash()) { + modified_canvas_items.push_back(canvas_item); + } + } + + if (modified_canvas_items.is_empty()) { + return; + } + + undo_redo->create_action(action_name); + for (List<CanvasItem *>::Element *E = modified_canvas_items.front(); E; E = E->next()) { + CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); - undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state); - if (commit_bones) { - for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) { - canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); - undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); - undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get()); + if (se) { + undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); + undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state); + if (commit_bones) { + for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) { + canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); + undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); + undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get()); + } } } } @@ -1006,6 +1025,32 @@ void CanvasItemEditor::_selection_menu_hide() { selection_menu->set_size(Vector2(0, 0)); } +void CanvasItemEditor::_add_node_pressed(int p_result) { + if (p_result == AddNodeOption::ADD_NODE) { + editor->get_scene_tree_dock()->open_add_child_dialog(); + } else if (p_result == AddNodeOption::ADD_INSTANCE) { + editor->get_scene_tree_dock()->open_instance_child_dialog(); + } +} + +void CanvasItemEditor::_node_created(Node *p_node) { + if (node_create_position == Point2()) { + return; + } + + CanvasItem *c = Object::cast_to<CanvasItem>(p_node); + if (c) { + Transform2D xform = c->get_global_transform_with_canvas().affine_inverse() * c->get_transform(); + c->_edit_set_position(xform.xform(node_create_position)); + } + + call_deferred("_reset_create_position"); // Defer the call in case more than one node is added. +} + +void CanvasItemEditor::_reset_create_position() { + node_create_position = Point2(); +} + bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; @@ -1050,7 +1095,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve } // Start dragging a guide - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed()) { // Press button if (b->get_position().x < RULER_WIDTH && b->get_position().y < RULER_WIDTH) { // Drag a new double guide @@ -1109,7 +1154,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve } // Release confirms the guide move - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed()) { if (show_guides && EditorNode::get_singleton()->get_edited_scene()) { Transform2D xform = viewport_scrollable->get_transform() * transform; @@ -1147,7 +1192,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve if (dragged_guide_index >= 0) { vguides.remove(dragged_guide_index); undo_redo->create_action(TTR("Remove Vertical Guide")); - if (vguides.empty()) { + if (vguides.is_empty()) { undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_vertical_guides_"); } else { undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); @@ -1180,7 +1225,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve if (dragged_guide_index >= 0) { hguides.remove(dragged_guide_index); undo_redo->create_action(TTR("Remove Horizontal Guide")); - if (hguides.empty()) { + if (hguides.is_empty()) { undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_horizontal_guides_"); } else { undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); @@ -1223,7 +1268,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo if (pan_on_scroll) { // Perform horizontal scrolling first so we can check for Shift being held. if (b->is_pressed() && - (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_shift() && b->get_button_index() == BUTTON_WHEEL_UP))) { + (b->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT || (b->get_shift() && b->get_button_index() == MOUSE_BUTTON_WHEEL_UP))) { // Pan left view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); update_viewport(); @@ -1231,7 +1276,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo } if (b->is_pressed() && - (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_shift() && b->get_button_index() == BUTTON_WHEEL_DOWN))) { + (b->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT || (b->get_shift() && b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN))) { // Pan right view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); update_viewport(); @@ -1239,7 +1284,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo } } - if (b->is_pressed() && b->get_button_index() == BUTTON_WHEEL_DOWN) { + if (b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { // Scroll or pan down if (pan_on_scroll) { view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); @@ -1254,7 +1299,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo return true; } - if (b->is_pressed() && b->get_button_index() == BUTTON_WHEEL_UP) { + if (b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { // Scroll or pan up if (pan_on_scroll) { view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); @@ -1271,17 +1316,17 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo if (!panning) { if (b->is_pressed() && - (b->get_button_index() == BUTTON_MIDDLE || - b->get_button_index() == BUTTON_RIGHT || - (b->get_button_index() == BUTTON_LEFT && tool == TOOL_PAN) || - (b->get_button_index() == BUTTON_LEFT && !EditorSettings::get_singleton()->get("editors/2d/simple_panning") && pan_pressed))) { + (b->get_button_index() == MOUSE_BUTTON_MIDDLE || + b->get_button_index() == MOUSE_BUTTON_RIGHT || + (b->get_button_index() == MOUSE_BUTTON_LEFT && tool == TOOL_PAN) || + (b->get_button_index() == MOUSE_BUTTON_LEFT && !EditorSettings::get_singleton()->get("editors/2d/simple_panning") && pan_pressed))) { // Pan the viewport panning = true; } } if (panning) { - if (!b->is_pressed() && (pan_on_scroll || (b->get_button_index() != BUTTON_WHEEL_DOWN && b->get_button_index() != BUTTON_WHEEL_UP))) { + if (!b->is_pressed() && (pan_on_scroll || (b->get_button_index() != MOUSE_BUTTON_WHEEL_DOWN && b->get_button_index() != MOUSE_BUTTON_WHEEL_UP))) { // Stop panning the viewport (for any mouse button press except zooming) panning = false; } @@ -1367,7 +1412,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { // Drag the pivot (in pivot mode / with V key) if (drag_type == DRAG_NONE) { - if ((b.is_valid() && b->is_pressed() && b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || + if ((b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_V)) { List<CanvasItem *> selection = _get_edited_canvas_items(); @@ -1421,7 +1466,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { // Confirm the pivot move if (drag_selection.size() >= 1 && - ((b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || + ((b.is_valid() && !b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || (k.is_valid() && !k->is_pressed() && k->get_keycode() == KEY_V))) { _commit_canvas_item_state( drag_selection, @@ -1435,7 +1480,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { } // Cancel a drag - if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); drag_type = DRAG_NONE; viewport->update(); @@ -1521,7 +1566,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { // Start rotation if (drag_type == DRAG_NONE) { - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed()) { if ((b->get_command() && !b->get_alt() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) { List<CanvasItem *> selection = _get_edited_canvas_items(); @@ -1565,7 +1610,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { } // Confirms the node rotation - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed()) { if (drag_selection.size() != 1) { _commit_canvas_item_state( drag_selection, @@ -1589,7 +1634,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { } // Cancel a drag - if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); drag_type = DRAG_NONE; viewport->update(); @@ -1603,7 +1648,7 @@ bool CanvasItemEditor::_gui_input_open_scene_on_double_click(const Ref<InputEven Ref<InputEventMouseButton> b = p_event; // Open a sub-scene on double-click - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && b->is_doubleclick() && tool == TOOL_SELECT) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && b->is_doubleclick() && tool == TOOL_SELECT) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { CanvasItem *canvas_item = selection[0]; @@ -1622,7 +1667,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { // Starts anchor dragging if needed if (drag_type == DRAG_NONE) { - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { Control *control = Object::cast_to<Control>(selection[0]); @@ -1742,7 +1787,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { } // Confirms new anchor position - if (drag_selection.size() >= 1 && b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + if (drag_selection.size() >= 1 && b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed()) { _commit_canvas_item_state( drag_selection, vformat(TTR("Move CanvasItem \"%s\" Anchor"), drag_selection[0]->get_name())); @@ -1751,7 +1796,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { } // Cancel a drag - if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); drag_type = DRAG_NONE; viewport->update(); @@ -1767,7 +1812,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { // Drag resize handles if (drag_type == DRAG_NONE) { - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { CanvasItem *canvas_item = selection[0]; @@ -1808,7 +1853,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { } ofs = (endpoints[i] + endpoints[next]) / 2; - ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2); + ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2); if (ofs.distance_to(b->get_position()) < radius) { resize_drag = dragger[i * 2 + 1]; } @@ -1921,7 +1966,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { } // Confirm resize - if (drag_selection.size() >= 1 && b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + if (drag_selection.size() >= 1 && b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed()) { const Node2D *node2d = Object::cast_to<Node2D>(drag_selection[0]); if (node2d) { // Extends from Node2D. @@ -1931,8 +1976,8 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { vformat( TTR("Scale Node2D \"%s\" to (%s, %s)"), drag_selection[0]->get_name(), - Math::stepify(drag_selection[0]->_edit_get_scale().x, 0.01), - Math::stepify(drag_selection[0]->_edit_get_scale().y, 0.01)), + Math::snapped(drag_selection[0]->_edit_get_scale().x, 0.01), + Math::snapped(drag_selection[0]->_edit_get_scale().y, 0.01)), true); } else { // Extends from Control. @@ -1958,7 +2003,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { } // Cancel a drag - if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; @@ -1976,7 +2021,7 @@ 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() == BUTTON_LEFT && b->is_pressed() && ((b->get_alt() && b->get_control()) || tool == TOOL_SCALE)) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && ((b->get_alt() && b->get_control()) || tool == TOOL_SCALE)) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { CanvasItem *canvas_item = selection[0]; @@ -2072,7 +2117,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { } // Confirm resize - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed()) { if (drag_selection.size() != 1) { _commit_canvas_item_state( drag_selection, @@ -2083,8 +2128,8 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { drag_selection, vformat(TTR("Scale CanvasItem \"%s\" to (%s, %s)"), drag_selection[0]->get_name(), - Math::stepify(drag_selection[0]->_edit_get_scale().x, 0.01), - Math::stepify(drag_selection[0]->_edit_get_scale().y, 0.01)), + Math::snapped(drag_selection[0]->_edit_get_scale().x, 0.01), + Math::snapped(drag_selection[0]->_edit_get_scale().y, 0.01)), true); } if (key_auto_insert_button->is_pressed()) { @@ -2097,7 +2142,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { } // Cancel a drag - if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); drag_type = DRAG_NONE; viewport->update(); @@ -2114,7 +2159,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() == BUTTON_LEFT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed()) { if ((b->get_alt() && !b->get_control()) || tool == TOOL_MOVE) { List<CanvasItem *> selection = _get_edited_canvas_items(); @@ -2197,17 +2242,19 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - - Node2D *node2d = Object::cast_to<Node2D>(canvas_item); - if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) { - real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); - real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); - _solve_IK(node2d, new_pos); - } else { - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); + if (se) { + Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); + + Node2D *node2d = Object::cast_to<Node2D>(canvas_item); + if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) { + real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); + real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); + _solve_IK(node2d, new_pos); + } else { + canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); + } } index++; } @@ -2215,7 +2262,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } // Confirm the move (only if it was moved) - if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT) { + if (b.is_valid() && !b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_LEFT) { if (transform.affine_inverse().xform(b->get_position()) != drag_from) { if (drag_selection.size() != 1) { _commit_canvas_item_state( @@ -2248,7 +2295,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } // Cancel a drag - if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection, true); snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; @@ -2331,17 +2378,19 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - - Node2D *node2d = Object::cast_to<Node2D>(canvas_item); - if (node2d && se->pre_drag_bones_undo_state.size() > 0) { - real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); - real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); - _solve_IK(node2d, new_pos); - } else { - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); + if (se) { + Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); + + Node2D *node2d = Object::cast_to<Node2D>(canvas_item); + if (node2d && se->pre_drag_bones_undo_state.size() > 0) { + real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); + real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); + node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); + _solve_IK(node2d, new_pos); + } else { + canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); + } } index++; } @@ -2386,8 +2435,8 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_NONE) { if (b.is_valid() && - ((b->get_button_index() == BUTTON_RIGHT && b->get_alt() && tool == TOOL_SELECT) || - (b->get_button_index() == BUTTON_LEFT && tool == TOOL_LIST_SELECT))) { + ((b->get_button_index() == MOUSE_BUTTON_RIGHT && b->get_alt() && tool == TOOL_SELECT) || + (b->get_button_index() == MOUSE_BUTTON_LEFT && tool == TOOL_LIST_SELECT))) { // Popup the selection menu list Point2 click = transform.affine_inverse().xform(b->get_position()); @@ -2400,7 +2449,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { _select_click_on_item(item, click, b->get_shift()); return true; - } else if (!selection_results.empty()) { + } else if (!selection_results.is_empty()) { // Sorts items according the their z-index selection_results.sort(); @@ -2448,7 +2497,15 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } } - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { + if (b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->get_control()) { + add_node_menu->set_position(get_global_transform().xform(get_local_mouse_position())); + add_node_menu->set_size(Vector2(1, 1)); + add_node_menu->popup(); + node_create_position = transform.affine_inverse().xform((get_local_mouse_position())); + return true; + } + + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { // Single item selection Point2 click = transform.affine_inverse().xform(b->get_position()); @@ -2463,13 +2520,13 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Retrieve the bones Vector<_SelectResult> selection = Vector<_SelectResult>(); _get_bones_at_pos(click, selection); - if (!selection.empty()) { + if (!selection.is_empty()) { canvas_item = selection[0].item; } else { // Retrieve the canvas items selection = Vector<_SelectResult>(); _get_canvas_items_at_pos(click, selection); - if (!selection.empty()) { + if (!selection.is_empty()) { canvas_item = selection[0].item; } } @@ -2514,7 +2571,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } if (drag_type == DRAG_BOX_SELECTION) { - if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT) { + if (b.is_valid() && !b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_LEFT) { // Confirms box selection Node *scene = editor->get_edited_scene(); if (scene) { @@ -2540,7 +2597,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { return true; } - if (b.is_valid() && b->is_pressed() && b->get_button_index() == BUTTON_RIGHT) { + if (b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT) { // Cancel box selection drag_type = DRAG_NONE; viewport->update(); @@ -2565,6 +2622,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) { if (tool != TOOL_RULER) { + ruler_tool_active = false; return false; } @@ -2576,7 +2634,7 @@ bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) { ruler_tool_origin = snap_point(viewport->get_local_mouse_position() / zoom + view_offset); } - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT) { if (b->is_pressed()) { ruler_tool_active = true; } else { @@ -2853,21 +2911,22 @@ void CanvasItemEditor::_draw_guides() { // Dragged guide Color text_color = get_theme_color("font_color", "Editor"); - text_color.a = 0.5; + Color outline_color = text_color.inverted(); + const float outline_size = 2; if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) { String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x))); - Ref<Font> font = get_theme_font("font", "Label"); - int font_size = get_theme_font_size("font_size", "Label"); + Ref<Font> font = get_theme_font("bold", "EditorFonts"); + int font_size = get_theme_font_size("bold_size", "EditorFonts"); Size2 text_size = font->get_string_size(str, font_size); - viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color); + viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, outline_size, outline_color); viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) { String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y))); - Ref<Font> font = get_theme_font("font", "Label"); - int font_size = get_theme_font_size("font_size", "Label"); + Ref<Font> font = get_theme_font("bold", "EditorFonts"); + int font_size = get_theme_font_size("bold_size", "EditorFonts"); Size2 text_size = font->get_string_size(str, font_size); - viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color); + viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, outline_size, outline_color); viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE)); } } @@ -3134,16 +3193,16 @@ void CanvasItemEditor::_draw_ruler_tool() { float arc_1_start_angle = end_to_begin.x < 0 ? - (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) : - (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad); + (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) : + (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad); float arc_1_end_angle = arc_1_start_angle + vertical_angle_rad; // Constrain arc to triangle height & max size float arc_1_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.y)), arc_max_radius); float arc_2_start_angle = end_to_begin.x < 0 ? - (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) : - (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI); + (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) : + (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI); float arc_2_end_angle = arc_2_start_angle + horizontal_angle_rad; // Constrain arc to triangle width & max size float arc_2_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.x)), arc_max_radius); @@ -3498,7 +3557,7 @@ void CanvasItemEditor::_draw_selection() { select_handle->draw(ci, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor()); ofs = (endpoints[i] + endpoints[next]) / 2; - ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2); + ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2); select_handle->draw(ci, (ofs - (select_handle->get_size() / 2)).floor()); } @@ -3852,7 +3911,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) { CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); Node *scene = editor->get_edited_scene(); - if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner()))) { + if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && canvas_item != scene->get_deepest_editable_node(canvas_item))) { return false; } @@ -3916,7 +3975,7 @@ void CanvasItemEditor::_draw_viewport() { bool all_locked = true; bool all_group = true; List<Node *> selection = editor_selection->get_selected_node_list(); - if (selection.empty()) { + if (selection.is_empty()) { all_locked = false; all_group = false; } else { @@ -3935,10 +3994,10 @@ void CanvasItemEditor::_draw_viewport() { } lock_button->set_visible(!all_locked); - lock_button->set_disabled(selection.empty()); + lock_button->set_disabled(selection.is_empty()); unlock_button->set_visible(all_locked); group_button->set_visible(!all_group); - group_button->set_disabled(selection.empty()); + group_button->set_disabled(selection.is_empty()); ungroup_button->set_visible(all_group); info_overlay->set_offset(SIDE_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10); @@ -3956,11 +4015,11 @@ void CanvasItemEditor::_draw_viewport() { RenderingServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D()); EditorPluginList *over_plugin_list = editor->get_editor_plugins_over(); - if (!over_plugin_list->empty()) { + if (!over_plugin_list->is_empty()) { over_plugin_list->forward_canvas_draw_over_viewport(viewport); } EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over(); - if (!force_over_plugin_list->empty()) { + if (!force_over_plugin_list->is_empty()) { force_over_plugin_list->forward_canvas_force_draw_over_viewport(viewport); } @@ -4148,7 +4207,7 @@ void CanvasItemEditor::_notification(int p_what) { // the icon will be dark, so we need to lighten it before blending it // with the red color. const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25); - key_auto_insert_button->add_theme_color_override("icon_color_pressed", key_auto_color.lerp(Color(1, 0, 0), 0.55)); + key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55)); animation_menu->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons")); zoom_minus->set_icon(get_theme_icon("ZoomLess", "EditorIcons")); @@ -4446,7 +4505,7 @@ void CanvasItemEditor::_set_anchors_and_offsets_preset(Control::LayoutPreset p_p case PRESET_CENTER_RIGHT: case PRESET_CENTER_BOTTOM: case PRESET_CENTER: - undo_redo->add_do_method(control, "set_margins_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE); + undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE); break; case PRESET_LEFT_WIDE: case PRESET_TOP_WIDE: @@ -4455,7 +4514,7 @@ void CanvasItemEditor::_set_anchors_and_offsets_preset(Control::LayoutPreset p_p case PRESET_VCENTER_WIDE: case PRESET_HCENTER_WIDE: case PRESET_WIDE: - undo_redo->add_do_method(control, "set_margins_preset", p_preset, Control::PRESET_MODE_MINSIZE); + undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_MINSIZE); break; } undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state()); @@ -4576,7 +4635,7 @@ void CanvasItemEditor::_update_zoom_label() { // Don't show a decimal when the zoom level is higher than 1000 %. zoom_text = TS->format_number(rtos(Math::round((zoom / MAX(1, EDSCALE)) * 100))) + " " + TS->percent_sign(); } else { - zoom_text = TS->format_number(rtos(Math::stepify((zoom / MAX(1, EDSCALE)) * 100, 0.1))) + " " + TS->percent_sign(); + zoom_text = TS->format_number(rtos(Math::snapped((zoom / MAX(1, EDSCALE)) * 100, 0.1))) + " " + TS->percent_sign(); } zoom_reset->set_text(zoom_text); @@ -5348,6 +5407,7 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input); ClassDB::bind_method("_queue_update_bone_list", &CanvasItemEditor::_update_bone_list); ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list); + ClassDB::bind_method("_reset_create_position", &CanvasItemEditor::_reset_create_position); ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state); ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport); @@ -5623,7 +5683,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { primary_grid_steps = 8; // A power-of-two value works better as a default grid_step_multiplier = 0; snap_rotation_offset = 0; - snap_rotation_step = 15 / (180 / Math_PI); + snap_rotation_step = Math::deg2rad(15.0); snap_scale_step = 0.1f; smart_snap_active = false; grid_snap_active = false; @@ -5669,6 +5729,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed)); + editor->get_scene_tree_dock()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); + editor->get_scene_tree_dock()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); + editor->call_deferred("connect", "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true)); editor->call_deferred("connect", "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false)); @@ -5764,7 +5827,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_reset->set_flat(true); zoom_hb->add_child(zoom_reset); zoom_reset->add_theme_constant_override("outline_size", 1); - zoom_reset->add_theme_color_override("font_outline_modulate", Color(0, 0, 0)); + zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0)); zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1)); zoom_reset->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_zoom_reset)); zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0)); @@ -6090,6 +6153,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed)); selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide)); + add_node_menu = memnew(PopupMenu); + add_child(add_node_menu); + add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Add", "EditorIcons"), TTR("Add Node Here")); + add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Instance", "EditorIcons"), TTR("Instance Scene Here")); + add_node_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_add_node_pressed)); + multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY); divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE); pan_view_shortcut = ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), KEY_SPACE); @@ -6139,7 +6208,7 @@ CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) { editor = p_node; canvas_item_editor = memnew(CanvasItemEditor(editor)); canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor->get_viewport()->add_child(canvas_item_editor); + editor->get_main_control()->add_child(canvas_item_editor); canvas_item_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE); canvas_item_editor->hide(); } @@ -6598,7 +6667,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte } label = memnew(Label); - label->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 1)); + label->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 1)); label->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE); label->hide(); canvas_item_editor->get_controls_container()->add_child(label); @@ -6606,7 +6675,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte label_desc = memnew(Label); label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type")); label_desc->add_theme_color_override("font_color", Color(0.6f, 0.6f, 0.6f, 1)); - label_desc->add_theme_color_override("font_color_shadow", Color(0.2f, 0.2f, 0.2f, 1)); + label_desc->add_theme_color_override("font_shadow_color", Color(0.2f, 0.2f, 0.2f, 1)); label_desc->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE); label_desc->add_theme_constant_override("line_spacing", 0); label_desc->hide(); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index f5da953810..62a9b1e162 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -79,6 +79,11 @@ public: TOOL_MAX }; + enum AddNodeOption { + ADD_NODE, + ADD_INSTANCE, + }; + private: EditorNode *editor; @@ -284,6 +289,7 @@ private: bool ruler_tool_active; Point2 ruler_tool_origin; + Point2 node_create_position; MenuOption last_option; @@ -376,6 +382,7 @@ private: Button *key_auto_insert_button; PopupMenu *selection_menu; + PopupMenu *add_node_menu; Control *top_ruler; Control *left_ruler; @@ -436,6 +443,9 @@ private: void _snap_changed(); void _selection_result_pressed(int); void _selection_menu_hide(); + void _add_node_pressed(int p_result); + void _node_created(Node *p_node); + void _reset_create_position(); UndoRedo *undo_redo; bool _build_bones_list(Node *p_node); diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp index 08d6fc966d..8e340b28ef 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h index 482f00a7f7..e78c486a39 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.h +++ b/editor/plugins/collision_polygon_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp index 6eb17685f6..b50a497ccf 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -142,7 +142,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con switch (mode) { case MODE_CREATE: { - if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) { if (!wip_active) { wip.clear(); wip.push_back(cpoint); @@ -166,14 +166,14 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con return true; } } - } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed() && wip_active) { _wip_close(); } } break; case MODE_EDIT: { - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { if (mb->get_control()) { if (poly.size() < 3) { @@ -267,7 +267,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con } } } - if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) { + if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) { int closest_idx = -1; Vector2 closest_pos; real_t closest_dist = 1e10; @@ -301,7 +301,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) { + if (edited_point != -1 && (wip_active || mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT)) { Vector2 gpoint = mm->get_position(); Vector3 ray_from = p_camera->project_ray_origin(gpoint); diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.h b/editor/plugins/collision_polygon_3d_editor_plugin.h index bb4ee2185e..c66518e3e5 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.h +++ b/editor/plugins/collision_polygon_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 23ab6a9de2..c38458c37f 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -98,7 +98,7 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const { Ref<RectangleShape2D> rect = node->get_shape(); if (idx < 3) { - return rect->get_extents().abs(); + return rect->get_size().abs(); } } break; @@ -179,13 +179,13 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { if (idx < 3) { Ref<RectangleShape2D> rect = node->get_shape(); - Vector2 extents = rect->get_extents(); + Vector2 size = rect->get_size(); if (idx == 2) { - extents = p_point; + size = p_point * 2; } else { - extents[idx] = p_point[idx]; + size[idx] = p_point[idx] * 2; } - rect->set_extents(extents.abs()); + rect->set_size(size.abs()); canvas_item_editor->update_viewport(); } @@ -207,7 +207,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } break; } - node->get_shape()->_change_notify(); + node->get_shape()->notify_property_list_changed(); } void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { @@ -279,9 +279,9 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { case RECTANGLE_SHAPE: { Ref<RectangleShape2D> rect = node->get_shape(); - undo_redo->add_do_method(rect.ptr(), "set_extents", rect->get_extents()); + undo_redo->add_do_method(rect.ptr(), "set_size", rect->get_size()); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); - undo_redo->add_undo_method(rect.ptr(), "set_extents", p_org); + undo_redo->add_undo_method(rect.ptr(), "set_size", p_org); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -325,7 +325,7 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e if (mb.is_valid()) { Vector2 gpoint = mb->get_position(); - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { for (int i = 0; i < handles.size(); i++) { if (xform.xform(handles[i]).distance_to(gpoint) < 8) { @@ -493,7 +493,7 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla Ref<RectangleShape2D> shape = node->get_shape(); handles.resize(3); - Vector2 ext = shape->get_extents(); + Vector2 ext = shape->get_size() / 2; handles.write[0] = Point2(ext.x, 0); handles.write[1] = Point2(0, ext.y); handles.write[2] = Point2(ext.x, ext.y); diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 083ceb4b38..054db1a61b 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index 32f7d02af2..3403aeceba 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.h b/editor/plugins/cpu_particles_2d_editor_plugin.h index 58984d6d16..b188df8e96 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.h +++ b/editor/plugins/cpu_particles_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp index d44e487ae4..f41ccfa86b 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -122,7 +122,7 @@ void CPUParticles3DEditorPlugin::make_visible(bool p_visible) { CPUParticles3DEditorPlugin::CPUParticles3DEditorPlugin(EditorNode *p_node) { editor = p_node; particles_editor = memnew(CPUParticles3DEditor); - editor->get_viewport()->add_child(particles_editor); + editor->get_main_control()->add_child(particles_editor); particles_editor->hide(); } diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.h b/editor/plugins/cpu_particles_3d_editor_plugin.h index d6886a24dc..9dced3ea86 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.h +++ b/editor/plugins/cpu_particles_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 4768cac217..db999f50ab 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -115,22 +115,22 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { } switch (mb.get_button_index()) { - case BUTTON_RIGHT: + case MOUSE_BUTTON_RIGHT: _context_click_pos = mpos; open_context_menu(get_global_transform().xform(mpos)); break; - case BUTTON_MIDDLE: + case MOUSE_BUTTON_MIDDLE: remove_point(_hover_point); break; - case BUTTON_LEFT: + case MOUSE_BUTTON_LEFT: _dragging = true; break; } } - if (!mb.is_pressed() && _dragging && mb.get_button_index() == BUTTON_LEFT) { + if (!mb.is_pressed() && _dragging && mb.get_button_index() == MOUSE_BUTTON_LEFT) { _dragging = false; if (_has_undo_data) { UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); @@ -353,8 +353,8 @@ void CurveEditor::open_context_menu(Vector2 pos) { _context_menu->add_check_item(TTR("Linear"), CONTEXT_LINEAR); bool is_linear = _selected_tangent == TANGENT_LEFT ? - _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR : - _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR; + _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR : + _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR; _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LINEAR), is_linear); diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index 2872f65730..2e8dd43d7e 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 0747e42045..1512e1817a 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h index c5ae4cd8a9..a6fab01c29 100644 --- a/editor/plugins/debugger_editor_plugin.h +++ b/editor/plugins/debugger_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/editor_debugger_plugin.cpp b/editor/plugins/editor_debugger_plugin.cpp index b775e871e2..85114d88ae 100644 --- a/editor/plugins/editor_debugger_plugin.cpp +++ b/editor/plugins/editor_debugger_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/editor_debugger_plugin.h b/editor/plugins/editor_debugger_plugin.h index 10fd1151de..b33a8ed925 100644 --- a/editor/plugins/editor_debugger_plugin.h +++ b/editor/plugins/editor_debugger_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 2fc0e35f82..eb3c06fba1 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -106,7 +106,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Siz } } - if (img.is_null() || img->empty()) { + if (img.is_null() || img->is_empty()) { return Ref<Texture2D>(); } @@ -150,7 +150,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const { Ref<Texture2D> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<Image> img = p_from; - if (img.is_null() || img->empty()) { + if (img.is_null() || img->is_empty()) { return Ref<Image>(); } @@ -301,7 +301,7 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() { ////////////////////////////////////////////////////////////////// void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) { - preview_done = true; + preview_done.set(); } void EditorMaterialPreviewPlugin::_bind_methods() { @@ -325,10 +325,10 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture - preview_done = false; + preview_done.clear(); RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant()); - while (!preview_done) { + while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); } @@ -382,7 +382,9 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { int lats = 32; int lons = 32; - float radius = 1.0; + const double lat_step = Math_TAU / lats; + const double lon_step = Math_TAU / lons; + real_t radius = 1.0; Vector<Vector3> vertices; Vector<Vector3> normals; @@ -391,20 +393,20 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { Basis tt = Basis(Vector3(0, 1, 0), Math_PI * 0.5); for (int i = 1; i <= lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); @@ -675,7 +677,7 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) { - preview_done = true; + preview_done.set(); } void EditorMeshPreviewPlugin::_bind_methods() { @@ -712,10 +714,10 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture - preview_done = false; + preview_done.clear(); RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant()); - while (!preview_done) { + while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); } @@ -790,7 +792,7 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// void EditorFontPreviewPlugin::_preview_done(const Variant &p_udata) { - preview_done = true; + preview_done.set(); } void EditorFontPreviewPlugin::_bind_methods() { @@ -881,11 +883,11 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, font->draw_string(canvas_item, pos, sample, HALIGN_LEFT, -1.f, 50, Color(1, 1, 1)); - preview_done = false; + preview_done.clear(); RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorFontPreviewPlugin *>(this), "_preview_done", Variant()); - while (!preview_done) { + while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); } diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 04e6be2354..6e8b9a34cf 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,8 @@ #include "editor/editor_resource_preview.h" +#include "core/templates/safe_refcount.h" + void post_process_preview(Ref<Image> p_image); class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { @@ -90,7 +92,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { RID light2; RID light_instance2; RID camera; - mutable volatile bool preview_done = false; + mutable SafeFlag preview_done; void _preview_done(const Variant &p_udata); @@ -134,7 +136,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { RID light2; RID light_instance2; RID camera; - mutable volatile bool preview_done = false; + mutable SafeFlag preview_done; void _preview_done(const Variant &p_udata); @@ -156,7 +158,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator { RID viewport_texture; RID canvas; RID canvas_item; - mutable volatile bool preview_done = false; + mutable SafeFlag preview_done; void _preview_done(const Variant &p_udata); diff --git a/editor/plugins/font_editor_plugin.cpp b/editor/plugins/font_editor_plugin.cpp index a82547182c..fa58eb5480 100644 --- a/editor/plugins/font_editor_plugin.cpp +++ b/editor/plugins/font_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -216,7 +216,7 @@ void FontDataEditor::init_script_edit() { void FontDataEditor::add_lang() { FontData *fd = Object::cast_to<FontData>(get_edited_object()); - if (fd != nullptr && !le->get_text().empty()) { + if (fd != nullptr && !le->get_text().is_empty()) { fd->set_language_support_override(le->get_text(), chk->is_pressed()); le->set_text(""); chk->set_pressed(false); diff --git a/editor/plugins/font_editor_plugin.h b/editor/plugins/font_editor_plugin.h index 1d3ffc8857..04e6c1dac7 100644 --- a/editor/plugins/font_editor_plugin.h +++ b/editor/plugins/font_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp index 2f5dd36ef1..f309c5da01 100644 --- a/editor/plugins/gi_probe_editor_plugin.cpp +++ b/editor/plugins/gi_probe_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h index 85d2b6f449..fdf0623561 100644 --- a/editor/plugins/gi_probe_editor_plugin.h +++ b/editor/plugins/gi_probe_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index d27df1d063..b447304a3f 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -81,7 +81,7 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) { cpu_particles->set_name(particles->get_name()); cpu_particles->set_transform(particles->get_transform()); cpu_particles->set_visible(particles->is_visible()); - cpu_particles->set_pause_mode(particles->get_pause_mode()); + cpu_particles->set_process_mode(particles->get_process_mode()); cpu_particles->set_z_index(particles->get_z_index()); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h index f3ca20b71a..0b2028b745 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.h +++ b/editor/plugins/gpu_particles_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index 0de52b3930..433a5ae51c 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -263,7 +263,7 @@ void GPUParticles3DEditor::_menu_option(int p_option) { cpu_particles->set_name(node->get_name()); cpu_particles->set_transform(node->get_transform()); cpu_particles->set_visible(node->is_visible()); - cpu_particles->set_pause_mode(node->get_pause_mode()); + cpu_particles->set_process_mode(node->get_process_mode()); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Convert to CPUParticles3D")); @@ -454,7 +454,7 @@ void GPUParticles3DEditorPlugin::make_visible(bool p_visible) { GPUParticles3DEditorPlugin::GPUParticles3DEditorPlugin(EditorNode *p_node) { editor = p_node; particles_editor = memnew(GPUParticles3DEditor); - editor->get_viewport()->add_child(particles_editor); + editor->get_main_control()->add_child(particles_editor); particles_editor->hide(); } diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h index ce376e4386..bd10895459 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.h +++ b/editor/plugins/gpu_particles_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp index 0288645f91..8c4928b7cb 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h index 0cdc70a62b..5a71fc44ef 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index 13b5c8cef5..46fa00f730 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index 4d3fc0d8a9..bcbb86e422 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index b4dcbdfe20..1ea6630622 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -145,7 +145,7 @@ int ItemListOptionButtonPlugin::get_flags() const { void ItemListOptionButtonPlugin::add_item() { ob->add_item(vformat(TTR("Item %d"), ob->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListOptionButtonPlugin::get_item_count() const { @@ -154,7 +154,7 @@ int ItemListOptionButtonPlugin::get_item_count() const { void ItemListOptionButtonPlugin::erase(int p_idx) { ob->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() { @@ -181,7 +181,7 @@ int ItemListPopupMenuPlugin::get_flags() const { void ItemListPopupMenuPlugin::add_item() { pp->add_item(vformat(TTR("Item %d"), pp->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListPopupMenuPlugin::get_item_count() const { @@ -190,7 +190,7 @@ int ItemListPopupMenuPlugin::get_item_count() const { void ItemListPopupMenuPlugin::erase(int p_idx) { pp->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() { @@ -213,7 +213,7 @@ int ItemListItemListPlugin::get_flags() const { void ItemListItemListPlugin::add_item() { pp->add_item(vformat(TTR("Item %d"), pp->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListItemListPlugin::get_item_count() const { @@ -222,7 +222,7 @@ int ItemListItemListPlugin::get_item_count() const { void ItemListItemListPlugin::erase(int p_idx) { pp->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListItemListPlugin::ItemListItemListPlugin() { diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h index fa5e802869..8c77f3d952 100644 --- a/editor/plugins/item_list_editor_plugin.h +++ b/editor/plugins/item_list_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index e422140efa..3d555d7eba 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h index e034a41ddc..eb1ce04788 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.h +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp index 77eeb19d26..08c5ef02a4 100644 --- a/editor/plugins/line_2d_editor_plugin.cpp +++ b/editor/plugins/line_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h index b3bc9df3a5..769109583a 100644 --- a/editor/plugins/line_2d_editor_plugin.h +++ b/editor/plugins/line_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index e45344b427..ad99ad7808 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 570ba9ae03..a4532b58b3 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 79dbf7d522..77719104b1 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,7 +34,7 @@ void MeshEditor::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { rot_x -= mm->get_relative().y * 0.01; rot_y -= mm->get_relative().x * 0.01; if (rot_x < -Math_PI / 2) { diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index 1fb0babb10..455fcb5fe9 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 2a08e3a8b5..0d2b2ea2f5 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,7 +63,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { List<Node *> selection = editor_selection->get_selected_node_list(); - if (selection.empty()) { + if (selection.is_empty()) { Ref<Shape3D> shape = mesh->create_trimesh_shape(); if (shape.is_null()) { err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape.")); @@ -505,7 +505,7 @@ void MeshInstance3DEditorPlugin::make_visible(bool p_visible) { MeshInstance3DEditorPlugin::MeshInstance3DEditorPlugin(EditorNode *p_node) { editor = p_node; mesh_editor = memnew(MeshInstance3DEditor); - editor->get_viewport()->add_child(mesh_editor); + editor->get_main_control()->add_child(mesh_editor); mesh_editor->options->hide(); } diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h index f42136942b..69f494de7f 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.h +++ b/editor/plugins/mesh_instance_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index fb34f4064a..f8932cd534 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -297,7 +297,7 @@ MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) { EDITOR_DEF("editors/grid_map/preview_size", 64); mesh_library_editor = memnew(MeshLibraryEditor(p_node)); - p_node->get_viewport()->add_child(mesh_library_editor); + p_node->get_main_control()->add_child(mesh_library_editor); mesh_library_editor->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE); mesh_library_editor->set_end(Point2(0, 22)); mesh_library_editor->hide(); diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h index fafbce9243..6c33c8bb9e 100644 --- a/editor/plugins/mesh_library_editor_plugin.h +++ b/editor/plugins/mesh_library_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 59ab622994..19c6dcf402 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -378,7 +378,7 @@ void MultiMeshEditorPlugin::make_visible(bool p_visible) { MultiMeshEditorPlugin::MultiMeshEditorPlugin(EditorNode *p_node) { editor = p_node; multimesh_editor = memnew(MultiMeshEditor); - editor->get_viewport()->add_child(multimesh_editor); + editor->get_main_control()->add_child(multimesh_editor); multimesh_editor->options->hide(); } diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h index 6a80fd4d16..2cdd7cf504 100644 --- a/editor/plugins/multimesh_editor_plugin.h +++ b/editor/plugins/multimesh_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 8cf9f01fa0..9971d3111d 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 3c5a7c2829..0f5928d416 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 610645eb9e..fccc042a02 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -48,6 +48,7 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/gui/center_container.h" #include "scene/gui/subviewport_container.h" #include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" @@ -185,7 +186,7 @@ void ViewportRotationControl::_get_sorted_axis(Vector<Axis2D> &r_axis) { void ViewportRotationControl::_gui_input(Ref<InputEvent> p_event) { const Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { Vector2 pos = mb->get_position(); if (mb->is_pressed()) { if (pos.distance_to(get_size() / 2.0) < get_size().x / 2.0) { @@ -535,8 +536,8 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b if (dist < closest_dist) { item = Object::cast_to<Node>(spat); - while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) { - item = item->get_owner(); + if (item != edited_scene) { + item = edited_scene->get_deepest_editable_node(item); } closest = item->get_instance_id(); @@ -612,7 +613,7 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_inclu results.push_back(res); } - if (results.empty()) { + if (results.is_empty()) { return; } @@ -697,8 +698,8 @@ void Node3DEditorViewport::_select_region() { } Node *item = Object::cast_to<Node>(sp); - while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) { - item = item->get_owner(); + if (item != edited_scene) { + item = edited_scene->get_deepest_editable_node(item); } // Replace the node by the group if grouped @@ -1027,7 +1028,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { for (int i = 0; i < selection_results.size(); i++) { Node3D *item = selection_results[i].item; - if (item != scene && item->get_owner() != scene && !scene->is_editable_instance(item->get_owner())) { + if (item != scene && item->get_owner() != scene && item != scene->get_deepest_editable_node(item)) { //invalid result selection_results.remove(i); i--; @@ -1045,7 +1046,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { clicked = ObjectID(); } - } else if (!selection_results.empty()) { + } else if (!selection_results.is_empty()) { NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); StringName root_name = root_path.get_name(root_path.get_name_count() - 1); @@ -1097,7 +1098,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { { EditorNode *en = editor; EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding(); - if (!force_input_forwarding_list->empty()) { + if (!force_input_forwarding_list->is_empty()) { bool discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true); if (discard) { return; @@ -1107,7 +1108,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { { EditorNode *en = editor; EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (!over_plugin_list->empty()) { + if (!over_plugin_list->is_empty()) { bool discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false); if (discard) { return; @@ -1122,23 +1123,21 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { float zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor(); switch (b->get_button_index()) { - case BUTTON_WHEEL_UP: { + case MOUSE_BUTTON_WHEEL_UP: { if (is_freelook_active()) { scale_freelook_speed(zoom_factor); } else { scale_cursor_distance(1.0 / zoom_factor); } } break; - - case BUTTON_WHEEL_DOWN: { + case MOUSE_BUTTON_WHEEL_DOWN: { if (is_freelook_active()) { scale_freelook_speed(1.0 / zoom_factor); } else { scale_cursor_distance(zoom_factor); } } break; - - case BUTTON_RIGHT: { + case MOUSE_BUTTON_RIGHT: { NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); if (b->is_pressed() && _edit.gizmo.is_valid()) { @@ -1199,7 +1198,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } break; - case BUTTON_MIDDLE: { + case MOUSE_BUTTON_MIDDLE: { if (b->is_pressed() && _edit.mode != TRANSFORM_NONE) { switch (_edit.plane) { case TRANSFORM_VIEW: { @@ -1230,7 +1229,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } } break; - case BUTTON_LEFT: { + case MOUSE_BUTTON_LEFT: { if (b->is_pressed()) { NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) { @@ -1439,7 +1438,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle); set_message(n + ": " + String(v)); - } else if (m->get_button_mask() & BUTTON_MASK_LEFT) { + } else if (m->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) { nav_mode = NAVIGATION_ORBIT; } else if (nav_scheme == NAVIGATION_MODO && m->get_alt() && m->get_shift()) { @@ -1829,8 +1828,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } } - - } else if ((m->get_button_mask() & BUTTON_MASK_RIGHT) || freelook_active) { + } else if ((m->get_button_mask() & MOUSE_BUTTON_MASK_RIGHT) || freelook_active) { if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) { nav_mode = NAVIGATION_ZOOM; } else if (freelook_active) { @@ -1839,10 +1837,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { nav_mode = NAVIGATION_PAN; } - } else if (m->get_button_mask() & BUTTON_MASK_MIDDLE) { + } else if (m->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE) { + const int mod = _get_key_modifier(m); if (nav_scheme == NAVIGATION_GODOT) { - const int mod = _get_key_modifier(m); - if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) { nav_mode = NAVIGATION_PAN; } else if (mod == _get_key_modifier_setting("editors/3d/navigation/zoom_modifier")) { @@ -1851,13 +1848,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { // Always allow Alt as a modifier to better support graphic tablets. nav_mode = NAVIGATION_ORBIT; } - } else if (nav_scheme == NAVIGATION_MAYA) { - if (m->get_alt()) { + if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) { nav_mode = NAVIGATION_PAN; } } - } else if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_3_button_mouse")) { // Handle trackpad (no external mouse) use case const int mod = _get_key_modifier(m); @@ -2210,8 +2205,8 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) { } void Node3DEditorViewport::scale_cursor_distance(real_t scale) { - real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); - real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + real_t min_distance = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN); + real_t max_distance = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX); if (unlikely(min_distance > max_distance)) { cursor.distance = (min_distance + max_distance) / 2; } else { @@ -2223,8 +2218,8 @@ void Node3DEditorViewport::scale_cursor_distance(real_t scale) { } void Node3DEditorViewport::scale_freelook_speed(real_t scale) { - real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); - real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + real_t min_speed = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN); + real_t max_speed = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX); if (unlikely(min_speed > max_speed)) { freelook_speed = (min_speed + max_speed) / 2; } else { @@ -2335,7 +2330,43 @@ void Node3DEditorPlugin::edited_scene_changed() { } } +void Node3DEditorViewport::_project_settings_changed() { + //update shadow atlas if changed + int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/size"); + bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/16_bits"); + int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_0_subdiv"); + int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_1_subdiv"); + int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_2_subdiv"); + int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_3_subdiv"); + + viewport->set_shadow_atlas_size(shadowmap_size); + viewport->set_shadow_atlas_16_bits(shadowmap_16_bits); + viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); + viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); + viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); + viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); + + bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); + + if (shrink != (subviewport_container->get_stretch_shrink() > 1)) { + subviewport_container->set_stretch_shrink(shrink ? 2 : 1); + } + + // Update MSAA, screen-space AA and debanding if changed + + const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/anti_aliasing/quality/msaa"); + viewport->set_msaa(Viewport::MSAA(msaa_mode)); + const int ssaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/screen_space_aa"); + viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + const bool use_debanding = GLOBAL_GET("rendering/anti_aliasing/quality/use_debanding"); + viewport->set_use_debanding(use_debanding); +} + void Node3DEditorViewport::_notification(int p_what) { + if (p_what == NOTIFICATION_READY) { + EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed)); + } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { bool visible = is_visible_in_tree(); @@ -2442,35 +2473,6 @@ void Node3DEditorViewport::_notification(int p_what) { } } - //update shadow atlas if changed - - int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size"); - int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv"); - int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv"); - int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv"); - int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv"); - - viewport->set_shadow_atlas_size(shadowmap_size); - viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); - viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); - viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); - viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); - - bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); - - if (shrink != (subviewport_container->get_stretch_shrink() > 1)) { - subviewport_container->set_stretch_shrink(shrink ? 2 : 1); - } - - // Update MSAA, screen-space AA and debanding if changed - - const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); - viewport->set_msaa(Viewport::MSAA(msaa_mode)); - const int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); - viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); - const bool use_debanding = GLOBAL_GET("rendering/quality/screen_filters/use_debanding"); - viewport->set_use_debanding(use_debanding); - bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); if (show_info != info_label->is_visible()) { info_label->set_visible(show_info); @@ -2491,6 +2493,13 @@ void Node3DEditorViewport::_notification(int p_what) { text += "Z: " + rtos(current_camera->get_translation().z).pad_decimals(1) + "\n"; text += TTR("Pitch") + ": " + itos(Math::round(current_camera->get_rotation_degrees().x)) + "\n"; text += TTR("Yaw") + ": " + itos(Math::round(current_camera->get_rotation_degrees().y)) + "\n\n"; + + text += TTR("Size") + + vformat( + ": %dx%d (%.1fMP)\n", + viewport->get_size().x, + viewport->get_size().y, + viewport->get_size().x * viewport->get_size().y * 0.000'001); text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n"; text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n"; text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n"; @@ -2505,6 +2514,8 @@ void Node3DEditorViewport::_notification(int p_what) { bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME)); if (show_fps != fps_label->is_visible()) { + cpu_time_label->set_visible(show_fps); + gpu_time_label->set_visible(show_fps); fps_label->set_visible(show_fps); RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps); for (int i = 0; i < FRAME_TIME_HISTORY; i++) { @@ -2531,12 +2542,28 @@ void Node3DEditorViewport::_notification(int p_what) { } gpu_time /= FRAME_TIME_HISTORY; - String text; - text += TTR("CPU Time") + ": " + String::num(cpu_time, 1) + " ms\n"; - text += TTR("GPU Time") + ": " + String::num(gpu_time, 1) + " ms\n"; - text += TTR("FPS") + ": " + itos(1000.0 / gpu_time); - - fps_label->set_text(text); + // Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red). + // Middle point is at 15 ms. + cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), String::num(cpu_time, 1))); + cpu_time_label->add_theme_color_override( + "font_color", + frame_time_gradient->get_color_at_offset( + Math::range_lerp(cpu_time, 0, 30, 0, 1))); + + gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), String::num(gpu_time, 1))); + // Middle point is at 15 ms. + gpu_time_label->add_theme_color_override( + "font_color", + frame_time_gradient->get_color_at_offset( + Math::range_lerp(gpu_time, 0, 30, 0, 1))); + + const float fps = 1000.0 / gpu_time; + fps_label->set_text(vformat(TTR("FPS: %d"), fps)); + // Middle point is at 60 FPS. + fps_label->add_theme_color_override( + "font_color", + frame_time_gradient->get_color_at_offset( + Math::range_lerp(fps, 110, 10, 0, 1))); } bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW)); @@ -2583,7 +2610,13 @@ void Node3DEditorViewport::_notification(int p_what) { preview_camera->add_theme_style_override("focus", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); preview_camera->add_theme_style_override("disabled", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); + frame_time_gradient->set_color(0, get_theme_color("success_color", "Editor")); + frame_time_gradient->set_color(1, get_theme_color("warning_color", "Editor")); + frame_time_gradient->set_color(2, get_theme_color("error_color", "Editor")); + info_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); + cpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); + gpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); fps_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); cinema_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); locked_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles")); @@ -2615,12 +2648,12 @@ static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2 void Node3DEditorViewport::_draw() { EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over(); - if (!over_plugin_list->empty()) { + if (!over_plugin_list->is_empty()) { over_plugin_list->forward_spatial_draw_over_viewport(surface); } EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over(); - if (!force_over_plugin_list->empty()) { + if (!force_over_plugin_list->is_empty()) { force_over_plugin_list->forward_spatial_force_draw_over_viewport(surface); } @@ -2674,7 +2707,8 @@ void Node3DEditorViewport::_draw() { break; } handle_color.a = 1.0; - handle_color *= Color(1.3, 1.3, 1.3, 1.0); + const float brightness = 1.3; + handle_color *= Color(brightness, brightness, brightness); RenderingServer::get_singleton()->canvas_item_add_line( ci, @@ -2714,8 +2748,8 @@ void Node3DEditorViewport::_draw() { if (is_freelook_active()) { // Show speed - real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); - real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + real_t min_speed = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN); + real_t max_speed = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX); real_t scale_length = (max_speed - min_speed); if (!Math::is_zero_approx(scale_length)) { @@ -2735,8 +2769,8 @@ void Node3DEditorViewport::_draw() { } else { // Show zoom - real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); - real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + real_t min_distance = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN); + real_t max_distance = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX); real_t scale_length = (max_distance - min_distance); if (!Math::is_zero_approx(scale_length)) { @@ -2797,7 +2831,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { } break; case VIEW_FRONT: { cursor.x_rot = 0; - cursor.y_rot = 0; + cursor.y_rot = Math_PI; set_message(TTR("Front View."), 2); name = TTR("Front"); _set_auto_orthogonal(); @@ -2806,7 +2840,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { } break; case VIEW_REAR: { cursor.x_rot = 0; - cursor.y_rot = Math_PI; + cursor.y_rot = 0; set_message(TTR("Rear View."), 2); name = TTR("Rear"); _set_auto_orthogonal(); @@ -3018,7 +3052,11 @@ void Node3DEditorViewport::_menu_option(int p_option) { case VIEW_DISPLAY_DEBUG_SDFGI: case VIEW_DISPLAY_DEBUG_SDFGI_PROBES: case VIEW_DISPLAY_DEBUG_GI_BUFFER: - case VIEW_DISPLAY_DEBUG_DISABLE_LOD: { + case VIEW_DISPLAY_DEBUG_DISABLE_LOD: + case VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS: + case VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS: + case VIEW_DISPLAY_DEBUG_CLUSTER_DECALS: + case VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES: { static const int display_options[] = { VIEW_DISPLAY_NORMAL, VIEW_DISPLAY_WIREFRAME, @@ -3040,6 +3078,10 @@ void Node3DEditorViewport::_menu_option(int p_option) { VIEW_DISPLAY_DEBUG_DECAL_ATLAS, VIEW_DISPLAY_DEBUG_SDFGI, VIEW_DISPLAY_DEBUG_SDFGI_PROBES, + VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_DECALS, + VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES, VIEW_MAX }; static const Viewport::DebugDraw debug_draw_modes[] = { @@ -3063,6 +3105,10 @@ void Node3DEditorViewport::_menu_option(int p_option) { Viewport::DEBUG_DRAW_DECAL_ATLAS, Viewport::DEBUG_DRAW_SDFGI, Viewport::DEBUG_DRAW_SDFGI_PROBES, + Viewport::DEBUG_DRAW_CLUSTER_OMNI_LIGHTS, + Viewport::DEBUG_DRAW_CLUSTER_SPOT_LIGHTS, + Viewport::DEBUG_DRAW_CLUSTER_DECALS, + Viewport::DEBUG_DRAW_CLUSTER_REFLECTION_PROBES, }; int idx = 0; @@ -3190,6 +3236,8 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) { void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) { previewing_cinema = p_activate; + rotation_control->set_visible(!p_activate); + if (!previewing_cinema) { if (previewing != nullptr) { previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); @@ -3280,6 +3328,21 @@ void Node3DEditorViewport::update_transform_gizmo_view() { xform.basis.scale(scale); + // if the determinant is zero, we should disable the gizmo from being rendered + // this prevents supplying bad values to the renderer and then having to filter it out again + if (xform.basis.determinant() == 0) { + for (int i = 0; i < 3; i++) { + RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false); + } + // Rotation white outline + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false); + return; + } + for (int i = 0; i < 3; i++) { RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform); RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE)); @@ -3964,6 +4027,12 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito display_submenu->add_radio_check_item(TTR("GI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER); display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Disable LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD); + display_submenu->add_separator(); + display_submenu->add_radio_check_item(TTR("Omni Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS); + display_submenu->add_radio_check_item(TTR("Spot Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS); + display_submenu->add_radio_check_item(TTR("Decal Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_DECALS); + display_submenu->add_radio_check_item(TTR("Reflection Probe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES); + display_submenu->set_name("display_advanced"); view_menu->get_popup()->add_submenu_item(TTR("Display Advanced..."), "display_advanced", VIEW_DISPLAY_ADVANCED); view_menu->get_popup()->add_separator(); @@ -4042,16 +4111,6 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito surface->add_child(info_label); info_label->hide(); - fps_label = memnew(Label); - fps_label->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -90 * EDSCALE); - fps_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE); - fps_label->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, -10 * EDSCALE); - fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN); - fps_label->set_tooltip(TTR("Note: The FPS is estimated on a 60hz refresh rate.")); - fps_label->set_mouse_filter(MOUSE_FILTER_PASS); // Otherwise tooltip doesn't show. - surface->add_child(fps_label); - fps_label->hide(); - cinema_label = memnew(Label); cinema_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE); cinema_label->set_h_grow_direction(GROW_DIRECTION_END); @@ -4071,9 +4130,17 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito locked_label->set_text(TTR("View Rotation Locked")); locked_label->hide(); + frame_time_gradient = memnew(Gradient); + // The color is set when the theme changes. + frame_time_gradient->add_point(0.5, Color()); + top_right_vbox = memnew(VBoxContainer); top_right_vbox->set_anchors_and_offsets_preset(PRESET_TOP_RIGHT, PRESET_MODE_MINSIZE, 2.0 * EDSCALE); top_right_vbox->set_h_grow_direction(GROW_DIRECTION_BEGIN); + // Make sure frame time labels don't touch the viewport's edge. + top_right_vbox->set_custom_minimum_size(Size2(100, 0) * EDSCALE); + // Prevent visible spacing between frame time labels. + top_right_vbox->add_theme_constant_override("separation", 0); rotation_control = memnew(ViewportRotationControl); rotation_control->set_custom_minimum_size(Size2(80, 80) * EDSCALE); @@ -4081,13 +4148,16 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito rotation_control->set_viewport(this); top_right_vbox->add_child(rotation_control); + // Individual Labels are used to allow coloring each label with its own color. + cpu_time_label = memnew(Label); + top_right_vbox->add_child(cpu_time_label); + cpu_time_label->hide(); + + gpu_time_label = memnew(Label); + top_right_vbox->add_child(gpu_time_label); + gpu_time_label->hide(); + fps_label = memnew(Label); - fps_label->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -90 * EDSCALE); - fps_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE); - fps_label->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, -10 * EDSCALE); - fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN); - fps_label->set_tooltip(TTR("Note: The FPS value displayed is the editor's framerate.\nIt cannot be used as a reliable indication of in-game performance.")); - fps_label->set_mouse_filter(MOUSE_FILTER_PASS); // Otherwise tooltip doesn't show. top_right_vbox->add_child(fps_label); fps_label->hide(); @@ -4115,12 +4185,16 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Node3DEditorViewport::update_transform_gizmo_view)); } +Node3DEditorViewport::~Node3DEditorViewport() { + memdelete(frame_time_gradient); +} + ////////////////////////////////////////////////////////////// void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { Vector2 size = get_size(); @@ -4573,8 +4647,8 @@ void Node3DEditor::_generate_selection_boxes() { Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - // Use a similar color to the 2D editor selection. - mat->set_albedo(Color(1, 0.5, 0)); + const Color selection_box_color = EDITOR_GET("editors/3d/selection_box_color"); + mat->set_albedo(selection_box_color); mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); st->set_material(mat); selection_box = st->commit(); @@ -4582,7 +4656,7 @@ void Node3DEditor::_generate_selection_boxes() { Ref<StandardMaterial3D> mat_xray = memnew(StandardMaterial3D); mat_xray->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); mat_xray->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); - mat_xray->set_albedo(Color(1, 0.5, 0, 0.15)); + mat_xray->set_albedo(selection_box_color * Color(1, 1, 1, 0.15)); mat_xray->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); st_xray->set_material(mat_xray); selection_box_xray = st_xray->commit(); @@ -4633,11 +4707,33 @@ Dictionary Node3DEditor::get_state() const { continue; } int state = gizmos_menu->get_item_state(gizmos_menu->get_item_index(i)); - String name = gizmo_plugins_by_name[i]->get_name(); + String name = gizmo_plugins_by_name[i]->get_gizmo_name(); gizmos_status[name] = state; } d["gizmos_status"] = gizmos_status; + { + Dictionary pd; + + pd["sun_rotation"] = sun_rotation; + + pd["environ_sky_color"] = environ_sky_color->get_pick_color(); + pd["environ_ground_color"] = environ_ground_color->get_pick_color(); + pd["environ_energy"] = environ_energy->get_value(); + pd["environ_glow_enabled"] = environ_glow_button->is_pressed(); + pd["environ_tonemap_enabled"] = environ_tonemap_button->is_pressed(); + pd["environ_ao_enabled"] = environ_ao_button->is_pressed(); + pd["environ_gi_enabled"] = environ_gi_button->is_pressed(); + pd["sun_max_distance"] = sun_max_distance->get_value(); + + pd["sun_color"] = sun_color->get_pick_color(); + pd["sun_energy"] = sun_energy->get_value(); + + pd["sun_disabled"] = sun_button->is_pressed(); + pd["environ_disabled"] = environ_button->is_pressed(); + + d["preview_sun_env"] = pd; + } return d; } @@ -4737,7 +4833,7 @@ void Node3DEditor::set_state(const Dictionary &p_state) { } int state = EditorNode3DGizmoPlugin::VISIBLE; for (int i = 0; i < keys.size(); i++) { - if (gizmo_plugins_by_name.write[j]->get_name() == String(keys[i])) { + if (gizmo_plugins_by_name.write[j]->get_gizmo_name() == String(keys[i])) { state = gizmos_status[keys[i]]; break; } @@ -4747,6 +4843,38 @@ void Node3DEditor::set_state(const Dictionary &p_state) { } _update_gizmos_menu(); } + + if (d.has("preview_sun_env")) { + sun_environ_updating = true; + Dictionary pd = d["preview_sun_env"]; + sun_rotation = pd["sun_rotation"]; + + environ_sky_color->set_pick_color(pd["environ_sky_color"]); + environ_ground_color->set_pick_color(pd["environ_ground_color"]); + environ_energy->set_value(pd["environ_energy"]); + environ_glow_button->set_pressed(pd["environ_glow_enabled"]); + environ_tonemap_button->set_pressed(pd["environ_tonemap_enabled"]); + environ_ao_button->set_pressed(pd["environ_ao_enabled"]); + environ_gi_button->set_pressed(pd["environ_gi_enabled"]); + sun_max_distance->set_value(pd["sun_max_distance"]); + + sun_color->set_pick_color(pd["sun_color"]); + sun_energy->set_value(pd["sun_energy"]); + + sun_button->set_pressed(pd["sun_disabled"]); + environ_button->set_pressed(pd["environ_disabled"]); + + sun_environ_updating = false; + + _preview_settings_changed(); + _update_preview_environment(); + } else { + _load_default_preview_settings(); + sun_button->set_pressed(false); + environ_button->set_pressed(false); + _preview_settings_changed(); + _update_preview_environment(); + } } void Node3DEditor::edit(Node3D *p_spatial) { @@ -5192,6 +5320,42 @@ void Node3DEditor::_init_indicators() { origin_points.push_back(axis * -1048576); } + Ref<Shader> grid_shader = memnew(Shader); + grid_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded; \n" + "uniform bool orthogonal; \n" + "uniform float grid_size; \n" + "\n" + "void vertex() { \n" + " // From FLAG_SRGB_VERTEX_COLOR \n" + " if (!OUTPUT_IS_SRGB) { \n" + " COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045))); \n" + " } \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = COLOR.rgb; \n" + " vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n" + " float angle_fade = abs(dot(dir, NORMAL)); \n" + " angle_fade = smoothstep(0.05, 0.2, angle_fade); \n" + " \n" + " vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n" + " vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n" + " vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n" + " vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n" + " float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n" + " dist_fade = smoothstep(0.02, 0.3, dist_fade); \n" + " \n" + " ALPHA = COLOR.a * dist_fade * angle_fade; \n" + "}"); + + for (int i = 0; i < 3; i++) { + grid_mat[i].instance(); + grid_mat[i]->set_shader(grid_shader); + } + grid_enable[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane"); grid_enable[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane"); grid_enable[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane"); @@ -5252,7 +5416,9 @@ void Node3DEditor::_init_indicators() { gizmo_color[i] = mat; Ref<StandardMaterial3D> mat_hl = mat->duplicate(); - mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0)); + const float brightness = 1.3; + const Color albedo = Color(col.r * brightness, col.g * brightness, col.b * brightness); + mat_hl->set_albedo(albedo); gizmo_color_hl[i] = mat_hl; Vector3 ivec; @@ -5282,9 +5448,10 @@ void Node3DEditor::_init_indicators() { int arrow_sides = 16; + const real_t arrow_sides_step = Math_TAU / arrow_sides; for (int k = 0; k < arrow_sides; k++) { - Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides); - Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides); + Basis ma(ivec, k * arrow_sides_step); + Basis mb(ivec, (k + 1) * arrow_sides_step); for (int j = 0; j < arrow_points - 1; j++) { Vector3 points[4] = { @@ -5347,7 +5514,7 @@ void Node3DEditor::_init_indicators() { surftool->commit(move_plane_gizmo[i]); Ref<StandardMaterial3D> plane_mat_hl = plane_mat->duplicate(); - plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0)); + plane_mat_hl->set_albedo(albedo); plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides } @@ -5359,13 +5526,14 @@ void Node3DEditor::_init_indicators() { int n = 128; // number of circle segments int m = 6; // number of thickness segments + real_t step = Math_TAU / n; for (int j = 0; j < n; ++j) { - Basis basis = Basis(ivec, (Math_PI * 2.0f * j) / n); + Basis basis = Basis(ivec, j * step); Vector3 vertex = basis.xform(ivec2 * GIZMO_CIRCLE_SIZE); for (int k = 0; k < m; ++k) { - Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m)); + Vector2 ofs = Vector2(Math::cos((Math_TAU * k) / m), Math::sin((Math_TAU * k) / m)); Vector3 normal = ivec * ofs.x + ivec2 * ofs.y; surftool->set_normal(basis.xform(normal)); @@ -5392,32 +5560,33 @@ void Node3DEditor::_init_indicators() { Ref<Shader> rotate_shader = memnew(Shader); - rotate_shader->set_code("\n" - "shader_type spatial; \n" - "render_mode unshaded, depth_test_disabled; \n" - "uniform vec4 albedo; \n" - "\n" - "mat3 orthonormalize(mat3 m) { \n" - " vec3 x = normalize(m[0]); \n" - " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" - " vec3 z = m[2] - x * dot(x, m[2]); \n" - " z = normalize(z - y * (dot(y,m[2]))); \n" - " return mat3(x,y,z); \n" - "} \n" - "\n" - "void vertex() { \n" - " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" - " vec3 n = mv * VERTEX; \n" - " float orientation = dot(vec3(0,0,-1),n); \n" - " if (orientation <= 0.005) { \n" - " VERTEX += NORMAL*0.02; \n" - " } \n" - "} \n" - "\n" - "void fragment() { \n" - " ALBEDO = albedo.rgb; \n" - " ALPHA = albedo.a; \n" - "}"); + rotate_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded, depth_test_disabled; \n" + "uniform vec4 albedo; \n" + "\n" + "mat3 orthonormalize(mat3 m) { \n" + " vec3 x = normalize(m[0]); \n" + " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" + " vec3 z = m[2] - x * dot(x, m[2]); \n" + " z = normalize(z - y * (dot(y,m[2]))); \n" + " return mat3(x,y,z); \n" + "} \n" + "\n" + "void vertex() { \n" + " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" + " vec3 n = mv * VERTEX; \n" + " float orientation = dot(vec3(0,0,-1),n); \n" + " if (orientation <= 0.005) { \n" + " VERTEX += NORMAL*0.02; \n" + " } \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = albedo.rgb; \n" + " ALPHA = albedo.a; \n" + "}"); Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX); @@ -5430,40 +5599,41 @@ void Node3DEditor::_init_indicators() { rotate_gizmo[i]->surface_set_material(0, rotate_mat); Ref<ShaderMaterial> rotate_mat_hl = rotate_mat->duplicate(); - rotate_mat_hl->set_shader_param("albedo", Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0)); + rotate_mat_hl->set_shader_param("albedo", albedo); rotate_gizmo_color_hl[i] = rotate_mat_hl; if (i == 2) { // Rotation white outline Ref<ShaderMaterial> border_mat = rotate_mat->duplicate(); Ref<Shader> border_shader = memnew(Shader); - border_shader->set_code("\n" - "shader_type spatial; \n" - "render_mode unshaded, depth_test_disabled; \n" - "uniform vec4 albedo; \n" - "\n" - "mat3 orthonormalize(mat3 m) { \n" - " vec3 x = normalize(m[0]); \n" - " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" - " vec3 z = m[2] - x * dot(x, m[2]); \n" - " z = normalize(z - y * (dot(y,m[2]))); \n" - " return mat3(x,y,z); \n" - "} \n" - "\n" - "void vertex() { \n" - " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" - " mv = inverse(mv); \n" - " VERTEX += NORMAL*0.008; \n" - " vec3 camera_dir_local = mv * vec3(0,0,1); \n" - " vec3 camera_up_local = mv * vec3(0,1,0); \n" - " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" - " VERTEX = rotation_matrix * VERTEX; \n" - "} \n" - "\n" - "void fragment() { \n" - " ALBEDO = albedo.rgb; \n" - " ALPHA = albedo.a; \n" - "}"); + border_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded, depth_test_disabled; \n" + "uniform vec4 albedo; \n" + "\n" + "mat3 orthonormalize(mat3 m) { \n" + " vec3 x = normalize(m[0]); \n" + " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" + " vec3 z = m[2] - x * dot(x, m[2]); \n" + " z = normalize(z - y * (dot(y,m[2]))); \n" + " return mat3(x,y,z); \n" + "} \n" + "\n" + "void vertex() { \n" + " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" + " mv = inverse(mv); \n" + " VERTEX += NORMAL*0.008; \n" + " vec3 camera_dir_local = mv * vec3(0,0,1); \n" + " vec3 camera_up_local = mv * vec3(0,1,0); \n" + " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" + " VERTEX = rotation_matrix * VERTEX; \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = albedo.rgb; \n" + " ALPHA = albedo.a; \n" + "}"); border_mat->set_shader(border_shader); border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); @@ -5492,9 +5662,10 @@ void Node3DEditor::_init_indicators() { int arrow_sides = 4; + const real_t arrow_sides_step = Math_TAU / arrow_sides; for (int k = 0; k < 4; k++) { - Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides); - Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides); + Basis ma(ivec, k * arrow_sides_step); + Basis mb(ivec, (k + 1) * arrow_sides_step); for (int j = 0; j < arrow_points - 1; j++) { Vector3 points[4] = { @@ -5557,7 +5728,7 @@ void Node3DEditor::_init_indicators() { surftool->commit(scale_plane_gizmo[i]); Ref<StandardMaterial3D> plane_mat_hl = plane_mat->duplicate(); - plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0)); + plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3)); plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides } } @@ -5573,7 +5744,7 @@ void Node3DEditor::_update_gizmos_menu() { if (!gizmo_plugins_by_name[i]->can_be_hidden()) { continue; } - String plugin_name = gizmo_plugins_by_name[i]->get_name(); + String plugin_name = gizmo_plugins_by_name[i]->get_gizmo_name(); const int plugin_state = gizmo_plugins_by_name[i]->get_state(); gizmos_menu->add_multistate_item(plugin_name, 3, plugin_state, i); const int idx = gizmos_menu->get_item_index(i); @@ -5625,8 +5796,11 @@ void Node3DEditor::_init_grid() { return; // Camera3D is invalid, don't draw the grid. } + bool orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL; + Vector<Color> grid_colors[3]; Vector<Vector3> grid_points[3]; + Vector<Vector3> grid_normals[3]; Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color"); Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color"); @@ -5641,7 +5815,7 @@ void Node3DEditor::_init_grid() { // Offsets division_level for bigger or smaller grids. // Default value is -0.2. -1.0 gives Blender-like behavior, 0.5 gives huge grids. real_t division_level_bias = EditorSettings::get_singleton()->get("editors/3d/grid_division_level_bias"); - // Default largest grid size is 100m, 10^2 (default value is 2). + // Default largest grid size is 8^2 when primary_grid_steps is 8 (64m apart, so primary grid lines are 512m apart). int division_level_max = EditorSettings::get_singleton()->get("editors/3d/grid_division_level_max"); // Default smallest grid size is 1cm, 10^-2 (default value is -2). int division_level_min = EditorSettings::get_singleton()->get("editors/3d/grid_division_level_min"); @@ -5662,10 +5836,26 @@ void Node3DEditor::_init_grid() { int b = (a + 1) % 3; int c = (a + 2) % 3; - real_t division_level = Math::log(Math::abs(camera_position[c])) / Math::log((double)primary_grid_steps) + division_level_bias; - division_level = CLAMP(division_level, division_level_min, division_level_max); - real_t division_level_floored = Math::floor(division_level); - real_t division_level_decimals = division_level - division_level_floored; + Vector3 normal; + normal[c] = 1.0; + + real_t camera_distance = Math::abs(camera_position[c]); + + if (orthogonal) { + camera_distance = camera->get_size() / 2.0; + Vector3 camera_direction = -camera->get_global_transform().get_basis().get_axis(2); + Plane grid_plane = Plane(Vector3(), normal); + Vector3 intersection; + if (grid_plane.intersects_ray(camera_position, camera_direction, &intersection)) { + camera_position = intersection; + } + } + + real_t division_level = Math::log(Math::abs(camera_distance)) / Math::log((double)primary_grid_steps) + division_level_bias; + + real_t clamped_division_level = CLAMP(division_level, division_level_min, division_level_max); + real_t division_level_floored = Math::floor(clamped_division_level); + real_t division_level_decimals = clamped_division_level - division_level_floored; real_t small_step_size = Math::pow(primary_grid_steps, division_level_floored); real_t large_step_size = small_step_size * primary_grid_steps; @@ -5677,6 +5867,15 @@ void Node3DEditor::_init_grid() { real_t bgn_b = center_b - grid_size * small_step_size; real_t end_b = center_b + grid_size * small_step_size; + real_t fade_size = Math::pow(primary_grid_steps, division_level - 1.0); + real_t min_fade_size = Math::pow(primary_grid_steps, float(division_level_min)); + real_t max_fade_size = Math::pow(primary_grid_steps, float(division_level_max)); + fade_size = CLAMP(fade_size, min_fade_size, max_fade_size); + + real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size; + grid_mat[c]->set_shader_param("grid_size", grid_fade_size); + grid_mat[c]->set_shader_param("orthogonal", orthogonal); + // In each iteration of this loop, draw one line in each direction (so two lines per loop, in each if statement). for (int i = -grid_size; i <= grid_size; i++) { Color line_color; @@ -5687,11 +5886,6 @@ void Node3DEditor::_init_grid() { line_color = secondary_grid_color; line_color.a = line_color.a * (1 - division_level_decimals); } - // Makes lines farther from the center fade out. - // Due to limitations of lines, any that come near the camera have full opacity always. - // This should eventually be replaced by some kind of "distance fade" system, outside of this function. - // But the effect is still somewhat convincing... - line_color.a *= 1 - (1 - division_level_decimals * 0.9) * (Math::abs(i / (float)grid_size)); real_t position_a = center_a + i * small_step_size; real_t position_b = center_b + i * small_step_size; @@ -5708,6 +5902,8 @@ void Node3DEditor::_init_grid() { grid_points[c].push_back(line_end); grid_colors[c].push_back(line_color); grid_colors[c].push_back(line_color); + grid_normals[c].push_back(normal); + grid_normals[c].push_back(normal); } if (!(origin_enabled && Math::is_zero_approx(position_b))) { @@ -5721,6 +5917,8 @@ void Node3DEditor::_init_grid() { grid_points[c].push_back(line_end); grid_colors[c].push_back(line_color); grid_colors[c].push_back(line_color); + grid_normals[c].push_back(normal); + grid_normals[c].push_back(normal); } } @@ -5730,8 +5928,9 @@ void Node3DEditor::_init_grid() { d.resize(RS::ARRAY_MAX); d[RenderingServer::ARRAY_VERTEX] = grid_points[c]; d[RenderingServer::ARRAY_COLOR] = grid_colors[c]; + d[RenderingServer::ARRAY_NORMAL] = grid_normals[c]; RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[c], RenderingServer::PRIMITIVE_LINES, d); - RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, indicator_mat->get_rid()); + RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, grid_mat[c]->get_rid()); grid_instance[c] = RenderingServer::get_singleton()->instance_create2(grid[c], get_tree()->get_root()->get_world_3d()->get_scenario()); // Yes, the end of this line is supposed to be a. @@ -5775,7 +5974,7 @@ void Node3DEditor::_refresh_menu_icons() { List<Node *> &selection = editor_selection->get_selected_node_list(); - if (selection.empty()) { + if (selection.is_empty()) { all_locked = false; all_grouped = false; } else { @@ -5794,11 +5993,11 @@ void Node3DEditor::_refresh_menu_icons() { } tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked); - tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty()); + tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.is_empty()); tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked); tool_button[TOOL_GROUP_SELECTED]->set_visible(!all_grouped); - tool_button[TOOL_GROUP_SELECTED]->set_disabled(selection.empty()); + tool_button[TOOL_GROUP_SELECTED]->set_disabled(selection.is_empty()); tool_button[TOOL_UNGROUP_SELECTED]->set_visible(all_grouped); } @@ -5848,17 +6047,20 @@ void Node3DEditor::snap_selected_nodes_to_floor() { // Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin Set<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp); Set<CollisionShape3D *> cs = _get_child_nodes<CollisionShape3D>(sp); + bool found_valid_shape = false; if (cs.size()) { AABB aabb; - bool found_valid_shape = false; - if (cs.front()->get()->get_shape().is_valid()) { - aabb = sp->get_global_transform().xform(cs.front()->get()->get_shape()->get_debug_mesh()->get_aabb()); + Set<CollisionShape3D *>::Element *I = cs.front(); + if (I->get()->get_shape().is_valid()) { + CollisionShape3D *collision_shape = cs.front()->get(); + aabb = collision_shape->get_global_transform().xform(collision_shape->get_shape()->get_debug_mesh()->get_aabb()); found_valid_shape = true; } - for (Set<CollisionShape3D *>::Element *I = cs.front(); I; I = I->next()) { - if (I->get()->get_shape().is_valid()) { - aabb.merge_with(sp->get_global_transform().xform(I->get()->get_shape()->get_debug_mesh()->get_aabb())); + for (I = I->next(); I; I = I->next()) { + CollisionShape3D *col_shape = I->get(); + if (col_shape->get_shape().is_valid()) { + aabb.merge_with(col_shape->get_global_transform().xform(col_shape->get_shape()->get_debug_mesh()->get_aabb())); found_valid_shape = true; } } @@ -5866,10 +6068,9 @@ void Node3DEditor::snap_selected_nodes_to_floor() { Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5); from = aabb.position + size; position_offset.y = from.y - sp->get_global_transform().origin.y; - } else { - from = sp->get_global_transform().origin; } - } else if (vi.size()) { + } + if (!found_valid_shape && vi.size()) { AABB aabb = vi.front()->get()->get_transformed_aabb(); for (Set<VisualInstance3D *>::Element *I = vi.front(); I; I = I->next()) { aabb.merge_with(I->get()->get_transformed_aabb()); @@ -5877,7 +6078,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() { Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5); from = aabb.position + size; position_offset.y = from.y - sp->get_global_transform().origin.y; - } else { + } else if (!found_valid_shape) { from = sp->get_global_transform().origin; } @@ -5960,6 +6161,51 @@ void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) { snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL); } +void Node3DEditor::_sun_environ_settings_pressed() { + Vector2 pos = sun_environ_settings->get_screen_position() + sun_environ_settings->get_size(); + sun_environ_popup->set_position(pos - Vector2(sun_environ_popup->get_contents_minimum_size().width / 2, 0)); + sun_environ_popup->popup(); +} + +void Node3DEditor::_add_sun_to_scene() { + sun_environ_popup->hide(); + + Node *base = get_tree()->get_edited_scene_root(); + if (!base) { + EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation")); + return; + } + ERR_FAIL_COND(!base); + Node *new_sun = preview_sun->duplicate(); + + undo_redo->create_action("Add Preview Sun to Scene"); + undo_redo->add_do_method(base, "add_child", new_sun); + undo_redo->add_do_method(new_sun, "set_owner", base); + undo_redo->add_undo_method(base, "remove_child", new_sun); + undo_redo->add_do_reference(new_sun); + undo_redo->commit_action(); +} +void Node3DEditor::_add_environment_to_scene() { + sun_environ_popup->hide(); + + Node *base = get_tree()->get_edited_scene_root(); + if (!base) { + EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation")); + return; + } + ERR_FAIL_COND(!base); + + WorldEnvironment *new_env = memnew(WorldEnvironment); + new_env->set_environment(preview_environment->get_environment()->duplicate(true)); + + undo_redo->create_action("Add Preview Environment to Scene"); + undo_redo->add_do_method(base, "add_child", new_env); + undo_redo->add_do_method(new_env, "set_owner", base); + undo_redo->add_undo_method(base, "remove_child", new_env); + undo_redo->add_do_reference(new_env); + undo_redo->commit_action(); +} + void Node3DEditor::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { tool_button[Node3DEditor::TOOL_MODE_SELECT]->set_icon(get_theme_icon("ToolSelect", "EditorIcons")); @@ -5988,17 +6234,31 @@ void Node3DEditor::_notification(int p_what) { _refresh_menu_icons(); get_tree()->connect("node_removed", callable_mp(this, &Node3DEditor::_node_removed)); + get_tree()->connect("node_added", callable_mp(this, &Node3DEditor::_node_added)); EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false)); editor->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true)); + + sun_button->set_icon(get_theme_icon("DirectionalLight3D", "EditorIcons")); + environ_button->set_icon(get_theme_icon("WorldEnvironment", "EditorIcons")); + sun_environ_settings->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons")); + + _update_preview_environment(); + sun_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); + environ_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); + + sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size()); + environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size()); } else if (p_what == NOTIFICATION_ENTER_TREE) { _register_all_gizmos(); _update_gizmos_menu(); _init_indicators(); } else if (p_what == NOTIFICATION_THEME_CHANGED) { _update_gizmos_menu_theme(); + sun_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); + environ_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); } else if (p_what == NOTIFICATION_EXIT_TREE) { _finish_indicators(); } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { @@ -6135,7 +6395,37 @@ void Node3DEditor::_toggle_maximize_view(Object *p_viewport) { } } +void Node3DEditor::_node_added(Node *p_node) { + if (EditorNode::get_singleton()->get_scene_root()->is_a_parent_of(p_node)) { + if (Object::cast_to<WorldEnvironment>(p_node)) { + world_env_count++; + if (world_env_count == 1) { + _update_preview_environment(); + } + } else if (Object::cast_to<DirectionalLight3D>(p_node)) { + directional_light_count++; + if (directional_light_count == 1) { + _update_preview_environment(); + } + } + } +} + void Node3DEditor::_node_removed(Node *p_node) { + if (EditorNode::get_singleton()->get_scene_root()->is_a_parent_of(p_node)) { + if (Object::cast_to<WorldEnvironment>(p_node)) { + world_env_count--; + if (world_env_count == 0) { + _update_preview_environment(); + } + } else if (Object::cast_to<DirectionalLight3D>(p_node)) { + directional_light_count--; + if (directional_light_count == 0) { + _update_preview_environment(); + } + } + } + if (p_node == selected) { selected = nullptr; } @@ -6162,6 +6452,7 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin))); add_gizmo_plugin(Ref<BakedLightmapGizmoPlugin>(memnew(BakedLightmapGizmoPlugin))); add_gizmo_plugin(Ref<LightmapProbeGizmoPlugin>(memnew(LightmapProbeGizmoPlugin))); + add_gizmo_plugin(Ref<CollisionObject3DGizmoPlugin>(memnew(CollisionObject3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionPolygon3DGizmoPlugin>(memnew(CollisionPolygon3DGizmoPlugin))); add_gizmo_plugin(Ref<NavigationRegion3DGizmoPlugin>(memnew(NavigationRegion3DGizmoPlugin))); @@ -6205,6 +6496,128 @@ void Node3DEditor::clear() { view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true); } +void Node3DEditor::_sun_direction_draw() { + sun_direction->draw_rect(Rect2(Vector2(), sun_direction->get_size()), Color(1, 1, 1, 1)); + sun_direction_material->set_shader_param("sun_direction", -preview_sun->get_transform().basis.get_axis(Vector3::AXIS_Z)); + float nrg = sun_energy->get_value(); + sun_direction_material->set_shader_param("sun_color", Vector3(sun_color->get_pick_color().r * nrg, sun_color->get_pick_color().g * nrg, sun_color->get_pick_color().b * nrg)); +} + +void Node3DEditor::_preview_settings_changed() { + if (sun_environ_updating) { + return; + } + + { // preview sun + Transform t; + t.basis = sun_rotation; + preview_sun->set_transform(t); + sun_direction->update(); + preview_sun->set_param(Light3D::PARAM_ENERGY, sun_energy->get_value()); + preview_sun->set_param(Light3D::PARAM_SHADOW_MAX_DISTANCE, sun_max_distance->get_value()); + preview_sun->set_color(sun_color->get_pick_color()); + } + + { //preview env + sky_material->set_sky_energy(environ_energy->get_value()); + Color hz_color = environ_sky_color->get_pick_color().lerp(environ_ground_color->get_pick_color(), 0.5).lerp(Color(1, 1, 1), 0.5); + sky_material->set_sky_top_color(environ_sky_color->get_pick_color()); + sky_material->set_sky_horizon_color(hz_color); + sky_material->set_ground_bottom_color(environ_ground_color->get_pick_color()); + sky_material->set_ground_horizon_color(hz_color); + + environment->set_ssao_enabled(environ_ao_button->is_pressed()); + environment->set_glow_enabled(environ_glow_button->is_pressed()); + environment->set_sdfgi_enabled(environ_gi_button->is_pressed()); + environment->set_tonemapper(environ_tonemap_button->is_pressed() ? Environment::TONE_MAPPER_FILMIC : Environment::TONE_MAPPER_LINEAR); + } +} +void Node3DEditor::_load_default_preview_settings() { + sun_environ_updating = true; + + sun_rotation = Basis(Vector3(0, 1, 0), Math_PI * 3.0 / 4) * Basis(Vector3(1, 0, 0), -Math_PI / 4); + + sun_direction->update(); + environ_sky_color->set_pick_color(Color::hex(0x91b2ceff)); + environ_ground_color->set_pick_color(Color::hex(0x1f1f21ff)); + environ_energy->set_value(1.0); + environ_glow_button->set_pressed(true); + environ_tonemap_button->set_pressed(true); + environ_ao_button->set_pressed(false); + environ_gi_button->set_pressed(false); + sun_max_distance->set_value(250); + + sun_color->set_pick_color(Color(1, 1, 1)); + sun_energy->set_value(1.0); + + sun_environ_updating = false; +} + +void Node3DEditor::_update_preview_environment() { + bool disable_light = directional_light_count > 0 || sun_button->is_pressed(); + + sun_button->set_disabled(directional_light_count > 0); + + if (disable_light) { + if (preview_sun->get_parent()) { + preview_sun->get_parent()->remove_child(preview_sun); + sun_state->show(); + sun_vb->hide(); + } + + if (directional_light_count > 0) { + sun_state->set_text(TTR("Scene contains\nDirectionalLight3D.\nPreview disabled.")); + } else { + sun_state->set_text(TTR("Preview disabled.")); + } + + } else { + if (!preview_sun->get_parent()) { + add_child(preview_sun); + sun_state->hide(); + sun_vb->show(); + } + } + + bool disable_env = world_env_count > 0 || environ_button->is_pressed(); + + environ_button->set_disabled(world_env_count > 0); + + if (disable_env) { + if (preview_environment->get_parent()) { + preview_environment->get_parent()->remove_child(preview_environment); + environ_state->show(); + environ_vb->hide(); + } + if (world_env_count > 0) { + environ_state->set_text(TTR("Scene contains\nWorldEnvironment.\nPreview disabled.")); + } else { + environ_state->set_text(TTR("Preview disabled.")); + } + + } else { + if (!preview_environment->get_parent()) { + add_child(preview_environment); + environ_state->hide(); + environ_vb->show(); + } + } +} + +void Node3DEditor::_sun_direction_input(const Ref<InputEvent> &p_event) { + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { + float x = -mm->get_relative().y * 0.02 * EDSCALE; + float y = mm->get_relative().x * 0.02 * EDSCALE; + + Basis rot = Basis(Vector3(0, 1, 0), y) * Basis(Vector3(1, 0, 0), x); + + sun_rotation = rot * sun_rotation; + sun_rotation.orthonormalize(); + _preview_settings_changed(); + } +} + Node3DEditor::Node3DEditor(EditorNode *p_editor) { gizmo.visible = true; gizmo.scale = 1.0; @@ -6342,6 +6755,32 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { _update_camera_override_button(false); hbc_menu->add_child(memnew(VSeparator)); + sun_button = memnew(Button); + sun_button->set_tooltip(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled.")); + sun_button->set_toggle_mode(true); + sun_button->set_flat(true); + sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); + sun_button->set_disabled(true); + + hbc_menu->add_child(sun_button); + + environ_button = memnew(Button); + environ_button->set_tooltip(TTR("Toggle preview environment.\nIf a WorldEnvironment node is added to the scene, preview environment is disabled.")); + environ_button->set_toggle_mode(true); + environ_button->set_flat(true); + environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); + environ_button->set_disabled(true); + + hbc_menu->add_child(environ_button); + + sun_environ_settings = memnew(Button); + sun_environ_settings->set_tooltip(TTR("Edit Sun and Environment settings.")); + sun_environ_settings->set_flat(true); + sun_environ_settings->connect("pressed", callable_mp(this, &Node3DEditor::_sun_environ_settings_pressed)); + + hbc_menu->add_child(sun_environ_settings); + + hbc_menu->add_child(memnew(VSeparator)); // Drag and drop support; preview_node = memnew(Node3D); @@ -6571,6 +7010,152 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true); over_gizmo_handle = -1; + { + //sun popup + + sun_environ_popup = memnew(PopupPanel); + add_child(sun_environ_popup); + + HBoxContainer *sun_environ_hb = memnew(HBoxContainer); + + sun_environ_popup->add_child(sun_environ_hb); + + sun_vb = memnew(VBoxContainer); + sun_environ_hb->add_child(sun_vb); + sun_vb->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); + sun_vb->hide(); + + sun_title = memnew(Label); + sun_vb->add_child(sun_title); + sun_title->set_text(TTR("Preview Sun")); + sun_title->set_align(Label::ALIGN_CENTER); + + CenterContainer *sun_direction_center = memnew(CenterContainer); + sun_direction = memnew(Control); + sun_direction->set_custom_minimum_size(Size2i(128, 128) * EDSCALE); + sun_direction_center->add_child(sun_direction); + sun_vb->add_margin_child(TTR("Sun Direction"), sun_direction_center); + sun_direction->connect("gui_input", callable_mp(this, &Node3DEditor::_sun_direction_input)); + sun_direction->connect("draw", callable_mp(this, &Node3DEditor::_sun_direction_draw)); + sun_direction->set_default_cursor_shape(CURSOR_MOVE); + + String sun_dir_shader_code = "shader_type canvas_item; uniform vec3 sun_direction; uniform vec3 sun_color; void fragment() { vec3 n; n.xy = UV * 2.0 - 1.0; n.z = sqrt(max(0.0, 1.0 - dot(n.xy, n.xy))); COLOR.rgb = dot(n,sun_direction) * sun_color; COLOR.a = 1.0 - smoothstep(0.99,1.0,length(n.xy)); }"; + sun_direction_shader.instance(); + sun_direction_shader->set_code(sun_dir_shader_code); + sun_direction_material.instance(); + sun_direction_material->set_shader(sun_direction_shader); + sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1)); + sun_direction_material->set_shader_param("sun_color", Vector3(1, 1, 1)); + sun_direction->set_material(sun_direction_material); + + sun_color = memnew(ColorPickerButton); + sun_color->set_edit_alpha(false); + sun_vb->add_margin_child(TTR("Sun Color"), sun_color); + sun_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + + sun_energy = memnew(EditorSpinSlider); + sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy); + sun_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + sun_energy->set_max(64.0); + + sun_max_distance = memnew(EditorSpinSlider); + sun_vb->add_margin_child(TTR("Shadow Max Distance"), sun_max_distance); + sun_max_distance->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + sun_max_distance->set_min(1); + sun_max_distance->set_max(4096); + + sun_add_to_scene = memnew(Button); + sun_add_to_scene->set_text(TTR("Add Sun to Scene")); + sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene)); + sun_vb->add_spacer(); + sun_vb->add_child(sun_add_to_scene); + + sun_state = memnew(Label); + sun_environ_hb->add_child(sun_state); + sun_state->set_align(Label::ALIGN_CENTER); + sun_state->set_valign(Label::VALIGN_CENTER); + sun_state->set_h_size_flags(SIZE_EXPAND_FILL); + + VSeparator *sc = memnew(VSeparator); + sc->set_custom_minimum_size(Size2(50 * EDSCALE, 0)); + sc->set_v_size_flags(SIZE_EXPAND_FILL); + sun_environ_hb->add_child(sc); + + environ_vb = memnew(VBoxContainer); + sun_environ_hb->add_child(environ_vb); + environ_vb->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); + environ_vb->hide(); + + environ_title = memnew(Label); + environ_vb->add_child(environ_title); + environ_title->set_text(TTR("Preview Environment")); + environ_title->set_align(Label::ALIGN_CENTER); + + environ_sky_color = memnew(ColorPickerButton); + environ_sky_color->set_edit_alpha(false); + environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_vb->add_margin_child(TTR("Sky Color"), environ_sky_color); + environ_ground_color = memnew(ColorPickerButton); + environ_ground_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_ground_color->set_edit_alpha(false); + environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color); + environ_energy = memnew(EditorSpinSlider); + environ_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_energy->set_max(8.0); + environ_vb->add_margin_child(TTR("Sky Energy"), environ_energy); + HBoxContainer *fx_vb = memnew(HBoxContainer); + fx_vb->set_h_size_flags(SIZE_EXPAND_FILL); + + environ_ao_button = memnew(Button); + environ_ao_button->set_text(TTR("AO")); + environ_ao_button->set_toggle_mode(true); + environ_ao_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_ao_button); + environ_glow_button = memnew(Button); + environ_glow_button->set_text(TTR("Glow")); + environ_glow_button->set_toggle_mode(true); + environ_glow_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_glow_button); + environ_tonemap_button = memnew(Button); + environ_tonemap_button->set_text(TTR("Tonemap")); + environ_tonemap_button->set_toggle_mode(true); + environ_tonemap_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_tonemap_button); + environ_gi_button = memnew(Button); + environ_gi_button->set_text(TTR("GI")); + environ_gi_button->set_toggle_mode(true); + environ_gi_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_gi_button); + environ_vb->add_margin_child(TTR("Post Process"), fx_vb); + + environ_add_to_scene = memnew(Button); + environ_add_to_scene->set_text(TTR("Add Environment to Scene")); + environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene)); + environ_vb->add_spacer(); + environ_vb->add_child(environ_add_to_scene); + + environ_state = memnew(Label); + sun_environ_hb->add_child(environ_state); + environ_state->set_align(Label::ALIGN_CENTER); + environ_state->set_valign(Label::VALIGN_CENTER); + environ_state->set_h_size_flags(SIZE_EXPAND_FILL); + + preview_sun = memnew(DirectionalLight3D); + preview_sun->set_shadow(true); + preview_sun->set_shadow_mode(DirectionalLight3D::SHADOW_PARALLEL_4_SPLITS); + preview_environment = memnew(WorldEnvironment); + environment.instance(); + preview_environment->set_environment(environment); + Ref<Sky> sky; + sky.instance(); + sky_material.instance(); + sky->set_material(sky_material); + environment->set_sky(sky); + environment->set_background(Environment::BG_SKY); + + _load_default_preview_settings(); + _preview_settings_changed(); + } } Node3DEditor::~Node3DEditor() { @@ -6661,7 +7246,7 @@ void Node3DEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) { struct _GizmoPluginPriorityComparator { bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const { if (p_a->get_priority() == p_b->get_priority()) { - return p_a->get_name() < p_b->get_name(); + return p_a->get_gizmo_name() < p_b->get_gizmo_name(); } return p_a->get_priority() > p_b->get_priority(); } @@ -6669,7 +7254,7 @@ struct _GizmoPluginPriorityComparator { struct _GizmoPluginNameComparator { bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const { - return p_a->get_name() < p_b->get_name(); + return p_a->get_gizmo_name() < p_b->get_gizmo_name(); } }; @@ -6696,7 +7281,7 @@ Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) { editor = p_node; spatial_editor = memnew(Node3DEditor(p_node)); spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor->get_viewport()->add_child(spatial_editor); + editor->get_main_control()->add_child(spatial_editor); spatial_editor->hide(); spatial_editor->connect("transform_key_request", Callable(editor->get_inspector_dock(), "_transform_keyed")); @@ -6880,7 +7465,7 @@ void EditorNode3DGizmoPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material, DEFVAL(Ref<EditorNode3DGizmo>())); - BIND_VMETHOD(MethodInfo(Variant::STRING, "get_name")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "get_gizmo_name")); BIND_VMETHOD(MethodInfo(Variant::INT, "get_priority")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_be_hidden")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_selectable_when_hidden")); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 079c86ceb4..ff4a941b06 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,7 +37,10 @@ #include "scene/3d/immediate_geometry_3d.h" #include "scene/3d/light_3d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/3d/world_environment.h" #include "scene/gui/panel_container.h" +#include "scene/resources/environment.h" +#include "scene/resources/sky_material.h" class Camera3D; class Node3DEditor; @@ -96,6 +99,7 @@ protected: public: void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); + void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>()); void add_collision_segments(const Vector<Vector3> &p_lines); void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); @@ -213,6 +217,11 @@ class Node3DEditorViewport : public Control { VIEW_DISPLAY_DEBUG_SDFGI_PROBES, VIEW_DISPLAY_DEBUG_GI_BUFFER, VIEW_DISPLAY_DEBUG_DISABLE_LOD, + VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_DECALS, + VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES, + VIEW_LOCK_ROTATION, VIEW_CINEMATIC_PREVIEW, VIEW_AUTO_ORTHOGONAL, @@ -289,6 +298,9 @@ private: VBoxContainer *top_right_vbox; ViewportRotationControl *rotation_control; + Gradient *frame_time_gradient; + Label *cpu_time_label; + Label *gpu_time_label; Label *fps_label; struct _RayResult { @@ -455,6 +467,8 @@ private: bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + void _project_settings_changed(); + protected: void _notification(int p_what); static void _bind_methods(); @@ -480,6 +494,7 @@ public: Camera3D *get_camera() { return camera; } // return the default camera object. Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index); + ~Node3DEditorViewport(); }; class Node3DEditorSelectedItem : public Object { @@ -581,7 +596,6 @@ private: ///// ToolMode tool_mode; - bool orthogonal; RenderingServer::ScenarioDebugMode scenario_debug; @@ -614,6 +628,7 @@ private: RID cursor_mesh; RID cursor_instance; Ref<StandardMaterial3D> indicator_mat; + Ref<ShaderMaterial> grid_mat[3]; Ref<StandardMaterial3D> cursor_material; // Scene drag and drop support @@ -721,6 +736,7 @@ private: static Node3DEditor *singleton; + void _node_added(Node *p_node); void _node_removed(Node *p_node); Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_priority; Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_name; @@ -733,6 +749,61 @@ private: void _refresh_menu_icons(); + // Preview Sun and Environment + + uint32_t world_env_count = 0; + uint32_t directional_light_count = 0; + + Button *sun_button; + Label *sun_state; + Label *sun_title; + VBoxContainer *sun_vb; + Popup *sun_environ_popup; + Control *sun_direction; + ColorPickerButton *sun_color; + EditorSpinSlider *sun_energy; + EditorSpinSlider *sun_max_distance; + Button *sun_add_to_scene; + + void _sun_direction_draw(); + void _sun_direction_input(const Ref<InputEvent> &p_event); + + Basis sun_rotation; + + Ref<Shader> sun_direction_shader; + Ref<ShaderMaterial> sun_direction_material; + + Button *environ_button; + Label *environ_state; + Label *environ_title; + VBoxContainer *environ_vb; + ColorPickerButton *environ_sky_color; + ColorPickerButton *environ_ground_color; + EditorSpinSlider *environ_energy; + Button *environ_ao_button; + Button *environ_glow_button; + Button *environ_tonemap_button; + Button *environ_gi_button; + Button *environ_add_to_scene; + + Button *sun_environ_settings; + + DirectionalLight3D *preview_sun; + WorldEnvironment *preview_environment; + Ref<Environment> environment; + Ref<ProceduralSkyMaterial> sky_material; + + bool sun_environ_updating = false; + + void _load_default_preview_settings(); + void _update_preview_environment(); + + void _preview_settings_changed(); + void _sun_environ_settings_pressed(); + + void _add_sun_to_scene(); + void _add_environment_to_scene(); + protected: void _notification(int p_what); //void _gui_input(InputEvent p_event); diff --git a/editor/plugins/ot_features_plugin.cpp b/editor/plugins/ot_features_plugin.cpp index 3478148521..ebfdf2c7cd 100644 --- a/editor/plugins/ot_features_plugin.cpp +++ b/editor/plugins/ot_features_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/ot_features_plugin.h b/editor/plugins/ot_features_plugin.h index 5b5f367b24..9559a6c0c3 100644 --- a/editor/plugins/ot_features_plugin.h +++ b/editor/plugins/ot_features_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 608b5c3104..0a949c8610 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,7 +42,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, // These properties are translated with the tr() function in the C++ code when being set or updated. Error err; - RES loaded_res = ResourceLoader::load(p_path, "PackedScene", false, &err); + RES loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; @@ -81,14 +81,14 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> str_values = property_value; for (int k = 0; k < str_values.size(); k++) { String desc = str_values[k].get_slice(";", 1).strip_edges(); - if (!desc.empty()) { + if (!desc.is_empty()) { parsed_strings.push_back(desc); } } } else if (property_value.get_type() == Variant::STRING) { String str_value = String(property_value); // Prevent reading text containing only spaces. - if (!str_value.strip_edges().empty()) { + if (!str_value.strip_edges().is_empty()) { parsed_strings.push_back(str_value); } } diff --git a/editor/plugins/packed_scene_translation_parser_plugin.h b/editor/plugins/packed_scene_translation_parser_plugin.h index a0ffdf692c..e51d65414e 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.h +++ b/editor/plugins/packed_scene_translation_parser_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index f79098ce5d..84b4516452 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -88,7 +88,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { real_t dist_to_p_in = gpoint.distance_to(xform.xform(curve->get_point_position(i) + curve->get_point_in(i))); // Check for point movement start (for point + in/out controls). - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mode == MODE_EDIT && !mb->get_shift() && dist_to_p < grab_threshold) { // Points can only be moved in edit mode. @@ -118,7 +118,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } // Check for point deletion. - if ((mb->get_button_index() == BUTTON_RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == BUTTON_LEFT && mode == MODE_DELETE)) { + if ((mb->get_button_index() == MOUSE_BUTTON_RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && mode == MODE_DELETE)) { if (dist_to_p < grab_threshold) { undo_redo->create_action(TTR("Remove Point from Curve")); undo_redo->add_do_method(curve.ptr(), "remove_point", i); @@ -149,7 +149,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } // Check for point creation. - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) { Ref<Curve2D> curve = node->get_curve(); undo_redo->create_action(TTR("Add Point to Curve")); @@ -170,7 +170,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } // Check for segment split. - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && mode == MODE_EDIT && on_edge) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mode == MODE_EDIT && on_edge) { Vector2 gpoint2 = mb->get_position(); Ref<Curve2D> curve = node->get_curve(); @@ -207,7 +207,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } // Check for point movement completion. - if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && action != ACTION_NONE) { + if (!mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && action != ACTION_NONE) { Ref<Curve2D> curve = node->get_curve(); Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index 8a420d7c8d..867e0ce74f 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 043693801e..47bd1114d2 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -316,7 +316,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref set_handle_clicked(false); } - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->get_control()))) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->get_control()))) { //click into curve, break it down Vector<Vector3> v3a = c->tessellate(); int idx = 0; @@ -411,7 +411,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref //add new at pos } - } else if (mb->is_pressed() && ((mb->get_button_index() == BUTTON_LEFT && curve_del->is_pressed()) || (mb->get_button_index() == BUTTON_RIGHT && curve_edit->is_pressed()))) { + } else if (mb->is_pressed() && ((mb->get_button_index() == MOUSE_BUTTON_LEFT && curve_del->is_pressed()) || (mb->get_button_index() == MOUSE_BUTTON_RIGHT && curve_edit->is_pressed()))) { for (int i = 0; i < c->get_point_count(); i++) { real_t dist_to_p = p_camera->unproject_position(gt.xform(c->get_point_position(i))).distance_to(mbpos); real_t dist_to_p_out = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_out(i))).distance_to(mbpos); @@ -609,7 +609,7 @@ Path3DEditorPlugin::Path3DEditorPlugin(EditorNode *p_node) { curve_edit->set_pressed(true); /* collision_polygon_editor = memnew( PathEditor(p_node) ); - editor->get_viewport()->add_child(collision_polygon_editor); + editor->get_main_control()->add_child(collision_polygon_editor); collision_polygon_editor->set_margin(MARGIN_LEFT,200); collision_polygon_editor->set_margin(MARGIN_RIGHT,230); collision_polygon_editor->set_margin(MARGIN_TOP,0); diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index 3b92a59143..13870d7591 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp index 30bf827b3c..4b52512933 100644 --- a/editor/plugins/physical_bone_3d_editor_plugin.cpp +++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/physical_bone_3d_editor_plugin.h b/editor/plugins/physical_bone_3d_editor_plugin.h index bdfcca8878..248aad9298 100644 --- a/editor/plugins/physical_bone_3d_editor_plugin.h +++ b/editor/plugins/physical_bone_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 0584ee894b..470d897dcc 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -447,7 +447,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouseButton> mb = p_input; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { uv_drag_from = snap_point(Vector2(mb->get_position().x, mb->get_position().y)); uv_drag = true; @@ -759,7 +759,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { bone_painting = false; } } - } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed()) { _cancel_editing(); if (bone_painting) { @@ -768,9 +768,9 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_edit_draw->update(); - } else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) { uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * mb->get_factor()))); - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) { uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * mb->get_factor()))); } } @@ -778,7 +778,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouseMotion> mm = p_input; if (mm.is_valid()) { - if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + if ((mm->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { Vector2 drag(mm->get_relative().x, mm->get_relative().y); uv_hscroll->set_value(uv_hscroll->get_value() - drag.x); uv_vscroll->set_value(uv_vscroll->get_value() - drag.y); @@ -1052,8 +1052,6 @@ void Polygon2DEditor::_uv_draw() { if (i < uv_draw_max /*&& polygons.size() == 0 && polygon_create.size() == 0*/) { //if using or creating polygons, do not show outline (will show polygons instead) uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), poly_line_color, Math::round(EDSCALE)); } - - rect.expand_to(mtx.basis_xform(uvs[i])); } for (int i = 0; i < polygons.size(); i++) { @@ -1160,8 +1158,8 @@ void Polygon2DEditor::_uv_draw() { uv_edit_draw->draw_circle(bone_paint_pos, bone_paint_radius->get_value() * EDSCALE, Color(1, 1, 1, 0.1)); } - rect.position -= uv_edit_draw->get_size(); - rect.size += uv_edit_draw->get_size() * 2.0; + rect.position = -uv_edit_draw->get_size(); + rect.size = uv_edit_draw->get_size() * 2.0 + base_tex->get_size() * uv_draw_zoom; updating_uv_scroll = true; diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 77580a5604..af3b2f5aef 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 684d43e963..b4b8e82124 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h index ddfb54c40b..bc10b48a16 100644 --- a/editor/plugins/resource_preloader_editor_plugin.h +++ b/editor/plugins/resource_preloader_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index e107435373..50f4d8493f 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index cc19228470..c70fff7db7 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 7607ab482c..b298474406 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -587,7 +587,7 @@ void ScriptEditor::_go_to_tab(int p_idx) { } void ScriptEditor::_add_recent_script(String p_path) { - if (p_path.empty()) { + if (p_path.is_empty()) { return; } @@ -702,7 +702,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { } } if (script.is_valid()) { - if (!script->get_path().empty()) { + if (!script->get_path().is_empty()) { // Only saved scripts can be restored. previous_scripts.push_back(script->get_path()); } @@ -755,8 +755,8 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { _save_layout(); } -void ScriptEditor::_close_current_tab() { - _close_tab(tab_container->get_current_tab()); +void ScriptEditor::_close_current_tab(bool p_save) { + _close_tab(tab_container->get_current_tab(), p_save); } void ScriptEditor::_close_discard_current_tab(const String &p_str) { @@ -802,7 +802,7 @@ void ScriptEditor::_close_other_tabs() { } } - _close_current_tab(); + _close_current_tab(false); } } @@ -820,7 +820,7 @@ void ScriptEditor::_close_all_tabs() { } } - _close_current_tab(); + _close_current_tab(false); } } @@ -894,7 +894,7 @@ void ScriptEditor::_reload_scripts() { Ref<Script> script = edited_res; if (script != nullptr) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); @@ -1129,7 +1129,7 @@ void ScriptEditor::_menu_option(int p_option) { return; } break; case FILE_REOPEN_CLOSED: { - if (previous_scripts.empty()) { + if (previous_scripts.is_empty()) { return; } @@ -1372,7 +1372,7 @@ void ScriptEditor::_menu_option(int p_option) { if (current->is_unsaved()) { _ask_close_current_unsaved_tab(current); } else { - _close_current_tab(); + _close_current_tab(false); } } break; case FILE_COPY_PATH: { @@ -1381,7 +1381,7 @@ void ScriptEditor::_menu_option(int p_option) { case SHOW_IN_FILE_SYSTEM: { const RES script = current->get_edited_resource(); const String path = script->get_path(); - if (!path.empty()) { + if (!path.is_empty()) { FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); file_system_dock->navigate_to_path(path); // Ensure that the FileSystem dock is visible. @@ -1887,7 +1887,7 @@ void ScriptEditor::_update_script_names() { if (se) { Ref<Texture2D> icon = se->get_theme_icon(); String path = se->get_edited_resource()->get_path(); - bool saved = !path.empty(); + bool saved = !path.is_empty(); if (saved) { // The script might be deleted, moved, or renamed, so make sure // to update original path to previously edited resource. @@ -1934,7 +1934,7 @@ void ScriptEditor::_update_script_names() { sd.name = name; } break; case DISPLAY_DIR_AND_NAME: { - if (!path.get_base_dir().get_file().empty()) { + if (!path.get_base_dir().get_file().is_empty()) { sd.name = path.get_base_dir().get_file().plus_file(name); } else { sd.name = name; @@ -1954,7 +1954,20 @@ void ScriptEditor::_update_script_names() { Vector<String> disambiguated_script_names; Vector<String> full_script_paths; for (int j = 0; j < sedata.size(); j++) { - disambiguated_script_names.append(sedata[j].name.replace("(*)", "").get_file()); + String name = sedata[j].name.replace("(*)", ""); + ScriptListName script_display = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/script_list/list_script_names_as"); + switch (script_display) { + case DISPLAY_NAME: { + name = name.get_file(); + } break; + case DISPLAY_DIR_AND_NAME: { + name = name.get_base_dir().get_file().plus_file(name.get_file()); + } break; + default: + break; + } + + disambiguated_script_names.append(name); full_script_paths.append(sedata[j].tooltip); } @@ -1988,7 +2001,7 @@ void ScriptEditor::_update_script_names() { } } - if (_sort_list_on_update && !sedata.empty()) { + if (_sort_list_on_update && !sedata.is_empty()) { sedata.sort(); // change actual order of tab_container so that the order can be rearranged by user @@ -2052,7 +2065,7 @@ void ScriptEditor::_update_script_names() { _update_help_overview_visibility(); _update_script_colors(); - file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.empty()); + file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.is_empty()); } void ScriptEditor::_update_script_connections() { @@ -2198,7 +2211,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra args.push_back(script_path); } - Error err = OS::get_singleton()->execute(path, args, false); + Error err = OS::get_singleton()->create_process(path, args); if (err == OK) { return false; } @@ -2724,7 +2737,7 @@ void ScriptEditor::_script_list_gui_input(const Ref<InputEvent> &ev) { Ref<InputEventMouseButton> mb = ev; if (mb.is_valid() && mb->is_pressed()) { switch (mb->get_button_index()) { - case BUTTON_MIDDLE: { + case MOUSE_BUTTON_MIDDLE: { // Right-click selects automatically; middle-click does not. int idx = script_list->get_item_at_position(mb->get_position(), true); if (idx >= 0) { @@ -2734,7 +2747,7 @@ void ScriptEditor::_script_list_gui_input(const Ref<InputEvent> &ev) { } } break; - case BUTTON_RIGHT: { + case MOUSE_BUTTON_RIGHT: { _make_script_list_context_menu(); } break; } @@ -2806,7 +2819,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { String path = scripts[i]; Dictionary script_info = scripts[i]; - if (!script_info.empty()) { + if (!script_info.is_empty()) { path = script_info["path"]; } @@ -2833,7 +2846,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { } } - if (!script_info.empty()) { + if (!script_info.is_empty()) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(tab_container->get_tab_count() - 1)); if (se) { se->set_edit_state(script_info["state"]); @@ -3484,7 +3497,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { erase_tab_confirm = memnew(ConfirmationDialog); erase_tab_confirm->get_ok_button()->set_text(TTR("Save")); erase_tab_confirm->add_button(TTR("Discard"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); - erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab)); + erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab), varray(true)); erase_tab_confirm->connect("custom_action", callable_mp(this, &ScriptEditor::_close_discard_current_tab)); add_child(erase_tab_confirm); @@ -3646,7 +3659,7 @@ void ScriptEditorPlugin::edited_scene_changed() { ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { editor = p_node; script_editor = memnew(ScriptEditor(p_node)); - editor->get_viewport()->add_child(script_editor); + editor->get_main_control()->add_child(script_editor); script_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); script_editor->hide(); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index aafd8cba18..b2172e7f10 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -325,7 +325,7 @@ class ScriptEditor : public PanelContainer { void _close_tab(int p_idx, bool p_save = true, bool p_history_back = true); - void _close_current_tab(); + void _close_current_tab(bool p_save = true); void _close_discard_current_tab(const String &p_str); void _close_docs_tab(); void _close_other_tabs(); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index ed2c0c9f26..3534809891 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -214,7 +214,7 @@ void ScriptTextEditor::_load_theme_settings() { text_edit->add_theme_color_override("line_number_color", line_number_color); text_edit->add_theme_color_override("caret_color", caret_color); text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_color_selected", text_selected_color); + text_edit->add_theme_color_override("font_selected_color", text_selected_color); text_edit->add_theme_color_override("selection_color", selection_color); text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); text_edit->add_theme_color_override("current_line_color", current_line_color); @@ -349,7 +349,7 @@ void ScriptTextEditor::update_settings() { bool ScriptTextEditor::is_unsaved() { const bool unsaved = code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() || - script->get_path().empty(); // In memory. + script->get_path().is_empty(); // In memory. return unsaved; } @@ -427,7 +427,7 @@ String ScriptTextEditor::get_name() { if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) { name = script->get_path().get_file(); if (is_unsaved()) { - if (script->get_path().empty()) { + if (script->get_path().is_empty()) { name = TTR("[unsaved]"); } name += "(*)"; @@ -551,7 +551,7 @@ void ScriptTextEditor::_validate_script() { if (safe_lines.has(i + 1)) { te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); last_is_safe = true; - } else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().empty())) { + } else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().is_empty())) { te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); } else { te->set_line_gutter_item_color(i, line_number_gutter, default_line_number_color); @@ -601,8 +601,7 @@ void ScriptTextEditor::_bookmark_item_pressed(int p_idx) { if (p_idx < 4) { // Any item before the separator. _edit_option(bookmarks_menu->get_item_id(p_idx)); } else { - code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx)); - code_editor->get_text_editor()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred(). + code_editor->goto_line_centered(bookmarks_menu->get_item_metadata(p_idx)); } } @@ -688,7 +687,7 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo uint64_t date = FileAccess::get_modified_time(script->get_path()); if (last_date != date) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); @@ -791,7 +790,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c emit_signal("request_open_script_at_line", result.script, result.location - 1); } else { emit_signal("request_save_history"); - _goto_line(result.location - 1); + goto_line_centered(result.location - 1); } } break; case ScriptLanguage::LookupResult::RESULT_CLASS: { @@ -1066,7 +1065,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->indent_left(); + tx->indent_selected_lines_left(); } break; case EDIT_INDENT_RIGHT: { Ref<Script> scr = script; @@ -1074,7 +1073,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->indent_right(); + tx->indent_selected_lines_right(); } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); @@ -1517,7 +1516,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { bool create_menu = false; CodeEdit *tx = code_editor->get_text_editor(); - if (mb.is_valid() && mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { + if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed()) { local_pos = mb->get_global_position() - tx->get_global_position(); create_menu = true; } else if (k.is_valid() && k->get_keycode() == KEY_MENU) { @@ -1632,16 +1631,16 @@ void ScriptTextEditor::_color_changed(const Color &p_color) { void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos) { context_menu->clear(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); @@ -1743,14 +1742,14 @@ void ScriptTextEditor::_enable_code_editor() { search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); edit_hb->add_child(edit_menu); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); @@ -1763,7 +1762,7 @@ void ScriptTextEditor::_enable_code_editor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); @@ -1915,12 +1914,6 @@ static ScriptEditorBase *create_editor(const RES &p_resource) { } void ScriptTextEditor::register_editor() { - ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD | KEY_Z); - ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD | KEY_Y); - ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD | KEY_X); - ED_SHORTCUT("script_text_editor/copy", TTR("Copy"), KEY_MASK_CMD | KEY_C); - ED_SHORTCUT("script_text_editor/paste", TTR("Paste"), KEY_MASK_CMD | KEY_V); - ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD | KEY_A); ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT | KEY_UP); ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN); ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K); @@ -1936,10 +1929,8 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0); #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE); #else ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D); - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE); #endif ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E); ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 1e436fbe65..17abfcf4cc 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 9bb34f4489..8f8a4b3054 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -117,7 +117,7 @@ void ShaderTextEditor::_load_theme_settings() { get_text_editor()->add_theme_color_override("line_number_color", line_number_color); get_text_editor()->add_theme_color_override("caret_color", caret_color); get_text_editor()->add_theme_color_override("caret_background_color", caret_background_color); - get_text_editor()->add_theme_color_override("font_color_selected", text_selected_color); + get_text_editor()->add_theme_color_override("font_selected_color", text_selected_color); get_text_editor()->add_theme_color_override("selection_color", selection_color); get_text_editor()->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); get_text_editor()->add_theme_color_override("current_line_color", current_line_color); @@ -282,7 +282,7 @@ void ShaderEditor::_menu_option(int p_option) { } CodeEdit *tx = shader_editor->get_text_editor(); - tx->indent_left(); + tx->indent_selected_lines_left(); } break; case EDIT_INDENT_RIGHT: { @@ -291,7 +291,7 @@ void ShaderEditor::_menu_option(int p_option) { } CodeEdit *tx = shader_editor->get_text_editor(); - tx->indent_right(); + tx->indent_selected_lines_right(); } break; case EDIT_DELETE_LINE: { @@ -339,7 +339,7 @@ void ShaderEditor::_menu_option(int p_option) { shader_editor->remove_all_bookmarks(); } break; case HELP_DOCS: { - OS::get_singleton()->shell_open("https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html"); + OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/index.html"); } break; } if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) { @@ -405,7 +405,7 @@ void ShaderEditor::_check_for_external_edit() { } void ShaderEditor::_reload_shader_from_disk() { - Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), true); + Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_FAIL_COND(!rel_shader.is_valid()); shader->set_code(rel_shader->get_code()); @@ -460,7 +460,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { Ref<InputEventMouseButton> mb = ev; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { + if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed()) { int col, row; CodeEdit *tx = shader_editor->get_text_editor(); tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col); @@ -533,15 +533,15 @@ void ShaderEditor::_bookmark_item_pressed(int p_idx) { void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) { context_menu->clear(); if (p_selection) { - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); } - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); @@ -585,14 +585,14 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { edit_menu->set_text(TTR("Edit")); edit_menu->set_switch_on_hover(true); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); @@ -602,7 +602,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); search_menu = memnew(MenuButton); diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index e81a782ac8..731c0a5b7e 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index f15a801530..47d7f8204b 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,7 +59,7 @@ void ShaderFileEditor::_version_selected(int p_option) { ERR_FAIL_COND(bytecode.is_null()); for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { - if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) { + if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).is_empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) { stages[i]->set_icon(Ref<Texture2D>()); continue; } @@ -182,7 +182,7 @@ void ShaderFileEditor::_update_options() { for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i)); String error = bytecode->get_stage_compile_error(RD::ShaderStage(i)); - bool disable = error == String() && bc.empty(); + bool disable = error == String() && bc.is_empty(); stages[i]->set_disabled(disable); if (!disable) { if (stages[i]->is_pressed()) { diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h index 6858f7d933..7d6e503b6c 100644 --- a/editor/plugins/shader_file_editor_plugin.h +++ b/editor/plugins/shader_file_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp index a198e4ff8f..44916e1d46 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.cpp +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -129,7 +129,7 @@ void Skeleton2DEditorPlugin::make_visible(bool p_visible) { Skeleton2DEditorPlugin::Skeleton2DEditorPlugin(EditorNode *p_node) { editor = p_node; sprite_editor = memnew(Skeleton2DEditor); - editor->get_viewport()->add_child(sprite_editor); + editor->get_main_control()->add_child(sprite_editor); make_visible(false); //sprite_editor->options->hide(); diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h index b8377fc914..dacd8fe43f 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.h +++ b/editor/plugins/skeleton_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 22f50c0689..121ccfa417 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -293,7 +293,7 @@ void BoneTransformEditor::_key_button_pressed() { const BoneId bone_id = property.get_slicec('/', 1).to_int(); const String name = skeleton->get_bone_name(bone_id); - if (name.empty()) + if (name.is_empty()) return; // Need to normalize the basis before you key it @@ -383,8 +383,12 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi CollisionShape3D *bone_shape = memnew(CollisionShape3D); bone_shape->set_shape(bone_shape_capsule); + Transform capsule_transform; + capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0)); + bone_shape->set_transform(capsule_transform); + Transform body_transform; - body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin, Vector3(0, 1, 0)); + body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin); body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height)); Transform joint_transform; diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 44dc1bc36e..14c213f7b2 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp index 8fc789b94a..2da49c1c0b 100644 --- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.h b/editor/plugins/skeleton_ik_3d_editor_plugin.h index c1585ea670..b0d2138115 100644 --- a/editor/plugins/skeleton_ik_3d_editor_plugin.h +++ b/editor/plugins/skeleton_ik_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index 1be6b979b1..4acacf3058 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -173,8 +173,13 @@ void Sprite2DEditor::_update_mesh_data() { Ref<Image> image = texture->get_data(); ERR_FAIL_COND(image.is_null()); + + if (image->is_compressed()) { + image->decompress(); + } + Rect2 rect; - if (node->is_region()) { + if (node->is_region_enabled()) { rect = node->get_region_rect(); } else { rect.size = Size2(image->get_width(), image->get_height()); @@ -340,7 +345,7 @@ void Sprite2DEditor::_convert_to_mesh_2d_node() { } void Sprite2DEditor::_convert_to_polygon_2d_node() { - if (computed_outline_lines.empty()) { + if (computed_outline_lines.is_empty()) { err_dialog->set_text(TTR("Invalid geometry, can't create polygon.")); err_dialog->popup_centered(); return; @@ -398,7 +403,7 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() { } void Sprite2DEditor::_create_collision_polygon_2d_node() { - if (computed_outline_lines.empty()) { + if (computed_outline_lines.is_empty()) { err_dialog->set_text(TTR("Invalid geometry, can't create collision polygon.")); err_dialog->popup_centered(); return; @@ -420,7 +425,7 @@ void Sprite2DEditor::_create_collision_polygon_2d_node() { } void Sprite2DEditor::_create_light_occluder_2d_node() { - if (computed_outline_lines.empty()) { + if (computed_outline_lines.is_empty()) { err_dialog->set_text(TTR("Invalid geometry, can't create light occluder.")); err_dialog->popup_centered(); return; @@ -583,7 +588,7 @@ void Sprite2DEditorPlugin::make_visible(bool p_visible) { Sprite2DEditorPlugin::Sprite2DEditorPlugin(EditorNode *p_node) { editor = p_node; sprite_editor = memnew(Sprite2DEditor); - editor->get_viewport()->add_child(sprite_editor); + editor->get_main_control()->add_child(sprite_editor); make_visible(false); //sprite_editor->options->hide(); diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h index 8769f19b5c..d4a1ef4312 100644 --- a/editor/plugins/sprite_2d_editor_plugin.h +++ b/editor/plugins/sprite_2d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index b79d829c34..bd6dac7490 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/3d/sprite_3d.h" @@ -104,7 +105,7 @@ void SpriteFramesEditor::_sheet_preview_draw() { void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { Size2i size = split_sheet_preview->get_size(); int h = split_sheet_h->get_value(); int v = split_sheet_v->get_value(); @@ -149,11 +150,11 @@ void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) { // Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer // to allow performing this action anywhere, even if the cursor isn't // hovering the texture in the workspace. - if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { _sheet_zoom_in(); // Don't scroll up after zooming in. accept_event(); - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { _sheet_zoom_out(); // Don't scroll down after zooming out. accept_event(); @@ -218,7 +219,8 @@ void SpriteFramesEditor::_sheet_zoom_out() { } void SpriteFramesEditor::_sheet_zoom_reset() { - sheet_zoom = 1.f; + // Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad. + sheet_zoom = MAX(1.0, EDSCALE); Size2 texture_size = split_sheet_preview->get_texture()->get_size(); split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom); } @@ -318,7 +320,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_ resources.push_back(resource); } - if (resources.empty()) { + if (resources.is_empty()) { return; } @@ -692,11 +694,11 @@ void SpriteFramesEditor::_tree_input(const Ref<InputEvent> &p_event) { const Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { _zoom_in(); // Don't scroll up after zooming in. accept_event(); - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { _zoom_out(); // Don't scroll down after zooming out. accept_event(); @@ -731,7 +733,7 @@ void SpriteFramesEditor::_zoom_out() { } void SpriteFramesEditor::_zoom_reset() { - thumbnail_zoom = 1.0f; + thumbnail_zoom = MAX(1.0, EDSCALE); tree->set_fixed_column_width(thumbnail_default_size * 3 / 2); tree->set_fixed_icon_size(Size2(thumbnail_default_size, thumbnail_default_size)); } @@ -952,7 +954,11 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "files") { Vector<String> files = d["files"]; - _file_load_request(files, at_pos); + if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + _prepare_sprite_sheet(files[0]); + } else { + _file_load_request(files, at_pos); + } } } @@ -1224,13 +1230,14 @@ SpriteFramesEditor::SpriteFramesEditor() { // Config scale. scale_ratio = 1.2f; - thumbnail_default_size = 96; - thumbnail_zoom = 1.0f; - max_thumbnail_zoom = 8.0f; - min_thumbnail_zoom = 0.1f; - sheet_zoom = 1.0f; - max_sheet_zoom = 16.0f; - min_sheet_zoom = 0.01f; + thumbnail_default_size = 96 * MAX(1.0, EDSCALE); + thumbnail_zoom = MAX(1.0, EDSCALE); + max_thumbnail_zoom = 8.0f * MAX(1.0, EDSCALE); + min_thumbnail_zoom = 0.1f * MAX(1.0, EDSCALE); + // Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad. + sheet_zoom = MAX(1.0, EDSCALE); + max_sheet_zoom = 16.0f * MAX(1.0, EDSCALE); + min_sheet_zoom = 0.01f * MAX(1.0, EDSCALE); _zoom_reset(); } diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 0dce93f55a..bbc26ca726 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index 3641052a4e..64df982d5d 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h index 41daa662db..d4a235cd10 100644 --- a/editor/plugins/style_box_editor_plugin.h +++ b/editor/plugins/style_box_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index b95abe8994..2b8bfe067d 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -96,7 +96,7 @@ void TextEditor::_load_theme_settings() { text_edit->add_theme_color_override("line_number_color", line_number_color); text_edit->add_theme_color_override("caret_color", caret_color); text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_color_selected", text_selected_color); + text_edit->add_theme_color_override("font_selected_color", text_selected_color); text_edit->add_theme_color_override("selection_color", selection_color); text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); text_edit->add_theme_color_override("current_line_color", current_line_color); @@ -119,7 +119,7 @@ String TextEditor::get_name() { if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) { name = text_file->get_path().get_file(); if (is_unsaved()) { - if (text_file->get_path().empty()) { + if (text_file->get_path().is_empty()) { name = TTR("[unsaved]"); } name += "(*)"; @@ -242,7 +242,7 @@ void TextEditor::apply_code() { bool TextEditor::is_unsaved() { const bool unsaved = code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() || - text_file->get_path().empty(); // In memory. + text_file->get_path().is_empty(); // In memory. return unsaved; } @@ -363,10 +363,10 @@ void TextEditor::_edit_option(int p_op) { code_editor->move_lines_down(); } break; case EDIT_INDENT_LEFT: { - tx->indent_left(); + tx->indent_selected_lines_left(); } break; case EDIT_INDENT_RIGHT: { - tx->indent_right(); + tx->indent_selected_lines_right(); } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); @@ -469,7 +469,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { Ref<InputEventMouseButton> mb = ev; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_RIGHT) { + if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) { int col, row; CodeEdit *tx = code_editor->get_text_editor(); tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col); @@ -514,15 +514,15 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded, Vector2 p_position) { context_menu->clear(); if (p_selection) { - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); } - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); @@ -584,14 +584,14 @@ TextEditor::TextEditor() { edit_menu->set_switch_on_hover(true); edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextEditor::_edit_option)); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("un_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index ea425bd033..c066d51b18 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index d13a865534..36297c8a4a 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -57,7 +57,7 @@ void Texture3DEditor::_notification(int p_what) { } } -void Texture3DEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void Texture3DEditor::_texture_changed() { if (!is_visible()) { return; } @@ -118,7 +118,7 @@ void Texture3DEditor::_texture_rect_update_area() { void Texture3DEditor::edit(Ref<Texture3D> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); } texture = p_texture; @@ -128,7 +128,7 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) { _make_shaders(); } - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); update(); texture_rect->set_material(material); setting = true; @@ -173,8 +173,7 @@ Texture3DEditor::Texture3DEditor() { info->set_h_grow_direction(GROW_DIRECTION_BEGIN); info->set_v_grow_direction(GROW_DIRECTION_BEGIN); info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5)); info->add_theme_constant_override("shadow_as_outline", 1); info->add_theme_constant_override("shadow_offset_x", 2); info->add_theme_constant_override("shadow_offset_y", 2); @@ -185,7 +184,7 @@ Texture3DEditor::Texture3DEditor() { Texture3DEditor::~Texture3DEditor() { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); } } diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h index 4fbf47ecfe..9d90d3653f 100644 --- a/editor/plugins/texture_3d_editor_plugin.h +++ b/editor/plugins/texture_3d_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -61,10 +61,12 @@ class Texture3DEditor : public Control { void _texture_rect_update_area(); void _texture_rect_draw(); + void _texture_changed(); + protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; + static void _bind_methods(); public: diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 9b760c0e50..253f8878d2 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -104,7 +104,7 @@ void TextureEditor::_notification(int p_what) { } } -void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureEditor::_texture_changed() { if (!is_visible()) { return; } @@ -113,13 +113,13 @@ void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { void TextureEditor::edit(Ref<Texture2D> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed)); } texture = p_texture; if (!texture.is_null()) { - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &TextureEditor::_texture_changed)); update(); } else { hide(); @@ -137,7 +137,7 @@ TextureEditor::TextureEditor() { TextureEditor::~TextureEditor() { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed)); } } diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 0d4452c662..ebe8882194 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,7 +43,7 @@ class TextureEditor : public Control { protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; + void _texture_changed(); static void _bind_methods(); public: diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index a807e8e99b..265d4ccc1e 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,7 +36,7 @@ void TextureLayeredEditor::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { y_rot += -mm->get_relative().x * 0.01; x_rot += mm->get_relative().y * 0.01; _update_material(); @@ -63,7 +63,7 @@ void TextureLayeredEditor::_notification(int p_what) { } } -void TextureLayeredEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureLayeredEditor::_texture_changed() { if (!is_visible()) { return; } @@ -173,7 +173,7 @@ void TextureLayeredEditor::_texture_rect_update_area() { void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); } texture = p_texture; @@ -183,7 +183,7 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { _make_shaders(); } - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); update(); texture_rect->set_material(materials[texture->get_layered_type()]); setting = true; @@ -238,8 +238,7 @@ TextureLayeredEditor::TextureLayeredEditor() { info->set_h_grow_direction(GROW_DIRECTION_BEGIN); info->set_v_grow_direction(GROW_DIRECTION_BEGIN); info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5)); info->add_theme_constant_override("shadow_as_outline", 1); info->add_theme_constant_override("shadow_offset_x", 2); info->add_theme_constant_override("shadow_offset_y", 2); @@ -249,9 +248,6 @@ TextureLayeredEditor::TextureLayeredEditor() { } TextureLayeredEditor::~TextureLayeredEditor() { - if (!texture.is_null()) { - texture->remove_change_receptor(this); - } } // diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h index 9a28d2dff8..c4ced62fb9 100644 --- a/editor/plugins/texture_layered_editor_plugin.h +++ b/editor/plugins/texture_layered_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,10 +63,11 @@ class TextureLayeredEditor : public Control { void _texture_rect_update_area(); void _texture_rect_draw(); + void _texture_changed(); + protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; static void _bind_methods(); public: diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 15d5c615bd..7b927ad98b 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,8 +42,21 @@ void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) { Vector2 line = (to - from).normalized() * 10; + + // Draw a translucent background line to make the foreground line visible on any background. + edit_draw->draw_line( + from, + to, + EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor").inverted() * Color(1, 1, 1, 0.5), + Math::round(2 * EDSCALE)); + while ((to - from).length_squared() > 200) { - edit_draw->draw_line(from, from + line, EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor"), 2); + edit_draw->draw_line( + from, + from + line, + EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor"), + Math::round(2 * EDSCALE)); + from += line * 2; } } @@ -177,7 +190,7 @@ void TextureRegionEditor::_region_draw() { } ofs = (endpoints[next] - endpoints[i]) / 2; - ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2); + ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2); if (snap_mode != SNAP_AUTOSLICE) { edit_draw->draw_texture(select_handle, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor() - draw_ofs * draw_zoom); @@ -272,7 +285,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouseButton> mb = p_input; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { if (node_ninepatch || obj_styleBox.is_valid()) { edited_margin = -1; @@ -434,7 +447,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { creating = false; } - } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed()) { if (drag) { drag = false; if (edited_margin >= 0) { @@ -453,9 +466,9 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { drag_index = -1; } } - } else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) { _zoom_on_position(draw_zoom * ((0.95 + (0.05 * mb->get_factor())) / 0.95), mb->get_position()); - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) { _zoom_on_position(draw_zoom * (1 - (0.05 * mb->get_factor())), mb->get_position()); } } @@ -463,24 +476,45 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouseMotion> mm = p_input; if (mm.is_valid()) { - if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + if (mm->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom); hscroll->set_value(hscroll->get_value() - dragged.x); vscroll->set_value(vscroll->get_value() - dragged.y); - } else if (drag) { if (edited_margin >= 0) { float new_margin = 0; - if (edited_margin == 0) { - new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom; - } else if (edited_margin == 1) { - new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom; - } else if (edited_margin == 2) { - new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom; - } else if (edited_margin == 3) { - new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom; + + if (snap_mode != SNAP_GRID) { + if (edited_margin == 0) { + new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom; + } else if (edited_margin == 1) { + new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom; + } else if (edited_margin == 2) { + new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom; + } else if (edited_margin == 3) { + new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom; + } else { + ERR_PRINT("Unexpected edited_margin"); + } + + if (snap_mode == SNAP_PIXEL) { + new_margin = Math::round(new_margin); + } } else { - ERR_PRINT("Unexpected edited_margin"); + Vector2 pos_snapped = snap_point(mtx.affine_inverse().xform(mm->get_position())); + Rect2 rect_rounded = Rect2(rect.position.round(), rect.size.round()); + + if (edited_margin == 0) { + new_margin = pos_snapped.y - rect_rounded.position.y; + } else if (edited_margin == 1) { + new_margin = rect_rounded.size.y + rect_rounded.position.y - pos_snapped.y; + } else if (edited_margin == 2) { + new_margin = pos_snapped.x - rect_rounded.position.x; + } else if (edited_margin == 3) { + new_margin = rect_rounded.size.x + rect_rounded.position.x - pos_snapped.x; + } else { + ERR_PRINT("Unexpected edited_margin"); + } } if (new_margin < 0) { @@ -829,19 +863,19 @@ Sprite2D *TextureRegionEditor::get_sprite() { void TextureRegionEditor::edit(Object *p_obj) { if (node_sprite) { - node_sprite->remove_change_receptor(this); + node_sprite->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_sprite_3d) { - node_sprite_3d->remove_change_receptor(this); + node_sprite_3d->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_ninepatch) { - node_ninepatch->remove_change_receptor(this); + node_ninepatch->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (obj_styleBox.is_valid()) { - obj_styleBox->remove_change_receptor(this); + obj_styleBox->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (atlas_tex.is_valid()) { - atlas_tex->remove_change_receptor(this); + atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (p_obj) { node_sprite = Object::cast_to<Sprite2D>(p_obj); @@ -853,7 +887,7 @@ void TextureRegionEditor::edit(Object *p_obj) { if (Object::cast_to<AtlasTexture>(p_obj)) { atlas_tex = Ref<AtlasTexture>(Object::cast_to<AtlasTexture>(p_obj)); } - p_obj->add_change_receptor(this); + p_obj->connect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); _edit_region(); } else { node_sprite = nullptr; @@ -863,7 +897,7 @@ void TextureRegionEditor::edit(Object *p_obj) { atlas_tex = Ref<AtlasTexture>(nullptr); } edit_draw->update(); - if ((node_sprite && !node_sprite->is_region()) || (node_sprite_3d && !node_sprite_3d->is_region())) { + if ((node_sprite && !node_sprite->is_region_enabled()) || (node_sprite_3d && !node_sprite_3d->is_region_enabled())) { set_process(true); } if (!p_obj) { @@ -871,14 +905,11 @@ void TextureRegionEditor::edit(Object *p_obj) { } } -void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureRegionEditor::_texture_changed() { if (!is_visible()) { return; } - String prop = p_prop; - if (prop == "atlas" || prop == "texture" || prop == "region") { - _edit_region(); - } + _edit_region(); } void TextureRegionEditor::_edit_region() { @@ -1084,7 +1115,7 @@ void TextureRegionEditorPlugin::_editor_visiblity_changed() { void TextureRegionEditorPlugin::make_visible(bool p_visible) { if (p_visible) { texture_region_button->show(); - bool is_node_configured = region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region()) || (region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region()); + bool is_node_configured = region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region_enabled()) || (region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region_enabled()); if ((is_node_configured && !manually_hidden) || texture_region_button->is_pressed()) { editor->make_bottom_panel_item_visible(region_editor); } diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index e9f58006a4..d3db0a08a9 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -117,6 +117,8 @@ class TextureRegionEditor : public VBoxContainer { void _update_rect(); void _update_autoslice(); + void _texture_changed(); + protected: void _notification(int p_what); void _node_removed(Object *p_obj); @@ -124,8 +126,6 @@ protected: Vector2 snap_point(Vector2 p_target) const; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; - public: void _edit_region(); void _region_draw(); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index e6fb6ba22a..dfa8c04145 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index e374dd8714..ab199f8e51 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 49eb68c93a..bd721244ea 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,7 +39,13 @@ #include "scene/gui/split_container.h" void TileMapEditor::_node_removed(Node *p_node) { - if (p_node == node) { + if (p_node == node && node) { + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (node->is_connected("settings_changed", callable_tileset_settings_changed)) { + // Fixes #44824, which describes a situation where you can reselect a TileMap node without first de-selecting it when switching scenes. + node->disconnect("settings_changed", callable_tileset_settings_changed); + } node = nullptr; } } @@ -227,11 +233,11 @@ void TileMapEditor::_palette_input(const Ref<InputEvent> &p_event) { // Zoom in/out using Ctrl + mouse wheel. if (mb.is_valid() && mb->is_pressed() && mb->get_command()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { size_slider->set_value(size_slider->get_value() + 0.2); } - if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { size_slider->set_value(size_slider->get_value() - 0.2); } } @@ -262,7 +268,7 @@ Vector<int> TileMapEditor::get_selected_tiles() const { } void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) { - palette->unselect_all(); + palette->deselect_all(); for (int i = p_tiles.size() - 1; i >= 0; i--) { int idx = palette->find_metadata(p_tiles[i]); @@ -449,7 +455,7 @@ void TileMapEditor::_update_palette() { List<int> tiles; tileset->get_tile_list(&tiles); - if (tiles.empty()) { + if (tiles.is_empty()) { return; } @@ -960,9 +966,9 @@ void TileMapEditor::_update_copydata() { tcd.flip_v = node->is_cell_y_flipped(j, i); tcd.transpose = node->is_cell_transposed(j, i); tcd.autotile_coord = node->get_cell_autotile_coord(j, i); - } - copydata.push_back(tcd); + copydata.push_back(tcd); + } } } } @@ -1021,7 +1027,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) { return false; // Drag. @@ -1171,7 +1177,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } } - } else if (mb->get_button_index() == BUTTON_RIGHT) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) { if (mb->is_pressed()) { if (tool == TOOL_SELECTING || selection_active) { tool = TOOL_NONE; @@ -1456,7 +1462,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } - if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) { _pick_tile(over_tile); return true; @@ -1779,7 +1785,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { return; } - if (paint_undo.empty()) { + if (paint_undo.is_empty()) { return; } @@ -1810,7 +1816,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { } } } else if (tool == TOOL_PASTING) { - if (copydata.empty()) { + if (copydata.is_empty()) { return; } @@ -1867,7 +1873,11 @@ void TileMapEditor::edit(Node *p_tile_map) { } if (node) { - node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (node->is_connected("settings_changed", callable_tileset_settings_changed)) { + node->disconnect("settings_changed", callable_tileset_settings_changed); + } } if (p_tile_map) { node = Object::cast_to<TileMap>(p_tile_map); @@ -1894,7 +1904,11 @@ void TileMapEditor::edit(Node *p_tile_map) { } if (node) { - node->connect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (!node->is_connected("settings_changed", callable_tileset_settings_changed)) { + node->connect("settings_changed", callable_tileset_settings_changed); + } } _clear_bucket_cache(); diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index 3a4cb22ac1..421a3b3f68 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 900a2c75a0..cca4f594e9 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,7 +39,6 @@ void TileSetEditor::edit(const Ref<TileSet> &p_tileset) { tileset = p_tileset; - tileset->add_change_receptor(this); texture_list->clear(); texture_map.clear(); @@ -81,7 +80,7 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) { Vector2 phys_offset; Size2 s; - if (mi->is_region()) { + if (mi->is_region_enabled()) { s = mi->get_region_rect().size; p_library->tile_set_region(id, mi->get_region_rect()); } else { @@ -1247,12 +1246,12 @@ void TileSetEditor::_on_scroll_container_input(const Ref<InputEvent> &p_event) { // Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer // to allow performing this action anywhere, even if the cursor isn't // hovering the texture in the workspace. - if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { print_line("zooming in"); _zoom_in(); // Don't scroll up after zooming in. accept_event(); - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { print_line("zooming out"); _zoom_out(); // Don't scroll down after zooming out. @@ -1281,7 +1280,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { const Ref<InputEventMouseMotion> mm = p_ie; if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && !creating_shape) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && !creating_shape) { if (!current_tile_region.has_point(mb->get_position())) { List<int> *tiles = new List<int>(); tileset->get_tile_list(tiles); @@ -1305,7 +1304,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } // Drag Middle Mouse if (mm.is_valid()) { - if (mm->get_button_mask() & BUTTON_MASK_MIDDLE) { + if (mm->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE) { Vector2 dragged(mm->get_relative().x, mm->get_relative().y); scroll->set_h_scroll(scroll->get_h_scroll() - dragged.x * workspace->get_scale().x); scroll->set_v_scroll(scroll->get_v_scroll() - dragged.y * workspace->get_scale().x); @@ -1314,7 +1313,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { if (edit_mode == EDITMODE_REGION) { if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (get_current_tile() >= 0 || workspace_mode != WORKSPACE_EDIT) { dragging = true; region_from = mb->get_position(); @@ -1323,13 +1322,13 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { workspace_overlay->update(); return; } - } else if (dragging && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { + } else if (dragging && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { dragging = false; edited_region = Rect2(); workspace->update(); workspace_overlay->update(); return; - } else if (dragging && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + } else if (dragging && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { dragging = false; update_edited_region(mb->get_position()); edited_region.position -= WORKSPACE_MARGIN; @@ -1429,7 +1428,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { switch (edit_mode) { case EDITMODE_ICON: { if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && current_tile_region.has_point(mb->get_position())) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && current_tile_region.has_point(mb->get_position())) { Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y))); undo_redo->create_action(TTR("Set Tile Icon")); undo_redo->add_do_method(tileset.ptr(), "autotile_set_icon_coordinate", get_current_tile(), coord); @@ -1446,9 +1445,9 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { if (dragging) { return; } - if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) { + if ((mb->get_button_index() == MOUSE_BUTTON_RIGHT || mb->get_button_index() == MOUSE_BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) { dragging = true; - erasing = (mb->get_button_index() == BUTTON_RIGHT); + erasing = (mb->get_button_index() == MOUSE_BUTTON_RIGHT); alternative = Input::get_singleton()->is_key_pressed(KEY_SHIFT); Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y))); Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y)); @@ -1519,7 +1518,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } } } else { - if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) { + if ((erasing && mb->get_button_index() == MOUSE_BUTTON_RIGHT) || (!erasing && mb->get_button_index() == MOUSE_BUTTON_LEFT)) { dragging = false; erasing = false; alternative = false; @@ -1613,7 +1612,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { shape_anchor += current_tile_region.position; if (tools[TOOL_SELECT]->is_pressed()) { if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) { int grabbed_point = get_grabbed_point(mb->get_position(), grab_threshold); @@ -1631,7 +1630,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } } workspace->update(); - } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + } else if (!mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (edit_mode == EDITMODE_COLLISION) { if (dragging_point >= 0) { dragging_point = -1; @@ -1706,7 +1705,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } } else if (tools[SHAPE_NEW_POLYGON]->is_pressed()) { if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { Vector2 pos = mb->get_position(); pos = snap_point(pos); if (creating_shape) { @@ -1726,7 +1725,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { current_shape.push_back(snap_point(pos)); workspace->update(); } - } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { + } else if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { if (creating_shape) { creating_shape = false; _select_edited_shape_coord(); @@ -1740,7 +1739,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } } else if (tools[SHAPE_NEW_RECTANGLE]->is_pressed()) { if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { _set_edited_collision_shape(Ref<ConvexPolygonShape2D>()); current_shape.resize(0); Vector2 pos = mb->get_position(); @@ -1752,13 +1751,13 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { creating_shape = true; workspace->update(); return; - } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { + } else if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { if (creating_shape) { creating_shape = false; _select_edited_shape_coord(); workspace->update(); } - } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + } else if (!mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (creating_shape) { // if the first two corners are within grabbing distance of one another, expand the rect to fill the tile if (is_within_grabbing_distance_of_first_point(current_shape[1], grab_threshold)) { @@ -1859,7 +1858,7 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { _update_toggle_shape_button(); workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } else if (p_tool == SELECT_NEXT) { _select_next_shape(); @@ -2173,7 +2172,7 @@ Array TileSetEditor::_get_tiles_in_current_texture(bool sorted) { } } if (sorted) { - a.sort_custom(this, "_sort_tiles"); + a.sort_custom(callable_mp(this, &TileSetEditor::_sort_tiles)); } return a; } @@ -2287,7 +2286,7 @@ void TileSetEditor::_select_next_shape() { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } @@ -2349,7 +2348,7 @@ void TileSetEditor::_select_previous_shape() { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } @@ -3012,7 +3011,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { undo_redo->add_undo_method(this, "_select_edited_shape_coord"); undo_redo->commit_action(); } - tileset->_change_notify(""); + tileset->notify_property_list_changed(); } void TileSetEditor::select_coord(const Vector2 &coord) { @@ -3115,7 +3114,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } Vector2 TileSetEditor::snap_point(const Vector2 &point) { @@ -3225,7 +3224,7 @@ void TileSetEditor::update_texture_list() { workspace_overlay->update(); } update_texture_list_icon(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } void TileSetEditor::update_texture_list_icon() { @@ -3389,7 +3388,7 @@ int TileSetEditor::get_current_tile() const { void TileSetEditor::set_current_tile(int p_id) { if (current_tile != p_id) { current_tile = p_id; - helper->_change_notify(""); + helper->notify_property_list_changed(); select_coord(Vector2(0, 0)); update_workspace_tile_mode(); if (p_id == -1) { @@ -3414,7 +3413,7 @@ void TilesetEditorContext::set_tileset(const Ref<TileSet> &p_tileset) { void TilesetEditorContext::set_snap_options_visible(bool p_visible) { snap_options_visible = p_visible; - _change_notify(""); + notify_property_list_changed(); } bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value) { @@ -3450,7 +3449,7 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/" + name2, p_value, &v); } if (v) { - tileset->_change_notify(""); + tileset->notify_property_list_changed(); tileset_editor->workspace->update(); tileset_editor->workspace_overlay->update(); } diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 72eb14941c..e778c18f44 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 7747c740df..0af3b936cb 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h index 3f107ddffb..7d7c66a7ee 100644 --- a/editor/plugins/version_control_editor_plugin.h +++ b/editor/plugins/version_control_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 2fbfa2a8e3..69bdc05b3a 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,6 +44,7 @@ #include "scene/gui/panel.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" +#include "scene/resources/visual_shader_sdf_nodes.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -618,7 +619,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) { Label *hint_label = memnew(Label); hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]"); - hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_color_readonly", "TextEdit")); + hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_readonly_color", "TextEdit")); hint_label->add_theme_style_override("normal", label_style); hb->add_child(hint_label); } @@ -1015,14 +1016,14 @@ void VisualShaderEditor::_update_options_menu() { TreeItem *root = members->create_item(); String filter = node_filter->get_text().strip_edges(); - bool use_filter = !filter.empty(); + bool use_filter = !filter.is_empty(); bool is_first_item = true; Color unsupported_color = get_theme_color("error_color", "Editor"); Color supported_color = get_theme_color("warning_color", "Editor"); - static bool low_driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES2"; + static bool low_driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES2"; Map<String, TreeItem *> folders; @@ -1281,6 +1282,9 @@ void VisualShaderEditor::_update_graph() { graph->connect_node(itos(from), from_idx, itos(to), to_idx); } + + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); } VisualShader::Type VisualShaderEditor::get_current_shader_type() const { @@ -1733,114 +1737,220 @@ void VisualShaderEditor::_add_curve_node(const String &p_path) { curve->set_texture(ResourceLoader::load(p_path)); } -VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { - ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); +void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { + // FLOAT_OP + { + VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(p_node); - Ref<VisualShaderNode> vsnode; + if (floatOp) { + floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); + return; + } + } - bool is_custom = add_options[p_idx].is_custom; + // FLOAT_FUNC + { + VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(p_node); - if (!is_custom && add_options[p_idx].type != String()) { - VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); - ERR_FAIL_COND_V(!vsn, nullptr); + if (floatFunc) { + floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); + // VECTOR_OP + { + VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(p_node); - if (constant) { - if ((int)add_options[p_idx].value != -1) { - constant->set_constant(add_options[p_idx].value); - } + if (vecOp) { + vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx); + return; } + } - if (p_op_idx != -1) { - VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn); + // VECTOR_FUNC + { + VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(p_node); - if (input) { - input->set_input_name(add_options[p_idx].sub_func_str); - } + if (vecFunc) { + vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(vsn); + // COLOR_OP + { + VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(p_node); - if (is) { - is->set_function((VisualShaderNodeIs::Function)p_op_idx); - } + if (colorOp) { + colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx); + return; + } + } - VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(vsn); + // COLOR_FUNC + { + VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(p_node); - if (cmp) { - cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); - } + if (colorFunc) { + colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(vsn); + // INT_OP + { + VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(p_node); - if (colorOp) { - colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx); - } + if (intOp) { + intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); + return; + } + } - VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(vsn); + // INT_FUNC + { + VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(p_node); - if (colorFunc) { - colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); - } + if (intFunc) { + intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(vsn); + // TRANSFORM_FUNC + { + VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(p_node); - if (floatOp) { - floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); - } + if (matFunc) { + matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(vsn); + // IS + { + VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node); - if (intOp) { - intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); - } + if (is) { + is->set_function((VisualShaderNodeIs::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(vsn); + // COMPARE + { + VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(p_node); - if (floatFunc) { - floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); - } + if (cmp) { + cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); + return; + } + } - VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(vsn); + // DERIVATIVE + { + VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(p_node); - if (intFunc) { - intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); - } + if (sderFunc) { + sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx); + return; + } - VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(vsn); + VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(p_node); - if (vecOp) { - vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx); - } + if (vderFunc) { + vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(vsn); + // MIX + { + VisualShaderNodeMix *mix = Object::cast_to<VisualShaderNodeMix>(p_node); - if (vecFunc) { - vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx); - } + if (mix) { + mix->set_op_type((VisualShaderNodeMix::OpType)p_op_idx); + return; + } + } - VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(vsn); + // CLAMP + { + VisualShaderNodeClamp *clampFunc = Object::cast_to<VisualShaderNodeClamp>(p_node); - if (matFunc) { - matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx); - } + if (clampFunc) { + clampFunc->set_op_type((VisualShaderNodeClamp::OpType)p_op_idx); + return; + } + } - VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(vsn); + // SWITCH + { + VisualShaderNodeSwitch *switchFunc = Object::cast_to<VisualShaderNodeSwitch>(p_node); - if (sderFunc) { - sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx); - } + if (switchFunc) { + switchFunc->set_op_type((VisualShaderNodeSwitch::OpType)p_op_idx); + return; + } + } - VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(vsn); + // SMOOTHSTEP + { + VisualShaderNodeSmoothStep *smoothStepFunc = Object::cast_to<VisualShaderNodeSmoothStep>(p_node); - if (vderFunc) { - vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx); - } + if (smoothStepFunc) { + smoothStepFunc->set_op_type((VisualShaderNodeSmoothStep::OpType)p_op_idx); + return; + } + } + + // STEP + { + VisualShaderNodeStep *stepFunc = Object::cast_to<VisualShaderNodeStep>(p_node); + + if (stepFunc) { + stepFunc->set_op_type((VisualShaderNodeStep::OpType)p_op_idx); + return; + } + } + + // MULTIPLY_ADD + { + VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(p_node); + + if (fmaFunc) { + fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx); + } + } +} + +VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { + ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); + + Ref<VisualShaderNode> vsnode; - VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(vsn); + bool is_custom = add_options[p_idx].is_custom; - if (fmaFunc) { - fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx); + if (!is_custom && add_options[p_idx].type != String()) { + VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); + ERR_FAIL_COND_V(!vsn, nullptr); + + VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); + + if (constant) { + if ((int)add_options[p_idx].value != -1) { + constant->set_constant(add_options[p_idx].value); + } + } else { + if (p_op_idx != -1) { + VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn); + + if (input) { + input->set_input_name(add_options[p_idx].sub_func_str); + } else { + _setup_node(vsn, p_op_idx); + } } } @@ -1879,28 +1989,95 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { undo_redo->add_do_method(expr, "set_size", Size2(250 * EDSCALE, 150 * EDSCALE)); } + bool created_expression_port = false; + if (to_node != -1 && to_slot != -1) { - if (vsnode->get_output_port_count() > 0) { + VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot); + + if (expr && expr->is_editable() && input_port_type != VisualShaderNode::PORT_TYPE_SAMPLER) { + undo_redo->add_do_method(expr, "add_output_port", 0, input_port_type, "output0"); + undo_redo->add_undo_method(expr, "remove_output_port", 0); + + String initial_expression_code; + + switch (input_port_type) { + case VisualShaderNode::PORT_TYPE_SCALAR: + initial_expression_code = "output0 = 1.0;"; + break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: + initial_expression_code = "output0 = 1;"; + break; + case VisualShaderNode::PORT_TYPE_VECTOR: + initial_expression_code = "output0 = vec3(1.0, 1.0, 1.0);"; + break; + case VisualShaderNode::PORT_TYPE_BOOLEAN: + initial_expression_code = "output0 = true;"; + break; + case VisualShaderNode::PORT_TYPE_TRANSFORM: + initial_expression_code = "output0 = mat4(1.0);"; + break; + default: + break; + } + + undo_redo->add_do_method(expr, "set_expression", initial_expression_code); + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, id_to_use); + + created_expression_port = true; + } + if (vsnode->get_output_port_count() > 0 || created_expression_port) { int _from_node = id_to_use; int _from_slot = 0; - if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(_from_slot), visual_shader->get_node(type, to_node)->get_input_port_type(to_slot))) { + if (created_expression_port) { undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot); + } else { + // Attempting to connect to the first correct port. + for (int i = 0; i < vsnode->get_output_port_count(); i++) { + if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type)) { + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); + break; + } + } } } } else if (from_node != -1 && from_slot != -1) { - if (vsnode->get_input_port_count() > 0) { + VisualShaderNode::PortType output_port_type = visual_shader->get_node(type, from_node)->get_output_port_type(from_slot); + + if (expr && expr->is_editable()) { + undo_redo->add_do_method(expr, "add_input_port", 0, output_port_type, "input0"); + undo_redo->add_undo_method(expr, "remove_input_port", 0); + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, id_to_use); + + created_expression_port = true; + } + + if (vsnode->get_input_port_count() > 0 || created_expression_port) { int _to_node = id_to_use; int _to_slot = 0; - if (visual_shader->is_port_types_compatible(visual_shader->get_node(type, from_node)->get_output_port_type(from_slot), vsnode->get_input_port_type(_to_slot))) { + if (created_expression_port) { undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + } else { + // Attempting to connect to the first correct port. + for (int i = 0; i < vsnode->get_input_port_count(); i++) { + if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) { + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i); + break; + } + } } } } @@ -2087,6 +2264,197 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { } } +void VisualShaderEditor::_replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to) { + undo_redo->add_do_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_to); + undo_redo->add_undo_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_from); +} + +void VisualShaderEditor::_update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) { + Ref<VisualShaderNode> node = visual_shader->get_node(p_type_id, p_node_id); + ERR_FAIL_COND(!node.is_valid()); + ERR_FAIL_COND(!node->has_method("set_constant")); + node->call("set_constant", p_var); + if (p_preview_port != -1) { + node->set_output_port_for_preview(p_preview_port); + } +} + +void VisualShaderEditor::_update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) { + Ref<VisualShaderNodeUniform> uniform = visual_shader->get_node(p_type_id, p_node_id); + ERR_FAIL_COND(!uniform.is_valid()); + + String valid_name = visual_shader->validate_uniform_name(uniform->get_uniform_name(), uniform); + uniform->set_uniform_name(valid_name); + graph_plugin->set_uniform_name(p_type_id, p_node_id, valid_name); + + if (uniform->has_method("set_default_value_enabled")) { + uniform->call("set_default_value_enabled", true); + uniform->call("set_default_value", p_var); + } + if (p_preview_port != -1) { + uniform->set_output_port_for_preview(p_preview_port); + } +} + +void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { + VisualShader::Type type_id = get_current_shader_type(); + + if (!p_vice_versa) { + undo_redo->create_action(TTR("Convert Constant Node(s) To Uniform(s)")); + } else { + undo_redo->create_action(TTR("Convert Uniform Node(s) To Constant(s)")); + } + + const Set<int> ¤t_set = p_vice_versa ? selected_uniforms : selected_constants; + Set<String> deleted_names; + + for (Set<int>::Element *E = current_set.front(); E; E = E->next()) { + int node_id = E->get(); + Ref<VisualShaderNode> node = visual_shader->get_node(type_id, node_id); + bool catched = false; + Variant var; + + // float + if (!p_vice_versa) { + Ref<VisualShaderNodeFloatConstant> float_const = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr()); + if (float_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatUniform"); + var = float_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeFloatUniform> float_uniform = Object::cast_to<VisualShaderNodeFloatUniform>(node.ptr()); + if (float_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeFloatUniform", "VisualShaderNodeFloatConstant"); + var = float_uniform->get_default_value(); + catched = true; + } + } + + // int + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeIntConstant> int_const = Object::cast_to<VisualShaderNodeIntConstant>(node.ptr()); + if (int_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntUniform"); + var = int_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeIntUniform> int_uniform = Object::cast_to<VisualShaderNodeIntUniform>(node.ptr()); + if (int_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeIntUniform", "VisualShaderNodeIntConstant"); + var = int_uniform->get_default_value(); + catched = true; + } + } + } + + // boolean + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeBooleanConstant> boolean_const = Object::cast_to<VisualShaderNodeBooleanConstant>(node.ptr()); + if (boolean_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanUniform"); + var = boolean_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeBooleanUniform> boolean_uniform = Object::cast_to<VisualShaderNodeBooleanUniform>(node.ptr()); + if (boolean_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanConstant"); + var = boolean_uniform->get_default_value(); + catched = true; + } + } + } + + // vec3 + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeVec3Constant> vec3_const = Object::cast_to<VisualShaderNodeVec3Constant>(node.ptr()); + if (vec3_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Uniform"); + var = vec3_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeVec3Uniform> vec3_uniform = Object::cast_to<VisualShaderNodeVec3Uniform>(node.ptr()); + if (vec3_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Constant"); + var = vec3_uniform->get_default_value(); + catched = true; + } + } + } + + // color + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeColorConstant> color_const = Object::cast_to<VisualShaderNodeColorConstant>(node.ptr()); + if (color_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorUniform"); + var = color_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeColorUniform> color_uniform = Object::cast_to<VisualShaderNodeColorUniform>(node.ptr()); + if (color_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeColorUniform", "VisualShaderNodeColorConstant"); + var = color_uniform->get_default_value(); + catched = true; + } + } + } + + // transform + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeTransformConstant> transform_const = Object::cast_to<VisualShaderNodeTransformConstant>(node.ptr()); + if (transform_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformUniform"); + var = transform_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeTransformUniform> transform_uniform = Object::cast_to<VisualShaderNodeTransformUniform>(node.ptr()); + if (transform_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformConstant"); + var = transform_uniform->get_default_value(); + catched = true; + } + } + } + ERR_CONTINUE(!catched); + int preview_port = node->get_output_port_for_preview(); + + if (!p_vice_versa) { + undo_redo->add_do_method(this, "_update_uniform", type_id, node_id, var, preview_port); + undo_redo->add_undo_method(this, "_update_constant", type_id, node_id, var, preview_port); + } else { + undo_redo->add_do_method(this, "_update_constant", type_id, node_id, var, preview_port); + undo_redo->add_undo_method(this, "_update_uniform", type_id, node_id, var, preview_port); + + Ref<VisualShaderNodeUniform> uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); + ERR_CONTINUE(!uniform.is_valid()); + + deleted_names.insert(uniform->get_uniform_name()); + } + + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, node_id); + undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, node_id); + } + + undo_redo->add_do_method(this, "_update_uniforms", true); + undo_redo->add_undo_method(this, "_update_uniforms", true); + + if (deleted_names.size() > 0) { + _update_uniform_refs(deleted_names); + } + + undo_redo->commit_action(); +} + void VisualShaderEditor::_delete_node_request(int p_type, int p_node) { List<int> to_erase; to_erase.push_back(p_node); @@ -2108,7 +2476,7 @@ void VisualShaderEditor::_delete_nodes_request() { } } - if (to_erase.empty()) { + if (to_erase.is_empty()) { return; } @@ -2134,27 +2502,69 @@ void VisualShaderEditor::_node_selected(Object *p_node) { void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; + VisualShader::Type type = get_current_shader_type(); + + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { + selected_constants.clear(); + selected_uniforms.clear(); - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { List<int> to_change; for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); if (gn) { if (gn->is_selected() && gn->is_close_button_visible()) { - to_change.push_back(gn->get_name().operator String().to_int()); + int id = gn->get_name().operator String().to_int(); + to_change.push_back(id); + + Ref<VisualShaderNode> node = visual_shader->get_node(type, id); + VisualShaderNodeConstant *cnode = Object::cast_to<VisualShaderNodeConstant>(node.ptr()); + if (cnode != nullptr) { + selected_constants.insert(id); + } + VisualShaderNodeUniform *unode = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); + if (unode != nullptr) { + selected_uniforms.insert(id); + } } } } - if (to_change.empty() && copy_nodes_buffer.empty()) { + if (to_change.is_empty() && copy_nodes_buffer.is_empty()) { _show_members_dialog(true); } else { - popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.empty()); - popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_nodes_buffer.empty()); - popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty()); - popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty()); + popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_nodes_buffer.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty()); + + int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2); + if (temp != -1) { + popup_menu->remove_item(temp); + } + temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); + if (temp != -1) { + popup_menu->remove_item(temp); + } + temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS); + if (temp != -1) { + popup_menu->remove_item(temp); + } + + if (selected_constants.size() > 0 || selected_uniforms.size() > 0) { + popup_menu->add_separator("", NodeMenuOptions::SEPARATOR2); + + if (selected_constants.size() > 0) { + popup_menu->add_item(TTR("Convert Constant(s) to Uniform(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); + } + + if (selected_uniforms.size() > 0) { + popup_menu->add_item(TTR("Convert Uniforms(s) to Constant(s)"), NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS); + } + } + menu_point = graph->get_local_mouse_position(); Point2 gpos = Input::get_singleton()->get_mouse_position(); popup_menu->set_position(gpos); + popup_menu->set_size(Size2(-1, -1)); popup_menu->popup(); } } @@ -2445,7 +2855,7 @@ void VisualShaderEditor::_duplicate_nodes() { _dup_copy_nodes(type, nodes, excluded); - if (nodes.empty()) { + if (nodes.is_empty()) { return; } @@ -2463,7 +2873,7 @@ void VisualShaderEditor::_copy_nodes() { } void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 &p_custom_position) { - if (copy_nodes_buffer.empty()) { + if (copy_nodes_buffer.is_empty()) { return; } @@ -2695,6 +3105,14 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) { case NodeMenuOptions::DUPLICATE: _duplicate_nodes(); break; + case NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS: + _convert_constants_to_uniforms(false); + break; + case NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS: + _convert_constants_to_uniforms(true); + break; + default: + break; } } @@ -2799,15 +3217,35 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da void VisualShaderEditor::_show_preview_text() { preview_showed = !preview_showed; - preview_vbox->set_visible(preview_showed); if (preview_showed) { + if (preview_first) { + preview_window->set_size(Size2(400 * EDSCALE, 600 * EDSCALE)); + preview_window->popup_centered(); + preview_first = false; + } else { + preview_window->popup(); + } + _preview_size_changed(); + if (pending_update_preview) { _update_preview(); pending_update_preview = false; } + } else { + preview_window->hide(); } } +void VisualShaderEditor::_preview_close_requested() { + preview_showed = false; + preview_window->hide(); + preview_shader->set_pressed(false); +} + +void VisualShaderEditor::_preview_size_changed() { + preview_vbox->set_custom_minimum_size(preview_window->get_size()); +} + static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); return RS::global_variable_type_get_shader_datatype(gvt); @@ -2843,6 +3281,16 @@ void VisualShaderEditor::_update_preview() { } } +void VisualShaderEditor::_visibility_changed() { + if (!is_visible()) { + if (preview_window->is_visible()) { + preview_shader->set_pressed(false); + preview_window->hide(); + preview_showed = false; + } + } +} + void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph); ClassDB::bind_method("_update_options_menu", &VisualShaderEditor::_update_options_menu); @@ -2856,6 +3304,8 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_set_mode", &VisualShaderEditor::_set_mode); ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged); ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected); + ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant); + ClassDB::bind_method("_update_uniform", &VisualShaderEditor::_update_uniform); ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw); @@ -2873,7 +3323,6 @@ VisualShaderEditor::VisualShaderEditor() { saved_node_pos = Point2(0, 0); ShaderLanguage::get_keyword_list(&keyword_list); - preview_showed = false; pending_update_preview = false; shader_error = false; @@ -2882,17 +3331,14 @@ VisualShaderEditor::VisualShaderEditor() { from_node = -1; from_slot = -1; - main_box = memnew(HSplitContainer); - main_box->set_v_size_flags(SIZE_EXPAND_FILL); - main_box->set_h_size_flags(SIZE_EXPAND_FILL); - add_child(main_box); - graph = memnew(GraphEdit); graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL); graph->set_v_size_flags(SIZE_EXPAND_FILL); graph->set_h_size_flags(SIZE_EXPAND_FILL); - main_box->add_child(graph); + add_child(graph); graph->set_drag_forwarding(this); + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN); @@ -2912,6 +3358,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect("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("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); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR); @@ -2966,29 +3413,35 @@ VisualShaderEditor::VisualShaderEditor() { preview_shader = memnew(Button); preview_shader->set_flat(true); preview_shader->set_toggle_mode(true); - preview_shader->set_tooltip(TTR("Show resulted shader code.")); + preview_shader->set_tooltip(TTR("Show generated shader code.")); graph->get_zoom_hbox()->add_child(preview_shader); preview_shader->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_preview_text)); /////////////////////////////////////// - // PREVIEW PANEL + // PREVIEW WINDOW /////////////////////////////////////// + preview_window = memnew(Window); + preview_window->set_title(TTR("Generated shader code")); + preview_window->set_visible(preview_showed); + preview_window->connect("close_requested", callable_mp(this, &VisualShaderEditor::_preview_close_requested)); + preview_window->connect("size_changed", callable_mp(this, &VisualShaderEditor::_preview_size_changed)); + add_child(preview_window); + preview_vbox = memnew(VBoxContainer); - preview_vbox->set_visible(preview_showed); - main_box->add_child(preview_vbox); + preview_window->add_child(preview_vbox); + preview_text = memnew(CodeEdit); syntax_highlighter.instance(); preview_vbox->add_child(preview_text); - preview_text->set_h_size_flags(SIZE_EXPAND_FILL); - preview_text->set_v_size_flags(SIZE_EXPAND_FILL); - preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0)); + preview_text->set_v_size_flags(Control::SIZE_EXPAND_FILL); preview_text->set_syntax_highlighter(syntax_highlighter); preview_text->set_draw_line_numbers(true); preview_text->set_readonly(true); error_text = memnew(Label); preview_vbox->add_child(error_text); + error_text->set_autowrap(true); error_text->set_visible(false); /////////////////////////////////////// @@ -3121,8 +3574,11 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SwitchS", "Conditional", "Functions", "VisualShaderNodeScalarSwitch", TTR("Returns an associated scalar if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SwitchInt", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("SwitchTransform", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); @@ -3345,8 +3801,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeScalarClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Constrains a value to lie between two further values."), VisualShaderNodeIntFunc::FUNC_CLAMP, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeFloatFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -3359,7 +3815,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), VisualShaderNodeFloatOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), VisualShaderNodeFloatOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeScalarInterp", TTR("Linear interpolation between two scalars."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), VisualShaderNodeMix::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("MultiplyAdd", "Scalar", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeFloatFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeIntFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR_INT)); @@ -3375,8 +3831,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeFloatOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeFloatFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -3397,7 +3853,17 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + // SDF + { + add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + } + // TEXTURES + cubemap_node_option_idx = add_options.size(); add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1)); curve_node_option_idx = add_options.size(); @@ -3450,7 +3916,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeVectorClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -3468,8 +3934,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeVectorInterp", TTR("Linear interpolation between two vectors."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeVectorScalarMix", TTR("Linear interpolation between two vectors using scalar."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), VisualShaderNodeMix::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), VisualShaderNodeMix::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -3486,10 +3952,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -4007,10 +4473,17 @@ void VisualShaderNodePortPreview::_shader_changed() { for (int i = EditorNode::get_singleton()->get_editor_history()->get_path_size() - 1; i >= 0; i--) { Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(i)); + ShaderMaterial *src_mat; if (!object) { continue; } - ShaderMaterial *src_mat = Object::cast_to<ShaderMaterial>(object); + if (object->has_method("get_material_override")) { // trying getting material from MeshInstance + src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material_override")); + } else if (object->has_method("get_material")) { // from CanvasItem/Node2D + src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material")); + } else { + src_mat = Object::cast_to<ShaderMaterial>(object); + } if (src_mat && src_mat->get_shader().is_valid()) { List<PropertyInfo> params; src_mat->get_shader()->get_param_list(¶ms); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index a5983410f9..182bed6ba6 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -134,7 +134,6 @@ class VisualShaderEditor : public VBoxContainer { int editing_port; Ref<VisualShader> visual_shader; - HSplitContainer *main_box; GraphEdit *graph; Button *add_node; Button *preview_shader; @@ -148,6 +147,7 @@ class VisualShaderEditor : public VBoxContainer { bool pending_update_preview; bool shader_error; + Window *preview_window; VBoxContainer *preview_vbox; CodeEdit *preview_text; Ref<CodeHighlighter> syntax_highlighter; @@ -161,7 +161,8 @@ class VisualShaderEditor : public VBoxContainer { PopupMenu *popup_menu; MenuButton *tools; - bool preview_showed; + bool preview_first = true; + bool preview_showed = false; bool particles_mode; enum TypeFlags { @@ -188,6 +189,9 @@ class VisualShaderEditor : public VBoxContainer { PASTE, DELETE, DUPLICATE, + SEPARATOR2, // ignore + CONVERT_CONSTANTS_TO_UNIFORMS, + CONVERT_UNIFORMS_TO_CONSTANTS, }; Tree *members; @@ -272,11 +276,14 @@ class VisualShaderEditor : public VBoxContainer { void _add_texture3d_node(const String &p_path); void _add_curve_node(const String &p_path); + void _setup_node(VisualShaderNode *p_node, int p_op_idx); VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1); void _update_options_menu(); void _set_mode(int p_which); void _show_preview_text(); + void _preview_close_requested(); + void _preview_size_changed(); void _update_preview(); String _get_description(int p_idx); @@ -316,6 +323,14 @@ class VisualShaderEditor : public VBoxContainer { int from_node; int from_slot; + Set<int> selected_constants; + Set<int> selected_uniforms; + + void _convert_constants_to_uniforms(bool p_vice_versa); + void _replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to); + void _update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); + void _update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); + 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); @@ -388,6 +403,8 @@ class VisualShaderEditor : public VBoxContainer { void _update_uniforms(bool p_update_refs); void _update_uniform_refs(Set<String> &p_names); + void _visibility_changed(); + protected: void _notification(int p_what); static void _bind_methods(); |