summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/filesystem_dock.cpp15
-rw-r--r--editor/icons/Listener2D.svg1
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp12
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.cpp49
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.h4
-rw-r--r--editor/plugins/script_text_editor.cpp1
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp7
-rw-r--r--editor/pot_generator.cpp13
-rw-r--r--editor/scene_tree_dock.cpp5
-rw-r--r--editor/scene_tree_dock.h1
-rw-r--r--editor/scene_tree_editor.cpp8
11 files changed, 84 insertions, 32 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index daee61c2dd..5dd5c050e0 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -2158,6 +2158,14 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
return true;
}
+ if (drag_data.has("type") && String(drag_data["type"]) == "nodes") {
+ // Save branch as scene.
+ String to_dir;
+ bool favorite;
+ _get_drag_target_folder(to_dir, favorite, p_point, p_from);
+ return !favorite && Array(drag_data["nodes"]).size() == 1;
+ }
+
return false;
}
@@ -2296,6 +2304,13 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
_update_tree(_compute_uncollapsed_paths());
}
}
+
+ if (drag_data.has("type") && String(drag_data["type"]) == "nodes") {
+ String to_dir;
+ bool favorite;
+ _get_drag_target_folder(to_dir, favorite, p_point, p_from);
+ EditorNode::get_singleton()->get_scene_tree_dock()->save_branch_to_file(to_dir);
+ }
}
void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favorites, const Point2 &p_point, Control *p_from) const {
diff --git a/editor/icons/Listener2D.svg b/editor/icons/Listener2D.svg
new file mode 100644
index 0000000000..db84dcfed7
--- /dev/null
+++ b/editor/icons/Listener2D.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.75-.54175 2.3583-1.1406 2.8574-.29944.2495-.62954.44071-.97656.69141-.17351.1253-.35729.26529-.53711.49219-.17982.227-.3457.58398-.3457.95898 0 1.2778-.31632 1.5742-.63867 1.7676-.32236.1934-.86133.23242-1.3613.23242h-1v2h1c.5 0 1.461.038922 2.3887-.51758.87316-.5239 1.4826-1.6633 1.5566-3.2266.011365-.0098.027247-.024684.10938-.083984.21547-.1556.63537-.40194 1.0859-.77734.90112-.751 1.8594-2.1445 1.8594-4.3945a5 5 0 0 0 -5-5zm7.9277 1-1.7383 1.0039a6 6 0 0 1 .81055 2.9961 6 6 0 0 1 -.80859 2.998l1.7363 1.002a8 8 0 0 0 0-8z" fill="#a5b7f3"/></svg>
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index d04e88e915..d20f3d105b 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -2097,7 +2097,6 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Color bonecolor = Color(1.0, 0.4, 0.4, 0.3);
Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
- //LocalVector<int> bones_to_process = skel->get_parentless_bones();
LocalVector<int> bones_to_process;
bones_to_process = skel->get_parentless_bones();
@@ -2109,19 +2108,18 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
child_bones_vector = skel->get_bone_children(current_bone_idx);
int child_bones_size = child_bones_vector.size();
- // You have children but no parent, then you must be a root/parentless bone.
- if (child_bones_size >= 0 && skel->get_bone_parent(current_bone_idx) <= 0) {
- grests[current_bone_idx] = skel->global_pose_to_local_pose(current_bone_idx, skel->get_bone_global_pose(current_bone_idx));
+ if (skel->get_bone_parent(current_bone_idx) < 0) {
+ grests[current_bone_idx] = skel->get_bone_rest(current_bone_idx);
}
for (int i = 0; i < child_bones_size; i++) {
int child_bone_idx = child_bones_vector[i];
- grests[child_bone_idx] = skel->global_pose_to_local_pose(child_bone_idx, skel->get_bone_global_pose(child_bone_idx));
+ grests[child_bone_idx] = grests[current_bone_idx] * skel->get_bone_rest(child_bone_idx);
Vector3 v0 = grests[current_bone_idx].origin;
Vector3 v1 = grests[child_bone_idx].origin;
- Vector3 d = skel->get_bone_rest(child_bone_idx).origin.normalized();
- real_t dist = skel->get_bone_rest(child_bone_idx).origin.length();
+ Vector3 d = (v1 - v0).normalized();
+ real_t dist = v0.distance_to(v1);
// Find closest axis.
int closest = -1;
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp
index 0a949c8610..53c5b8dd70 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.cpp
+++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp
@@ -31,6 +31,7 @@
#include "packed_scene_translation_parser_plugin.h"
#include "core/io/resource_loader.h"
+#include "scene/gui/option_button.h"
#include "scene/resources/packed_scene.h"
void PackedSceneEditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_extensions) const {
@@ -50,21 +51,31 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
Ref<SceneState> state = Ref<PackedScene>(loaded_res)->get_state();
Vector<String> parsed_strings;
- String property_name;
- Variant property_value;
for (int i = 0; i < state->get_node_count(); i++) {
- if (!ClassDB::is_parent_class(state->get_node_type(i), "Control") && !ClassDB::is_parent_class(state->get_node_type(i), "Viewport")) {
+ String node_type = state->get_node_type(i);
+ if (!ClassDB::is_parent_class(node_type, "Control") && !ClassDB::is_parent_class(node_type, "Window")) {
continue;
}
+ // Find the `auto_translate` property, and abort the string parsing of the node if disabled.
+ bool auto_translating = true;
for (int j = 0; j < state->get_node_property_count(i); j++) {
- property_name = state->get_node_property_name(i, j);
- if (!lookup_properties.has(property_name)) {
- continue;
+ if (state->get_node_property_name(i, j) == "auto_translate" && (bool)state->get_node_property_value(i, j) == false) {
+ auto_translating = false;
+ break;
}
+ }
+ if (!auto_translating) {
+ continue;
+ }
- property_value = state->get_node_property_value(i, j);
+ for (int j = 0; j < state->get_node_property_count(i); j++) {
+ String property_name = state->get_node_property_name(i, j);
+ if (!lookup_properties.has(property_name) || (exception_list.has(node_type) && exception_list[node_type].has(property_name))) {
+ continue;
+ }
+ Variant property_value = state->get_node_property_value(i, j);
if (property_name == "script" && property_value.get_type() == Variant::OBJECT && !property_value.is_null()) {
// Parse built-in script.
Ref<Script> s = Object::cast_to<Script>(property_value);
@@ -76,7 +87,16 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
parsed_strings.append_array(temp);
r_ids_ctx_plural->append_array(ids_context_plural);
}
- } else if (property_name == "filters") {
+ } else if ((node_type == "MenuButton" || node_type == "OptionButton") && property_name == "items") {
+ Vector<String> str_values = property_value;
+ int incr_value = node_type == "MenuButton" ? PopupMenu::ITEM_PROPERTY_SIZE : OptionButton::ITEM_PROPERTY_SIZE;
+ for (int k = 0; k < str_values.size(); k += incr_value) {
+ String desc = str_values[k].get_slice(";", 1).strip_edges();
+ if (!desc.is_empty()) {
+ parsed_strings.push_back(desc);
+ }
+ }
+ } else if (node_type == "FileDialog" && property_name == "filters") {
// Extract FileDialog's filters property with values in format "*.png ; PNG Images","*.gd ; GDScript Files".
Vector<String> str_values = property_value;
for (int k = 0; k < str_values.size(); k++) {
@@ -105,12 +125,17 @@ PackedSceneEditorTranslationParserPlugin::PackedSceneEditorTranslationParserPlug
lookup_properties.insert("text");
lookup_properties.insert("hint_tooltip");
lookup_properties.insert("placeholder_text");
+ lookup_properties.insert("items");
+ lookup_properties.insert("title");
lookup_properties.insert("dialog_text");
lookup_properties.insert("filters");
lookup_properties.insert("script");
- //Add exception list (to prevent false positives)
- //line edit, text edit, richtextlabel
- //Set<String> exception_list;
- //exception_list.insert("RichTextLabel");
+ // Exception list (to prevent false positives).
+ exception_list.insert("LineEdit", Vector<StringName>());
+ exception_list["LineEdit"].append("text");
+ exception_list.insert("TextEdit", Vector<StringName>());
+ exception_list["TextEdit"].append("text");
+ exception_list.insert("CodeEdit", Vector<StringName>());
+ exception_list["CodeEdit"].append("text");
}
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.h b/editor/plugins/packed_scene_translation_parser_plugin.h
index e51d65414e..af0291b69c 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.h
+++ b/editor/plugins/packed_scene_translation_parser_plugin.h
@@ -37,7 +37,9 @@ class PackedSceneEditorTranslationParserPlugin : public EditorTranslationParserP
GDCLASS(PackedSceneEditorTranslationParserPlugin, EditorTranslationParserPlugin);
// Scene Node's properties that contain translation strings.
- Set<String> lookup_properties;
+ Set<StringName> lookup_properties;
+ // Properties from specific Nodes that should be ignored.
+ Map<StringName, Vector<StringName>> exception_list;
public:
virtual Error parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) override;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index c44760807f..48239a5d99 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -158,7 +158,6 @@ void ScriptTextEditor::enable_editor() {
editor_enabled = true;
_enable_code_editor();
- _set_theme_for_script();
_validate_script();
}
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index d406c2514c..fd5c59af34 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -1465,12 +1465,13 @@ void TileDataTerrainsEditor::_tile_set_changed() {
ERR_FAIL_COND(!tile_set.is_valid());
// Fix if wrong values are selected.
- if (int(dummy_object->get("terrain_set")) > tile_set->get_terrain_sets_count()) {
+ int terrain_set = int(dummy_object->get("terrain_set"));
+ if (terrain_set >= tile_set->get_terrain_sets_count()) {
+ terrain_set = -1;
dummy_object->set("terrain_set", -1);
}
- int terrain_set = int(dummy_object->get("terrain"));
if (terrain_set >= 0) {
- if (int(dummy_object->get("terrain")) > tile_set->get_terrains_count(terrain_set)) {
+ if (int(dummy_object->get("terrain")) >= tile_set->get_terrains_count(terrain_set)) {
dummy_object->set("terrain", -1);
}
}
diff --git a/editor/pot_generator.cpp b/editor/pot_generator.cpp
index b58b7e4cac..d57345cac1 100644
--- a/editor/pot_generator.cpp
+++ b/editor/pot_generator.cpp
@@ -108,7 +108,6 @@ void POTGenerator::_write_to_pot(const String &p_file) {
const String header =
"# LANGUAGE translation for " + project_name + " for the following files:\n" + extracted_files +
"#\n"
- "#\n"
"# FIRST AUTHOR < EMAIL @ADDRESS>, YEAR.\n"
"#\n"
"#, fuzzy\n"
@@ -116,8 +115,9 @@ void POTGenerator::_write_to_pot(const String &p_file) {
"msgstr \"\"\n"
"\"Project-Id-Version: " +
project_name + "\\n\"\n"
+ "\"MIME-Version: 1.0\\n\"\n"
"\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
- "\"Content-Transfer-Encoding: 8-bit\\n\"\n\n";
+ "\"Content-Transfer-Encoding: 8-bit\\n\"\n";
file->store_string(header);
@@ -129,6 +129,9 @@ void POTGenerator::_write_to_pot(const String &p_file) {
String plural = v_msgid_data[i].plural;
const Set<String> &locations = v_msgid_data[i].locations;
+ // Put the blank line at the start, to avoid a double at the end when closing the file.
+ file->store_line("");
+
// Write file locations.
for (Set<String>::Element *E = locations.front(); E; E = E->next()) {
file->store_line("#: " + E->get().trim_prefix("res://"));
@@ -142,13 +145,13 @@ void POTGenerator::_write_to_pot(const String &p_file) {
// Write msgid.
_write_msgid(file, msgid, false);
- // Write msgid_plural
+ // Write msgid_plural.
if (!plural.is_empty()) {
_write_msgid(file, plural, true);
file->store_line("msgstr[0] \"\"");
- file->store_line("msgstr[1] \"\"\n");
+ file->store_line("msgstr[1] \"\"");
} else {
- file->store_line("msgstr \"\"\n");
+ file->store_line("msgstr \"\"");
}
}
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 2ec4a088a2..a08a628216 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2837,6 +2837,11 @@ void SceneTreeDock::set_filter(const String &p_filter) {
scene_tree->set_filter(p_filter);
}
+void SceneTreeDock::save_branch_to_file(String p_directory) {
+ new_scene_from_dialog->set_current_dir(p_directory);
+ _tool_selected(TOOL_NEW_SCENE_FROM);
+}
+
void SceneTreeDock::_focus_node() {
Node *node = scene_tree->get_selected();
ERR_FAIL_COND(!node);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 387a35acbb..1086e8615f 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -269,6 +269,7 @@ protected:
public:
String get_filter();
void set_filter(const String &p_filter);
+ void save_branch_to_file(String p_directory);
void _focus_node();
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index e7ba80677d..d54bf73028 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -291,10 +291,12 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
}
}
+ // Display the node name in all tooltips so that long node names can be previewed
+ // without having to rename them.
if (p_node == get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
- String tooltip = TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class();
+ String tooltip = String(p_node->get_name()) + "\n" + TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class();
if (p_node->get_editor_description() != String()) {
tooltip += "\n\n" + p_node->get_editor_description();
}
@@ -303,7 +305,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
} else if (p_node != get_scene_node() && p_node->get_filename() != "" && can_open_instance) {
item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
- String tooltip = TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class();
+ String tooltip = String(p_node->get_name()) + "\n" + TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class();
if (p_node->get_editor_description() != String()) {
tooltip += "\n\n" + p_node->get_editor_description();
}
@@ -315,7 +317,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
type = p_node->get_class();
}
- String tooltip = TTR("Type:") + " " + type;
+ String tooltip = String(p_node->get_name()) + "\n" + TTR("Type:") + " " + type;
if (p_node->get_editor_description() != String()) {
tooltip += "\n\n" + p_node->get_editor_description();
}