summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_inspector.cpp333
-rw-r--r--editor/editor_inspector.h13
-rw-r--r--editor/editor_log.cpp4
-rw-r--r--editor/editor_node.cpp15
-rw-r--r--editor/editor_resource_picker.cpp2
-rw-r--r--editor/editor_settings.cpp4
-rw-r--r--editor/editor_themes.cpp4
-rw-r--r--editor/editor_toaster.cpp6
-rw-r--r--editor/icons/GradientTexture1D.svg (renamed from editor/icons/GradientTexture.svg)0
-rw-r--r--editor/icons/InterpCubic.svg2
-rw-r--r--editor/icons/InterpLinear.svg2
-rw-r--r--editor/icons/InterpWrapClamp.svg2
-rw-r--r--editor/icons/InterpWrapLoop.svg2
-rw-r--r--editor/icons/ReverseGradient.svg1
-rw-r--r--editor/icons/TrackCapture.svg2
-rw-r--r--editor/icons/TrackDiscrete.svg2
-rw-r--r--editor/icons/TrackTrigger.svg2
-rw-r--r--editor/import/editor_import_collada.cpp4
-rw-r--r--editor/import/resource_importer_bmfont.cpp29
-rw-r--r--editor/import/resource_importer_obj.cpp2
-rw-r--r--editor/import/resource_importer_scene.cpp20
-rw-r--r--editor/import/scene_import_settings.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp10
-rw-r--r--editor/plugins/editor_preview_plugins.cpp56
-rw-r--r--editor/plugins/editor_preview_plugins.h32
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp45
-rw-r--r--editor/plugins/gradient_editor_plugin.h16
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp12
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp28
-rw-r--r--editor/plugins/script_editor_plugin.cpp30
-rw-r--r--editor/plugins/script_text_editor.cpp4
-rw-r--r--editor/plugins/shader_editor_plugin.cpp5
-rw-r--r--editor/plugins/text_control_editor_plugin.cpp375
-rw-r--r--editor/plugins/text_control_editor_plugin.h119
-rw-r--r--editor/plugins/text_editor.cpp2
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp2
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp19
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h6
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--editor/property_editor.cpp44
-rw-r--r--editor/property_editor.h1
-rw-r--r--editor/rename_dialog.cpp6
-rw-r--r--editor/scene_tree_dock.cpp26
45 files changed, 928 insertions, 377 deletions
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 9f049a0e58..4ffa90777c 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -39,6 +39,7 @@
#include "editor_scale.h"
#include "editor_settings.h"
#include "multi_node_edit.h"
+#include "scene/property_utils.h"
#include "scene/resources/packed_scene.h"
Size2 EditorProperty::get_minimum_size() const {
@@ -305,6 +306,20 @@ void EditorProperty::_notification(int p_what) {
revert_rect = Rect2();
}
+ if (!pin_hidden && pinned) {
+ Ref<Texture2D> pinned_icon = get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"));
+ int margin_w = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2;
+ int total_icon_w = margin_w + pinned_icon->get_width();
+ int text_w = font->get_string_size(label, font_size, rtl ? HALIGN_RIGHT : HALIGN_LEFT, text_limit - total_icon_w).x;
+ int y = (size.height - pinned_icon->get_height()) / 2;
+ if (rtl) {
+ draw_texture(pinned_icon, Vector2(size.width - ofs - text_w - total_icon_w, y), color);
+ } else {
+ draw_texture(pinned_icon, Vector2(ofs + text_w + margin_w, y), color);
+ }
+ text_limit -= total_icon_w;
+ }
+
int v_ofs = (size.height - font->get_height(font_size)) / 2;
if (rtl) {
draw_string(font, Point2(size.width - ofs - text_limit, v_ofs + font->get_ascent(font_size)), label, HALIGN_RIGHT, text_limit, font_size, color);
@@ -398,177 +413,12 @@ bool EditorProperty::is_read_only() const {
return read_only;
}
-bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) {
- Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
-
- bool might_be = false;
- Node *node = p_node;
-
- while (node) {
- if (node == edited_scene) {
- if (node->get_scene_inherited_state().is_valid()) {
- might_be = true;
- break;
- }
- might_be = false;
- break;
- }
- if (node->get_scene_instance_state().is_valid()) {
- might_be = true;
- break;
- }
- node = node->get_owner();
- }
-
- return might_be; // or might not be
-}
-
-bool EditorPropertyRevert::get_instantiated_node_original_property(Node *p_node, const StringName &p_prop, Variant &value, bool p_check_class_default) {
- Node *node = p_node;
- Node *orig = node;
-
- Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
-
- bool found = false;
-
- while (node) {
- Ref<SceneState> ss;
-
- if (node == edited_scene) {
- ss = node->get_scene_inherited_state();
-
- } else {
- ss = node->get_scene_instance_state();
- }
-
- if (ss.is_valid()) {
- NodePath np = node->get_path_to(orig);
- int node_idx = ss->find_node_by_path(np);
- if (node_idx >= 0) {
- bool lfound = false;
- Variant lvar;
- lvar = ss->get_property_value(node_idx, p_prop, lfound);
- if (lfound) {
- found = true;
- value = lvar;
- }
- }
- }
- if (node == edited_scene) {
- //just in case
- break;
- }
- node = node->get_owner();
- }
-
- if (p_check_class_default && !found && p_node) {
- //if not found, try default class value
- Variant attempt = ClassDB::class_get_default_property_value(p_node->get_class_name(), p_prop);
- if (attempt.get_type() != Variant::NIL) {
- found = true;
- value = attempt;
- }
- }
-
- return found;
-}
-
-bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig) {
- // this is a pretty difficult function, because a property may not be saved but may have
- // the flag to not save if one or if zero
-
- //make sure there is an actual state
- {
- Node *node = p_node;
- if (!node) {
- return false;
- }
-
- Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
- bool found_state = false;
-
- while (node) {
- Ref<SceneState> ss;
-
- if (node == edited_scene) {
- ss = node->get_scene_inherited_state();
-
- } else {
- ss = node->get_scene_instance_state();
- }
-
- if (ss.is_valid()) {
- found_state = true;
- break;
- }
- if (node == edited_scene) {
- //just in case
- break;
- }
- node = node->get_owner();
- }
-
- if (!found_state) {
- return false; //pointless to check if we are not comparing against anything.
- }
- }
-
- return is_property_value_different(p_current, p_orig);
-}
-
-bool EditorPropertyRevert::is_property_value_different(const Variant &p_a, const Variant &p_b) {
- if (p_a.get_type() == Variant::FLOAT && p_b.get_type() == Variant::FLOAT) {
- //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
- return !Math::is_equal_approx((float)p_a, (float)p_b);
- } else {
- return p_a != p_b;
- }
-}
-
Variant EditorPropertyRevert::get_property_revert_value(Object *p_object, const StringName &p_property) {
- // If the object implements property_can_revert, rely on that completely
- // (i.e. don't then try to revert to default value - the property_get_revert implementation
- // can do that if so desired)
if (p_object->has_method("property_can_revert") && p_object->call("property_can_revert", p_property)) {
return p_object->call("property_get_revert", p_property);
}
- Ref<Script> scr = p_object->get_script();
- Node *node = Object::cast_to<Node>(p_object);
- if (node && EditorPropertyRevert::may_node_be_in_instance(node)) {
- //if this node is an instance or inherits, but it has a script attached which is unrelated
- //to the one set for the parent and also has a default value for the property, consider that
- //has precedence over the value from the parent, because that is an explicit source of defaults
- //closer in the tree to the current node
- bool ignore_parent = false;
- if (scr.is_valid()) {
- Variant sorig;
- if (EditorPropertyRevert::get_instantiated_node_original_property(node, "script", sorig) && !scr->inherits_script(sorig)) {
- Variant dummy;
- if (scr->get_property_default_value(p_property, dummy)) {
- ignore_parent = true;
- }
- }
- }
-
- if (!ignore_parent) {
- //check for difference including instantiation
- Variant vorig;
- if (EditorPropertyRevert::get_instantiated_node_original_property(node, p_property, vorig, false)) {
- return vorig;
- }
- }
- }
-
- if (scr.is_valid()) {
- Variant orig_value;
- if (scr->get_property_default_value(p_property, orig_value)) {
- return orig_value;
- }
- }
-
- //report default class value instead
- return ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property);
+ return PropertyUtils::get_property_default_value(p_object, p_property);
}
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) {
@@ -577,18 +427,25 @@ bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringNam
return false;
}
Variant current_value = p_object->get(p_property);
- return EditorPropertyRevert::is_property_value_different(current_value, revert_value);
+ return PropertyUtils::is_property_value_different(current_value, revert_value);
}
-void EditorProperty::update_reload_status() {
+void EditorProperty::update_revert_and_pin_status() {
if (property == StringName()) {
return; //no property, so nothing to do
}
- bool has_reload = EditorPropertyRevert::can_property_revert(object, property);
+ bool new_pinned = false;
+ if (can_pin) {
+ Node *node = Object::cast_to<Node>(object);
+ CRASH_COND(!node);
+ new_pinned = node->is_property_pinned(property);
+ }
+ bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property) && !is_read_only();
- if (has_reload != can_revert) {
- can_revert = has_reload;
+ if (new_can_revert != can_revert || new_pinned != pinned) {
+ can_revert = new_can_revert;
+ pinned = new_pinned;
update();
}
}
@@ -791,7 +648,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) {
emit_signal(SNAME("property_checked"), property, checked);
}
} else if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
- _ensure_popup();
+ _update_popup();
menu->set_position(get_screen_position() + get_local_mouse_position());
menu->set_size(Vector2(1, 1));
menu->popup();
@@ -914,6 +771,56 @@ float EditorProperty::get_name_split_ratio() const {
void EditorProperty::set_object_and_property(Object *p_object, const StringName &p_property) {
object = p_object;
property = p_property;
+ _update_pin_flags();
+}
+
+static bool _is_value_potential_override(Node *p_node, const String &p_property) {
+ // Consider a value is potentially overriding another if either of the following is true:
+ // a) The node is foreign (inheriting or an instance), so the original value may come from another scene.
+ // b) The node belongs to the scene, but the original value comes from somewhere but the builtin class (i.e., a script).
+ Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
+ Vector<SceneState::PackState> states_stack = PropertyUtils::get_node_states_stack(p_node, edited_scene);
+ if (states_stack.size()) {
+ return true;
+ } else {
+ bool is_class_default = false;
+ PropertyUtils::get_property_default_value(p_node, p_property, &states_stack, false, nullptr, &is_class_default);
+ return !is_class_default;
+ }
+}
+
+void EditorProperty::_update_pin_flags() {
+ can_pin = false;
+ pin_hidden = true;
+ if (read_only) {
+ return;
+ }
+ if (Node *node = Object::cast_to<Node>(object)) {
+ // Avoid errors down the road by ignoring nodes which are not part of a scene
+ if (!node->get_owner()) {
+ bool is_scene_root = false;
+ for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_edited_scene_count(); ++i) {
+ if (EditorNode::get_singleton()->get_editor_data().get_edited_scene_root(i) == node) {
+ is_scene_root = true;
+ break;
+ }
+ }
+ if (!is_scene_root) {
+ return;
+ }
+ }
+ if (!_is_value_potential_override(node, property)) {
+ return;
+ }
+ pin_hidden = false;
+ {
+ Set<StringName> storable_properties;
+ node->get_storable_properties(storable_properties);
+ if (storable_properties.has(node->get_property_store_alias(property))) {
+ can_pin = true;
+ }
+ }
+ }
}
Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
@@ -955,6 +862,10 @@ void EditorProperty::menu_option(int p_option) {
case MENU_COPY_PROPERTY_PATH: {
DisplayServer::get_singleton()->clipboard_set(property);
} break;
+ case MENU_PIN_VALUE: {
+ emit_signal(SNAME("property_pinned"), property, !pinned);
+ update();
+ } break;
}
}
@@ -1003,12 +914,14 @@ void EditorProperty::_bind_methods() {
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING_NAME, "property")));
ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property")));
ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
- ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::STRING, "bool")));
+ ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "checked")));
+ ADD_SIGNAL(MethodInfo("property_pinned", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "pinned")));
ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx")));
GDVIRTUAL_BIND(_update_property)
+ ClassDB::bind_method(D_METHOD("_update_revert_and_pin_status"), &EditorProperty::update_revert_and_pin_status);
}
EditorProperty::EditorProperty() {
@@ -1027,6 +940,9 @@ EditorProperty::EditorProperty() {
revert_hover = false;
check_hover = false;
can_revert = false;
+ can_pin = false;
+ pin_hidden = false;
+ pinned = false;
use_folding = false;
property_usage = 0;
selected = false;
@@ -1038,17 +954,29 @@ EditorProperty::EditorProperty() {
set_process_unhandled_key_input(true);
}
-void EditorProperty::_ensure_popup() {
+void EditorProperty::_update_popup() {
if (menu) {
- return;
+ menu->clear();
+ } else {
+ menu = memnew(PopupMenu);
+ add_child(menu);
+ menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
}
- menu = memnew(PopupMenu);
menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property"), MENU_COPY_PROPERTY);
menu->add_shortcut(ED_GET_SHORTCUT("property_editor/paste_property"), MENU_PASTE_PROPERTY);
menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
- menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
menu->set_item_disabled(MENU_PASTE_PROPERTY, is_read_only());
- add_child(menu);
+ if (!pin_hidden) {
+ menu->add_separator();
+ if (can_pin) {
+ menu->add_check_item(TTR("Pin value"), MENU_PIN_VALUE);
+ menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), pinned);
+ menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default."));
+ } else {
+ menu->add_check_item(vformat(TTR("Pin value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
+ menu->set_item_disabled(menu->get_item_index(MENU_PIN_VALUE), true);
+ }
+ }
}
////////////////////////////////////////////////
@@ -2296,6 +2224,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED);
ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value));
ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked));
+ ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned));
ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected));
ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed));
ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED);
@@ -2324,7 +2253,8 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->set_read_only(read_only);
ep->update_property();
- ep->update_reload_status();
+ ep->_update_pin_flags();
+ ep->update_revert_and_pin_status();
ep->set_deletable(deletable_properties);
ep->update_cache();
}
@@ -2877,6 +2807,7 @@ void EditorInspector::update_tree() {
ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED);
ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value));
ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked));
+ ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned));
ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected));
ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed));
ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED);
@@ -2887,7 +2818,8 @@ void EditorInspector::update_tree() {
ep->set_tooltip(property_prefix + p.name);
}
ep->update_property();
- ep->update_reload_status();
+ ep->_update_pin_flags();
+ ep->update_revert_and_pin_status();
ep->update_cache();
if (current_selected && ep->property == current_selected) {
@@ -2917,7 +2849,7 @@ void EditorInspector::update_property(const String &p_prop) {
for (EditorProperty *E : editor_property_map[p_prop]) {
E->update_property();
- E->update_reload_status();
+ E->update_revert_and_pin_status();
E->update_cache();
}
}
@@ -3196,7 +3128,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
if (editor_property_map.has(p_name)) {
for (EditorProperty *E : editor_property_map[p_name]) {
- E->update_reload_status();
+ E->update_revert_and_pin_status();
}
}
}
@@ -3295,7 +3227,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
if (editor_property_map.has(p_path)) {
for (EditorProperty *E : editor_property_map[p_path]) {
E->update_property();
- E->update_reload_status();
+ E->update_revert_and_pin_status();
E->update_cache();
}
}
@@ -3305,6 +3237,35 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
}
}
+void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) {
+ if (!object) {
+ return;
+ }
+
+ Node *node = Object::cast_to<Node>(object);
+ ERR_FAIL_COND(!node);
+
+ if (undo_redo) {
+ undo_redo->create_action(vformat(p_pinned ? TTR("Pinned %s") : TTR("Unpinned %s"), p_path));
+ undo_redo->add_do_method(node, "_set_property_pinned", p_path, p_pinned);
+ undo_redo->add_undo_method(node, "_set_property_pinned", p_path, !p_pinned);
+ if (editor_property_map.has(p_path)) {
+ for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
+ undo_redo->add_do_method(E->get(), "_update_revert_and_pin_status");
+ undo_redo->add_undo_method(E->get(), "_update_revert_and_pin_status");
+ }
+ }
+ undo_redo->commit_action();
+ } else {
+ node->set_property_pinned(p_path, p_pinned);
+ if (editor_property_map.has(p_path)) {
+ for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
+ E->get()->update_revert_and_pin_status();
+ }
+ }
+ }
+}
+
void EditorInspector::_property_selected(const String &p_path, int p_focusable) {
property_selected = p_path;
property_focusable = p_focusable;
@@ -3375,7 +3336,7 @@ void EditorInspector::_notification(int p_what) {
for (EditorProperty *E : F.value) {
if (!E->is_cache_valid()) {
E->update_property();
- E->update_reload_status();
+ E->update_revert_and_pin_status();
E->update_cache();
}
}
@@ -3397,7 +3358,7 @@ void EditorInspector::_notification(int p_what) {
if (editor_property_map.has(prop)) {
for (EditorProperty *E : editor_property_map[prop]) {
E->update_property();
- E->update_reload_status();
+ E->update_revert_and_pin_status();
E->update_cache();
}
}
@@ -3490,7 +3451,7 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
String path = s->get_path();
String name = EditorNode::get_editor_data().script_class_get_name(path);
if (name.is_empty()) {
- if (!path.is_empty() && path.find("::") == -1) {
+ if (!s->is_built_in()) {
name = path.get_file();
} else {
name = TTR("Built-in script");
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 124ea31302..aabb66eeb4 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -43,7 +43,6 @@ class UndoRedo;
class EditorPropertyRevert {
public:
- static bool may_node_be_in_instance(Node *p_node);
static bool get_instantiated_node_original_property(Node *p_node, const StringName &p_prop, Variant &value, bool p_check_class_default = true);
static bool is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig);
static bool is_property_value_different(const Variant &p_a, const Variant &p_b);
@@ -60,6 +59,7 @@ public:
MENU_COPY_PROPERTY,
MENU_PASTE_PROPERTY,
MENU_COPY_PROPERTY_PATH,
+ MENU_PIN_VALUE,
};
private:
@@ -91,11 +91,14 @@ private:
bool delete_hover = false;
bool can_revert;
+ bool can_pin;
+ bool pin_hidden;
+ bool pinned;
bool use_folding;
bool draw_top_bg;
- void _ensure_popup();
+ void _update_popup();
void _focusable_focused(int p_index);
bool selectable;
@@ -114,6 +117,8 @@ private:
Map<StringName, Variant> cache;
GDVIRTUAL0(_update_property)
+ void _update_pin_flags();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -138,7 +143,7 @@ public:
StringName get_edited_property();
virtual void update_property();
- void update_reload_status();
+ void update_revert_and_pin_status();
virtual bool use_keying_next() const;
@@ -459,8 +464,8 @@ class EditorInspector : public ScrollContainer {
void _property_keyed(const String &p_path, bool p_advance);
void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance);
void _property_deleted(const String &p_path);
-
void _property_checked(const String &p_path, bool p_checked);
+ void _property_pinned(const String &p_path, bool p_pinned);
void _resource_selected(const String &p_path, RES p_resource);
void _property_selected(const String &p_path, int p_focusable);
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 251e1c2385..5f2f8e91c9 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -45,9 +45,9 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f
String err_str;
if (p_errorexp && p_errorexp[0]) {
- err_str = p_errorexp;
+ err_str = String::utf8(p_errorexp);
} else {
- err_str = String(p_file) + ":" + itos(p_line) + " - " + String(p_error);
+ err_str = String::utf8(p_file) + ":" + itos(p_line) + " - " + String::utf8(p_error);
}
if (p_editor_notify) {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index bb4a05efba..4af7763caa 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -174,6 +174,7 @@
#include "editor/plugins/sprite_frames_editor_plugin.h"
#include "editor/plugins/style_box_editor_plugin.h"
#include "editor/plugins/sub_viewport_preview_editor_plugin.h"
+#include "editor/plugins/text_control_editor_plugin.h"
#include "editor/plugins/text_editor.h"
#include "editor/plugins/texture_3d_editor_plugin.h"
#include "editor/plugins/texture_editor_plugin.h"
@@ -1791,7 +1792,7 @@ void EditorNode::_save_all_scenes() {
} else {
_save_scene_with_preview(scene->get_scene_file_path());
}
- } else {
+ } else if (scene->get_scene_file_path() != "") {
all_saved = false;
}
}
@@ -2256,7 +2257,8 @@ void EditorNode::_edit_current() {
if (main_plugin) {
// special case if use of external editor is true
- if (main_plugin->get_name() == "Script" && current_obj->get_class_name() != StringName("VisualScript") && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
+ Resource *res = Object::cast_to<Resource>(current_obj);
+ if (main_plugin->get_name() == "Script" && current_obj->get_class_name() != StringName("VisualScript") && res && !res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
if (!changing_scene) {
main_plugin->edit(current_obj);
}
@@ -3356,7 +3358,7 @@ void EditorNode::set_edited_scene(Node *p_scene) {
if (p_scene) {
if (p_scene->get_parent() != scene_root) {
- scene_root->add_child(p_scene);
+ scene_root->add_child(p_scene, true);
}
}
}
@@ -3488,7 +3490,7 @@ void EditorNode::set_current_scene(int p_idx) {
if (new_scene) {
if (new_scene->get_parent() != scene_root) {
- scene_root->add_child(new_scene);
+ scene_root->add_child(new_scene, true);
}
}
@@ -3622,7 +3624,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
sdata->set_path(lpath, true); // take over path
}
- Node *new_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_MAIN);
+ Node *new_scene = sdata->instantiate(p_set_inherited ? PackedScene::GEN_EDIT_STATE_MAIN_INHERITED : PackedScene::GEN_EDIT_STATE_MAIN);
if (!new_scene) {
sdata.unref();
@@ -7009,6 +7011,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(GPUParticlesCollisionSDFEditorPlugin(this)));
add_editor_plugin(memnew(InputEventEditorPlugin(this)));
add_editor_plugin(memnew(SubViewportPreviewEditorPlugin(this)));
+ add_editor_plugin(memnew(TextControlEditorPlugin(this)));
for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) {
add_editor_plugin(EditorPlugins::create(i, this));
@@ -7139,8 +7142,6 @@ EditorNode::EditorNode() {
_build_icon_type_cache();
- Node::set_human_readable_collision_renaming(true);
-
pick_main_scene = memnew(ConfirmationDialog);
gui_base->add_child(pick_main_scene);
pick_main_scene->get_ok_button()->set_text(TTR("Select"));
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index f05c401f1d..4775ca418b 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -84,7 +84,7 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const
if (p_preview.is_valid()) {
preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox(SNAME("normal"))->get_default_margin(SIDE_LEFT) + get_theme_constant(SNAME("hseparation"), SNAME("Button")));
- if (type == "GradientTexture") {
+ if (type == "GradientTexture1D") {
preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE);
assign_button->set_custom_minimum_size(Size2(1, 1));
} else {
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 1da9213b89..739fc0e4f5 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -293,8 +293,8 @@ void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(pi);
}
- p_list->push_back(PropertyInfo(Variant::ARRAY, "shortcuts", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); //do not edit
- p_list->push_back(PropertyInfo(Variant::ARRAY, "builtin_action_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "shortcuts", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); //do not edit
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "builtin_action_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
void EditorSettings::_add_property_info_bind(const Dictionary &p_info) {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 06c39a957c..8e8437f1b2 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1207,7 +1207,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0));
theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE);
theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE);
- theme->set_constant("shadow_as_outline", "RichTextLabel", 0 * EDSCALE);
+ theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * EDSCALE);
theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox());
theme->set_stylebox("normal", "RichTextLabel", style_tree_bg);
@@ -1223,7 +1223,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0));
theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE);
theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE);
- theme->set_constant("shadow_as_outline", "Label", 0 * EDSCALE);
+ theme->set_constant("shadow_outline_size", "Label", 1 * EDSCALE);
theme->set_constant("line_spacing", "Label", 3 * EDSCALE);
// LinkButton
diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp
index 22da12b59b..0d9a546b8e 100644
--- a/editor/editor_toaster.cpp
+++ b/editor/editor_toaster.cpp
@@ -158,11 +158,11 @@ void EditorToaster::_error_handler(void *p_self, const char *p_func, const char
if (p_editor_notify || (show_all_setting == 0 && in_dev) || show_all_setting == 1) {
String err_str;
if (p_errorexp && p_errorexp[0]) {
- err_str = p_errorexp;
+ err_str = String::utf8(p_errorexp);
} else {
- err_str = String(p_error);
+ err_str = String::utf8(p_error);
}
- String tooltip_str = String(p_file) + ":" + itos(p_line);
+ String tooltip_str = String::utf8(p_file) + ":" + itos(p_line);
if (!p_editor_notify) {
if (p_type == ERR_HANDLER_WARNING) {
diff --git a/editor/icons/GradientTexture.svg b/editor/icons/GradientTexture1D.svg
index fa03e69805..fa03e69805 100644
--- a/editor/icons/GradientTexture.svg
+++ b/editor/icons/GradientTexture1D.svg
diff --git a/editor/icons/InterpCubic.svg b/editor/icons/InterpCubic.svg
index ad2ed51ee1..b542986ea6 100644
--- a/editor/icons/InterpCubic.svg
+++ b/editor/icons/InterpCubic.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c3 0 3-4 6-4s3 4 6 4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 3-4 6-4s1 4 6 4" fill="none" stroke="#5fb2ff" stroke-linecap="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
diff --git a/editor/icons/InterpLinear.svg b/editor/icons/InterpLinear.svg
index 241a82fc8f..966ddfdc31 100644
--- a/editor/icons/InterpLinear.svg
+++ b/editor/icons/InterpLinear.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 6-4 6 4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 6-4 6 4" fill="none" stroke="#ffca5f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
diff --git a/editor/icons/InterpWrapClamp.svg b/editor/icons/InterpWrapClamp.svg
index 6ba8e78500..b589542019 100644
--- a/editor/icons/InterpWrapClamp.svg
+++ b/editor/icons/InterpWrapClamp.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v6h2v-2.9863-3.0137zm2 3.0137a1.0001 1.0001 0 0 0 .29297.69336l2 2a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-.29297-.29297h3.1719l-.29297.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 .29297-.72266 1.0001 1.0001 0 0 0 -.29297-.69141l-2-2a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l.29297.29297h-3.1719l.29297-.29297a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-2 2a1.0001 1.0001 0 0 0 -.29297.7207zm10-.029297v3.0156h2v-6h-2z" fill="#e0e0e0"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v6h2v-2.9863-3.0137zm2 3.0137a1.0001 1.0001 0 0 0 .29297.69336l2 2a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-.29297-.29297h3.1719l-.29297.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 .29297-.72266 1.0001 1.0001 0 0 0 -.29297-.69141l-2-2a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l.29297.29297h-3.1719l.29297-.29297a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-2 2a1.0001 1.0001 0 0 0 -.29297.7207zm10-.029297v3.0156h2v-6h-2z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/InterpWrapLoop.svg b/editor/icons/InterpWrapLoop.svg
index 57670f97ce..4faf7805f8 100644
--- a/editor/icons/InterpWrapLoop.svg
+++ b/editor/icons/InterpWrapLoop.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 0-3 2 3 2v-1h3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3h-3zm-5 1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h3v1l3-2-3-2v1h-3a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#e0e0e0"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 0-3 2 3 2v-1h3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3h-3zm-5 1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h3v1l3-2-3-2v1h-3a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#c38ef1"/></svg>
diff --git a/editor/icons/ReverseGradient.svg b/editor/icons/ReverseGradient.svg
new file mode 100644
index 0000000000..12f80d12dd
--- /dev/null
+++ b/editor/icons/ReverseGradient.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="b" x1=".26458" x2="3.9688" y1=".79375" y2=".79375" gradientTransform="scale(3.7795)" gradientUnits="userSpaceOnUse"><stop stop-color="#ccc" offset="0"/><stop stop-color="#ccc" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="a" x1=".26458" x2="3.9688" y1="3.4396" y2="3.4396" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -1.1865e-7)" gradientUnits="userSpaceOnUse"><stop stop-color="#ccc" offset="0"/><stop stop-color="#ccc" stop-opacity="0" offset="1"/></linearGradient></defs><g><rect x="1" y="1" width="14" height="4" ry="1" fill="url(#b)"/><rect transform="scale(-1,1)" x="-15" y="11" width="14" height="4" ry="1" fill="url(#a)" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.7795"/><path d="m6 6 2 4 2-4z" fill="#ccc"/></g></svg>
diff --git a/editor/icons/TrackCapture.svg b/editor/icons/TrackCapture.svg
index aaa4a20e4a..b3d5f09eff 100644
--- a/editor/icons/TrackCapture.svg
+++ b/editor/icons/TrackCapture.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m2.1665128.99764963c-.422625 0-.763672.34104737-.763672.76367187v4.5742187c0 .4226242.341047.7617192.763672.7617192h4.472656c.422625 0 .763672-.339095.763672-.7617192v-.9882812h-3.300781c-.1662 0-.298828-.3390943-.298828-.7617188v-1.2246094c0-.4226244.132628-.7636718.298828-.7636718h3.300781v-.8359375c0-.4226245-.341047-.76367187-.763672-.76367187z"/><path d="m9.1827441 4.7953408c.5166221-1.0415625 1.0955249-2.2117429 1.2864509-2.600401l.347137-.7066511.679654.00665.679654.00665.956945 2.3125c.526319 1.271875 1.007254 2.4334375 1.068744 2.5812497l.1118.26875h-.597215-.597214l-.332849-.6437497-.332849-.64375h-1.133826-1.133825l-.3786749.6561133-.3786747.6561134-.5922856.000137-.592285.000136zm3.1779349-.369483c.0042-.00346-.233487-.4884588-.528245-1.0777779l-.535922-1.0714891-.03691.0875c-.0203.048125-.183516.425-.362699.8375-.179182.4125-.355738.85125-.392346.975-.03661.12375-.07127.2390723-.07703.2562715-.0083.024853.188215.027989.957503.015278.532385-.0088.971429-.018823.975651-.022283z" stroke="#e0e0e0" stroke-width=".803"/></g></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e1da5b"><path d="m2.1665128.99764963c-.422625 0-.763672.34104737-.763672.76367187v4.5742187c0 .4226242.341047.7617192.763672.7617192h4.472656c.422625 0 .763672-.339095.763672-.7617192v-.9882812h-3.300781c-.1662 0-.298828-.3390943-.298828-.7617188v-1.2246094c0-.4226244.132628-.7636718.298828-.7636718h3.300781v-.8359375c0-.4226245-.341047-.76367187-.763672-.76367187z"/><path d="m9.1827441 4.7953408c.5166221-1.0415625 1.0955249-2.2117429 1.2864509-2.600401l.347137-.7066511.679654.00665.679654.00665.956945 2.3125c.526319 1.271875 1.007254 2.4334375 1.068744 2.5812497l.1118.26875h-.597215-.597214l-.332849-.6437497-.332849-.64375h-1.133826-1.133825l-.3786749.6561133-.3786747.6561134-.5922856.000137-.592285.000136zm3.1779349-.369483c.0042-.00346-.233487-.4884588-.528245-1.0777779l-.535922-1.0714891-.03691.0875c-.0203.048125-.183516.425-.362699.8375-.179182.4125-.355738.85125-.392346.975-.03661.12375-.07127.2390723-.07703.2562715-.0083.024853.188215.027989.957503.015278.532385-.0088.971429-.018823.975651-.022283z" stroke="#e1da5b" stroke-width=".803"/></g></svg>
diff --git a/editor/icons/TrackDiscrete.svg b/editor/icons/TrackDiscrete.svg
index d1df4b1667..6498742233 100644
--- a/editor/icons/TrackDiscrete.svg
+++ b/editor/icons/TrackDiscrete.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-6 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-6 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#e0e0e0"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-6 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-6 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#b9ec41"/></svg>
diff --git a/editor/icons/TrackTrigger.svg b/editor/icons/TrackTrigger.svg
index 6e46a74121..c403fba59a 100644
--- a/editor/icons/TrackTrigger.svg
+++ b/editor/icons/TrackTrigger.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h2v4h2v-4h2v-2zm13 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-3 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-3 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#e0e0e0"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h2v4h2v-4h2v-2zm13 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-3 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-3 2a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#f68f45"/></svg>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index f9aa550e7d..076c0cc62b 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -314,7 +314,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
xf = collada.fix_transform(xf) * p_node->post_transform;
node->set_transform(xf);
- p_parent->add_child(node);
+ p_parent->add_child(node, true);
node->set_owner(scene);
if (p_node->empty_draw_type != "") {
@@ -1804,7 +1804,7 @@ Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint3
ap->add_animation(name, state.animations[i]);
}
- state.scene->add_child(ap);
+ state.scene->add_child(ap, true);
ap->set_owner(state.scene);
}
diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp
index 2e7ef1402b..a64be54f2d 100644
--- a/editor/import/resource_importer_bmfont.cpp
+++ b/editor/import/resource_importer_bmfont.cpp
@@ -359,6 +359,8 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
int height = 0;
int ascent = 0;
int outline = 0;
+ uint32_t st_flags = 0;
+ String font_name;
bool packed = false;
uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA
@@ -382,13 +384,23 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
base_size = f->get_16();
uint8_t flags = f->get_8();
ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
+ if (flags & (1 << 3)) {
+ st_flags |= TextServer::FONT_BOLD;
+ }
+ if (flags & (1 << 2)) {
+ st_flags |= TextServer::FONT_ITALIC;
+ }
f->get_8(); // non-unicode charset, skip
f->get_16(); // stretch_h, skip
f->get_8(); // aa, skip
f->get_32(); // padding, skip
f->get_16(); // spacing, skip
outline = f->get_8();
- // font name, skip
+ // font name
+ PackedByteArray name_data;
+ name_data.resize(block_size - 14);
+ f->get_buffer(name_data.ptrw(), block_size - 14);
+ font_name = String::utf8((const char *)name_data.ptr(), block_size - 14);
font->set_fixed_size(base_size);
} break;
case 2: /* common */ {
@@ -601,6 +613,19 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
if (keys.has("outline")) {
outline = keys["outline"].to_int();
}
+ if (keys.has("bold")) {
+ if (keys["bold"].to_int()) {
+ st_flags |= TextServer::FONT_BOLD;
+ }
+ }
+ if (keys.has("italic")) {
+ if (keys["italic"].to_int()) {
+ st_flags |= TextServer::FONT_ITALIC;
+ }
+ }
+ if (keys.has("face")) {
+ font_name = keys["face"];
+ }
ERR_FAIL_COND_V_MSG((!keys.has("unicode") || keys["unicode"].to_int() != 1), ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
} else if (type == "common") {
if (keys.has("lineHeight")) {
@@ -778,6 +803,8 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
}
}
+ font->set_font_name(font_name);
+ font->set_font_style(st_flags);
font->set_ascent(0, base_size, ascent);
font->set_descent(0, base_size, height - ascent);
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 4f75faedcb..01af75c338 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -448,7 +448,7 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
ImporterMeshInstance3D *mi = memnew(ImporterMeshInstance3D);
mi->set_mesh(mesh);
mi->set_name(m->get_name());
- scene->add_child(mi);
+ scene->add_child(mi, true);
mi->set_owner(scene);
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 7d3b945b04..5efb08b95d 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -502,7 +502,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
sphereShape->set_radius(1);
colshape->set_shape(sphereShape);
}
- sb->add_child(colshape);
+ sb->add_child(colshape, true);
colshape->set_owner(sb->get_owner());
}
@@ -528,7 +528,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
rigid_body->set_transform(mi->get_transform());
p_node = rigid_body;
mi->set_transform(Transform3D());
- rigid_body->add_child(mi);
+ rigid_body->add_child(mi, true);
mi->set_owner(rigid_body->get_owner());
_add_shapes(rigid_body, shapes);
@@ -566,7 +566,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
if (shapes.size()) {
StaticBody3D *col = memnew(StaticBody3D);
- mi->add_child(col);
+ mi->add_child(col, true);
col->set_owner(mi->get_owner());
_add_shapes(col, shapes);
@@ -614,7 +614,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
if (shapes.size()) {
StaticBody3D *col = memnew(StaticBody3D);
- p_node->add_child(col);
+ p_node->add_child(col, true);
col->set_owner(p_node->get_owner());
_add_shapes(col, shapes);
@@ -749,7 +749,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
switch (mesh_physics_mode) {
case MESH_PHYSICS_MESH_AND_STATIC_COLLIDER: {
StaticBody3D *col = memnew(StaticBody3D);
- p_node->add_child(col);
+ p_node->add_child(col, true);
col->set_owner(p_node->get_owner());
col->set_transform(get_collision_shapes_transform(node_settings));
base = col;
@@ -761,7 +761,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
rigid_body->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
p_node = rigid_body;
mi->set_transform(Transform3D());
- rigid_body->add_child(mi);
+ rigid_body->add_child(mi, true);
mi->set_owner(rigid_body->get_owner());
base = rigid_body;
} break;
@@ -790,7 +790,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
for (const Ref<Shape3D> &E : shapes) {
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E);
- base->add_child(cshape);
+ base->add_child(cshape, true);
cshape->set_owner(base->get_owner());
idx++;
@@ -823,7 +823,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
memdelete(p_node);
p_node = nmi;
} else {
- mi->add_child(nmi);
+ mi->add_child(nmi, true);
nmi->set_owner(mi->get_owner());
}
}
@@ -1431,7 +1431,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
- r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), Dictionary()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary()));
for (int i = 0; i < post_importer_plugins.size(); i++) {
post_importer_plugins.write[i]->get_import_options(r_options);
@@ -1680,7 +1680,7 @@ void ResourceImporterScene::_add_shapes(Node *p_node, const Vector<Ref<Shape3D>>
for (const Ref<Shape3D> &E : p_shapes) {
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E);
- p_node->add_child(cshape);
+ p_node->add_child(cshape, true);
cshape->set_owner(p_node->get_owner());
}
diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index 95a96f9e26..9b9320ad6d 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -327,7 +327,7 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
MeshInstance3D *collider_view = memnew(MeshInstance3D);
collider_view->set_name("collider_view");
collider_view->set_visible(false);
- mesh_node->add_child(collider_view);
+ mesh_node->add_child(collider_view, true);
collider_view->set_owner(mesh_node);
Transform3D accum_xform;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 0e1bdf0155..061483decf 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2264,9 +2264,9 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
}
- if (b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_ctrl_pressed()) {
- add_node_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ if (b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT) {
add_node_menu->set_size(Vector2(1, 1));
+ add_node_menu->set_position(get_screen_position() + b->get_position());
add_node_menu->popup();
node_create_position = transform.affine_inverse().xform((get_local_mouse_position()));
return true;
@@ -5836,7 +5836,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(ResourceCache::get(path)));
if (parent) {
- editor_data->get_undo_redo().add_do_method(parent, "add_child", child);
+ editor_data->get_undo_redo().add_do_method(parent, "add_child", child, true);
editor_data->get_undo_redo().add_do_method(child, "set_owner", editor->get_edited_scene());
editor_data->get_undo_redo().add_do_reference(child);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", child);
@@ -6192,14 +6192,14 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
label = memnew(Label);
label->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 1));
- label->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE);
+ label->add_theme_constant_override("shadow_outline_size", 1 * EDSCALE);
label->hide();
canvas_item_editor->get_controls_container()->add_child(label);
label_desc = memnew(Label);
label_desc->add_theme_color_override("font_color", Color(0.6f, 0.6f, 0.6f, 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("shadow_outline_size", 1 * EDSCALE);
label_desc->add_theme_constant_override("line_spacing", 0);
label_desc->hide();
canvas_item_editor->get_controls_container()->add_child(label_desc);
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 4cb2c0a76b..9702c7e734 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -297,12 +297,14 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
//////////////////////////////////////////////////////////////////
-void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) {
- preview_done.set();
+void EditorMaterialPreviewPlugin::_generate_frame_started() {
+ RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+
+ RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_preview_done));
}
-void EditorMaterialPreviewPlugin::_bind_methods() {
- ClassDB::bind_method("_preview_done", &EditorMaterialPreviewPlugin::_preview_done);
+void EditorMaterialPreviewPlugin::_preview_done() {
+ preview_done.post();
}
bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
@@ -320,14 +322,9 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si
if (material->get_shader_mode() == Shader::MODE_SPATIAL) {
RS::get_singleton()->mesh_surface_set_material(sphere, 0, material->get_rid());
- RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+ RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
- preview_done.clear();
- RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant());
-
- while (!preview_done.is_set()) {
- OS::get_singleton()->delay_usec(10);
- }
+ preview_done.wait();
Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
RS::get_singleton()->mesh_surface_set_material(sphere, 0, RID());
@@ -699,12 +696,14 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
-void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) {
- preview_done.set();
+void EditorMeshPreviewPlugin::_generate_frame_started() {
+ RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+
+ RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_preview_done));
}
-void EditorMeshPreviewPlugin::_bind_methods() {
- ClassDB::bind_method("_preview_done", &EditorMeshPreviewPlugin::_preview_done);
+void EditorMeshPreviewPlugin::_preview_done() {
+ preview_done.post();
}
bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
@@ -735,14 +734,9 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2
xform.origin.z -= rot_aabb.size.z * 2;
RS::get_singleton()->instance_set_transform(mesh_instance, xform);
- RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+ RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
- preview_done.clear();
- RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant());
-
- while (!preview_done.is_set()) {
- OS::get_singleton()->delay_usec(10);
- }
+ preview_done.wait();
Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>());
@@ -814,12 +808,14 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
-void EditorFontPreviewPlugin::_preview_done(const Variant &p_udata) {
- preview_done.set();
+void EditorFontPreviewPlugin::_generate_frame_started() {
+ RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+
+ RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_preview_done));
}
-void EditorFontPreviewPlugin::_bind_methods() {
- ClassDB::bind_method("_preview_done", &EditorFontPreviewPlugin::_preview_done);
+void EditorFontPreviewPlugin::_preview_done() {
+ preview_done.post();
}
bool EditorFontPreviewPlugin::handles(const String &p_type) const {
@@ -857,13 +853,9 @@ 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.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());
+ RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
- while (!preview_done.is_set()) {
- OS::get_singleton()->delay_usec(10);
- }
+ preview_done.wait();
RS::get_singleton()->canvas_item_clear(canvas_item);
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 091feae5fb..bf52f5771d 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -92,12 +92,10 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- mutable SafeFlag preview_done;
+ Semaphore preview_done;
- void _preview_done(const Variant &p_udata);
-
-protected:
- static void _bind_methods();
+ void _generate_frame_started();
+ void _preview_done();
public:
virtual bool handles(const String &p_type) const override;
@@ -136,12 +134,10 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- mutable SafeFlag preview_done;
-
- void _preview_done(const Variant &p_udata);
+ Semaphore preview_done;
-protected:
- static void _bind_methods();
+ void _generate_frame_started();
+ void _preview_done();
public:
virtual bool handles(const String &p_type) const override;
@@ -158,12 +154,10 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator {
RID viewport_texture;
RID canvas;
RID canvas_item;
- mutable SafeFlag preview_done;
+ Semaphore preview_done;
- void _preview_done(const Variant &p_udata);
-
-protected:
- static void _bind_methods();
+ void _generate_frame_started();
+ void _preview_done();
public:
virtual bool handles(const String &p_type) const override;
@@ -177,12 +171,10 @@ public:
class EditorTileMapPatternPreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorTileMapPatternPreviewPlugin, EditorResourcePreviewGenerator);
- mutable SafeFlag preview_done;
-
- void _preview_done(const Variant &p_udata);
+ Semaphore preview_done;
-protected:
- static void _bind_methods();
+ void _generate_frame_started();
+ void _preview_done();
public:
virtual bool handles(const String &p_type) const override;
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 355bdb69d8..da050abc02 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -46,6 +46,8 @@ void GradientEditor::_gradient_changed() {
editing = true;
Vector<Gradient::Point> points = gradient->get_points();
set_points(points);
+ set_interpolation_mode(gradient->get_interpolation_mode());
+ update();
editing = false;
}
@@ -55,8 +57,10 @@ void GradientEditor::_ramp_changed() {
undo_redo->create_action(TTR("Gradient Edited"));
undo_redo->add_do_method(gradient.ptr(), "set_offsets", get_offsets());
undo_redo->add_do_method(gradient.ptr(), "set_colors", get_colors());
+ undo_redo->add_do_method(gradient.ptr(), "set_interpolation_mode", get_interpolation_mode());
undo_redo->add_undo_method(gradient.ptr(), "set_offsets", gradient->get_offsets());
undo_redo->add_undo_method(gradient.ptr(), "set_colors", gradient->get_colors());
+ undo_redo->add_undo_method(gradient.ptr(), "set_interpolation_mode", gradient->get_interpolation_mode());
undo_redo->commit_action();
editing = false;
}
@@ -69,6 +73,14 @@ void GradientEditor::set_gradient(const Ref<Gradient> &p_gradient) {
connect("ramp_changed", callable_mp(this, &GradientEditor::_ramp_changed));
gradient->connect("changed", callable_mp(this, &GradientEditor::_gradient_changed));
set_points(gradient->get_points());
+ set_interpolation_mode(gradient->get_interpolation_mode());
+}
+
+void GradientEditor::reverse_gradient() {
+ gradient->reverse();
+ set_points(gradient->get_points());
+ emit_signal(SNAME("ramp_changed"));
+ update();
}
GradientEditor::GradientEditor() {
@@ -77,6 +89,23 @@ GradientEditor::GradientEditor() {
///////////////////////
+void GradientReverseButton::_notification(int p_what) {
+ if (p_what == NOTIFICATION_DRAW) {
+ Ref<Texture2D> icon = get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons"));
+ if (is_pressed()) {
+ draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()), false, get_theme_color(SNAME("icon_pressed_color"), SNAME("Button")));
+ } else {
+ draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()));
+ }
+ }
+}
+
+Size2 GradientReverseButton::get_minimum_size() const {
+ return (get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons"))->get_size() + Size2(margin * 2, margin * 2));
+}
+
+///////////////////////
+
bool EditorInspectorPluginGradient::can_handle(Object *p_object) {
return Object::cast_to<Gradient>(p_object) != nullptr;
}
@@ -85,9 +114,23 @@ void EditorInspectorPluginGradient::parse_begin(Object *p_object) {
Gradient *gradient = Object::cast_to<Gradient>(p_object);
Ref<Gradient> g(gradient);
- GradientEditor *editor = memnew(GradientEditor);
+ editor = memnew(GradientEditor);
editor->set_gradient(g);
add_custom_control(editor);
+
+ reverse_btn = memnew(GradientReverseButton);
+
+ gradient_tools_hbox = memnew(HBoxContainer);
+ gradient_tools_hbox->add_child(reverse_btn);
+
+ add_custom_control(gradient_tools_hbox);
+
+ reverse_btn->connect("pressed", callable_mp(this, &EditorInspectorPluginGradient::_reverse_button_pressed));
+ reverse_btn->set_tooltip(TTR("Reverse/mirror gradient."));
+}
+
+void EditorInspectorPluginGradient::_reverse_button_pressed() {
+ editor->reverse_gradient();
}
GradientEditorPlugin::GradientEditorPlugin(EditorNode *p_node) {
diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h
index bcbb86e422..95b7b466c9 100644
--- a/editor/plugins/gradient_editor_plugin.h
+++ b/editor/plugins/gradient_editor_plugin.h
@@ -50,12 +50,28 @@ protected:
public:
virtual Size2 get_minimum_size() const override;
void set_gradient(const Ref<Gradient> &p_gradient);
+ void reverse_gradient();
GradientEditor();
};
+class GradientReverseButton : public BaseButton {
+ GDCLASS(GradientReverseButton, BaseButton);
+
+ int margin = 2;
+
+ void _notification(int p_what);
+ virtual Size2 get_minimum_size() const override;
+};
+
class EditorInspectorPluginGradient : public EditorInspectorPlugin {
GDCLASS(EditorInspectorPluginGradient, EditorInspectorPlugin);
+ GradientEditor *editor;
+ HBoxContainer *gradient_tools_hbox;
+ GradientReverseButton *reverse_btn;
+
+ void _reverse_button_pressed();
+
public:
virtual bool can_handle(Object *p_object) override;
virtual void parse_begin(Object *p_object) override;
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index 574d3ef27e..7a85c5167b 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -79,7 +79,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();
ur->create_action(TTR("Create Static Trimesh Body"));
- ur->add_do_method(node, "add_child", body);
+ ur->add_do_method(node, "add_child", body, true);
ur->add_do_method(body, "set_owner", owner);
ur->add_do_method(cshape, "set_owner", owner);
ur->add_do_reference(body);
@@ -113,7 +113,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
Node *owner = instance == get_tree()->get_edited_scene_root() ? instance : instance->get_owner();
- ur->add_do_method(instance, "add_child", body);
+ ur->add_do_method(instance, "add_child", body, true);
ur->add_do_method(body, "set_owner", owner);
ur->add_do_method(cshape, "set_owner", owner);
ur->add_do_reference(body);
@@ -146,7 +146,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->create_action(TTR("Create Trimesh Static Shape"));
- ur->add_do_method(node->get_parent(), "add_child", cshape);
+ ur->add_do_method(node->get_parent(), "add_child", cshape, true);
ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
ur->add_do_method(cshape, "set_owner", owner);
ur->add_do_reference(cshape);
@@ -185,7 +185,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
Node *owner = node->get_owner();
- ur->add_do_method(node->get_parent(), "add_child", cshape);
+ ur->add_do_method(node->get_parent(), "add_child", cshape, true);
ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
ur->add_do_method(cshape, "set_owner", owner);
ur->add_do_reference(cshape);
@@ -247,7 +247,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Create Navigation Mesh"));
- ur->add_do_method(node, "add_child", nmi);
+ ur->add_do_method(node, "add_child", nmi, true);
ur->add_do_method(nmi, "set_owner", owner);
ur->add_do_reference(nmi);
@@ -426,7 +426,7 @@ void MeshInstance3DEditor::_create_outline_mesh() {
ur->create_action(TTR("Create Outline"));
- ur->add_do_method(node, "add_child", mi);
+ ur->add_do_method(node, "add_child", mi, true);
ur->add_do_method(mi, "set_owner", owner);
ur->add_do_reference(mi);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index b99ccc1012..fa5381bb10 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -3936,9 +3936,13 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
Vector3 point = world_pos + world_ray * MAX_DISTANCE;
PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();
- PhysicsDirectSpaceState3D::RayResult result;
- if (ss->intersect_ray(world_pos, world_pos + world_ray * MAX_DISTANCE, result)) {
+ PhysicsDirectSpaceState3D::RayParameters ray_params;
+ ray_params.from = world_pos;
+ ray_params.to = world_pos + world_ray * MAX_DISTANCE;
+
+ PhysicsDirectSpaceState3D::RayResult result;
+ if (ss->intersect_ray(ray_params, result)) {
point = result.position;
}
@@ -6566,7 +6570,12 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
Set<RID> excluded = _get_physics_bodies_rid(sp);
- if (ss->intersect_ray(from, to, result, excluded)) {
+ PhysicsDirectSpaceState3D::RayParameters ray_params;
+ ray_params.from = from;
+ ray_params.to = to;
+ ray_params.exclude = excluded;
+
+ if (ss->intersect_ray(ray_params, result)) {
snapped_to_floor = true;
}
}
@@ -6583,7 +6592,12 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
Set<RID> excluded = _get_physics_bodies_rid(sp);
- if (ss->intersect_ray(from, to, result, excluded)) {
+ PhysicsDirectSpaceState3D::RayParameters ray_params;
+ ray_params.from = from;
+ ray_params.to = to;
+ ray_params.exclude = excluded;
+
+ if (ss->intersect_ray(ray_params, result)) {
Vector3 position_offset = d["position_offset"];
Transform3D new_transform = sp->get_global_transform();
@@ -6636,7 +6650,7 @@ void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) {
Node *new_sun = preview_sun->duplicate();
undo_redo->create_action(TTR("Add Preview Sun to Scene"));
- undo_redo->add_do_method(base, "add_child", new_sun);
+ undo_redo->add_do_method(base, "add_child", new_sun, true);
// Move to the beginning of the scene tree since more "global" nodes
// generally look better when placed at the top.
undo_redo->add_do_method(base, "move_child", new_sun, 0);
@@ -6666,7 +6680,7 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) {
new_env->set_environment(preview_environment->get_environment()->duplicate(true));
undo_redo->create_action(TTR("Add Preview Environment to Scene"));
- undo_redo->add_do_method(base, "add_child", new_env);
+ undo_redo->add_do_method(base, "add_child", new_env, true);
// Move to the beginning of the scene tree since more "global" nodes
// generally look better when placed at the top.
undo_redo->add_do_method(base, "move_child", new_env, 0);
@@ -7132,7 +7146,7 @@ void Node3DEditor::_update_preview_environment() {
} else {
if (!preview_sun->get_parent()) {
- add_child(preview_sun);
+ add_child(preview_sun, true);
sun_state->hide();
sun_vb->show();
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 3f98560a2f..aad378ecec 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -227,12 +227,6 @@ void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text")));
}
-static bool _is_built_in_script(Script *p_script) {
- String path = p_script->get_path();
-
- return path.find("::") != -1;
-}
-
class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache {
struct Cache {
uint64_t time_loaded = 0;
@@ -764,7 +758,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
if (p_save && file.is_valid()) {
// Do not try to save internal scripts, but prompt to save in-memory
// scripts which are not saved to disk yet (have empty path).
- if (file->get_path().find("local://") == -1 && file->get_path().find("::") == -1) {
+ if (file->is_built_in()) {
save_current_script();
}
}
@@ -910,7 +904,7 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
RES script = se->get_edited_resource();
- if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
+ if (script->is_built_in()) {
continue; //internal script, who cares
}
@@ -951,7 +945,7 @@ void ScriptEditor::_reload_scripts() {
RES edited_res = se->get_edited_resource();
- if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) {
+ if (edited_res->is_built_in()) {
continue; //internal script, who cares
}
@@ -995,7 +989,7 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
RES script = se->get_edited_resource();
- if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
+ if (script->is_built_in()) {
continue; //internal script, who cares
}
@@ -1037,7 +1031,7 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
continue;
}
- if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) {
+ if (edited_res->is_built_in()) {
continue; //internal script, who cares
}
@@ -1624,7 +1618,7 @@ void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
continue;
}
- if (script->get_path().find("::") != -1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
+ if (script->is_built_in() && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
_close_tab(i);
i--;
}
@@ -2180,9 +2174,10 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
Ref<Script> script = p_resource;
// Don't open dominant script if using an external editor.
- const bool use_external_editor =
+ bool use_external_editor =
EditorSettings::get_singleton()->get("text_editor/external/use_external_editor") ||
(script.is_valid() && script->get_language()->overrides_external_editor());
+ use_external_editor = use_external_editor && !(script.is_valid() && script->is_built_in()); // Ignore external editor for built-in scripts.
const bool open_dominant = EditorSettings::get_singleton()->get("text_editor/behavior/files/open_dominant_script_on_scene_change");
const bool should_open = (open_dominant && !use_external_editor) || !EditorNode::get_singleton()->is_changing_scene();
@@ -2450,7 +2445,7 @@ void ScriptEditor::save_all_scripts() {
se->apply_code();
}
- if (edited_res->get_path() != "" && edited_res->get_path().find("local://") == -1 && edited_res->get_path().find("::") == -1) {
+ if (!edited_res->is_built_in()) {
Ref<TextFile> text_file = edited_res;
Ref<Script> script = edited_res;
@@ -2570,7 +2565,7 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const
script_list->select(script_list->find_metadata(i));
// Save the current script so the changes can be picked up by an external editor.
- if (!_is_built_in_script(script.ptr())) { // But only if it's not built-in script.
+ if (!script.ptr()->is_built_in()) { // But only if it's not built-in script.
save_current_script();
}
@@ -3346,9 +3341,10 @@ Array ScriptEditor::_get_open_script_editors() const {
void ScriptEditor::set_scene_root_script(Ref<Script> p_script) {
// Don't open dominant script if using an external editor.
- const bool use_external_editor =
+ bool use_external_editor =
EditorSettings::get_singleton()->get("text_editor/external/use_external_editor") ||
(p_script.is_valid() && p_script->get_language()->overrides_external_editor());
+ use_external_editor = use_external_editor && !(p_script.is_valid() && p_script->is_built_in()); // Ignore external editor for built-in scripts.
const bool open_dominant = EditorSettings::get_singleton()->get("text_editor/behavior/files/open_dominant_script_on_scene_change");
if (open_dominant && !use_external_editor && p_script.is_valid()) {
@@ -3858,7 +3854,7 @@ void ScriptEditorPlugin::edit(Object *p_object) {
Script *p_script = Object::cast_to<Script>(p_object);
String res_path = p_script->get_path().get_slice("::", 0);
- if (_is_built_in_script(p_script)) {
+ if (p_script->is_built_in()) {
if (ResourceLoader::get_resource_type(res_path) == "PackedScene") {
if (!EditorNode::get_singleton()->is_scene_open(res_path)) {
EditorNode::get_singleton()->load_scene(res_path);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 219498b5e7..24cdc06d78 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -375,7 +375,7 @@ void ScriptTextEditor::ensure_focus() {
String ScriptTextEditor::get_name() {
String name;
- if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
+ if (!script->is_built_in()) {
name = script->get_path().get_file();
if (is_unsaved()) {
if (script->get_path().is_empty()) {
@@ -658,7 +658,7 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
continue;
}
- if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
+ if (script->is_built_in()) {
continue; //internal script, who cares, though weird
}
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 2731582288..9d2b4c88c5 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -482,8 +482,7 @@ void ShaderEditor::_check_for_external_edit() {
return;
}
- // internal shader.
- if (shader->get_path() == "" || shader->get_path().find("local://") != -1 || shader->get_path().find("::") != -1) {
+ if (shader->is_built_in()) {
return;
}
@@ -530,7 +529,7 @@ void ShaderEditor::save_external_data(const String &p_str) {
}
apply_shaders();
- if (shader->get_path() != "" && shader->get_path().find("local://") == -1 && shader->get_path().find("::") == -1) {
+ if (!shader->is_built_in()) {
//external shader, save it
ResourceSaver::save(shader->get_path(), shader);
}
diff --git a/editor/plugins/text_control_editor_plugin.cpp b/editor/plugins/text_control_editor_plugin.cpp
new file mode 100644
index 0000000000..c878c83430
--- /dev/null
+++ b/editor/plugins/text_control_editor_plugin.cpp
@@ -0,0 +1,375 @@
+/*************************************************************************/
+/* text_control_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* 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 */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "text_control_editor_plugin.h"
+
+#include "editor/editor_scale.h"
+
+void TextControlEditor::_notification(int p_notification) {
+ switch (p_notification) {
+ case NOTIFICATION_ENTER_TREE: {
+ if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts))) {
+ EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts), make_binds(""));
+ }
+ [[fallthrough]];
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ clear_formatting->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ if (EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts))) {
+ EditorFileSystem::get_singleton()->disconnect("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts));
+ }
+ } break;
+ default:
+ break;
+ }
+}
+
+void TextControlEditor::_find_resources(EditorFileSystemDirectory *p_dir) {
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
+ _find_resources(p_dir->get_subdir(i));
+ }
+
+ for (int i = 0; i < p_dir->get_file_count(); i++) {
+ if (p_dir->get_file_type(i) == "FontData") {
+ Ref<FontData> fd = ResourceLoader::load(p_dir->get_file_path(i));
+ if (fd.is_valid()) {
+ String name = fd->get_font_name();
+ String sty = fd->get_font_style_name();
+ if (sty.is_empty()) {
+ sty = "Default";
+ }
+ fonts[name][sty] = p_dir->get_file_path(i);
+ }
+ }
+ }
+}
+
+void TextControlEditor::_reload_fonts(const String &p_path) {
+ fonts.clear();
+ _find_resources(EditorFileSystem::get_singleton()->get_filesystem());
+ _update_control();
+}
+
+void TextControlEditor::_update_fonts_menu() {
+ font_list->clear();
+ font_list->add_item(TTR("[Theme Default]"), FONT_INFO_THEME_DEFAULT);
+ if (custom_font.is_valid()) {
+ font_list->add_item(TTR("[Custom Font]"), FONT_INFO_USER_CUSTOM);
+ }
+
+ int id = FONT_INFO_ID;
+ for (Map<String, Map<String, String>>::Element *E = fonts.front(); E; E = E->next()) {
+ font_list->add_item(E->key(), id++);
+ }
+
+ if (font_list->get_item_count() > 1) {
+ font_list->show();
+ } else {
+ font_list->hide();
+ }
+}
+
+void TextControlEditor::_update_styles_menu() {
+ font_style_list->clear();
+ if ((font_list->get_selected_id() >= FONT_INFO_ID)) {
+ const String &name = font_list->get_item_text(font_list->get_selected());
+ for (Map<String, String>::Element *E = fonts[name].front(); E; E = E->next()) {
+ font_style_list->add_item(E->key());
+ }
+ } else {
+ font_style_list->add_item("Default");
+ }
+
+ if (font_style_list->get_item_count() > 1) {
+ font_style_list->show();
+ } else {
+ font_style_list->hide();
+ }
+}
+
+void TextControlEditor::_update_control() {
+ if (edited_control) {
+ // Get override names.
+ if (edited_control->is_class("RichTextLabel")) {
+ edited_color = "default_color";
+ edited_font = "normal_font";
+ edited_font_size = "normal_font_size";
+ } else {
+ edited_color = "font_color";
+ edited_font = "font";
+ edited_font_size = "font_size";
+ }
+
+ // Get font override.
+ Ref<Font> font;
+ if (edited_control->has_theme_font_override(edited_font)) {
+ font = edited_control->get_theme_font(edited_font);
+ }
+ if (font.is_valid()) {
+ if (font->get_data_count() != 1) {
+ // Composite font, save it to "custom_font" to allow undoing font change.
+ custom_font = font;
+ _update_fonts_menu();
+ font_list->select(FONT_INFO_USER_CUSTOM);
+ _update_styles_menu();
+ font_style_list->select(0);
+ } else {
+ // Single face font, search for the font with matching name and style.
+ String name = font->get_data(0)->get_font_name();
+ String style = font->get_data(0)->get_font_style_name();
+ if (fonts.has(name) && fonts[name].has(style)) {
+ _update_fonts_menu();
+ for (int i = 0; i < font_list->get_item_count(); i++) {
+ if (font_list->get_item_text(i) == name) {
+ font_list->select(i);
+ break;
+ }
+ }
+ _update_styles_menu();
+ for (int i = 0; i < font_style_list->get_item_count(); i++) {
+ if (font_style_list->get_item_text(i) == style) {
+ font_style_list->select(i);
+ break;
+ }
+ }
+ } else {
+ // Unknown font, save it to "custom_font" to allow undoing font change.
+ custom_font = font;
+ _update_fonts_menu();
+ font_list->select(FONT_INFO_USER_CUSTOM);
+ _update_styles_menu();
+ font_style_list->select(0);
+ }
+ }
+ } else {
+ // No font override, select "Theme Default".
+ _update_fonts_menu();
+ font_list->select(FONT_INFO_THEME_DEFAULT);
+ _update_styles_menu();
+ font_style_list->select(0);
+ }
+
+ // Get other theme overrides.
+ font_size_list->set_value(edited_control->get_theme_font_size(edited_font_size));
+ outline_size_list->set_value(edited_control->get_theme_constant("outline_size"));
+
+ font_color_picker->set_pick_color(edited_control->get_theme_color(edited_color));
+ outline_color_picker->set_pick_color(edited_control->get_theme_color("font_outline_color"));
+ }
+}
+
+void TextControlEditor::_font_selected(int p_id) {
+ _update_styles_menu();
+ _set_font();
+}
+
+void TextControlEditor::_font_style_selected(int p_id) {
+ _set_font();
+}
+
+void TextControlEditor::_set_font() {
+ if (edited_control) {
+ if (font_list->get_selected_id() == FONT_INFO_THEME_DEFAULT) {
+ // Remove font override.
+ edited_control->remove_theme_font_override(edited_font);
+ return;
+ } else if (font_list->get_selected_id() == FONT_INFO_USER_CUSTOM) {
+ // Restore "custom_font".
+ edited_control->add_theme_font_override(edited_font, custom_font);
+ return;
+ } else {
+ // Load new font resource using selected name and style.
+ String name = font_list->get_item_text(font_list->get_selected());
+ String sty = font_style_list->get_item_text(font_style_list->get_selected());
+ if (sty.is_empty()) {
+ sty = "Default";
+ }
+ if (fonts.has(name)) {
+ Ref<FontData> fd = ResourceLoader::load(fonts[name][sty]);
+ if (fd.is_valid()) {
+ Ref<Font> f;
+ f.instantiate();
+ f->add_data(fd);
+ edited_control->add_theme_font_override(edited_font, f);
+ }
+ }
+ }
+ }
+}
+
+void TextControlEditor::_font_size_selected(double p_size) {
+ if (edited_control) {
+ edited_control->add_theme_font_size_override(edited_font_size, p_size);
+ }
+}
+
+void TextControlEditor::_outline_size_selected(double p_size) {
+ if (edited_control) {
+ edited_control->add_theme_constant_override("outline_size", p_size);
+ }
+}
+
+void TextControlEditor::_font_color_changed(const Color &p_color) {
+ if (edited_control) {
+ edited_control->add_theme_color_override(edited_color, p_color);
+ }
+}
+
+void TextControlEditor::_outline_color_changed(const Color &p_color) {
+ if (edited_control) {
+ edited_control->add_theme_color_override("font_outline_color", p_color);
+ }
+}
+
+void TextControlEditor::_clear_formatting() {
+ if (edited_control) {
+ edited_control->begin_bulk_theme_override();
+ edited_control->remove_theme_font_override(edited_font);
+ edited_control->remove_theme_font_size_override(edited_font_size);
+ edited_control->remove_theme_color_override(edited_color);
+ edited_control->remove_theme_color_override("font_outline_color");
+ edited_control->remove_theme_constant_override("outline_size");
+ edited_control->end_bulk_theme_override();
+ _update_control();
+ }
+}
+
+void TextControlEditor::edit(Object *p_object) {
+ Control *ctrl = Object::cast_to<Control>(p_object);
+ if (!ctrl) {
+ edited_control = nullptr;
+ custom_font = Ref<Font>();
+ } else {
+ edited_control = ctrl;
+ custom_font = Ref<Font>();
+ _update_control();
+ }
+}
+
+bool TextControlEditor::handles(Object *p_object) const {
+ Control *ctrl = Object::cast_to<Control>(p_object);
+ if (!ctrl) {
+ return false;
+ } else {
+ bool valid = false;
+ ctrl->get("text", &valid);
+ return valid;
+ }
+}
+
+TextControlEditor::TextControlEditor() {
+ add_child(memnew(VSeparator));
+
+ font_list = memnew(OptionButton);
+ font_list->set_flat(true);
+ font_list->set_tooltip(TTR("Font"));
+ add_child(font_list);
+ font_list->connect("item_selected", callable_mp(this, &TextControlEditor::_font_selected));
+
+ font_style_list = memnew(OptionButton);
+ font_style_list->set_flat(true);
+ font_style_list->set_tooltip(TTR("Font style"));
+ font_style_list->set_toggle_mode(true);
+ add_child(font_style_list);
+ font_style_list->connect("item_selected", callable_mp(this, &TextControlEditor::_font_style_selected));
+
+ font_size_list = memnew(SpinBox);
+ font_size_list->set_tooltip(TTR("Font Size"));
+ font_size_list->get_line_edit()->add_theme_constant_override("minimum_character_width", 2);
+ font_size_list->set_min(6);
+ font_size_list->set_step(1);
+ font_size_list->set_max(96);
+ font_size_list->get_line_edit()->set_flat(true);
+ add_child(font_size_list);
+ font_size_list->connect("value_changed", callable_mp(this, &TextControlEditor::_font_size_selected));
+
+ font_color_picker = memnew(ColorPickerButton);
+ font_color_picker->set_custom_minimum_size(Size2(20, 0) * EDSCALE);
+ font_color_picker->set_flat(true);
+ font_color_picker->set_tooltip(TTR("Text Color"));
+ add_child(font_color_picker);
+ font_color_picker->connect("color_changed", callable_mp(this, &TextControlEditor::_font_color_changed));
+
+ add_child(memnew(VSeparator));
+
+ outline_size_list = memnew(SpinBox);
+ outline_size_list->set_tooltip(TTR("Outline Size"));
+ outline_size_list->get_line_edit()->add_theme_constant_override("minimum_character_width", 2);
+ outline_size_list->set_min(0);
+ outline_size_list->set_step(1);
+ outline_size_list->set_max(96);
+ outline_size_list->get_line_edit()->set_flat(true);
+ add_child(outline_size_list);
+ outline_size_list->connect("value_changed", callable_mp(this, &TextControlEditor::_outline_size_selected));
+
+ outline_color_picker = memnew(ColorPickerButton);
+ outline_color_picker->set_custom_minimum_size(Size2(20, 0) * EDSCALE);
+ outline_color_picker->set_flat(true);
+ outline_color_picker->set_tooltip(TTR("Outline Color"));
+ add_child(outline_color_picker);
+ outline_color_picker->connect("color_changed", callable_mp(this, &TextControlEditor::_outline_color_changed));
+
+ add_child(memnew(VSeparator));
+
+ clear_formatting = memnew(Button);
+ clear_formatting->set_flat(true);
+ clear_formatting->set_tooltip(TTR("Clear Formatting"));
+ add_child(clear_formatting);
+ clear_formatting->connect("pressed", callable_mp(this, &TextControlEditor::_clear_formatting));
+}
+
+/*************************************************************************/
+
+void TextControlEditorPlugin::edit(Object *p_object) {
+ text_ctl_editor->edit(p_object);
+}
+
+bool TextControlEditorPlugin::handles(Object *p_object) const {
+ return text_ctl_editor->handles(p_object);
+}
+
+void TextControlEditorPlugin::make_visible(bool p_visible) {
+ if (p_visible) {
+ text_ctl_editor->show();
+ } else {
+ text_ctl_editor->hide();
+ text_ctl_editor->edit(nullptr);
+ }
+}
+
+TextControlEditorPlugin::TextControlEditorPlugin(EditorNode *p_node) {
+ editor = p_node;
+ text_ctl_editor = memnew(TextControlEditor);
+ CanvasItemEditor::get_singleton()->add_control_to_menu_panel(text_ctl_editor);
+
+ text_ctl_editor->hide();
+}
diff --git a/editor/plugins/text_control_editor_plugin.h b/editor/plugins/text_control_editor_plugin.h
new file mode 100644
index 0000000000..7f4aa3754c
--- /dev/null
+++ b/editor/plugins/text_control_editor_plugin.h
@@ -0,0 +1,119 @@
+/*************************************************************************/
+/* text_control_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* 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 */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEXT_CONTROL_EDITOR_PLUGIN_H
+#define TEXT_CONTROL_EDITOR_PLUGIN_H
+
+#include "canvas_item_editor_plugin.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_inspector.h"
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/gui/color_rect.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/popup_menu.h"
+
+/*************************************************************************/
+
+class TextControlEditor : public HBoxContainer {
+ GDCLASS(TextControlEditor, HBoxContainer);
+
+ enum FontInfoID {
+ FONT_INFO_THEME_DEFAULT = 0,
+ FONT_INFO_USER_CUSTOM = 1,
+ FONT_INFO_ID = 100,
+ };
+
+ Map<String, Map<String, String>> fonts;
+
+ OptionButton *font_list = nullptr;
+ SpinBox *font_size_list = nullptr;
+ OptionButton *font_style_list = nullptr;
+ ColorPickerButton *font_color_picker = nullptr;
+ SpinBox *outline_size_list = nullptr;
+ ColorPickerButton *outline_color_picker = nullptr;
+ Button *clear_formatting = nullptr;
+
+ Control *edited_control = nullptr;
+ String edited_color;
+ String edited_font;
+ String edited_font_size;
+ Ref<Font> custom_font;
+
+protected:
+ void _notification(int p_notification);
+ static void _bind_methods(){};
+
+ void _find_resources(EditorFileSystemDirectory *p_dir);
+ void _reload_fonts(const String &p_path);
+
+ void _update_fonts_menu();
+ void _update_styles_menu();
+ void _update_control();
+
+ void _font_selected(int p_id);
+ void _font_style_selected(int p_id);
+ void _set_font();
+
+ void _font_size_selected(double p_size);
+ void _outline_size_selected(double p_size);
+
+ void _font_color_changed(const Color &p_color);
+ void _outline_color_changed(const Color &p_color);
+
+ void _clear_formatting();
+
+public:
+ void edit(Object *p_object);
+ bool handles(Object *p_object) const;
+
+ TextControlEditor();
+};
+
+/*************************************************************************/
+
+class TextControlEditorPlugin : public EditorPlugin {
+ GDCLASS(TextControlEditorPlugin, EditorPlugin);
+
+ TextControlEditor *text_ctl_editor;
+ EditorNode *editor;
+
+public:
+ virtual String get_name() const override { return "TextControlFontEditor"; }
+ bool has_main_screen() const override { return false; }
+ virtual void edit(Object *p_object) override;
+ virtual bool handles(Object *p_object) const override;
+ virtual void make_visible(bool p_visible) override;
+
+ TextControlEditorPlugin(EditorNode *p_node);
+};
+
+#endif // TEXT_CONTROL_EDITOR_PLUGIN_H
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 1fc7eb98e0..3b45f32927 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -65,7 +65,7 @@ void TextEditor::_load_theme_settings() {
String TextEditor::get_name() {
String name;
- if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
+ if (!text_file->is_built_in()) {
name = text_file->get_path().get_file();
if (is_unsaved()) {
if (text_file->get_path().is_empty()) {
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
index bd1923f4ab..b4e394a1c0 100644
--- a/editor/plugins/texture_3d_editor_plugin.cpp
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -173,7 +173,7 @@ Texture3DEditor::Texture3DEditor() {
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_shadow_color", Color(0, 0, 0, 0.5));
- info->add_theme_constant_override("shadow_as_outline", 1);
+ info->add_theme_constant_override("shadow_outline_size", 1);
info->add_theme_constant_override("shadow_offset_x", 2);
info->add_theme_constant_override("shadow_offset_y", 2);
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index b9ec6bf5ab..e25b0270b4 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -101,7 +101,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
metadata_label->add_theme_color_override("font_outline_color", Color::named("black"));
metadata_label->add_theme_constant_override("outline_size", 2 * EDSCALE);
- metadata_label->add_theme_constant_override("shadow_as_outline", 1);
+ metadata_label->add_theme_constant_override("shadow_outline_size", 1);
metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END);
metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END);
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index 424e018a47..ee62138d12 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -249,7 +249,7 @@ TextureLayeredEditor::TextureLayeredEditor() {
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_shadow_color", Color(0, 0, 0, 0.5));
- info->add_theme_constant_override("shadow_as_outline", 1);
+ info->add_theme_constant_override("shadow_outline_size", 1);
info->add_theme_constant_override("shadow_offset_x", 2);
info->add_theme_constant_override("shadow_offset_y", 2);
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index f1918073fb..47dfc57b0f 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -47,8 +47,12 @@
TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr;
-void TilesEditorPlugin::_pattern_preview_done(const Variant &p_udata) {
- pattern_preview_done.set();
+void TilesEditorPlugin::_preview_frame_started() {
+ RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_pattern_preview_done));
+}
+
+void TilesEditorPlugin::_pattern_preview_done() {
+ pattern_preview_done.post();
}
void TilesEditorPlugin::_thread_func(void *ud) {
@@ -112,12 +116,9 @@ void TilesEditorPlugin::_thread() {
// Add the viewport at the lasst moment to avoid rendering too early.
EditorNode::get_singleton()->add_child(viewport);
- pattern_preview_done.clear();
- RS::get_singleton()->request_frame_drawn_callback(const_cast<TilesEditorPlugin *>(this), "_pattern_preview_done", Variant());
+ RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
- while (!pattern_preview_done.is_set()) {
- OS::get_singleton()->delay_usec(10);
- }
+ pattern_preview_done.wait();
Ref<Image> image = viewport->get_texture()->get_image();
Ref<ImageTexture> image_texture;
@@ -274,10 +275,6 @@ bool TilesEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("TileMap") || p_object->is_class("TileSet");
}
-void TilesEditorPlugin::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_pattern_preview_done", "pattern"), &TilesEditorPlugin::_pattern_preview_done);
-}
-
TilesEditorPlugin::TilesEditorPlugin(EditorNode *p_node) {
set_process_internal(true);
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index dd52bdc31a..33493040f6 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -77,14 +77,14 @@ private:
Thread pattern_preview_thread;
SafeFlag pattern_thread_exit;
SafeFlag pattern_thread_exited;
- mutable SafeFlag pattern_preview_done;
- void _pattern_preview_done(const Variant &p_udata);
+ Semaphore pattern_preview_done;
+ void _preview_frame_started();
+ void _pattern_preview_done();
static void _thread_func(void *ud);
void _thread();
protected:
void _notification(int p_what);
- static void _bind_methods();
public:
_FORCE_INLINE_ static TilesEditorPlugin *get_singleton() { return singleton; }
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index c06eafae50..10a9b2bb10 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -4977,7 +4977,7 @@ public:
}
}
- void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, const Map<StringName, String> &p_overrided_names, Ref<VisualShaderNode> p_node) {
parent_resource = p_parent_resource;
updating = false;
node = p_node;
@@ -4993,7 +4993,11 @@ public:
Label *prop_name = memnew(Label);
String prop_name_str = p_names[i];
- prop_name_str = prop_name_str.capitalize() + ":";
+ if (p_overrided_names.has(p_names[i])) {
+ prop_name_str = p_overrided_names[p_names[i]] + ":";
+ } else {
+ prop_name_str = prop_name_str.capitalize() + ":";
+ }
prop_name->set_text(prop_name_str);
prop_name->set_visible(false);
hbox->add_child(prop_name);
@@ -5085,7 +5089,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
properties.push_back(pinfo[i].name);
}
VisualShaderNodePluginDefaultEditor *editor = memnew(VisualShaderNodePluginDefaultEditor);
- editor->setup(p_parent_resource, editors, properties, p_node);
+ editor->setup(p_parent_resource, editors, properties, p_node->get_editable_properties_names(), p_node);
return editor;
}
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index db560af657..62c5cc5cc1 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -1671,7 +1671,7 @@ void CustomPropertyEditor::_focus_exit() {
}
void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings) {
- Ref<StyleBox> sb = action_buttons[0]->get_theme_stylebox(SNAME("panel"));
+ Ref<StyleBox> sb = action_buttons[0]->get_theme_stylebox(SNAME("button"));
int margin_top = sb->get_margin(SIDE_TOP);
int margin_left = sb->get_margin(SIDE_LEFT);
int margin_bottom = sb->get_margin(SIDE_BOTTOM);
@@ -1804,26 +1804,18 @@ CustomPropertyEditor::CustomPropertyEditor() {
}
text_edit = memnew(TextEdit);
- add_child(text_edit);
+ value_vbox->add_child(text_edit);
text_edit->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 5);
+ text_edit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
text_edit->set_offset(SIDE_BOTTOM, -30);
text_edit->hide();
text_edit->connect("text_changed", callable_mp(this, &CustomPropertyEditor::_text_edit_changed));
- for (int i = 0; i < MAX_ACTION_BUTTONS; i++) {
- action_buttons[i] = memnew(Button);
- action_buttons[i]->hide();
- add_child(action_buttons[i]);
- Vector<Variant> binds;
- binds.push_back(i);
- action_buttons[i]->connect("pressed", callable_mp(this, &CustomPropertyEditor::_action_pressed), binds);
- }
-
color_picker = nullptr;
file = memnew(EditorFileDialog);
- add_child(file);
+ value_vbox->add_child(file);
file->hide();
file->connect("file_selected", callable_mp(this, &CustomPropertyEditor::_file_selected));
@@ -1831,46 +1823,58 @@ CustomPropertyEditor::CustomPropertyEditor() {
error = memnew(ConfirmationDialog);
error->set_title(TTR("Error!"));
- add_child(error);
+ value_vbox->add_child(error);
scene_tree = memnew(SceneTreeDialog);
- add_child(scene_tree);
+ value_vbox->add_child(scene_tree);
scene_tree->connect("selected", callable_mp(this, &CustomPropertyEditor::_node_path_selected));
scene_tree->get_scene_tree()->set_show_enabled_subscene(true);
texture_preview = memnew(TextureRect);
- add_child(texture_preview);
+ value_vbox->add_child(texture_preview);
texture_preview->hide();
easing_draw = memnew(Control);
- add_child(easing_draw);
+ value_vbox->add_child(easing_draw);
easing_draw->hide();
easing_draw->connect("draw", callable_mp(this, &CustomPropertyEditor::_draw_easing));
easing_draw->connect("gui_input", callable_mp(this, &CustomPropertyEditor::_drag_easing));
easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE);
type_button = memnew(MenuButton);
- add_child(type_button);
+ value_vbox->add_child(type_button);
type_button->hide();
type_button->get_popup()->connect("id_pressed", callable_mp(this, &CustomPropertyEditor::_type_create_selected));
menu = memnew(PopupMenu);
// menu->set_pass_on_modal_close_click(false);
- add_child(menu);
+ value_vbox->add_child(menu);
menu->connect("id_pressed", callable_mp(this, &CustomPropertyEditor::_menu_option));
evaluator = nullptr;
spinbox = memnew(SpinBox);
- add_child(spinbox);
+ value_vbox->add_child(spinbox);
spinbox->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 5);
spinbox->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified));
slider = memnew(HSlider);
- add_child(slider);
+ value_vbox->add_child(slider);
slider->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 5);
slider->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified));
+ action_hboxes = memnew(HBoxContainer);
+ action_hboxes->set_alignment(BoxContainer::ALIGN_CENTER);
+ value_vbox->add_child(action_hboxes);
+ for (int i = 0; i < MAX_ACTION_BUTTONS; i++) {
+ action_buttons[i] = memnew(Button);
+ action_buttons[i]->hide();
+ action_hboxes->add_child(action_buttons[i]);
+ Vector<Variant> binds;
+ binds.push_back(i);
+ action_buttons[i]->connect("pressed", callable_mp(this, &CustomPropertyEditor::_action_pressed), binds);
+ }
+
create_dialog = nullptr;
property_select = nullptr;
}
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 23771b7494..2565c6ee27 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -110,6 +110,7 @@ class CustomPropertyEditor : public PopupPanel {
int focused_value_editor;
Label *value_label[MAX_VALUE_EDITORS];
HScrollBar *scroll[4];
+ HBoxContainer *action_hboxes;
Button *action_buttons[MAX_ACTION_BUTTONS];
MenuButton *type_button;
Vector<String> inheritors_array;
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 2792c193d9..f5b70504fa 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -461,7 +461,7 @@ String RenameDialog::_substitute(const String &subject, const Node *node, int co
void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) {
RenameDialog *self = (RenameDialog *)p_self;
- String source_file(p_file);
+ String source_file = String::utf8(p_file);
// Only show first error that is related to "regex"
if (self->has_errors || source_file.find("regex") < 0) {
@@ -470,9 +470,9 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *
String err_str;
if (p_errorexp && p_errorexp[0]) {
- err_str = p_errorexp;
+ err_str = String::utf8(p_errorexp);
} else {
- err_str = p_error;
+ err_str = String::utf8(p_error);
}
self->has_errors = true;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 336a0e4c37..921befbb6b 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -47,6 +47,7 @@
#include "editor/plugins/script_editor_plugin.h"
#include "editor/shader_create_dialog.h"
#include "scene/main/window.h"
+#include "scene/property_utils.h"
#include "scene/resources/packed_scene.h"
#include "servers/display_server.h"
#include "servers/rendering_server.h"
@@ -2153,7 +2154,7 @@ void SceneTreeDock::_do_create(Node *p_parent) {
editor_data->get_undo_redo().create_action(TTR("Create Node"));
if (edited_scene) {
- editor_data->get_undo_redo().add_do_method(p_parent, "add_child", child);
+ editor_data->get_undo_redo().add_do_method(p_parent, "add_child", child, true);
editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene);
editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", child);
@@ -3132,7 +3133,9 @@ void SceneTreeDock::_clear_clipboard() {
void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) {
List<PropertyInfo> props;
p_node->get_property_list(&props);
- bool is_instantiated = EditorPropertyRevert::may_node_be_in_instance(p_node);
+
+ Vector<SceneState::PackState> states_stack;
+ bool states_stack_ready = false;
for (const PropertyInfo &E : props) {
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
@@ -3143,16 +3146,17 @@ void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap)
if (v.is_ref()) {
RES res = v;
if (res.is_valid()) {
- if (is_instantiated) {
- Variant orig;
- if (EditorPropertyRevert::get_instantiated_node_original_property(p_node, E.name, orig)) {
- if (!EditorPropertyRevert::is_node_property_different(p_node, v, orig)) {
- continue;
- }
- }
+ if (!states_stack_ready) {
+ states_stack = PropertyUtils::get_node_states_stack(p_node);
+ states_stack_ready = true;
+ }
+
+ Variant orig = PropertyUtils::get_property_default_value(p_node, E.name, &states_stack);
+ if (!PropertyUtils::is_property_value_different(v, orig)) {
+ continue;
}
- if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) {
+ if (res->is_built_in() && !r_remap.has(res)) {
_create_remap_for_resource(res, r_remap);
}
}
@@ -3179,7 +3183,7 @@ void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_
if (v.is_ref()) {
RES res = v;
if (res.is_valid()) {
- if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) {
+ if (res->is_built_in() && !r_remap.has(res)) {
_create_remap_for_resource(res, r_remap);
}
}