summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/SCsub169
-rw-r--r--editor/animation_track_editor.cpp70
-rw-r--r--editor/animation_track_editor_plugins.cpp8
-rw-r--r--editor/audio_stream_preview.cpp4
-rw-r--r--editor/code_editor.cpp341
-rw-r--r--editor/code_editor.h23
-rw-r--r--editor/collada/collada.cpp64
-rw-r--r--editor/collada/collada.h4
-rw-r--r--editor/connections_dialog.cpp2
-rw-r--r--editor/create_dialog.cpp119
-rw-r--r--editor/doc/doc_data.cpp28
-rw-r--r--editor/editor_autoload_settings.cpp2
-rw-r--r--editor/editor_builders.py412
-rw-r--r--editor/editor_data.cpp63
-rw-r--r--editor/editor_data.h3
-rw-r--r--editor/editor_export.cpp24
-rw-r--r--editor/editor_file_dialog.cpp4
-rw-r--r--editor/editor_inspector.cpp78
-rw-r--r--editor/editor_inspector.h3
-rw-r--r--editor/editor_node.cpp96
-rw-r--r--editor/editor_node.h4
-rw-r--r--editor/editor_profiler.cpp26
-rw-r--r--editor/editor_profiler.h2
-rw-r--r--editor/editor_properties.cpp170
-rw-r--r--editor/editor_properties.h19
-rw-r--r--editor/editor_resource_preview.cpp4
-rw-r--r--editor/editor_resource_preview.h4
-rw-r--r--editor/editor_settings.cpp14
-rw-r--r--editor/editor_spin_slider.cpp5
-rw-r--r--editor/editor_spin_slider.h2
-rw-r--r--editor/editor_themes.cpp6
-rw-r--r--editor/fileserver/editor_file_server.cpp4
-rw-r--r--editor/filesystem_dock.cpp28
-rw-r--r--editor/filesystem_dock.h7
-rw-r--r--editor/find_in_files.cpp2
-rw-r--r--editor/icons/SCsub90
-rw-r--r--editor/icons/editor_icons_builders.py96
-rw-r--r--editor/icons/icon_soft_body.svg56
-rw-r--r--editor/icons/icon_texture_3_d.svg75
-rw-r--r--editor/icons/icon_texture_array.svg77
-rw-r--r--editor/import/editor_import_collada.cpp50
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp103
-rw-r--r--editor/import/editor_scene_importer_gltf.h3
-rw-r--r--editor/import/resource_importer_csv_translation.cpp2
-rw-r--r--editor/import/resource_importer_image.cpp79
-rw-r--r--editor/import/resource_importer_image.h27
-rw-r--r--editor/import/resource_importer_layered_texture.cpp274
-rw-r--r--editor/import/resource_importer_layered_texture.h57
-rw-r--r--editor/import/resource_importer_obj.cpp9
-rw-r--r--editor/import/resource_importer_scene.cpp2
-rw-r--r--editor/import/resource_importer_wav.cpp134
-rw-r--r--editor/import/resource_importer_wav.h113
-rw-r--r--editor/inspector_dock.cpp1
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp4
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp4
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp4
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp2
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp20
-rw-r--r--editor/plugins/editor_preview_plugins.cpp95
-rw-r--r--editor/plugins/editor_preview_plugins.h35
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp22
-rw-r--r--editor/plugins/particles_editor_plugin.cpp5
-rw-r--r--editor/plugins/script_editor_plugin.cpp411
-rw-r--r--editor/plugins/script_editor_plugin.h20
-rw-r--r--editor/plugins/script_text_editor.cpp532
-rw-r--r--editor/plugins/script_text_editor.h15
-rw-r--r--editor/plugins/shader_editor_plugin.cpp138
-rw-r--r--editor/plugins/skeleton_editor_plugin.cpp6
-rw-r--r--editor/plugins/skeleton_ik_editor_plugin.cpp110
-rw-r--r--editor/plugins/skeleton_ik_editor_plugin.h65
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp250
-rw-r--r--editor/plugins/spatial_editor_plugin.h17
-rw-r--r--editor/plugins/sprite_editor_plugin.cpp2
-rw-r--r--editor/plugins/text_editor.cpp607
-rw-r--r--editor/plugins/text_editor.h146
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp22
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp2
-rw-r--r--editor/project_manager.cpp211
-rw-r--r--editor/project_settings_editor.cpp4
-rw-r--r--editor/property_editor.cpp4
-rw-r--r--editor/property_editor.h2
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/scene_tree_dock.cpp88
-rw-r--r--editor/scene_tree_dock.h2
-rw-r--r--editor/script_editor_debugger.cpp12
-rw-r--r--editor/spatial_editor_gizmos.cpp164
-rw-r--r--editor/spatial_editor_gizmos.h17
-rw-r--r--editor/translations/af.po4
-rw-r--r--editor/translations/ar.po19
-rw-r--r--editor/translations/bg.po5
-rw-r--r--editor/translations/bn.po5
-rw-r--r--editor/translations/ca.po5
-rw-r--r--editor/translations/cs.po5
-rw-r--r--editor/translations/da.po5
-rw-r--r--editor/translations/de.po25
-rw-r--r--editor/translations/de_CH.po5
-rw-r--r--editor/translations/editor.pot4
-rw-r--r--editor/translations/el.po32
-rw-r--r--editor/translations/es.po286
-rw-r--r--editor/translations/es_AR.po5
-rw-r--r--editor/translations/fa.po22
-rw-r--r--editor/translations/fi.po36
-rw-r--r--editor/translations/fr.po23
-rw-r--r--editor/translations/he.po4
-rw-r--r--editor/translations/hi.po4
-rw-r--r--editor/translations/hu.po5
-rw-r--r--editor/translations/id.po39
-rw-r--r--editor/translations/is.po4
-rw-r--r--editor/translations/it.po17
-rw-r--r--editor/translations/ja.po5
-rw-r--r--editor/translations/ko.po13
-rw-r--r--editor/translations/lt.po4
-rw-r--r--editor/translations/ms.po19
-rw-r--r--editor/translations/nb.po16
-rw-r--r--editor/translations/nl.po16
-rw-r--r--editor/translations/pl.po33
-rw-r--r--editor/translations/pr.po4
-rw-r--r--editor/translations/pt_BR.po20
-rw-r--r--editor/translations/pt_PT.po5
-rw-r--r--editor/translations/ro.po5
-rw-r--r--editor/translations/ru.po30
-rw-r--r--editor/translations/sk.po5
-rw-r--r--editor/translations/sl.po122
-rw-r--r--editor/translations/sr_Cyrl.po5
-rw-r--r--editor/translations/sr_Latn.po4
-rw-r--r--editor/translations/sv.po23
-rw-r--r--editor/translations/ta.po4
-rw-r--r--editor/translations/th.po5
-rw-r--r--editor/translations/tr.po15
-rw-r--r--editor/translations/uk.po5
-rw-r--r--editor/translations/ur_PK.po4
-rw-r--r--editor/translations/vi.po216
-rw-r--r--editor/translations/zh_CN.po5
-rw-r--r--editor/translations/zh_HK.po5
-rw-r--r--editor/translations/zh_TW.po281
140 files changed, 5393 insertions, 2149 deletions
diff --git a/editor/SCsub b/editor/SCsub
index a9343f7f36..4fa287c33b 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -5,149 +5,14 @@ env.editor_sources = []
import os
import os.path
-from compat import encode_utf8, byte_to_str, open_utf8, escape_string
-
-def make_certs_header(target, source, env):
-
- src = source[0].srcnode().abspath
- dst = target[0].srcnode().abspath
- f = open(src, "rb")
- g = open_utf8(dst, "w")
- buf = f.read()
- decomp_size = len(buf)
- import zlib
- buf = zlib.compress(buf)
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _CERTS_RAW_H\n")
- g.write("#define _CERTS_RAW_H\n")
- g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
- g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
- g.write("static const unsigned char _certs_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
- g.write("};\n")
- g.write("#endif")
-
- g.close()
- f.close()
-
-
-def make_doc_header(target, source, env):
-
- dst = target[0].srcnode().abspath
- g = open_utf8(dst, "w")
- buf = ""
- docbegin = ""
- docend = ""
- for s in source:
- src = s.srcnode().abspath
- if not src.endswith(".xml"):
- continue
- with open_utf8(src, "r") as f:
- content = f.read()
- buf += content
-
- buf = encode_utf8(docbegin + buf + docend)
- decomp_size = len(buf)
- import zlib
- buf = zlib.compress(buf)
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _DOC_DATA_RAW_H\n")
- g.write("#define _DOC_DATA_RAW_H\n")
- g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
- g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
- g.write("static const unsigned char _doc_data_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
- g.write("};\n")
-
- g.write("#endif")
-
- g.close()
-
-
-def make_fonts_header(target, source, env):
-
- dst = target[0].srcnode().abspath
-
- g = open_utf8(dst, "w")
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _EDITOR_FONTS_H\n")
- g.write("#define _EDITOR_FONTS_H\n")
-
- # saving uncompressed, since freetype will reference from memory pointer
- xl_names = []
- for i in range(len(source)):
- with open(source[i].srcnode().abspath, "rb")as f:
- buf = f.read()
-
- name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0]
-
- g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n")
- g.write("static const unsigned char _font_" + name + "[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
-
- g.write("};\n")
-
- g.write("#endif")
-
- g.close()
-
+from platform_methods import run_in_subprocess
+from compat import open_utf8
+import editor_builders
-def make_translations_header(target, source, env):
-
- dst = target[0].srcnode().abspath
-
- g = open_utf8(dst, "w")
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _EDITOR_TRANSLATIONS_H\n")
- g.write("#define _EDITOR_TRANSLATIONS_H\n")
-
- import zlib
- import os.path
-
- paths = [node.srcnode().abspath for node in source]
- sorted_paths = sorted(paths, key=lambda path: os.path.splitext(os.path.basename(path))[0])
-
- xl_names = []
- for i in range(len(sorted_paths)):
- with open(sorted_paths[i], "rb") as f:
- buf = f.read()
- decomp_size = len(buf)
- buf = zlib.compress(buf)
- name = os.path.splitext(os.path.basename(sorted_paths[i]))[0]
-
- g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
-
- g.write("};\n")
-
- xl_names.append([name, len(buf), str(decomp_size)])
-
- g.write("struct EditorTranslationList {\n")
- g.write("\tconst char* lang;\n")
- g.write("\tint comp_size;\n")
- g.write("\tint uncomp_size;\n")
- g.write("\tconst unsigned char* data;\n")
- g.write("};\n\n")
- g.write("static EditorTranslationList _editor_translations[] = {\n")
- for x in xl_names:
- g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ", _translation_" + x[0] + "_compressed},\n")
- g.write("\t{NULL, 0, 0, NULL}\n")
- g.write("};\n")
-
- g.write("#endif")
-
- g.close()
def _make_doc_data_class_path(to_path):
- g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w")
+ # NOTE: It is safe to generate this file here, since this is still executed serially
+ g = open_utf8(os.path.join(to_path, "doc_data_class_path.gen.h"), "w")
g.write("static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n")
g.write("struct _DocDataClassPath { const char* name; const char* path; };\n")
@@ -169,6 +34,8 @@ if env['tools']:
reg_exporters += '\tregister_' + e + '_exporter();\n'
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
reg_exporters += '}\n'
+
+ # NOTE: It is safe to generate this file here, since this is still executed serially
with open_utf8("register_exporters.gen.cpp", "w") as f:
f.write(reg_exporters_inc)
f.write(reg_exporters)
@@ -192,24 +59,38 @@ if env['tools']:
docs = sorted(docs)
env.Depends("#editor/doc_data_compressed.gen.h", docs)
- env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, make_doc_header)
+ env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header))
+
# Certificates
env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt")
- env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", make_certs_header)
+ env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(editor_builders.make_certs_header))
import glob
+
path = env.Dir('.').abspath
# Translations
tlist = glob.glob(path + "/translations/*.po")
env.Depends('#editor/translations.gen.h', tlist)
- env.CommandNoCache('#editor/translations.gen.h', tlist, make_translations_header)
+ env.CommandNoCache('#editor/translations.gen.h', tlist, run_in_subprocess(editor_builders.make_translations_header))
# Fonts
flist = glob.glob(path + "/../thirdparty/fonts/*.ttf")
flist.append(glob.glob(path + "/../thirdparty/fonts/*.otf"))
env.Depends('#editor/builtin_fonts.gen.h', flist)
- env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, make_fonts_header)
+ env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, run_in_subprocess(editor_builders.make_fonts_header))
+
+ # Authors
+ env.Depends('#editor/authors.gen.h', "../AUTHORS.md")
+ env.CommandNoCache('#editor/authors.gen.h', "../AUTHORS.md", run_in_subprocess(editor_builders.make_authors_header))
+
+ # Donors
+ env.Depends('#editor/donors.gen.h', "../DONORS.md")
+ env.CommandNoCache('#editor/donors.gen.h', "../DONORS.md", run_in_subprocess(editor_builders.make_donors_header))
+
+ # License
+ env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
+ env.CommandNoCache('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(editor_builders.make_license_header))
env.add_source_files(env.editor_sources, "*.cpp")
env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"])
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 42d5ea120e..4c4830ad7a 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -231,10 +231,10 @@ public:
if (Variant::can_convert(args[idx].get_type(), t)) {
Variant old = args[idx];
Variant *ptrs[1] = { &old };
- args[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
+ args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
} else {
- args[idx] = Variant::construct(t, NULL, 0, err);
+ args.write[idx] = Variant::construct(t, NULL, 0, err);
}
change_notify_deserved = true;
d_new["args"] = args;
@@ -248,7 +248,7 @@ public:
_fix_node_path(value);
}
- args[idx] = value;
+ args.write[idx] = value;
d_new["args"] = args;
mergeable = true;
}
@@ -3014,12 +3014,12 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b
if (res.is_valid()) {
property_info_base = res;
if (r_current_val) {
- *r_current_val = res->get(leftover_path[leftover_path.size() - 1]);
+ *r_current_val = res->get_indexed(leftover_path);
}
} else if (node) {
property_info_base = node;
if (r_current_val) {
- *r_current_val = node->get(leftover_path[leftover_path.size() - 1]);
+ *r_current_val = node->get_indexed(leftover_path);
}
}
@@ -3053,31 +3053,31 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
subindices.push_back("");
} break;
case Variant::VECTOR2: {
- subindices.push_back(".x");
- subindices.push_back(".y");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
} break;
case Variant::VECTOR3: {
- subindices.push_back(".x");
- subindices.push_back(".y");
- subindices.push_back(".z");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
+ subindices.push_back(":z");
} break;
case Variant::QUAT: {
- subindices.push_back(".x");
- subindices.push_back(".y");
- subindices.push_back(".z");
- subindices.push_back(".w");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
+ subindices.push_back(":z");
+ subindices.push_back(":w");
} break;
case Variant::COLOR: {
- subindices.push_back(".r");
- subindices.push_back(".g");
- subindices.push_back(".b");
- subindices.push_back(".a");
+ subindices.push_back(":r");
+ subindices.push_back(":g");
+ subindices.push_back(":b");
+ subindices.push_back(":a");
} break;
case Variant::PLANE: {
- subindices.push_back(".x");
- subindices.push_back(".y");
- subindices.push_back(".z");
- subindices.push_back(".d");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
+ subindices.push_back(":z");
+ subindices.push_back(":d");
} break;
default: {
if (r_valid) {
@@ -3288,35 +3288,23 @@ void AnimationTrackEditor::_update_tracks() {
if (root && root->has_node_and_resource(path)) {
RES res;
+ NodePath base_path;
Vector<StringName> leftover_path;
Node *node = root->get_node_and_resource(path, res, leftover_path, true);
+ PropertyInfo pinfo = _find_hint_for_track(i, base_path);
Object *object = node;
if (res.is_valid()) {
object = res.ptr();
- } else {
- object = node;
}
if (object && !leftover_path.empty()) {
- //not a property (value track?)
- PropertyInfo pinfo;
- pinfo.name = leftover_path[leftover_path.size() - 1];
- //now let's see if we can get more info about it
-
- List<PropertyInfo> plist;
- object->get_property_list(&plist);
-
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (E->get().name == leftover_path[leftover_path.size() - 1]) {
- pinfo = E->get();
- break;
- }
+ if (pinfo.name.empty()) {
+ pinfo.name = leftover_path[leftover_path.size() - 1];
}
for (int j = 0; j < track_edit_plugins.size(); j++) {
- track_edit = track_edit_plugins[j]->create_value_track_edit(object, pinfo.type, pinfo.name, pinfo.hint, pinfo.hint_string, pinfo.usage);
+ track_edit = track_edit_plugins.write[j]->create_value_track_edit(object, pinfo.type, pinfo.name, pinfo.hint, pinfo.hint_string, pinfo.usage);
if (track_edit) {
break;
}
@@ -3327,7 +3315,7 @@ void AnimationTrackEditor::_update_tracks() {
if (animation->track_get_type(i) == Animation::TYPE_AUDIO) {
for (int j = 0; j < track_edit_plugins.size(); j++) {
- track_edit = track_edit_plugins[j]->create_audio_track_edit();
+ track_edit = track_edit_plugins.write[j]->create_audio_track_edit();
if (track_edit) {
break;
}
@@ -3344,7 +3332,7 @@ void AnimationTrackEditor::_update_tracks() {
if (node && Object::cast_to<AnimationPlayer>(node)) {
for (int j = 0; j < track_edit_plugins.size(); j++) {
- track_edit = track_edit_plugins[j]->create_animation_track_edit(node);
+ track_edit = track_edit_plugins.write[j]->create_animation_track_edit(node);
if (track_edit) {
break;
}
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index d0c91f10d9..6d444c5422 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -271,8 +271,8 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
int idx = i - from_x;
- lines[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
- lines[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
+ lines.write[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
+ lines.write[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
}
Vector<Color> color;
@@ -883,8 +883,8 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
int idx = i - from_x;
- lines[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
- lines[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
+ lines.write[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
+ lines.write[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
}
Vector<Color> color;
diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp
index 6ee4d7f4b0..6ae5ec43a9 100644
--- a/editor/audio_stream_preview.cpp
+++ b/editor/audio_stream_preview.cpp
@@ -118,8 +118,8 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
uint8_t pfrom = CLAMP((min * 0.5 + 0.5) * 255, 0, 255);
uint8_t pto = CLAMP((max * 0.5 + 0.5) * 255, 0, 255);
- preview->preview->preview[(ofs_write + i) * 2 + 0] = pfrom;
- preview->preview->preview[(ofs_write + i) * 2 + 1] = pto;
+ preview->preview->preview.write[(ofs_write + i) * 2 + 0] = pfrom;
+ preview->preview->preview.write[(ofs_write + i) * 2 + 1] = pto;
}
frames_todo -= to_read;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 6aec6135f1..4ce8556add 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -725,7 +725,7 @@ void CodeTextEditor::_complete_request() {
int i = 0;
for (List<String>::Element *E = entries.front(); E; E = E->next()) {
- strs[i++] = E->get();
+ strs.write[i++] = E->get();
}
text_editor->code_complete(strs, forced);
@@ -784,6 +784,345 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
}
+void CodeTextEditor::trim_trailing_whitespace() {
+ bool trimed_whitespace = false;
+ for (int i = 0; i < text_editor->get_line_count(); i++) {
+ String line = text_editor->get_line(i);
+ if (line.ends_with(" ") || line.ends_with("\t")) {
+
+ if (!trimed_whitespace) {
+ text_editor->begin_complex_operation();
+ trimed_whitespace = true;
+ }
+
+ int end = 0;
+ for (int j = line.length() - 1; j > -1; j--) {
+ if (line[j] != ' ' && line[j] != '\t') {
+ end = j + 1;
+ break;
+ }
+ }
+ text_editor->set_line(i, line.substr(0, end));
+ }
+ }
+
+ if (trimed_whitespace) {
+ text_editor->end_complex_operation();
+ text_editor->update();
+ }
+}
+
+void CodeTextEditor::convert_indent_to_spaces() {
+ int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
+ String indent = "";
+
+ for (int i = 0; i < indent_size; i++) {
+ indent += " ";
+ }
+
+ int cursor_line = text_editor->cursor_get_line();
+ int cursor_column = text_editor->cursor_get_column();
+
+ bool changed_indentation = false;
+ for (int i = 0; i < text_editor->get_line_count(); i++) {
+ String line = text_editor->get_line(i);
+
+ if (line.length() <= 0) {
+ continue;
+ }
+
+ int j = 0;
+ while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
+ if (line[j] == '\t') {
+ if (!changed_indentation) {
+ text_editor->begin_complex_operation();
+ changed_indentation = true;
+ }
+ if (cursor_line == i && cursor_column > j) {
+ cursor_column += indent_size - 1;
+ }
+ line = line.left(j) + indent + line.right(j + 1);
+ }
+ j++;
+ }
+ if (changed_indentation) {
+ text_editor->set_line(i, line);
+ }
+ }
+ if (changed_indentation) {
+ text_editor->cursor_set_column(cursor_column);
+ text_editor->end_complex_operation();
+ text_editor->update();
+ }
+}
+
+void CodeTextEditor::convert_indent_to_tabs() {
+ int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
+ indent_size -= 1;
+
+ int cursor_line = text_editor->cursor_get_line();
+ int cursor_column = text_editor->cursor_get_column();
+
+ bool changed_indentation = false;
+ for (int i = 0; i < text_editor->get_line_count(); i++) {
+ String line = text_editor->get_line(i);
+
+ if (line.length() <= 0) {
+ continue;
+ }
+
+ int j = 0;
+ int space_count = -1;
+ while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
+ if (line[j] != '\t') {
+ space_count++;
+
+ if (space_count == indent_size) {
+ if (!changed_indentation) {
+ text_editor->begin_complex_operation();
+ changed_indentation = true;
+ }
+ if (cursor_line == i && cursor_column > j) {
+ cursor_column -= indent_size;
+ }
+ line = line.left(j - indent_size) + "\t" + line.right(j + 1);
+ j = 0;
+ space_count = -1;
+ }
+ } else {
+ space_count = -1;
+ }
+ j++;
+ }
+ if (changed_indentation) {
+ text_editor->set_line(i, line);
+ }
+ }
+ if (changed_indentation) {
+ text_editor->cursor_set_column(cursor_column);
+ text_editor->end_complex_operation();
+ text_editor->update();
+ }
+}
+
+void CodeTextEditor::convert_case(CaseStyle p_case) {
+ if (!text_editor->is_selection_active()) {
+ return;
+ }
+
+ text_editor->begin_complex_operation();
+
+ int begin = text_editor->get_selection_from_line();
+ int end = text_editor->get_selection_to_line();
+ int begin_col = text_editor->get_selection_from_column();
+ int end_col = text_editor->get_selection_to_column();
+
+ for (int i = begin; i <= end; i++) {
+ int len = text_editor->get_line(i).length();
+ if (i == end)
+ len -= len - end_col;
+ if (i == begin)
+ len -= begin_col;
+ String new_line = text_editor->get_line(i).substr(i == begin ? begin_col : 0, len);
+
+ switch (p_case) {
+ case UPPER: {
+ new_line = new_line.to_upper();
+ } break;
+ case LOWER: {
+ new_line = new_line.to_lower();
+ } break;
+ case CAPITALIZE: {
+ new_line = new_line.capitalize();
+ } break;
+ }
+
+ if (i == begin) {
+ new_line = text_editor->get_line(i).left(begin_col) + new_line;
+ }
+ if (i == end) {
+ new_line = new_line + text_editor->get_line(i).right(end_col);
+ }
+ text_editor->set_line(i, new_line);
+ }
+ text_editor->end_complex_operation();
+}
+
+void CodeTextEditor::move_lines_up() {
+ text_editor->begin_complex_operation();
+ if (text_editor->is_selection_active()) {
+ int from_line = text_editor->get_selection_from_line();
+ int from_col = text_editor->get_selection_from_column();
+ int to_line = text_editor->get_selection_to_line();
+ int to_column = text_editor->get_selection_to_column();
+
+ for (int i = from_line; i <= to_line; i++) {
+ int line_id = i;
+ int next_id = i - 1;
+
+ if (line_id == 0 || next_id < 0)
+ return;
+
+ text_editor->unfold_line(line_id);
+ text_editor->unfold_line(next_id);
+
+ text_editor->swap_lines(line_id, next_id);
+ text_editor->cursor_set_line(next_id);
+ }
+ int from_line_up = from_line > 0 ? from_line - 1 : from_line;
+ int to_line_up = to_line > 0 ? to_line - 1 : to_line;
+ text_editor->select(from_line_up, from_col, to_line_up, to_column);
+ } else {
+ int line_id = text_editor->cursor_get_line();
+ int next_id = line_id - 1;
+
+ if (line_id == 0 || next_id < 0)
+ return;
+
+ text_editor->unfold_line(line_id);
+ text_editor->unfold_line(next_id);
+
+ text_editor->swap_lines(line_id, next_id);
+ text_editor->cursor_set_line(next_id);
+ }
+ text_editor->end_complex_operation();
+ text_editor->update();
+}
+
+void CodeTextEditor::move_lines_down() {
+ text_editor->begin_complex_operation();
+ if (text_editor->is_selection_active()) {
+ int from_line = text_editor->get_selection_from_line();
+ int from_col = text_editor->get_selection_from_column();
+ int to_line = text_editor->get_selection_to_line();
+ int to_column = text_editor->get_selection_to_column();
+
+ for (int i = to_line; i >= from_line; i--) {
+ int line_id = i;
+ int next_id = i + 1;
+
+ if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count())
+ return;
+
+ text_editor->unfold_line(line_id);
+ text_editor->unfold_line(next_id);
+
+ text_editor->swap_lines(line_id, next_id);
+ text_editor->cursor_set_line(next_id);
+ }
+ int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line;
+ int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line;
+ text_editor->select(from_line_down, from_col, to_line_down, to_column);
+ } else {
+ int line_id = text_editor->cursor_get_line();
+ int next_id = line_id + 1;
+
+ if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count())
+ return;
+
+ text_editor->unfold_line(line_id);
+ text_editor->unfold_line(next_id);
+
+ text_editor->swap_lines(line_id, next_id);
+ text_editor->cursor_set_line(next_id);
+ }
+ text_editor->end_complex_operation();
+ text_editor->update();
+}
+
+void CodeTextEditor::delete_lines() {
+ text_editor->begin_complex_operation();
+ if (text_editor->is_selection_active()) {
+ int to_line = text_editor->get_selection_to_line();
+ int from_line = text_editor->get_selection_from_line();
+ int count = Math::abs(to_line - from_line) + 1;
+ while (count) {
+ text_editor->set_line(text_editor->cursor_get_line(), "");
+ text_editor->backspace_at_cursor();
+ count--;
+ if (count)
+ text_editor->unfold_line(from_line);
+ }
+ text_editor->cursor_set_line(from_line - 1);
+ text_editor->deselect();
+ } else {
+ int line = text_editor->cursor_get_line();
+ text_editor->set_line(text_editor->cursor_get_line(), "");
+ text_editor->backspace_at_cursor();
+ text_editor->unfold_line(line);
+ text_editor->cursor_set_line(line);
+ }
+ text_editor->end_complex_operation();
+}
+
+void CodeTextEditor::code_lines_down() {
+ int from_line = text_editor->cursor_get_line();
+ int to_line = text_editor->cursor_get_line();
+ int column = text_editor->cursor_get_column();
+
+ if (text_editor->is_selection_active()) {
+ from_line = text_editor->get_selection_from_line();
+ to_line = text_editor->get_selection_to_line();
+ column = text_editor->cursor_get_column();
+ }
+ int next_line = to_line + 1;
+
+ if (to_line >= text_editor->get_line_count() - 1) {
+ text_editor->set_line(to_line, text_editor->get_line(to_line) + "\n");
+ }
+
+ text_editor->begin_complex_operation();
+ for (int i = from_line; i <= to_line; i++) {
+
+ text_editor->unfold_line(i);
+ if (i >= text_editor->get_line_count() - 1) {
+ text_editor->set_line(i, text_editor->get_line(i) + "\n");
+ }
+ String line_clone = text_editor->get_line(i);
+ text_editor->insert_at(line_clone, next_line);
+ next_line++;
+ }
+
+ text_editor->cursor_set_column(column);
+ if (text_editor->is_selection_active()) {
+ text_editor->select(to_line + 1, text_editor->get_selection_from_column(), next_line - 1, text_editor->get_selection_to_column());
+ }
+
+ text_editor->end_complex_operation();
+ text_editor->update();
+}
+
+void CodeTextEditor::goto_line(int p_line) {
+ text_editor->deselect();
+ text_editor->unfold_line(p_line);
+ text_editor->call_deferred("cursor_set_line", p_line);
+}
+
+void CodeTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
+ text_editor->unfold_line(p_line);
+ text_editor->call_deferred("cursor_set_line", p_line);
+ text_editor->call_deferred("cursor_set_column", p_begin);
+ text_editor->select(p_line, p_begin, p_line, p_end);
+}
+
+Variant CodeTextEditor::get_edit_state() {
+ Dictionary state;
+
+ state["scroll_position"] = text_editor->get_v_scroll();
+ state["column"] = text_editor->cursor_get_column();
+ state["row"] = text_editor->cursor_get_line();
+
+ return state;
+}
+
+void CodeTextEditor::set_edit_state(const Variant &p_state) {
+ Dictionary state = p_state;
+ text_editor->cursor_set_column(state["column"]);
+ text_editor->cursor_set_line(state["row"]);
+ text_editor->set_v_scroll(state["scroll_position"]);
+ text_editor->grab_focus();
+}
+
void CodeTextEditor::set_error(const String &p_error) {
error->set_text(p_error);
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 2a3bb1ba76..903f61d87d 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -186,6 +186,29 @@ protected:
static void _bind_methods();
public:
+ void trim_trailing_whitespace();
+
+ void convert_indent_to_spaces();
+ void convert_indent_to_tabs();
+
+ enum CaseStyle {
+ UPPER,
+ LOWER,
+ CAPITALIZE,
+ };
+ void convert_case(CaseStyle p_case);
+
+ void move_lines_up();
+ void move_lines_down();
+ void delete_lines();
+ void code_lines_down();
+
+ void goto_line(int p_line);
+ void goto_line_selection(int p_line, int p_begin, int p_end);
+
+ Variant get_edit_state();
+ void set_edit_state(const Variant &p_state);
+
void update_editor_settings();
void set_error(const String &p_error);
void update_line_and_column() { _line_col_changed(); }
diff --git a/editor/collada/collada.cpp b/editor/collada/collada.cpp
index 734229d014..fa7e37eb1f 100644
--- a/editor/collada/collada.cpp
+++ b/editor/collada/collada.cpp
@@ -191,7 +191,7 @@ Transform Collada::Node::get_global_transform() const {
return default_transform;
}
-Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
+Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
int i = 0;
@@ -225,22 +225,22 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
ret.resize(16);
Transform tr;
// i wonder why collada matrices are transposed, given that's opposed to opengl..
- ret[0] = interp.basis.elements[0][0];
- ret[1] = interp.basis.elements[0][1];
- ret[2] = interp.basis.elements[0][2];
- ret[4] = interp.basis.elements[1][0];
- ret[5] = interp.basis.elements[1][1];
- ret[6] = interp.basis.elements[1][2];
- ret[8] = interp.basis.elements[2][0];
- ret[9] = interp.basis.elements[2][1];
- ret[10] = interp.basis.elements[2][2];
- ret[3] = interp.origin.x;
- ret[7] = interp.origin.y;
- ret[11] = interp.origin.z;
- ret[12] = 0;
- ret[13] = 0;
- ret[14] = 0;
- ret[15] = 1;
+ ret.write[0] = interp.basis.elements[0][0];
+ ret.write[1] = interp.basis.elements[0][1];
+ ret.write[2] = interp.basis.elements[0][2];
+ ret.write[4] = interp.basis.elements[1][0];
+ ret.write[5] = interp.basis.elements[1][1];
+ ret.write[6] = interp.basis.elements[1][2];
+ ret.write[8] = interp.basis.elements[2][0];
+ ret.write[9] = interp.basis.elements[2][1];
+ ret.write[10] = interp.basis.elements[2][2];
+ ret.write[3] = interp.origin.x;
+ ret.write[7] = interp.origin.y;
+ ret.write[11] = interp.origin.z;
+ ret.write[12] = 0;
+ ret.write[13] = 0;
+ ret.write[14] = 0;
+ ret.write[15] = 1;
return ret;
} else {
@@ -249,7 +249,7 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
dest.resize(keys[i].data.size());
for (int j = 0; j < dest.size(); j++) {
- dest[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
+ dest.write[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
}
return dest;
//interpolate one by one
@@ -452,7 +452,7 @@ Transform Collada::_read_transform(XMLParser &parser) {
Vector<float> farr;
farr.resize(16);
for (int i = 0; i < 16; i++) {
- farr[i] = array[i].to_double();
+ farr.write[i] = array[i].to_double();
}
return _read_transform_from_array(farr);
@@ -1104,7 +1104,7 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
int from = prim.indices.size();
prim.indices.resize(from + values.size());
for (int i = 0; i < values.size(); i++)
- prim.indices[from + i] = values[i];
+ prim.indices.write[from + i] = values[i];
} else if (prim.vertex_size > 0) {
prim.indices = values;
@@ -1884,7 +1884,7 @@ void Collada::_parse_animation(XMLParser &parser) {
track.keys.resize(key_count);
for (int j = 0; j < key_count; j++) {
- track.keys[j].time = time_keys[j];
+ track.keys.write[j].time = time_keys[j];
state.animation_length = MAX(state.animation_length, time_keys[j]);
}
@@ -1905,9 +1905,9 @@ void Collada::_parse_animation(XMLParser &parser) {
ERR_CONTINUE((output.size() / stride) != key_count);
for (int j = 0; j < key_count; j++) {
- track.keys[j].data.resize(output_len);
+ track.keys.write[j].data.resize(output_len);
for (int k = 0; k < output_len; k++)
- track.keys[j].data[k] = output[l + j * stride + k]; //super weird but should work:
+ track.keys.write[j].data.write[k] = output[l + j * stride + k]; //super weird but should work:
}
if (sampler.has("INTERPOLATION")) {
@@ -1919,9 +1919,9 @@ void Collada::_parse_animation(XMLParser &parser) {
for (int j = 0; j < key_count; j++) {
if (interps[j] == "BEZIER")
- track.keys[j].interp_type = AnimationTrack::INTERP_BEZIER;
+ track.keys.write[j].interp_type = AnimationTrack::INTERP_BEZIER;
else
- track.keys[j].interp_type = AnimationTrack::INTERP_LINEAR;
+ track.keys.write[j].interp_type = AnimationTrack::INTERP_LINEAR;
}
}
@@ -1939,8 +1939,8 @@ void Collada::_parse_animation(XMLParser &parser) {
ERR_CONTINUE(outangents.size() != key_count * 2 * names.size());
for (int j = 0; j < key_count; j++) {
- track.keys[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
- track.keys[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
+ track.keys.write[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
+ track.keys.write[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
}
}
@@ -2118,7 +2118,7 @@ void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
for (int i = 0; i < nj->children.size(); i++) {
- _joint_set_owner(nj->children[i], p_owner);
+ _joint_set_owner(nj->children.write[i], p_owner);
}
}
}
@@ -2147,7 +2147,7 @@ void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton
}
for (int i = 0; i < node->children.size(); i++) {
- _create_skeletons(&node->children[i], p_skeleton);
+ _create_skeletons(&node->children.write[i], p_skeleton);
}
}
@@ -2314,7 +2314,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
for (int i = 0; i < gp->children.size(); i++) {
if (gp->children[i] == parent) {
- gp->children[i] = node;
+ gp->children.write[i] = node;
found = true;
break;
}
@@ -2330,7 +2330,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
if (p_vscene->root_nodes[i] == parent) {
- p_vscene->root_nodes[i] = node;
+ p_vscene->root_nodes.write[i] = node;
found = true;
break;
}
@@ -2466,7 +2466,7 @@ void Collada::_optimize() {
VisualScene &vs = E->get();
for (int i = 0; i < vs.root_nodes.size(); i++) {
- _create_skeletons(&vs.root_nodes[i]);
+ _create_skeletons(&vs.root_nodes.write[i]);
}
for (int i = 0; i < vs.root_nodes.size(); i++) {
diff --git a/editor/collada/collada.h b/editor/collada/collada.h
index ec3284bc5c..7535162f74 100644
--- a/editor/collada/collada.h
+++ b/editor/collada/collada.h
@@ -312,7 +312,7 @@ public:
total += weights[i].weight;
if (total)
for (int i = 0; i < 4; i++)
- weights[i].weight /= total;
+ weights.write[i].weight /= total;
}
}
@@ -515,7 +515,7 @@ public:
Key() { interp_type = INTERP_LINEAR; }
};
- Vector<float> get_value_at_time(float p_time);
+ Vector<float> get_value_at_time(float p_time) const;
Vector<Key> keys;
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index c4f4e28fec..da73a3930a 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -51,7 +51,7 @@ public:
if (name.begins_with("bind/")) {
int which = name.get_slice("/", 1).to_int() - 1;
ERR_FAIL_INDEX_V(which, params.size(), false);
- params[which] = p_value;
+ params.write[which] = p_value;
} else
return false;
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 6b2a072e20..3e0c1f2d53 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -40,6 +40,11 @@
void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {
+ type_list.clear();
+ ClassDB::get_class_list(&type_list);
+ ScriptServer::get_global_class_list(&type_list);
+ type_list.sort_custom<StringName::AlphCompare>();
+
recent->clear();
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ);
@@ -173,10 +178,28 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
if (p_types.has(p_type))
return;
- if (!ClassDB::is_parent_class(p_type, base_type) || p_type == base_type)
+
+ bool cpp_type = ClassDB::class_exists(p_type);
+ EditorData &ed = EditorNode::get_singleton()->get_editor_data();
+
+ if (p_type == base_type)
return;
- String inherits = ClassDB::get_parent_class(p_type);
+ if (cpp_type) {
+ if (!ClassDB::is_parent_class(p_type, base_type))
+ return;
+ } else {
+ if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type))
+ return;
+
+ String script_path = ScriptServer::get_global_class_path(p_type);
+ if (script_path.find("res://addons/", 0) != -1) {
+ if (!EditorNode::get_singleton()->is_addon_plugin_enabled(script_path.get_slicec('/', 3)))
+ return;
+ }
+ }
+
+ String inherits = cpp_type ? ClassDB::get_parent_class(p_type) : ed.script_class_get_base(p_type);
TreeItem *parent = p_root;
@@ -189,17 +212,32 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
if (p_types.has(inherits))
parent = p_types[inherits];
+ else if (ScriptServer::is_global_class(inherits))
+ return;
}
+ bool can_instance = (cpp_type && ClassDB::can_instance(p_type)) || ScriptServer::is_global_class(p_type);
+
TreeItem *item = search_options->create_item(parent);
- item->set_text(0, p_type);
- if (!ClassDB::can_instance(p_type)) {
+ if (cpp_type) {
+ item->set_text(0, p_type);
+ } else {
+ item->set_metadata(0, p_type);
+ item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
+ }
+ if (!can_instance) {
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
item->set_selectable(0, false);
} else {
bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type);
String to_select_type = *to_select ? (*to_select)->get_text(0) : "";
- bool current_item_is_preffered = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type);
+ to_select_type = to_select_type.split(" ")[0];
+ bool current_item_is_preffered;
+ if (cpp_type) {
+ current_item_is_preffered = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type);
+ } else {
+ current_item_is_preffered = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type);
+ }
if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) {
current_item_is_preffered = true;
}
@@ -217,16 +255,19 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
// don't collapse the root node
collapse &= (item != p_root);
// don't collapse abstract nodes on the first tree level
- collapse &= ((parent != p_root) || (ClassDB::can_instance(p_type)));
+ collapse &= ((parent != p_root) || (can_instance));
item->set_collapsed(collapse);
}
const String &description = EditorHelp::get_doc_data()->class_list[p_type].brief_description;
item->set_tooltip(0, description);
- if (has_icon(p_type, "EditorIcons")) {
+ if (cpp_type && has_icon(p_type, "EditorIcons")) {
item->set_icon(0, get_icon(p_type, "EditorIcons"));
+ } else if (!cpp_type && has_icon(ScriptServer::get_global_class_base(p_type), "EditorIcons")) {
+
+ item->set_icon(0, get_icon(ScriptServer::get_global_class_base(p_type), "EditorIcons"));
}
p_types[p_type] = item;
@@ -243,47 +284,38 @@ void CreateDialog::_update_search() {
_parse_fs(EditorFileSystem::get_singleton()->get_filesystem());
*/
- List<StringName> global_classes;
- ScriptServer::get_global_class_list(&global_classes);
-
- Map<String, List<String> > global_class_map;
- for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
- String base = ScriptServer::get_global_class_base(E->get());
- if (!global_class_map.has(base)) {
- global_class_map[base] = List<String>();
- }
- global_class_map[base].push_back(E->get());
- }
-
HashMap<String, TreeItem *> types;
TreeItem *root = search_options->create_item();
+ EditorData &ed = EditorNode::get_singleton()->get_editor_data();
root->set_text(0, base_type);
if (has_icon(base_type, "EditorIcons")) {
root->set_icon(0, get_icon(base_type, "EditorIcons"));
}
- List<StringName>::Element *I = type_list.front();
TreeItem *to_select = search_box->get_text() == base_type ? root : NULL;
- for (; I; I = I->next()) {
+ for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {
String type = I->get();
+ bool cpp_type = ClassDB::class_exists(type);
if (base_type == "Node" && type.begins_with("Editor"))
continue; // do not show editor nodes
- if (!ClassDB::can_instance(type))
+ if (cpp_type && !ClassDB::can_instance(type))
continue; // can't create what can't be instanced
bool skip = false;
- for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
- if (ClassDB::is_parent_class(type, E->get()))
- skip = true;
+ if (cpp_type) {
+ for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
+ if (ClassDB::is_parent_class(type, E->get()))
+ skip = true;
+ }
+ if (skip)
+ continue;
}
- if (skip)
- continue;
if (search_box->get_text() == "") {
add_type(type, types, root, &to_select);
@@ -291,7 +323,7 @@ void CreateDialog::_update_search() {
bool found = false;
String type = I->get();
- while (type != "" && ClassDB::is_parent_class(type, base_type) && type != base_type) {
+ while (type != "" && (cpp_type ? ClassDB::is_parent_class(type, base_type) : ed.script_class_is_parent(type, base_type)) && type != base_type) {
if (search_box->get_text().is_subsequence_ofi(type)) {
found = true;
@@ -305,32 +337,6 @@ void CreateDialog::_update_search() {
add_type(I->get(), types, root, &to_select);
}
- if (global_class_map.has(type) && ClassDB::is_parent_class(type, base_type)) {
- for (List<String>::Element *J = global_class_map[type].front(); J; J = J->next()) {
- bool show = search_box->get_text().is_subsequence_ofi(J->get());
-
- if (!show)
- continue;
-
- if (!types.has(type))
- add_type(type, types, root, &to_select);
-
- TreeItem *ti;
- if (types.has(type))
- ti = types[type];
- else
- ti = search_options->get_root();
-
- TreeItem *item = search_options->create_item(ti);
- item->set_metadata(0, J->get());
- item->set_text(0, J->get() + " (" + ScriptServer::get_global_class_path(J->get()).get_file() + ")");
- item->set_icon(0, _get_editor_icon(type));
- if (!to_select || J->get() == search_box->get_text()) {
- to_select = item;
- }
- }
- }
-
if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
//there are custom types based on this... cool.
@@ -694,9 +700,6 @@ CreateDialog::CreateDialog() {
is_replace_mode = false;
- ClassDB::get_class_list(&type_list);
- type_list.sort_custom<StringName::AlphCompare>();
-
set_resizable(true);
HSplitContainer *hsc = memnew(HSplitContainer);
@@ -762,4 +765,6 @@ CreateDialog::CreateDialog() {
type_blacklist.insert("PluginScript"); // PluginScript must be initialized before use, which is not possible here
type_blacklist.insert("ScriptCreateDialog"); // This is an exposed editor Node that doesn't have an Editor prefix.
+
+ EDITOR_DEF("interface/editors/derive_script_globals_by_name", true);
}
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index 542dca74e0..2803762973 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -58,7 +58,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.methods.size(); i++) {
- MethodDoc &m = c.methods[i];
+ MethodDoc &m = c.methods.write[i];
for (int j = 0; j < cf.methods.size(); j++) {
@@ -72,13 +72,13 @@ void DocData::merge_from(const DocData &p_data) {
Vector<bool> arg_used;
arg_used.resize(arg_count);
for (int l = 0; l < arg_count; ++l)
- arg_used[l] = false;
+ arg_used.write[l] = false;
// also there is no guarantee that argument ordering will match, so we
// have to check one by one so we make sure we have an exact match
for (int k = 0; k < arg_count; ++k) {
for (int l = 0; l < arg_count; ++l)
if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
- arg_used[l] = true;
+ arg_used.write[l] = true;
break;
}
}
@@ -98,7 +98,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.signals.size(); i++) {
- MethodDoc &m = c.signals[i];
+ MethodDoc &m = c.signals.write[i];
for (int j = 0; j < cf.signals.size(); j++) {
@@ -113,7 +113,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.constants.size(); i++) {
- ConstantDoc &m = c.constants[i];
+ ConstantDoc &m = c.constants.write[i];
for (int j = 0; j < cf.constants.size(); j++) {
@@ -128,7 +128,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.properties.size(); i++) {
- PropertyDoc &p = c.properties[i];
+ PropertyDoc &p = c.properties.write[i];
for (int j = 0; j < cf.properties.size(); j++) {
@@ -146,7 +146,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.theme_properties.size(); i++) {
- PropertyDoc &p = c.theme_properties[i];
+ PropertyDoc &p = c.theme_properties.write[i];
for (int j = 0; j < cf.theme_properties.size(); j++) {
@@ -1020,7 +1020,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
for (int i = 0; i < c.methods.size(); i++) {
- MethodDoc &m = c.methods[i];
+ const MethodDoc &m = c.methods[i];
String qualifiers;
if (m.qualifiers != "")
@@ -1040,7 +1040,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
for (int j = 0; j < m.arguments.size(); j++) {
- ArgumentDoc &a = m.arguments[j];
+ const ArgumentDoc &a = m.arguments[j];
String enum_text;
if (a.enumeration != String()) {
@@ -1075,7 +1075,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
if (c.properties[i].enumeration != String()) {
enum_text = " enum=\"" + c.properties[i].enumeration + "\"";
}
- PropertyDoc &p = c.properties[i];
+ const PropertyDoc &p = c.properties[i];
_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + enum_text + ">");
_write_string(f, 3, p.description.strip_edges().xml_escape());
_write_string(f, 2, "</member>");
@@ -1090,11 +1090,11 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 1, "<signals>");
for (int i = 0; i < c.signals.size(); i++) {
- MethodDoc &m = c.signals[i];
+ const MethodDoc &m = c.signals[i];
_write_string(f, 2, "<signal name=\"" + m.name + "\">");
for (int j = 0; j < m.arguments.size(); j++) {
- ArgumentDoc &a = m.arguments[j];
+ const ArgumentDoc &a = m.arguments[j];
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">");
_write_string(f, 3, "</argument>");
}
@@ -1113,7 +1113,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
for (int i = 0; i < c.constants.size(); i++) {
- ConstantDoc &k = c.constants[i];
+ const ConstantDoc &k = c.constants[i];
if (k.enumeration != String()) {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
} else {
@@ -1132,7 +1132,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 1, "<theme_items>");
for (int i = 0; i < c.theme_properties.size(); i++) {
- PropertyDoc &p = c.theme_properties[i];
+ const PropertyDoc &p = c.theme_properties[i];
_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">");
_write_string(f, 2, "</theme_item>");
}
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 2f0982e5d9..d12c85861b 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -598,7 +598,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
int i = 0;
for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
- orders[i++] = E->get().order;
+ orders.write[i++] = E->get().order;
}
orders.sort();
diff --git a/editor/editor_builders.py b/editor/editor_builders.py
new file mode 100644
index 0000000000..6c2f9e298e
--- /dev/null
+++ b/editor/editor_builders.py
@@ -0,0 +1,412 @@
+"""Functions used to generate source files during build time
+
+All such functions are invoked in a subprocess on Windows to prevent build flakiness.
+
+"""
+import os
+import os.path
+from platform_methods import subprocess_main
+from compat import encode_utf8, byte_to_str, open_utf8, escape_string
+
+
+def make_certs_header(target, source, env):
+
+ src = source[0]
+ dst = target[0]
+ f = open(src, "rb")
+ g = open_utf8(dst, "w")
+ buf = f.read()
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _CERTS_RAW_H\n")
+ g.write("#define _CERTS_RAW_H\n")
+ g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _certs_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+ g.write("};\n")
+ g.write("#endif")
+
+ g.close()
+ f.close()
+
+
+def make_doc_header(target, source, env):
+
+ dst = target[0]
+ g = open_utf8(dst, "w")
+ buf = ""
+ docbegin = ""
+ docend = ""
+ for src in source:
+ if not src.endswith(".xml"):
+ continue
+ with open_utf8(src, "r") as f:
+ content = f.read()
+ buf += content
+
+ buf = encode_utf8(docbegin + buf + docend)
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _DOC_DATA_RAW_H\n")
+ g.write("#define _DOC_DATA_RAW_H\n")
+ g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _doc_data_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
+def make_fonts_header(target, source, env):
+
+ dst = target[0]
+
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_FONTS_H\n")
+ g.write("#define _EDITOR_FONTS_H\n")
+
+ # saving uncompressed, since freetype will reference from memory pointer
+ xl_names = []
+ for i in range(len(source)):
+ with open(source[i], "rb")as f:
+ buf = f.read()
+
+ name = os.path.splitext(os.path.basename(source[i]))[0]
+
+ g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n")
+ g.write("static const unsigned char _font_" + name + "[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
+def make_translations_header(target, source, env):
+
+ dst = target[0]
+
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_TRANSLATIONS_H\n")
+ g.write("#define _EDITOR_TRANSLATIONS_H\n")
+
+ import zlib
+ import os.path
+
+ sorted_paths = sorted(source, key=lambda path: os.path.splitext(os.path.basename(path))[0])
+
+ xl_names = []
+ for i in range(len(sorted_paths)):
+ with open(sorted_paths[i], "rb") as f:
+ buf = f.read()
+ decomp_size = len(buf)
+ buf = zlib.compress(buf)
+ name = os.path.splitext(os.path.basename(sorted_paths[i]))[0]
+
+ g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+
+ g.write("};\n")
+
+ xl_names.append([name, len(buf), str(decomp_size)])
+
+ g.write("struct EditorTranslationList {\n")
+ g.write("\tconst char* lang;\n")
+ g.write("\tint comp_size;\n")
+ g.write("\tint uncomp_size;\n")
+ g.write("\tconst unsigned char* data;\n")
+ g.write("};\n\n")
+ g.write("static EditorTranslationList _editor_translations[] = {\n")
+ for x in xl_names:
+ g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ", _translation_" + x[0] + "_compressed},\n")
+ g.write("\t{NULL, 0, 0, NULL}\n")
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
+def make_authors_header(target, source, env):
+
+ sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"]
+ sections_id = ["dev_founders", "dev_lead", "dev_manager", "dev_names"]
+
+ src = source[0]
+ dst = target[0]
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_AUTHORS_H\n")
+ g.write("#define _EDITOR_AUTHORS_H\n")
+
+ current_section = ""
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading:
+ if line.startswith(" "):
+ g.write("\t\"" + escape_string(line.strip()) + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for i in range(len(sections)):
+ if line.strip().endswith(sections[i]):
+ current_section = escape_string(sections_id[i])
+ reading = True
+ g.write("static const char *" + current_section + "[] = {\n")
+ break
+
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+ g.close()
+ f.close()
+
+def make_donors_header(target, source, env):
+
+ sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"]
+ sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"]
+
+ src = source[0]
+ dst = target[0]
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_DONORS_H\n")
+ g.write("#define _EDITOR_DONORS_H\n")
+
+ current_section = ""
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading >= 0:
+ if line.startswith(" "):
+ g.write("\t\"" + escape_string(line.strip()) + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for i in range(len(sections)):
+ if line.strip().endswith(sections[i]):
+ current_section = escape_string(sections_id[i])
+ reading = True
+ g.write("static const char *" + current_section + "[] = {\n")
+ break
+
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+ g.close()
+ f.close()
+
+
+def make_license_header(target, source, env):
+
+ src_copyright = source[0]
+ src_license = source[1]
+ dst = target[0]
+ f = open_utf8(src_license, "r")
+ fc = open_utf8(src_copyright, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_LICENSE_H\n")
+ g.write("#define _EDITOR_LICENSE_H\n")
+ g.write("static const char *about_license =")
+
+ for line in f:
+ escaped_string = escape_string(line.strip())
+ g.write("\n\t\"" + escaped_string + "\\n\"")
+
+ g.write(";\n")
+
+ tp_current = 0
+ tp_file = ""
+ tp_comment = ""
+ tp_copyright = ""
+ tp_license = ""
+
+ tp_licensename = ""
+ tp_licensebody = ""
+
+ tp = []
+ tp_licensetext = []
+ for line in fc:
+ if line.startswith("#"):
+ continue
+
+ if line.startswith("Files:"):
+ tp_file = line[6:].strip()
+ tp_current = 1
+ elif line.startswith("Comment:"):
+ tp_comment = line[8:].strip()
+ tp_current = 2
+ elif line.startswith("Copyright:"):
+ tp_copyright = line[10:].strip()
+ tp_current = 3
+ elif line.startswith("License:"):
+ if tp_current != 0:
+ tp_license = line[8:].strip()
+ tp_current = 4
+ else:
+ tp_licensename = line[8:].strip()
+ tp_current = 5
+ elif line.startswith(" "):
+ if tp_current == 1:
+ tp_file += "\n" + line.strip()
+ elif tp_current == 3:
+ tp_copyright += "\n" + line.strip()
+ elif tp_current == 5:
+ if line.strip() == ".":
+ tp_licensebody += "\n"
+ else:
+ tp_licensebody += line[1:]
+ else:
+ if tp_current != 0:
+ if tp_current == 5:
+ tp_licensetext.append([tp_licensename, tp_licensebody])
+
+ tp_licensename = ""
+ tp_licensebody = ""
+ else:
+ added = False
+ for i in tp:
+ if i[0] == tp_comment:
+ i[1].append([tp_file, tp_copyright, tp_license])
+ added = True
+ break
+ if not added:
+ tp.append([tp_comment,[[tp_file, tp_copyright, tp_license]]])
+
+ tp_file = []
+ tp_comment = ""
+ tp_copyright = []
+ tp_license = ""
+ tp_current = 0
+
+ tp_licensetext.append([tp_licensename, tp_licensebody])
+
+ about_thirdparty = ""
+ about_tp_copyright_count = ""
+ about_tp_license = ""
+ about_tp_copyright = ""
+ about_tp_file = ""
+
+ for i in tp:
+ about_thirdparty += "\t\"" + i[0] + "\",\n"
+ about_tp_copyright_count += str(len(i[1])) + ", "
+ for j in i[1]:
+ file_body = ""
+ copyright_body = ""
+ for k in j[0].split("\n"):
+ if file_body != "":
+ file_body += "\\n\"\n"
+ escaped_string = escape_string(k.strip())
+ file_body += "\t\"" + escaped_string
+ for k in j[1].split("\n"):
+ if copyright_body != "":
+ copyright_body += "\\n\"\n"
+ escaped_string = escape_string(k.strip())
+ copyright_body += "\t\"" + escaped_string
+
+ about_tp_file += "\t" + file_body + "\",\n"
+ about_tp_copyright += "\t" + copyright_body + "\",\n"
+ about_tp_license += "\t\"" + j[2] + "\",\n"
+
+ about_license_name = ""
+ about_license_body = ""
+
+ for i in tp_licensetext:
+ body = ""
+ for j in i[1].split("\n"):
+ if body != "":
+ body += "\\n\"\n"
+ escaped_string = escape_string(j.strip())
+ body += "\t\"" + escaped_string
+
+ about_license_name += "\t\"" + i[0] + "\",\n"
+ about_license_body += "\t" + body + "\",\n"
+
+ g.write("static const char *about_thirdparty[] = {\n")
+ g.write(about_thirdparty)
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define THIRDPARTY_COUNT " + str(len(tp)) + "\n")
+
+ g.write("static const int about_tp_copyright_count[] = {\n\t")
+ g.write(about_tp_copyright_count)
+ g.write("0\n};\n")
+
+ g.write("static const char *about_tp_file[] = {\n")
+ g.write(about_tp_file)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_tp_copyright[] = {\n")
+ g.write(about_tp_copyright)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_tp_license[] = {\n")
+ g.write(about_tp_license)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_license_name[] = {\n")
+ g.write(about_license_name)
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define LICENSE_COUNT " + str(len(tp_licensetext)) + "\n")
+
+ g.write("static const char *about_license_body[] = {\n")
+ g.write(about_license_body)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("#endif\n")
+
+ g.close()
+ fc.close()
+ f.close()
+
+
+if __name__ == '__main__':
+ subprocess_main(globals())
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 4dde893c6d..f4ef11eb36 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -62,7 +62,7 @@ void EditorHistory::cleanup_history() {
fail = true;
} else {
//after level, clip
- history[i].path.resize(j);
+ history.write[i].path.resize(j);
}
break;
@@ -100,14 +100,14 @@ void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int
if (p_property != "" && has_prev) {
//add a sub property
- History &pr = history[current];
+ History &pr = history.write[current];
h = pr;
h.path.resize(h.level + 1);
h.path.push_back(o);
h.level++;
} else if (p_level_change != -1 && has_prev) {
//add a sub property
- History &pr = history[current];
+ History &pr = history.write[current];
h = pr;
ERR_FAIL_INDEX(p_level_change, h.path.size());
h.level = p_level_change;
@@ -206,7 +206,7 @@ ObjectID EditorHistory::get_current() {
if (current < 0 || current >= history.size())
return 0;
- History &h = history[current];
+ History &h = history.write[current];
Object *obj = ObjectDB::get_instance(h.path[h.level].object);
if (!obj)
return 0;
@@ -558,7 +558,7 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
- SWAP(edited_scene[p_idx], edited_scene[p_to_idx]);
+ SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]);
}
void EditorData::remove_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
@@ -644,7 +644,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
//transfer selection
List<Node *> new_selection;
- for (List<Node *>::Element *E = edited_scene[p_idx].selection.front(); E; E = E->next()) {
+ for (List<Node *>::Element *E = edited_scene.write[p_idx].selection.front(); E; E = E->next()) {
NodePath p = edited_scene[p_idx].root->get_path_to(E->get());
Node *new_node = new_scene->get_node(p);
if (new_node)
@@ -654,8 +654,8 @@ bool EditorData::check_and_update_scene(int p_idx) {
new_scene->set_filename(edited_scene[p_idx].root->get_filename());
memdelete(edited_scene[p_idx].root);
- edited_scene[p_idx].root = new_scene;
- edited_scene[p_idx].selection = new_selection;
+ edited_scene.write[p_idx].root = new_scene;
+ edited_scene.write[p_idx].selection = new_selection;
return true;
}
@@ -685,7 +685,7 @@ Node *EditorData::get_edited_scene_root(int p_idx) {
void EditorData::set_edited_scene_root(Node *p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
- edited_scene[current_edited_scene].root = p_root;
+ edited_scene.write[current_edited_scene].root = p_root;
}
int EditorData::get_edited_scene_count() const {
@@ -707,10 +707,10 @@ Vector<EditorData::EditedScene> EditorData::get_edited_scenes() const {
void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
if (p_scene_idx < 0) {
- edited_scene[current_edited_scene].version = version;
+ edited_scene.write[current_edited_scene].version = version;
} else {
ERR_FAIL_INDEX(p_scene_idx, edited_scene.size());
- edited_scene[p_scene_idx].version = version;
+ edited_scene.write[p_scene_idx].version = version;
}
}
@@ -793,7 +793,7 @@ String EditorData::get_scene_path(int p_idx) const {
void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
- edited_scene[current_edited_scene].live_edit_root = p_root;
+ edited_scene.write[current_edited_scene].live_edit_root = p_root;
}
NodePath EditorData::get_edited_scene_live_edit_root() {
@@ -806,7 +806,7 @@ void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHis
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
- EditedScene &es = edited_scene[current_edited_scene];
+ EditedScene &es = edited_scene.write[current_edited_scene];
es.selection = p_selection->get_selected_node_list();
es.history_current = p_history->current;
es.history_stored = p_history->history;
@@ -817,7 +817,7 @@ void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHis
Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) {
ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary());
- EditedScene &es = edited_scene[current_edited_scene];
+ EditedScene &es = edited_scene.write[current_edited_scene];
p_history->current = es.history_current;
p_history->history = es.history_stored;
@@ -853,6 +853,41 @@ void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) {
}
}
+bool EditorData::script_class_is_parent(const String &p_class, const String &p_inherits) {
+ if (!ScriptServer::is_global_class(p_class))
+ return false;
+ String base = script_class_get_base(p_class);
+ while (p_inherits != base) {
+ if (ClassDB::class_exists(base)) {
+ return ClassDB::is_parent_class(base, p_inherits);
+ } else if (ScriptServer::is_global_class(base)) {
+ base = script_class_get_base(base);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+StringName EditorData::script_class_get_base(const String &p_class) {
+
+ if (!ScriptServer::is_global_class(p_class))
+ return StringName();
+
+ String path = ScriptServer::get_global_class_path(p_class);
+
+ Ref<Script> script = ResourceLoader::load(path, "Script");
+ if (script.is_null())
+ return StringName();
+
+ Ref<Script> base_script = script->get_base_script();
+ if (base_script.is_null()) {
+ return ScriptServer::get_global_class_base(p_class);
+ }
+
+ return script->get_language()->get_global_class_name(base_script->get_path());
+}
+
EditorData::EditorData() {
current_edited_scene = -1;
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 0ecef8ae31..fac6635cd2 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -211,6 +211,9 @@ public:
void notify_edited_scene_changed();
void notify_resource_saved(const Ref<Resource> &p_resource);
+ bool script_class_is_parent(const String &p_class, const String &p_inherits);
+ StringName script_class_get_base(const String &p_class);
+
EditorData();
};
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 317fffad64..5c911a00ca 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -187,7 +187,7 @@ void EditorExportPreset::remove_patch(int p_idx) {
void EditorExportPreset::set_patch(int p_index, const String &p_path) {
ERR_FAIL_INDEX(p_index, patches.size());
- patches[p_index] = p_path;
+ patches.write[p_index] = p_path;
EditorExport::singleton->save_presets();
}
String EditorExportPreset::get_patch(int p_index) {
@@ -295,7 +295,7 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
MD5Final(&ctx);
sd.md5.resize(16);
for (int i = 0; i < 16; i++) {
- sd.md5[i] = ctx.digest[i];
+ sd.md5.write[i] = ctx.digest[i];
}
}
@@ -584,9 +584,9 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla
//initial export plugin callback
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->get_script_instance()) { //script based
- export_plugins[i]->_export_begin_script(features.features_pv, p_debug, p_path, p_flags);
+ export_plugins.write[i]->_export_begin_script(features.features_pv, p_debug, p_path, p_flags);
} else {
- export_plugins[i]->_export_begin(features.features, p_debug, p_path, p_flags);
+ export_plugins.write[i]->_export_begin(features.features, p_debug, p_path, p_flags);
}
}
}
@@ -594,7 +594,7 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla
EditorExportPlatform::ExportNotifier::~ExportNotifier() {
Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
- export_plugins[i]->_export_end();
+ export_plugins.write[i]->_export_end();
}
}
@@ -632,7 +632,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
}
- export_plugins[i]->_clear();
+ export_plugins.write[i]->_clear();
}
FeatureContainers feature_containers = get_feature_containers(p_preset);
@@ -687,9 +687,9 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
bool do_export = true;
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->get_script_instance()) { //script based
- export_plugins[i]->_export_file_script(path, type, features_pv);
+ export_plugins.write[i]->_export_file_script(path, type, features_pv);
} else {
- export_plugins[i]->_export_file(path, type, features);
+ export_plugins.write[i]->_export_file(path, type, features);
}
if (p_so_func) {
for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
@@ -709,7 +709,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
if (export_plugins[i]->skipped) {
do_export = false;
}
- export_plugins[i]->_clear();
+ export_plugins.write[i]->_clear();
if (!do_export)
break; //apologies, not exporting
@@ -751,7 +751,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<uint8_t> new_file;
new_file.resize(utf8.length());
for (int j = 0; j < utf8.length(); j++) {
- new_file[j] = utf8[j];
+ new_file.write[j] = utf8[j];
}
p_func(p_udata, from + ".remap", new_file, idx, total);
@@ -1130,7 +1130,7 @@ void EditorExport::load_config() {
for (int i = 0; i < export_platforms.size(); i++) {
if (export_platforms[i]->get_name() == platform) {
- preset = export_platforms[i]->create_preset();
+ preset = export_platforms.write[i]->create_preset();
break;
}
}
@@ -1203,7 +1203,7 @@ bool EditorExport::poll_export_platforms() {
bool changed = false;
for (int i = 0; i < export_platforms.size(); i++) {
- if (export_platforms[i]->poll_devices()) {
+ if (export_platforms.write[i]->poll_devices()) {
changed = true;
}
}
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 8a8a21543b..7d56c4985a 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -1135,7 +1135,7 @@ void EditorFileDialog::_favorite_move_up() {
if (a_idx == -1 || b_idx == -1)
return;
- SWAP(favorited[a_idx], favorited[b_idx]);
+ SWAP(favorited.write[a_idx], favorited.write[b_idx]);
EditorSettings::get_singleton()->set_favorite_dirs(favorited);
@@ -1155,7 +1155,7 @@ void EditorFileDialog::_favorite_move_down() {
if (a_idx == -1 || b_idx == -1)
return;
- SWAP(favorited[a_idx], favorited[b_idx]);
+ SWAP(favorited.write[a_idx], favorited.write[b_idx]);
EditorSettings::get_singleton()->set_favorite_dirs(favorited);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 488980db07..99a2b2aa67 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -43,6 +43,9 @@
Size2 EditorProperty::get_minimum_size() const {
Size2 ms;
+ Ref<Font> font = get_font("font", "Tree");
+ ms.height = font->get_height();
+
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -70,12 +73,10 @@ Size2 EditorProperty::get_minimum_size() const {
ms.width += check->get_width() + get_constant("hseparator", "Tree");
}
- if (bottom_editor != NULL) {
- Ref<Font> font = get_font("font", "Tree");
- ms.height += font->get_height();
+ if (bottom_editor != NULL && bottom_editor->is_visible()) {
ms.height += get_constant("vseparation", "Tree");
Size2 bems = bottom_editor->get_combined_minimum_size();
- bems.width += get_constant("item_margin", "Tree");
+ //bems.width += get_constant("item_margin", "Tree");
ms.height += bems.height;
ms.width = MAX(ms.width, bems.width);
}
@@ -98,6 +99,7 @@ void EditorProperty::_notification(int p_what) {
int child_room = size.width * (1.0 - split_ratio);
Ref<Font> font = get_font("font", "Tree");
int height = font->get_height();
+ bool no_children = true;
//compute room needed
for (int i = 0; i < get_child_count(); i++) {
@@ -113,11 +115,16 @@ void EditorProperty::_notification(int p_what) {
Size2 minsize = c->get_combined_minimum_size();
child_room = MAX(child_room, minsize.width);
height = MAX(height, minsize.height);
+ no_children = false;
}
- text_size = MAX(0, size.width - child_room + 4 * EDSCALE);
-
- rect = Rect2(text_size, 0, size.width - text_size, height);
+ if (no_children) {
+ text_size = size.width;
+ rect = Rect2(size.width - 1, 0, 1, height);
+ } else {
+ text_size = MAX(0, size.width - (child_room + 4 * EDSCALE));
+ rect = Rect2(size.width - child_room, 0, child_room, height);
+ }
if (bottom_editor) {
@@ -178,7 +185,7 @@ void EditorProperty::_notification(int p_what) {
draw_style_box(sb, Rect2(Vector2(), size));
}
- if (right_child_rect != Rect2()) {
+ if (draw_top_bg && right_child_rect != Rect2()) {
draw_rect(right_child_rect, dark_color);
}
if (bottom_child_rect != Rect2()) {
@@ -189,7 +196,7 @@ void EditorProperty::_notification(int p_what) {
if (draw_red) {
color = get_color("error_color", "Editor");
} else {
- color = get_color("font_color", "Tree");
+ color = get_color("property_color", "Editor");
}
if (label.find(".") != -1) {
color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides
@@ -787,6 +794,8 @@ void EditorProperty::_bind_methods() {
EditorProperty::EditorProperty() {
+ draw_top_bg = true;
+ object = NULL;
split_ratio = 0.5;
selectable = true;
text_size = 0;
@@ -1613,32 +1622,10 @@ void EditorInspector::update_tree() {
for (List<EditorInspectorPlugin::AddedEditor>::Element *F = editors.front(); F; F = F->next()) {
EditorProperty *ep = Object::cast_to<EditorProperty>(F->get().property_editor);
- current_vbox->add_child(F->get().property_editor);
if (ep) {
-
+ //set all this before the control gets the ENTER_TREE notification
ep->object = object;
- ep->connect("property_changed", this, "_property_changed");
- if (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED) {
- ep->connect("property_changed", this, "_property_changed_update_all", varray(), CONNECT_DEFERRED);
- }
- ep->connect("property_keyed", this, "_property_keyed");
- ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
- ep->connect("property_checked", this, "_property_checked");
- ep->connect("selected", this, "_property_selected");
- ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
- ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
- ep->connect("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
- if (doc_hint != String()) {
- ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
- } else {
- ep->set_tooltip(property_prefix + p.name);
- }
- ep->set_draw_red(draw_red);
- ep->set_use_folding(use_folding);
- ep->set_checkable(checkable);
- ep->set_checked(checked);
- ep->set_keying(keying);
if (F->get().properties.size()) {
@@ -1664,8 +1651,35 @@ void EditorInspector::update_tree() {
editor_property_map[prop].push_back(ep);
}
}
+ ep->set_draw_red(draw_red);
+ ep->set_use_folding(use_folding);
+ ep->set_checkable(checkable);
+ ep->set_checked(checked);
+ ep->set_keying(keying);
ep->set_read_only(read_only);
+ }
+
+ current_vbox->add_child(F->get().property_editor);
+
+ if (ep) {
+
+ ep->connect("property_changed", this, "_property_changed");
+ if (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED) {
+ ep->connect("property_changed", this, "_property_changed_update_all", varray(), CONNECT_DEFERRED);
+ }
+ ep->connect("property_keyed", this, "_property_keyed");
+ ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
+ ep->connect("property_checked", this, "_property_checked");
+ ep->connect("selected", this, "_property_selected");
+ ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
+ ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
+ ep->connect("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
+ if (doc_hint != String()) {
+ ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
+ } else {
+ ep->set_tooltip(property_prefix + p.name);
+ }
ep->update_property();
ep->update_reload_status();
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 454622d662..ebe2124a40 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -68,6 +68,7 @@ private:
bool can_revert;
bool use_folding;
+ bool draw_top_bg;
bool _might_be_in_instance();
bool _is_property_different(const Variant &p_current, const Variant &p_orig, int p_usage);
@@ -149,6 +150,8 @@ public:
String get_tooltip_text() const;
+ void set_draw_top_bg(bool p_draw) { draw_top_bg = p_draw; }
+
EditorProperty();
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ff97878e71..c37b644757 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -62,6 +62,8 @@
#include "editor/import/editor_scene_importer_gltf.h"
#include "editor/import/resource_importer_bitmask.h"
#include "editor/import/resource_importer_csv_translation.h"
+#include "editor/import/resource_importer_image.h"
+#include "editor/import/resource_importer_layered_texture.h"
#include "editor/import/resource_importer_obj.h"
#include "editor/import/resource_importer_scene.h"
#include "editor/import/resource_importer_texture.h"
@@ -108,10 +110,12 @@
#include "editor/plugins/shader_graph_editor_plugin.h"
#include "editor/plugins/skeleton_2d_editor_plugin.h"
#include "editor/plugins/skeleton_editor_plugin.h"
+#include "editor/plugins/skeleton_ik_editor_plugin.h"
#include "editor/plugins/spatial_editor_plugin.h"
#include "editor/plugins/sprite_editor_plugin.h"
#include "editor/plugins/sprite_frames_editor_plugin.h"
#include "editor/plugins/style_box_editor_plugin.h"
+#include "editor/plugins/text_editor.h"
#include "editor/plugins/texture_editor_plugin.h"
#include "editor/plugins/texture_region_editor_plugin.h"
#include "editor/plugins/theme_editor_plugin.h"
@@ -156,7 +160,6 @@ void EditorNode::_update_scene_tabs() {
scene_tabs->set_current_tab(editor_data.get_edited_scene());
- int current = editor_data.get_edited_scene();
if (scene_tabs->get_offset_buttons_visible()) {
// move add button to fixed position on the tabbar
if (scene_tab_add->get_parent() == scene_tabs) {
@@ -946,8 +949,6 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
int x = (img->get_width() - vp_size) / 2;
int y = (img->get_height() - vp_size) / 2;
- img->convert(Image::FORMAT_RGB8);
-
if (vp_size < preview_size) {
// just square it.
img->crop_from_point(x, y, vp_size, vp_size);
@@ -962,6 +963,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
// We could get better pictures with better filters
img->resize(preview_size, preview_size, Image::INTERPOLATE_CUBIC);
}
+ img->convert(Image::FORMAT_RGB8);
img->flip_y();
@@ -1502,7 +1504,7 @@ void EditorNode::_edit_current() {
if (main_plugin) {
// special case if use of external editor is true
- if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
+ 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))) {
if (!changing_scene)
main_plugin->edit(current_obj);
}
@@ -1753,6 +1755,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} else {
tab_closing = editor_data.get_edited_scene();
}
+ if (!editor_data.get_edited_scene_root(tab_closing)) {
+ // empty tab
+ _scene_tab_closed(tab_closing);
+ break;
+ }
} // fallthrough
case SCENE_TAB_CLOSE:
@@ -2047,6 +2054,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
project_settings->popup_project_settings();
} break;
+ case RUN_PROJECT_DATA_FOLDER: {
+
+ OS::get_singleton()->shell_open(OS::get_singleton()->get_user_data_dir());
+ } break;
case FILE_QUIT:
case RUN_PROJECT_MANAGER: {
@@ -2179,6 +2190,14 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
settings_config_dialog->popup_edit_settings();
} break;
+ case SETTINGS_EDITOR_DATA_FOLDER: {
+
+ OS::get_singleton()->shell_open(EditorSettings::get_singleton()->get_data_dir());
+ } break;
+ case SETTINGS_EDITOR_CONFIG_FOLDER: {
+
+ OS::get_singleton()->shell_open(EditorSettings::get_singleton()->get_settings_dir());
+ } break;
case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
export_template_manager->popup_manager();
@@ -3833,6 +3852,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
+
if (scene_tabs->get_hovered_tab() >= 0) {
if (mb->get_button_index() == BUTTON_MIDDLE && mb->is_pressed()) {
_scene_tab_closed(scene_tabs->get_hovered_tab());
@@ -3842,6 +3862,26 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
_menu_option_confirm(FILE_NEW_SCENE, true);
}
}
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
+
+ // context menu
+ scene_tabs_context_menu->clear();
+ scene_tabs_context_menu->set_size(Size2(1, 1));
+
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/new_scene"), FILE_NEW_SCENE);
+ if (scene_tabs->get_hovered_tab() >= 0) {
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene"), FILE_SAVE_SCENE);
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene_as"), FILE_SAVE_AS_SCENE);
+ }
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), FILE_SAVE_ALL_SCENES);
+ if (scene_tabs->get_hovered_tab() >= 0) {
+ scene_tabs_context_menu->add_separator();
+ scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
+ scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
+ }
+ scene_tabs_context_menu->set_position(mb->get_global_position());
+ scene_tabs_context_menu->popup();
+ }
}
}
@@ -3935,7 +3975,7 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
if (bottom_panel_items[i].control == p_item) {
bottom_panel_items[i].button->raise();
- SWAP(bottom_panel_items[i], bottom_panel_items[bottom_panel_items.size() - 1]);
+ SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]);
break;
}
}
@@ -4627,6 +4667,20 @@ EditorNode::EditorNode() {
import_texture.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_texture);
+ Ref<ResourceImporterLayeredTexture> import_3d;
+ import_3d.instance();
+ import_3d->set_3d(true);
+ ResourceFormatImporter::get_singleton()->add_importer(import_3d);
+
+ Ref<ResourceImporterLayeredTexture> import_array;
+ import_array.instance();
+ import_array->set_3d(false);
+ ResourceFormatImporter::get_singleton()->add_importer(import_array);
+
+ Ref<ResourceImporterImage> import_image;
+ import_image.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(import_image);
+
Ref<ResourceImporterCSVTranslation> import_csv_translation;
import_csv_translation.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
@@ -4719,6 +4773,8 @@ EditorNode::EditorNode() {
EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
EDITOR_DEF_RST("interface/inspector/disable_folding", false);
+ EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
+ EDITOR_DEF("interface/inspector/horizontal_vector3_editing", true);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
EDITOR_DEF("interface/inspector/resources_types_to_open_in_new_inspector", "SpatialMaterial");
EDITOR_DEF("run/auto_save/save_before_running", true);
@@ -4897,6 +4953,7 @@ EditorNode::EditorNode() {
scene_tabs = memnew(Tabs);
scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
+ scene_tabs->set_select_with_rmb(true);
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_LEFT);
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
@@ -4914,6 +4971,11 @@ EditorNode::EditorNode() {
tabbar_container = memnew(HBoxContainer);
scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ scene_tabs_context_menu = memnew(PopupMenu);
+ tabbar_container->add_child(scene_tabs_context_menu);
+ scene_tabs_context_menu->connect("id_pressed", this, "_menu_option");
+ scene_tabs_context_menu->set_hide_on_window_lose_focus(true);
+
srt->add_child(tabbar_container);
tabbar_container->add_child(scene_tabs);
distraction_free = memnew(ToolButton);
@@ -5020,6 +5082,7 @@ EditorNode::EditorNode() {
file_menu->set_tooltip(TTR("Operations with scene files."));
p = file_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE);
@@ -5065,6 +5128,7 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(project_menu);
p = project_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->add_item(TTR("Project Settings"), RUN_SETTINGS);
p->add_separator();
p->connect("id_pressed", this, "_menu_option");
@@ -5078,6 +5142,9 @@ EditorNode::EditorNode() {
tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
p->add_separator();
+ p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
+ p->add_separator();
+
#ifdef OSX_ENABLED
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
#else
@@ -5097,6 +5164,7 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(debug_menu);
p = debug_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->set_hide_on_item_selection(false);
p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
@@ -5121,10 +5189,12 @@ EditorNode::EditorNode() {
settings_menu->set_text(TTR("Editor"));
settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
left_menu_hb->add_child(settings_menu);
- p = settings_menu->get_popup();
+ p = settings_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
p->add_separator();
+
editor_layouts = memnew(PopupMenu);
editor_layouts->set_name("Layouts");
p->add_child(editor_layouts);
@@ -5136,6 +5206,17 @@ EditorNode::EditorNode() {
p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN);
#endif
p->add_separator();
+
+ if (OS::get_singleton()->get_data_path() == OS::get_singleton()->get_config_path()) {
+ // Configuration and data folders are located in the same place (Windows/macOS)
+ p->add_item(TTR("Open Editor Data/Settings Folder"), SETTINGS_EDITOR_DATA_FOLDER);
+ } else {
+ // Separate configuration and data folders (Linux)
+ p->add_item(TTR("Open Editor Data Folder"), SETTINGS_EDITOR_DATA_FOLDER);
+ p->add_item(TTR("Open Editor Settings Folder"), SETTINGS_EDITOR_CONFIG_FOLDER);
+ }
+ p->add_separator();
+
p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
// Help Menu
@@ -5146,6 +5227,7 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(help_menu);
p = help_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->connect("id_pressed", this, "_menu_option");
p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES);
p->add_icon_item(gui_base->get_icon("HelpSearch", "EditorIcons"), TTR("Search"), HELP_SEARCH);
@@ -5469,6 +5551,7 @@ EditorNode::EditorNode() {
EditorAudioBuses *audio_bus_editor = EditorAudioBuses::register_editor();
ScriptTextEditor::register_editor(); //register one for text scripts
+ TextEditor::register_editor();
if (StreamPeerSSL::is_available()) {
add_editor_plugin(memnew(AssetLibraryEditorPlugin(this)));
@@ -5527,6 +5610,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(SkeletonEditorPlugin(this)));
+ add_editor_plugin(memnew(SkeletonIKEditorPlugin(this)));
add_editor_plugin(memnew(PhysicalBonePlugin(this)));
// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 38e68b2e09..85aa37ec7e 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -154,6 +154,7 @@ private:
RUN_PLAY_CUSTOM_SCENE,
RUN_SCENE_SETTINGS,
RUN_SETTINGS,
+ RUN_PROJECT_DATA_FOLDER,
RUN_PROJECT_MANAGER,
RUN_FILE_SERVER,
RUN_LIVE_DEBUG,
@@ -168,6 +169,8 @@ private:
SETTINGS_LAYOUT_SAVE,
SETTINGS_LAYOUT_DELETE,
SETTINGS_LAYOUT_DEFAULT,
+ SETTINGS_EDITOR_DATA_FOLDER,
+ SETTINGS_EDITOR_CONFIG_FOLDER,
SETTINGS_MANAGE_EXPORT_TEMPLATES,
SETTINGS_PICK_MAIN_SCENE,
SETTINGS_TOGGLE_FULLSCREEN,
@@ -220,6 +223,7 @@ private:
//main tabs
Tabs *scene_tabs;
+ PopupMenu *scene_tabs_context_menu;
Panel *tab_preview_panel;
TextureRect *tab_preview;
int tab_closing;
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index d4a97b7095..67700b59de 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -37,9 +37,9 @@
void EditorProfiler::_make_metric_ptrs(Metric &m) {
for (int i = 0; i < m.categories.size(); i++) {
- m.category_ptrs[m.categories[i].signature] = &m.categories[i];
+ m.category_ptrs[m.categories[i].signature] = &m.categories.write[i];
for (int j = 0; j < m.categories[i].items.size(); j++) {
- m.item_ptrs[m.categories[i].items[j].signature] = &m.categories[i].items[j];
+ m.item_ptrs[m.categories[i].items[j].signature] = &m.categories.write[i].items.write[j];
}
}
}
@@ -50,8 +50,8 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
if (last_metric >= frame_metrics.size())
last_metric = 0;
- frame_metrics[last_metric] = p_metric;
- _make_metric_ptrs(frame_metrics[last_metric]);
+ frame_metrics.write[last_metric] = p_metric;
+ _make_metric_ptrs(frame_metrics.write[last_metric]);
updating_frame = true;
cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number);
@@ -108,7 +108,7 @@ static String _get_percent_txt(float p_value, float p_total) {
return String::num((p_value / p_total) * 100, 1) + "%";
}
-String EditorProfiler::_get_time_as_text(Metric &m, float p_time, int p_calls) {
+String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_calls) {
int dmode = display_mode->get_selected();
@@ -192,18 +192,18 @@ void EditorProfiler::_update_plot() {
float highest = 0;
for (int i = 0; i < frame_metrics.size(); i++) {
- Metric &m = frame_metrics[i];
+ const Metric &m = frame_metrics[i];
if (!m.valid)
continue;
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
- Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+ const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
if (F) {
highest = MAX(F->get()->total_time, highest);
}
- Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+ const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
if (G) {
if (use_self) {
highest = MAX(G->get()->self, highest);
@@ -256,18 +256,18 @@ void EditorProfiler::_update_plot() {
}
//get
- Metric &m = frame_metrics[idx];
+ const Metric &m = frame_metrics[idx];
if (m.valid == false)
continue; //skip because invalid
float value = 0;
- Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+ const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
if (F) {
value = F->get()->total_time;
}
- Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+ const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
if (G) {
if (use_self) {
value = G->get()->self;
@@ -375,7 +375,7 @@ void EditorProfiler::_update_frame() {
variables->clear();
TreeItem *root = variables->create_item();
- Metric &m = frame_metrics[cursor_metric];
+ const Metric &m = frame_metrics[cursor_metric];
int dtime = display_time->get_selected();
@@ -394,7 +394,7 @@ void EditorProfiler::_update_frame() {
}
for (int j = 0; j < m.categories[i].items.size(); j++) {
- Metric::Category::Item &it = m.categories[i].items[j];
+ const Metric::Category::Item &it = m.categories[i].items[j];
TreeItem *item = variables->create_item(category);
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
diff --git a/editor/editor_profiler.h b/editor/editor_profiler.h
index cb451475e7..d445ad58aa 100644
--- a/editor/editor_profiler.h
+++ b/editor/editor_profiler.h
@@ -136,7 +136,7 @@ private:
void _activate_pressed();
void _clear_pressed();
- String _get_time_as_text(Metric &m, float p_time, int p_calls);
+ String _get_time_as_text(const Metric &m, float p_time, int p_calls);
void _make_metric_ptrs(Metric &m);
void _item_edited();
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 0b49b5a801..83a3662f21 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -258,6 +258,51 @@ EditorPropertyPath::EditorPropertyPath() {
global = false;
}
+///////////////////// CLASS NAME /////////////////////////
+
+void EditorPropertyClassName::setup(const String &p_base_type, const String &p_selected_type) {
+
+ base_type = p_base_type;
+ dialog->set_base_type(base_type);
+ selected_type = p_selected_type;
+ property->set_text(selected_type);
+}
+
+void EditorPropertyClassName::update_property() {
+
+ String s = get_edited_object()->get(get_edited_property());
+ property->set_text(s);
+ selected_type = s;
+}
+
+void EditorPropertyClassName::_property_selected() {
+ dialog->popup_create(true);
+}
+
+void EditorPropertyClassName::_dialog_created() {
+ selected_type = dialog->get_selected_type();
+ emit_signal("property_changed", get_edited_property(), selected_type);
+ update_property();
+}
+
+void EditorPropertyClassName::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_dialog_created"), &EditorPropertyClassName::_dialog_created);
+ ClassDB::bind_method(D_METHOD("_property_selected"), &EditorPropertyClassName::_property_selected);
+}
+
+EditorPropertyClassName::EditorPropertyClassName() {
+ property = memnew(Button);
+ property->set_clip_text(true);
+ add_child(property);
+ add_focusable(property);
+ property->set_text(selected_type);
+ property->connect("pressed", this, "_property_selected");
+ dialog = memnew(CreateDialog);
+ dialog->set_base_type(base_type);
+ dialog->connect("create", this, "_dialog_created");
+ add_child(dialog);
+}
+
///////////////////// MEMBER /////////////////////////
void EditorPropertyMember::_property_selected(const String &p_selected) {
@@ -523,6 +568,7 @@ public:
uint32_t value;
Vector<Rect2> flag_rects;
Vector<String> names;
+ Vector<String> tooltips;
virtual Size2 get_minimum_size() const {
Ref<Font> font = get_font("font", "Label");
@@ -531,8 +577,8 @@ public:
virtual String get_tooltip(const Point2 &p_pos) const {
for (int i = 0; i < flag_rects.size(); i++) {
- if (i < names.size() && flag_rects[i].has_point(p_pos)) {
- return names[i];
+ if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) {
+ return tooltips[i];
}
}
return String();
@@ -636,6 +682,7 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
}
Vector<String> names;
+ Vector<String> tooltips;
for (int i = 0; i < 20; i++) {
String name;
@@ -647,12 +694,12 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
name = TTR("Layer") + " " + itos(i + 1);
}
- name += "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i);
-
names.push_back(name);
+ tooltips.push_back(name + "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i));
}
grid->names = names;
+ grid->tooltips = tooltips;
}
void EditorPropertyLayers::_button_pressed() {
@@ -681,6 +728,7 @@ void EditorPropertyLayers::_menu_pressed(int p_menu) {
grid->value |= (1 << p_menu);
}
grid->update();
+ layers->set_item_checked(layers->get_item_index(p_menu), grid->value & (1 << p_menu));
_grid_changed(grid->value);
}
@@ -706,6 +754,7 @@ EditorPropertyLayers::EditorPropertyLayers() {
set_bottom_editor(hb);
layers = memnew(PopupMenu);
add_child(layers);
+ layers->set_hide_on_checkable_item_selection(false);
layers->connect("id_pressed", this, "_menu_pressed");
}
///////////////////// INT /////////////////////////
@@ -1020,18 +1069,35 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo
}
EditorPropertyVector2::EditorPropertyVector2() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[2] = { "x", "y" };
for (int i = 0; i < 2; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_flat(true);
spin[i]->set_label(desc[i]);
- vb->add_child(spin[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
@@ -1146,19 +1212,35 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo
}
EditorPropertyVector3::EditorPropertyVector3() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[3] = { "x", "y", "z" };
for (int i = 0; i < 3; i++) {
spin[i] = memnew(EditorSpinSlider);
- spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
-
- vb->add_child(spin[i]);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
///////////////////// PLANE /////////////////////////
@@ -1210,18 +1292,36 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool
}
EditorPropertyPlane::EditorPropertyPlane() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[4] = { "x", "y", "z", "d" };
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
- spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
- vb->add_child(spin[i]);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
@@ -1274,19 +1374,35 @@ void EditorPropertyQuat::setup(double p_min, double p_max, double p_step, bool p
}
EditorPropertyQuat::EditorPropertyQuat() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[4] = { "x", "y", "z", "w" };
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
- spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
-
- vb->add_child(spin[i]);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
@@ -2607,6 +2723,10 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) {
EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText);
add_property_editor(p_path, editor);
+ } else if (p_hint == PROPERTY_HINT_TYPE_STRING) {
+ EditorPropertyClassName *editor = memnew(EditorPropertyClassName);
+ editor->setup("Object", p_hint_text);
+ add_property_editor(p_path, editor);
} else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
Vector<String> extensions = p_hint_text.split(",");
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 0afb1bf955..ccd73d2539 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -119,6 +119,25 @@ public:
EditorPropertyPath();
};
+class EditorPropertyClassName : public EditorProperty {
+ GDCLASS(EditorPropertyClassName, EditorProperty)
+private:
+ CreateDialog *dialog;
+ Button *property;
+ String selected_type;
+ String base_type;
+ void _property_selected();
+ void _dialog_created();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void setup(const String &p_base_type, const String &p_selected_type);
+ virtual void update_property();
+ EditorPropertyClassName();
+};
+
class EditorPropertyMember : public EditorProperty {
GDCLASS(EditorPropertyMember, EditorProperty)
public:
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index aa67ea03d7..a9eaad47b7 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -46,7 +46,7 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden");
ERR_FAIL_V(false);
}
-Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) {
+Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) const {
if (get_script_instance() && get_script_instance()->has_method("generate")) {
return get_script_instance()->call("generate", p_from);
@@ -55,7 +55,7 @@ Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) {
ERR_FAIL_V(Ref<Texture>());
}
-Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) {
+Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) const {
if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) {
return get_script_instance()->call("generate_from_path", p_path);
diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h
index e2276aa11d..74841b1a1e 100644
--- a/editor/editor_resource_preview.h
+++ b/editor/editor_resource_preview.h
@@ -63,8 +63,8 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
- virtual Ref<Texture> generate_from_path(const String &p_path);
+ virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path) const;
EditorResourcePreviewGenerator();
};
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 466b12157d..02e121b5f1 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -298,17 +298,17 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/main_font_size", 14);
hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "10,40,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/code_font_size", 14);
- hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font_hinting", 2);
- hints["interface/editor/main_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/main_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/main_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/main_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/code_font_hinting", 2);
- hints["interface/editor/code_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/code_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/code_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/code_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font", "");
- hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font_bold", "");
- hints["interface/editor/main_font_bold"] = PropertyInfo(Variant::STRING, "interface/editor/main_font_bold", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/main_font_bold"] = PropertyInfo(Variant::STRING, "interface/editor/main_font_bold", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/code_font", "");
- hints["interface/editor/code_font"] = PropertyInfo(Variant::STRING, "interface/editor/code_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/code_font"] = PropertyInfo(Variant::STRING, "interface/editor/code_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/dim_editor_on_dialog_popup", true);
_initial_set("interface/editor/dim_amount", 0.6f);
hints["interface/editor/dim_amount"] = PropertyInfo(Variant::REAL, "interface/editor/dim_amount", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT);
@@ -881,7 +881,7 @@ fail:
Vector<String> list = extra_config->get_value("init_projects", "list");
for (int i = 0; i < list.size(); i++) {
- list[i] = exe_path + "/" + list[i];
+ list.write[i] = exe_path + "/" + list[i];
};
extra_config->set_value("init_projects", "list", list);
};
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 0e6d81d13b..e3fd7d5308 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -31,6 +31,11 @@
#include "editor_spin_slider.h"
#include "editor_scale.h"
#include "os/input.h"
+
+String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
+ return rtos(get_value());
+}
+
String EditorSpinSlider::get_text_value() const {
int zeros = Math::step_decimals(get_step());
return String::num(get_value(), zeros);
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index fb32534ef4..c8707b9867 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -82,6 +82,8 @@ protected:
void _focus_entered();
public:
+ String get_tooltip(const Point2 &p_pos) const;
+
String get_text_value() const;
void set_label(const String &p_label);
String get_label() const;
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index ea9f6db61a..0a22026591 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -237,8 +237,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
ImageLoaderSVG::set_convert_colors(NULL);
clock_t end_time = clock();
-
- double time_d = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
#else
print_line("Sorry no icons for you");
#endif
@@ -257,7 +255,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
String preset = EDITOR_DEF("interface/theme/preset", "Default");
- int icon_font_color_setting = EDITOR_DEF("interface/theme/icon_and_font_color", 0);
bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false);
int border_size = EDITOR_DEF("interface/theme/border_size", 1);
@@ -370,6 +367,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color success_color = accent_color.linear_interpolate(Color(0.2, 1, 0.2), 0.6) * 1.2;
Color warning_color = accent_color.linear_interpolate(Color(1, 1, 0), 0.7) * 1.2;
Color error_color = accent_color.linear_interpolate(Color(1, 0, 0), 0.8) * 1.7;
+ Color property_color = font_color.linear_interpolate(Color(0.5, 0.5, 0.5), 0.5);
+
if (!dark_theme) {
// yellow on white themes is a P.I.T.A.
warning_color = accent_color.linear_interpolate(Color(1, 0.8, 0), 0.9);
@@ -380,6 +379,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("success_color", "Editor", success_color);
theme->set_color("warning_color", "Editor", warning_color);
theme->set_color("error_color", "Editor", error_color);
+ theme->set_color("property_color", "Editor", property_color);
// 2d grid color
const Color grid_minor_color = mono_color * Color(1.0, 1.0, 1.0, 0.07);
diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp
index a218070933..b9e0c7d0fa 100644
--- a/editor/fileserver/editor_file_server.cpp
+++ b/editor/fileserver/editor_file_server.cpp
@@ -78,7 +78,7 @@ void EditorFileServer::_subthread_start(void *s) {
_close_client(cd);
ERR_FAIL_COND(err != OK);
}
- passutf8[passlen] = 0;
+ passutf8.write[passlen] = 0;
String s;
s.parse_utf8(passutf8.ptr());
if (s != cd->efs->password) {
@@ -145,7 +145,7 @@ void EditorFileServer::_subthread_start(void *s) {
_close_client(cd);
ERR_FAIL_COND(err != OK);
}
- fileutf8[namelen] = 0;
+ fileutf8.write[namelen] = 0;
String s;
s.parse_utf8(fileutf8.ptr());
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index f65fb5365b..1718badbfa 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1319,6 +1319,9 @@ void FileSystemDock::_file_option(int p_option) {
String fpath = files->get_item_metadata(idx);
OS::get_singleton()->set_clipboard(fpath);
} break;
+ case FILE_NEW_RESOURCE: {
+ new_resource_dialog->popup_create(true);
+ } break;
}
}
@@ -1393,6 +1396,21 @@ void FileSystemDock::_folder_option(int p_option) {
}
}
+void FileSystemDock::_resource_created() const {
+ Object *c = new_resource_dialog->instance_selected();
+
+ ERR_FAIL_COND(!c);
+ Resource *r = Object::cast_to<Resource>(c);
+ ERR_FAIL_COND(!r);
+
+ REF res(r);
+ editor->push_item(c);
+
+ RES current_res = RES(r);
+
+ editor->save_resource_as(current_res);
+}
+
void FileSystemDock::_go_to_file_list() {
if (low_height_mode) {
@@ -1738,6 +1756,7 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
file_options->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
file_options->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
+ file_options->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
file_options->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER);
file_options->set_position(files->get_global_position() + p_pos);
@@ -1750,6 +1769,7 @@ void FileSystemDock::_rmb_pressed(const Vector2 &p_pos) {
file_options->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
file_options->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
+ file_options->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
file_options->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER);
file_options->set_position(files->get_global_position() + p_pos);
file_options->popup();
@@ -1862,6 +1882,7 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_file_option"), &FileSystemDock::_file_option);
ClassDB::bind_method(D_METHOD("_folder_option"), &FileSystemDock::_folder_option);
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm);
+ ClassDB::bind_method(D_METHOD("_resource_created"), &FileSystemDock::_resource_created);
ClassDB::bind_method(D_METHOD("_move_operation_confirm", "to_path", "overwrite"), &FileSystemDock::_move_operation_confirm, DEFVAL(false));
ClassDB::bind_method(D_METHOD("_move_with_overwrite"), &FileSystemDock::_move_with_overwrite);
ClassDB::bind_method(D_METHOD("_rename_operation_confirm"), &FileSystemDock::_rename_operation_confirm);
@@ -1962,9 +1983,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
*/
file_options = memnew(PopupMenu);
+ file_options->set_hide_on_window_lose_focus(true);
add_child(file_options);
folder_options = memnew(PopupMenu);
+ folder_options->set_hide_on_window_lose_focus(true);
add_child(folder_options);
split_box = memnew(VSplitContainer);
@@ -2087,6 +2110,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
make_script_dialog_text->set_title(TTR("Create Script"));
add_child(make_script_dialog_text);
+ new_resource_dialog = memnew(CreateDialog);
+ add_child(new_resource_dialog);
+ new_resource_dialog->set_base_type("Resource");
+ new_resource_dialog->connect("create", this, "_resource_created");
+
updating_tree = false;
initialized = false;
import_dock_needs_update = false;
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index e8ab803cca..6a0c73d52e 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -47,6 +47,8 @@
#include "os/dir_access.h"
#include "os/thread.h"
+#include "create_dialog.h"
+
#include "dependency_editor.h"
#include "editor_dir_dialog.h"
#include "editor_file_system.h"
@@ -78,7 +80,8 @@ private:
FILE_NEW_FOLDER,
FILE_NEW_SCRIPT,
FILE_SHOW_IN_EXPLORER,
- FILE_COPY_PATH
+ FILE_COPY_PATH,
+ FILE_NEW_RESOURCE
};
enum FolderMenu {
@@ -131,6 +134,7 @@ private:
LineEdit *make_dir_dialog_text;
ConfirmationDialog *overwrite_dialog;
ScriptCreateDialog *make_script_dialog_text;
+ CreateDialog *new_resource_dialog;
class FileOrFolder {
public:
@@ -191,6 +195,7 @@ private:
void _update_favorite_dirs_list_after_move(const Map<String, String> &p_renames) const;
void _update_project_settings_after_move(const Map<String, String> &p_renames) const;
+ void _resource_created() const;
void _make_dir_confirm();
void _rename_operation_confirm();
void _duplicate_operation_confirm();
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 004a49e2b4..2be1f1644e 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -143,7 +143,7 @@ void FindInFiles::_iterate() {
// Scan folders first so we can build a list of files and have progress info later
- PoolStringArray &folders_to_scan = _folders_stack[_folders_stack.size() - 1];
+ PoolStringArray &folders_to_scan = _folders_stack.write[_folders_stack.size() - 1];
if (folders_to_scan.size() != 0) {
// Scan one folder below
diff --git a/editor/icons/SCsub b/editor/icons/SCsub
index 7f94073e01..31bf8f116a 100644
--- a/editor/icons/SCsub
+++ b/editor/icons/SCsub
@@ -1,96 +1,14 @@
#!/usr/bin/env python
Import('env')
-from compat import StringIO
+from platform_methods import run_in_subprocess
+import editor_icons_builders
-def make_editor_icons_action(target, source, env):
- import os
-
- dst = target[0].srcnode().abspath
- svg_icons = source
-
- icons_string = StringIO()
-
- for f in svg_icons:
-
- fname = str(f)
-
- icons_string.write('\t"')
-
- with open(fname, 'rb') as svgf:
- b = svgf.read(1)
- while(len(b) == 1):
- icons_string.write("\\" + str(hex(ord(b)))[1:])
- b = svgf.read(1)
-
-
- icons_string.write('"')
- if fname != svg_icons[-1]:
- icons_string.write(",")
- icons_string.write('\n')
-
- s = StringIO()
- s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- s.write("#ifndef _EDITOR_ICONS_H\n")
- s.write("#define _EDITOR_ICONS_H\n")
- s.write("static const int editor_icons_count = {};\n".format(len(svg_icons)))
- s.write("static const char *editor_icons_sources[] = {\n")
- s.write(icons_string.getvalue())
- s.write('};\n\n')
- s.write("static const char *editor_icons_names[] = {\n")
-
- # this is used to store the indices of thumbnail icons
- thumb_medium_indices = [];
- thumb_big_indices = [];
- index = 0
- for f in svg_icons:
-
- fname = str(f)
-
- icon_name = os.path.basename(fname)[5:-4].title().replace("_", "")
- # some special cases
- if icon_name in ['Int', 'Bool', 'Float']:
- icon_name = icon_name.lower()
- if icon_name.endswith("MediumThumb"): # don't know a better way to handle this
- thumb_medium_indices.append(str(index))
- if icon_name.endswith("BigThumb"): # don't know a better way to handle this
- thumb_big_indices.append(str(index))
-
- s.write('\t"{0}"'.format(icon_name))
-
- if fname != svg_icons[-1]:
- s.write(",")
- s.write('\n')
-
- index += 1
-
- s.write('};\n')
-
- if thumb_medium_indices:
- s.write("\n\n")
- s.write("static const int editor_md_thumbs_count = {};\n".format(len(thumb_medium_indices)))
- s.write("static const int editor_md_thumbs_indices[] = {")
- s.write(", ".join(thumb_medium_indices))
- s.write("};\n")
- if thumb_big_indices:
- s.write("\n\n")
- s.write("static const int editor_bg_thumbs_count = {};\n".format(len(thumb_big_indices)))
- s.write("static const int editor_bg_thumbs_indices[] = {")
- s.write(", ".join(thumb_big_indices))
- s.write("};\n")
-
- s.write("#endif\n")
-
- with open(dst, "w") as f:
- f.write(s.getvalue())
-
- s.close()
- icons_string.close()
-
-make_editor_icons_builder = Builder(action=make_editor_icons_action,
+make_editor_icons_builder = Builder(action=run_in_subprocess(editor_icons_builders.make_editor_icons_action),
suffix='.h',
src_suffix='.svg')
+
env['BUILDERS']['MakeEditorIconsBuilder'] = make_editor_icons_builder
env.Alias('editor_icons', [env.MakeEditorIconsBuilder('#editor/editor_icons.gen.h', Glob("*.svg"))])
diff --git a/editor/icons/editor_icons_builders.py b/editor/icons/editor_icons_builders.py
new file mode 100644
index 0000000000..dfd0802ce9
--- /dev/null
+++ b/editor/icons/editor_icons_builders.py
@@ -0,0 +1,96 @@
+"""Functions used to generate source files during build time
+
+All such functions are invoked in a subprocess on Windows to prevent build flakiness.
+
+"""
+import os
+from platform_methods import subprocess_main
+from compat import StringIO
+
+
+def make_editor_icons_action(target, source, env):
+
+ dst = target[0]
+ svg_icons = source
+
+ icons_string = StringIO()
+
+ for f in svg_icons:
+
+ fname = str(f)
+
+ icons_string.write('\t"')
+
+ with open(fname, 'rb') as svgf:
+ b = svgf.read(1)
+ while(len(b) == 1):
+ icons_string.write("\\" + str(hex(ord(b)))[1:])
+ b = svgf.read(1)
+
+
+ icons_string.write('"')
+ if fname != svg_icons[-1]:
+ icons_string.write(",")
+ icons_string.write('\n')
+
+ s = StringIO()
+ s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ s.write("#ifndef _EDITOR_ICONS_H\n")
+ s.write("#define _EDITOR_ICONS_H\n")
+ s.write("static const int editor_icons_count = {};\n".format(len(svg_icons)))
+ s.write("static const char *editor_icons_sources[] = {\n")
+ s.write(icons_string.getvalue())
+ s.write('};\n\n')
+ s.write("static const char *editor_icons_names[] = {\n")
+
+ # this is used to store the indices of thumbnail icons
+ thumb_medium_indices = [];
+ thumb_big_indices = [];
+ index = 0
+ for f in svg_icons:
+
+ fname = str(f)
+
+ icon_name = os.path.basename(fname)[5:-4].title().replace("_", "")
+ # some special cases
+ if icon_name in ['Int', 'Bool', 'Float']:
+ icon_name = icon_name.lower()
+ if icon_name.endswith("MediumThumb"): # don't know a better way to handle this
+ thumb_medium_indices.append(str(index))
+ if icon_name.endswith("BigThumb"): # don't know a better way to handle this
+ thumb_big_indices.append(str(index))
+
+ s.write('\t"{0}"'.format(icon_name))
+
+ if fname != svg_icons[-1]:
+ s.write(",")
+ s.write('\n')
+
+ index += 1
+
+ s.write('};\n')
+
+ if thumb_medium_indices:
+ s.write("\n\n")
+ s.write("static const int editor_md_thumbs_count = {};\n".format(len(thumb_medium_indices)))
+ s.write("static const int editor_md_thumbs_indices[] = {")
+ s.write(", ".join(thumb_medium_indices))
+ s.write("};\n")
+ if thumb_big_indices:
+ s.write("\n\n")
+ s.write("static const int editor_bg_thumbs_count = {};\n".format(len(thumb_big_indices)))
+ s.write("static const int editor_bg_thumbs_indices[] = {")
+ s.write(", ".join(thumb_big_indices))
+ s.write("};\n")
+
+ s.write("#endif\n")
+
+ with open(dst, "w") as f:
+ f.write(s.getvalue())
+
+ s.close()
+ icons_string.close()
+
+
+if __name__ == '__main__':
+ subprocess_main(globals())
diff --git a/editor/icons/icon_soft_body.svg b/editor/icons/icon_soft_body.svg
new file mode 100644
index 0000000000..9930026b61
--- /dev/null
+++ b/editor/icons/icon_soft_body.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon_soft_body.svg">
+ <metadata
+ id="metadata14">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs12" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1027"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="18.792233"
+ inkscape:cx="2.8961304"
+ inkscape:cy="4.3816933"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ style="opacity:1;fill:#fc9c9c;fill-opacity:0.99607843;fill-rule:nonzero;stroke:none;stroke-width:1.42799997;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 2.3447105,1.6091897 c -0.011911,1.9816766 -1.4168958,3.9344766 0,5.9495986 1.4168957,2.0151221 0,6.6693597 0,6.6693597 l 10.9510055,0 c 0,0 1.780829,-4.4523824 0,-6.489075 -1.780829,-2.0366925 -0.183458,-4.119112 0,-6.1298833 z m 1.8894067,0.7549031 7.4390658,0 c -0.431995,1.5996085 -1.62289,4.0426807 0,5.3749802 1.622888,1.3322996 0,5.887932 0,5.887932 l -7.4390658,0 c 0,0 1.3903413,-4.3680495 0,-5.9780743 -1.3903412,-1.6100247 -0.3951213,-3.7149271 0,-5.2848379 z"
+ id="rect4142"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czcczcccczcczc" />
+</svg>
diff --git a/editor/icons/icon_texture_3_d.svg b/editor/icons/icon_texture_3_d.svg
new file mode 100644
index 0000000000..dafdc8c68d
--- /dev/null
+++ b/editor/icons/icon_texture_3_d.svg
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg6"
+ sodipodi:docname="icon_texture_3_d.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1853"
+ inkscape:window-height="1016"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="29.5"
+ inkscape:cx="15.226978"
+ inkscape:cy="9.4909723"
+ inkscape:window-x="67"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg6" />
+ <g
+ id="g830"
+ transform="translate(0.35954582,-0.28763666)">
+ <path
+ d="M 2,1 C 1.4477153,1 1,1.4477153 1,2 v 12 c 0,0.552285 0.4477153,1 1,1 h 12 c 0.552285,0 1,-0.447715 1,-1 V 2 C 15,1.4477153 14.552285,1 14,1 Z m 1,2 h 10 v 8 H 3 Z"
+ id="path2"
+ inkscape:connector-curvature="0"
+ style="fill:#e0e0e0;fill-opacity:0.99607999"
+ sodipodi:nodetypes="sssssssssccccc" />
+ </g>
+ <g
+ aria-label="3D"
+ transform="scale(0.9167105,1.0908569)"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.12847996px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:0.20321201"
+ id="text834">
+ <path
+ d="m 5.8175194,8.9717502 q -0.2194689,0 -0.4633233,-0.032514 Q 5.1103417,8.9148508 4.8827442,8.86608 4.6551468,8.8173091 4.4681918,8.7604097 4.2812367,8.7035104 4.1755665,8.6547395 L 4.4112924,7.646808 q 0.2113405,0.089413 0.5364797,0.1950835 0.3332677,0.097542 0.8209765,0.097542 0.5608651,0 0.8209764,-0.2113404 0.2601114,-0.2113405 0.2601114,-0.5689936 0,-0.219469 -0.097542,-0.3657816 Q 6.6628814,6.6388764 6.5003118,6.5494632 6.3377422,6.4519214 6.1101447,6.4194075 5.8906758,6.3787651 5.6386929,6.3787651 H 5.167241 V 5.4033475 h 0.5364797 q 0.1788266,0 0.3413962,-0.032514 0.1706981,-0.032514 0.3007537,-0.1056703 0.1300557,-0.081285 0.203212,-0.2113404 0.081285,-0.1381842 0.081285,-0.3413962 0,-0.1544411 -0.065028,-0.2682398 Q 6.5003118,4.3303881 6.3946415,4.2572318 6.2970998,4.1840755 6.1589156,4.1515616 6.0288599,4.1109192 5.8906758,4.1109192 q -0.3495247,0 -0.6502784,0.1056702 Q 4.9477721,4.3222597 4.7039177,4.4767008 L 4.2731082,3.5906965 Q 4.4031639,3.5094117 4.573862,3.4199984 4.7526886,3.3305851 4.964029,3.2574288 5.1753695,3.1842725 5.4110954,3.1355016 q 0.2438544,-0.048771 0.5120943,-0.048771 0.4958373,0 0.8534904,0.1219272 0.3657816,0.1137987 0.6015075,0.3332677 0.2357259,0.2113405 0.3495246,0.5039657 0.1137987,0.2844968 0.1137987,0.625893 0,0.3332677 -0.186955,0.6502784 -0.186955,0.3088822 -0.5039657,0.4714518 0.4389379,0.1788266 0.6746638,0.5364797 0.2438544,0.3495246 0.2438544,0.8453619 0,0.3901671 -0.1300557,0.7234347 Q 7.808997,8.22393 7.5326287,8.4677844 7.2562604,8.7035104 6.825451,8.8416945 6.40277,8.9717502 5.8175194,8.9717502 Z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.20321201"
+ id="path836" />
+ <path
+ d="m 10.502445,7.817506 q 0.08941,0.00813 0.203212,0.016257 0.121927,0 0.284497,0 0.951032,0 1.406227,-0.4795803 0.463323,-0.4795803 0.463323,-1.3249422 0,-0.8860044 -0.438938,-1.3411992 -0.438938,-0.4551949 -1.38997,-0.4551949 -0.130055,0 -0.26824,0.00813 -0.138184,0 -0.260111,0.016257 z M 14.16839,6.0292405 q 0,0.7315631 -0.227598,1.2761713 -0.227597,0.5446082 -0.650278,0.9022613 -0.414553,0.3576531 -1.01606,0.5364797 -0.601508,0.1788265 -1.349328,0.1788265 -0.341396,0 -0.796591,-0.032514 Q 9.6733402,8.86608 9.2344022,8.7766667 v -5.486724 q 0.438938,-0.081285 0.9103898,-0.1056702 0.47958,-0.032514 0.820976,-0.032514 0.723435,0 1.308686,0.1625696 0.593379,0.1625696 1.01606,0.5120943 0.422681,0.3495246 0.650278,0.8941328 0.227598,0.5446081 0.227598,1.3086853 z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.20321201"
+ id="path838" />
+ </g>
+</svg>
diff --git a/editor/icons/icon_texture_array.svg b/editor/icons/icon_texture_array.svg
new file mode 100644
index 0000000000..8297fc0f5d
--- /dev/null
+++ b/editor/icons/icon_texture_array.svg
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg6"
+ sodipodi:docname="icon_texture_array.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1526"
+ inkscape:window-height="766"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="29.5"
+ inkscape:cx="8.3117238"
+ inkscape:cy="9.4909723"
+ inkscape:window-x="67"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg6" />
+ <g
+ id="g830"
+ transform="translate(0.35954582,-0.28763666)">
+ <path
+ d="M 2,1 C 1.4477153,1 1,1.4477153 1,2 v 12 c 0,0.552285 0.4477153,1 1,1 h 12 c 0.552285,0 1,-0.447715 1,-1 V 2 C 15,1.4477153 14.552285,1 14,1 Z m 1,2 h 10 v 8 H 3 Z"
+ id="path2"
+ inkscape:connector-curvature="0"
+ style="fill:#e0e0e0;fill-opacity:0.99607999"
+ sodipodi:nodetypes="sssssssssccccc" />
+ </g>
+ <g
+ aria-label="[]"
+ transform="matrix(1.6197742,0,0,0.750929,-3.7231532,1.8329569)"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.29580784px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:0.2073952"
+ id="text834">
+ <path
+ d="M 4.7302951,2.4553483 H 6.978459 V 3.4425495 H 5.9082998 V 9.4984892 H 6.978459 V 10.48569 H 4.7302951 Z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.2073952"
+ id="path862"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 10.138643,10.48569 H 7.8904794 V 9.4984892 H 8.9606386 V 3.4425495 H 7.8904794 V 2.4553483 h 2.2481636 z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.2073952"
+ id="path864"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index a13f741ee7..22ea5883e8 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -579,12 +579,12 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
.normalized();
}
- tangents[index_arrayr[idx * 3 + 0]] += tangent;
- binormals[index_arrayr[idx * 3 + 0]] += binormal;
- tangents[index_arrayr[idx * 3 + 1]] += tangent;
- binormals[index_arrayr[idx * 3 + 1]] += binormal;
- tangents[index_arrayr[idx * 3 + 2]] += tangent;
- binormals[index_arrayr[idx * 3 + 2]] += binormal;
+ tangents.write[index_arrayr[idx * 3 + 0]] += tangent;
+ binormals.write[index_arrayr[idx * 3 + 0]] += binormal;
+ tangents.write[index_arrayr[idx * 3 + 1]] += tangent;
+ binormals.write[index_arrayr[idx * 3 + 1]] += binormal;
+ tangents.write[index_arrayr[idx * 3 + 2]] += tangent;
+ binormals.write[index_arrayr[idx * 3 + 2]] += binormal;
//print_line(itos(idx)+" tangent: "+tangent);
//print_line(itos(idx)+" binormal: "+binormal);
@@ -800,7 +800,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
total += weights[i].weight;
if (total)
for (int i = 0; i < weights.size(); i++)
- weights[i].weight /= total;
+ weights.write[i].weight /= total;
if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0
//no weights assigned
@@ -987,7 +987,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
vertex_array.resize(vertex_set.size());
for (Set<Collada::Vertex>::Element *F = vertex_set.front(); F; F = F->next()) {
- vertex_array[F->get().idx] = F->get();
+ vertex_array.write[F->get().idx] = F->get();
}
if (has_weights) {
@@ -996,9 +996,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
Transform local_xform = p_local_xform;
for (int i = 0; i < vertex_array.size(); i++) {
- vertex_array[i].vertex = local_xform.xform(vertex_array[i].vertex);
- vertex_array[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
- vertex_array[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
+ vertex_array.write[i].vertex = local_xform.xform(vertex_array[i].vertex);
+ vertex_array.write[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
+ vertex_array.write[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
if (local_xform_mirror) {
//i shouldn't do this? wtf?
//vertex_array[i].normal*=-1.0;
@@ -1061,13 +1061,13 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
//float sum=0.0;
for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
if (l < vertex_array[k].weights.size()) {
- weights[l] = vertex_array[k].weights[l].weight;
- bones[l] = vertex_array[k].weights[l].bone_idx;
+ weights.write[l] = vertex_array[k].weights[l].weight;
+ bones.write[l] = vertex_array[k].weights[l].bone_idx;
//sum += vertex_array[k].weights[l].weight;
} else {
- weights[l] = 0;
- bones[l] = 0;
+ weights.write[l] = 0;
+ bones.write[l] = 0;
}
}
@@ -1286,7 +1286,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
String str = joint_src->sarray[i];
ERR_FAIL_COND_V(!bone_remap_map.has(str), ERR_INVALID_DATA);
- bone_remap[i] = bone_remap_map[str];
+ bone_remap.write[i] = bone_remap_map[str];
}
}
@@ -1506,7 +1506,7 @@ void ColladaImport::_fix_param_animation_tracks() {
const Vector<int> &rt = collada.state.referenced_tracks[track_name];
for (int rti = 0; rti < rt.size(); rti++) {
- Collada::AnimationTrack *at = &collada.state.animation_tracks[rt[rti]];
+ Collada::AnimationTrack *at = &collada.state.animation_tracks.write[rt[rti]];
at->target = E->key();
at->param = "morph/" + collada.state.mesh_name_map[mesh_name];
@@ -1540,7 +1540,7 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_im
for (int i = 0; i < collada.state.animation_tracks.size(); i++) {
- Collada::AnimationTrack &at = collada.state.animation_tracks[i];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[i];
//print_line("CHANNEL: "+at.target+" PARAM: "+at.param);
String node;
@@ -1698,7 +1698,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
if (nm.anim_tracks.size() == 1) {
//use snapshot keys from anim track instead, because this was most likely exported baked
- Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
snapshots.clear();
for (int i = 0; i < at.keys.size(); i++)
snapshots.push_back(at.keys[i].time);
@@ -1723,7 +1723,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
found_anim = true;
- Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
int xform_idx = -1;
for (int j = 0; j < cn->xform_list.size(); j++) {
@@ -1745,18 +1745,18 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Vector<float> data = at.get_value_at_time(snapshots[i]);
ERR_CONTINUE(data.empty());
- Collada::Node::XForm &xf = cn->xform_list[xform_idx];
+ Collada::Node::XForm &xf = cn->xform_list.write[xform_idx];
if (at.component == "ANGLE") {
ERR_CONTINUE(data.size() != 1);
ERR_CONTINUE(xf.op != Collada::Node::XForm::OP_ROTATE);
ERR_CONTINUE(xf.data.size() < 4);
- xf.data[3] = data[0];
+ xf.data.write[3] = data[0];
} else if (at.component == "X" || at.component == "Y" || at.component == "Z") {
int cn = at.component[0] - 'X';
ERR_CONTINUE(cn >= xf.data.size());
ERR_CONTINUE(data.size() > 1);
- xf.data[cn] = data[0];
+ xf.data.write[cn] = data[0];
} else if (data.size() == xf.data.size()) {
xf.data = data;
@@ -1862,7 +1862,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
continue;
}
- Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
// take snapshots
if (!collada.state.scene_map.has(at.target))
@@ -1965,7 +1965,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
if (p_flags & IMPORT_ANIMATION_DETECT_LOOP) {
if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
- state.animations[i]->set_loop(true);
+ state.animations.write[i]->set_loop(true);
}
}
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index eb0bc0f782..906d902b4a 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -203,7 +203,6 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
GLTFNode *node = memnew(GLTFNode);
Dictionary n = nodes[i];
- print_line("node " + itos(i) + ": " + String(Variant(n)));
if (n.has("name")) {
node->name = n["name"];
}
@@ -651,7 +650,7 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
} else {
//fill with zeros, as bufferview is not defined.
for (int i = 0; i < (a.count * component_count); i++) {
- dst_buffer[i] = 0;
+ dst_buffer.write[i] = 0;
}
}
@@ -794,7 +793,7 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state,
ret.resize(ret_size);
{
for (int i = 0; i < ret_size; i++) {
- ret[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
+ ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
}
}
return ret;
@@ -808,8 +807,8 @@ Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFSta
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
ret.resize(attribs.size() / 4);
for (int i = 0; i < ret.size(); i++) {
- ret[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
- ret[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
+ ret.write[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
+ ret.write[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
}
return ret;
}
@@ -823,9 +822,9 @@ Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &stat
ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
ret.resize(attribs.size() / 9);
for (int i = 0; i < ret.size(); i++) {
- ret[i].set_axis(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
- ret[i].set_axis(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
- ret[i].set_axis(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
+ ret.write[i].set_axis(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
+ ret.write[i].set_axis(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
+ ret.write[i].set_axis(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
}
return ret;
}
@@ -838,10 +837,10 @@ Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &
ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
ret.resize(attribs.size() / 16);
for (int i = 0; i < ret.size(); i++) {
- ret[i].basis.set_axis(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
- ret[i].basis.set_axis(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
- ret[i].basis.set_axis(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
- ret[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
+ ret.write[i].basis.set_axis(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
+ ret.write[i].basis.set_axis(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
+ ret.write[i].basis.set_axis(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
+ ret.write[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
}
return ret;
}
@@ -1085,7 +1084,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
ERR_FAIL_COND_V(mesh.mesh->get_blend_shape_count() != weights.size(), ERR_PARSE_ERROR);
mesh.blend_weights.resize(weights.size());
for (int j = 0; j < weights.size(); j++) {
- mesh.blend_weights[j] = weights[j];
+ mesh.blend_weights.write[j] = weights[j];
}
}
@@ -1139,7 +1138,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
ERR_FAIL_INDEX_V(bvi, state.buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
- GLTFBufferView &bv = state.buffer_views[bvi];
+ const GLTFBufferView &bv = state.buffer_views[bvi];
int bi = bv.buffer;
ERR_FAIL_INDEX_V(bi, state.buffers.size(), ERR_PARAMETER_RANGE_ERROR);
@@ -1596,7 +1595,7 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
PoolVector<float> weights = _decode_accessor_as_floats(state, output, false);
ERR_FAIL_INDEX_V(state.nodes[node]->mesh, state.meshes.size(), ERR_PARSE_ERROR);
- GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
+ const GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
ERR_FAIL_COND_V(mesh->blend_weights.size() == 0, ERR_PARSE_ERROR);
int wc = mesh->blend_weights.size();
@@ -1611,11 +1610,11 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
Vector<float> wdata;
wdata.resize(wlen);
for (int l = 0; l < wlen; l++) {
- wdata[l] = r[l * wc + k];
+ wdata.write[l] = r[l * wc + k];
}
cf.values = wdata;
- track->weight_tracks[k] = cf;
+ track->weight_tracks.write[k] = cf;
}
} else {
WARN_PRINTS("Invalid path: " + path);
@@ -1657,7 +1656,8 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
if (n->mesh >= 0) {
ERR_FAIL_INDEX(n->mesh, state.meshes.size());
MeshInstance *mi = memnew(MeshInstance);
- GLTFMesh &mesh = state.meshes[n->mesh];
+ print_line("**creating mesh for: " + n->name);
+ GLTFMesh &mesh = state.meshes.write[n->mesh];
mi->set_mesh(mesh.mesh);
if (mesh.mesh->get_name() == "") {
mesh.mesh->set_name(n->name);
@@ -1686,20 +1686,22 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
node->set_name(n->name);
- p_parent->add_child(node);
- node->set_owner(p_owner);
- node->set_transform(n->xform);
-
n->godot_nodes.push_back(node);
if (n->skin >= 0 && Object::cast_to<MeshInstance>(node)) {
MeshInstance *mi = Object::cast_to<MeshInstance>(node);
- //move skeleton around and place it on node, as the node _is_ a skeleton.
+
Skeleton *s = skeletons[n->skin];
- state.paths_to_skeleton[mi] = s;
- //move it later, as skeleton may be moved around first
+ s->add_child(node); //According to spec, mesh should actually act as a child of the skeleton, as it inherits its transform
+ mi->set_skeleton_path(String(".."));
+
+ } else {
+ p_parent->add_child(node);
+ node->set_transform(n->xform);
}
+ node->set_owner(p_owner);
+
#if 0
for (int i = 0; i < n->skeleton_children.size(); i++) {
@@ -1711,14 +1713,14 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
#endif
for (int i = 0; i < n->children.size(); i++) {
if (state.nodes[n->children[i]]->joints.size()) {
- _generate_bone(state, n->children[i], skeletons, Vector<int>(), node);
+ _generate_bone(state, n->children[i], skeletons, node);
} else {
_generate_node(state, n->children[i], node, p_owner, skeletons);
}
}
}
-void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, const Vector<int> &p_parent_bones, Node *p_parent_node) {
+void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node) {
ERR_FAIL_INDEX(p_node, state.nodes.size());
if (state.skeleton_nodes.has(p_node)) {
@@ -1729,34 +1731,34 @@ void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vecto
skeletons[i]->get_parent()->remove_child(skeletons[i]);
p_parent_node->add_child(skeletons[i]);
skeletons[i]->set_owner(owner);
+ //may have meshes as children, set owner in them too
+ for (int j = 0; j < skeletons[i]->get_child_count(); j++) {
+ skeletons[i]->get_child(j)->set_owner(owner);
+ }
}
}
GLTFNode *n = state.nodes[p_node];
- Vector<int> parent_bones;
for (int i = 0; i < n->joints.size(); i++) {
- ERR_FAIL_COND(n->joints[i].skin < 0);
-
- int bone_index = n->joints[i].bone;
+ const int skin = n->joints[i].skin;
+ ERR_FAIL_COND(skin < 0);
- Skeleton *s = skeletons[n->joints[i].skin];
- while (s->get_bone_count() <= bone_index) {
- s->add_bone("Bone " + itos(s->get_bone_count()));
- }
+ Skeleton *s = skeletons[skin];
+ const GLTFNode *gltf_bone_node = state.nodes[state.skins[skin].bones[n->joints[i].bone].node];
+ const String bone_name = gltf_bone_node->name;
+ const int parent = gltf_bone_node->parent;
+ const int parent_index = s->find_bone(state.nodes[parent]->name);
- if (p_parent_bones.size()) {
- s->set_bone_parent(bone_index, p_parent_bones[i]);
- }
- s->set_bone_rest(bone_index, state.skins[n->joints[i].skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
+ const int bone_index = s->find_bone(bone_name);
+ s->set_bone_parent(bone_index, parent_index);
n->godot_nodes.push_back(s);
- n->joints[i].godot_bone_index = bone_index;
- parent_bones.push_back(bone_index);
+ n->joints.write[i].godot_bone_index = bone_index;
}
for (int i = 0; i < n->children.size(); i++) {
- _generate_bone(state, n->children[i], skeletons, parent_bones, p_parent_node);
+ _generate_bone(state, n->children[i], skeletons, p_parent_node);
}
}
@@ -1981,8 +1983,9 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
if (node->joints.size()) {
Transform xform;
- xform.basis = Basis(rot);
- xform.basis.scale(scale);
+ //xform.basis = Basis(rot);
+ //xform.basis.scale(scale);
+ xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;
Skeleton *skeleton = skeletons[node->joints[i].skin];
@@ -2063,6 +2066,10 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
if (name == "") {
name = _gen_unique_name(state, "Skeleton");
}
+ for (int j = 0; j < state.skins[i].bones.size(); j++) {
+ s->add_bone(state.nodes[state.skins[i].bones[j].node]->name);
+ s->set_bone_rest(j, state.skins[i].bones[j].inverse_bind.affine_inverse());
+ }
s->set_name(name);
root->add_child(s);
s->set_owner(root);
@@ -2070,18 +2077,12 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
}
for (int i = 0; i < state.root_nodes.size(); i++) {
if (state.nodes[state.root_nodes[i]]->joints.size()) {
- _generate_bone(state, state.root_nodes[i], skeletons, Vector<int>(), root);
+ _generate_bone(state, state.root_nodes[i], skeletons, root);
} else {
_generate_node(state, state.root_nodes[i], root, root, skeletons);
}
}
- for (Map<Node *, Skeleton *>::Element *E = state.paths_to_skeleton.front(); E; E = E->next()) {
- MeshInstance *mi = Object::cast_to<MeshInstance>(E->key());
- ERR_CONTINUE(!mi);
- mi->set_skeleton_path(mi->get_path_to(E->get()));
- }
-
for (int i = 0; i < skeletons.size(); i++) {
skeletons[i]->localize_rests();
}
diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h
index 088036ce75..8258ec41fd 100644
--- a/editor/import/editor_scene_importer_gltf.h
+++ b/editor/import/editor_scene_importer_gltf.h
@@ -275,7 +275,6 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<GLTFAnimation> animations;
Map<int, Vector<int> > skeleton_nodes;
- Map<Node *, Skeleton *> paths_to_skeleton;
//Map<int, Vector<int> > skin_users; //cache skin users
@@ -311,7 +310,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<Basis> _decode_accessor_as_basis(GLTFState &state, int p_accessor, bool p_for_vertex);
Vector<Transform> _decode_accessor_as_xform(GLTFState &state, int p_accessor, bool p_for_vertex);
- void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, const Vector<int> &p_parent_bones, Node *p_parent_node);
+ void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node);
void _generate_node(GLTFState &state, int p_node, Node *p_parent, Node *p_owner, Vector<Skeleton *> &skeletons);
void _import_animation(GLTFState &state, AnimationPlayer *ap, int index, int bake_fps, Vector<Skeleton *> skeletons);
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index ec0500361d..cf850eef03 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -119,7 +119,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
if (key != "") {
for (int i = 1; i < line.size(); i++) {
- translations[i - 1]->add_message(key, line[i]);
+ translations.write[i - 1]->add_message(key, line[i]);
}
}
diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp
new file mode 100644
index 0000000000..b6a67c0cd3
--- /dev/null
+++ b/editor/import/resource_importer_image.cpp
@@ -0,0 +1,79 @@
+#include "resource_importer_image.h"
+
+#include "io/image_loader.h"
+#include "io/resource_saver.h"
+#include "os/file_access.h"
+#include "scene/resources/texture.h"
+
+String ResourceImporterImage::get_importer_name() const {
+
+ return "image";
+}
+
+String ResourceImporterImage::get_visible_name() const {
+
+ return "Image";
+}
+void ResourceImporterImage::get_recognized_extensions(List<String> *p_extensions) const {
+
+ ImageLoader::get_recognized_extensions(p_extensions);
+}
+
+String ResourceImporterImage::get_save_extension() const {
+ return "image";
+}
+
+String ResourceImporterImage::get_resource_type() const {
+
+ return "Image";
+}
+
+bool ResourceImporterImage::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterImage::get_preset_count() const {
+ return 0;
+}
+String ResourceImporterImage::get_preset_name(int p_idx) const {
+
+ return String();
+}
+
+void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+}
+
+Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+
+ FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
+ if (!f) {
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ }
+
+ size_t len = f->get_len();
+
+ Vector<uint8_t> data;
+ data.resize(len);
+
+ f->get_buffer(data.ptrw(), len);
+
+ memdelete(f);
+
+ f = FileAccess::open(p_save_path + ".image", FileAccess::WRITE);
+
+ //save the header GDIM
+ const uint8_t header[4] = { 'G', 'D', 'I', 'M' };
+ f->store_buffer(header, 4);
+ //SAVE the extension (so it can be recognized by the loader later
+ f->store_pascal_string(p_source_file.get_extension().to_lower());
+ //SAVE the actual image
+ f->store_buffer(data.ptr(), len);
+
+ memdelete(f);
+
+ return OK;
+}
+
+ResourceImporterImage::ResourceImporterImage() {
+}
diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h
new file mode 100644
index 0000000000..5aadd00a35
--- /dev/null
+++ b/editor/import/resource_importer_image.h
@@ -0,0 +1,27 @@
+#ifndef RESOURCE_IMPORTER_IMAGE_H
+#define RESOURCE_IMPORTER_IMAGE_H
+
+#include "image.h"
+#include "io/resource_import.h"
+
+class ResourceImporterImage : public ResourceImporter {
+ GDCLASS(ResourceImporterImage, ResourceImporter)
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+
+ ResourceImporterImage();
+};
+
+#endif // RESOURCE_IMPORTER_IMAGE_H
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
new file mode 100644
index 0000000000..2f958a6fdd
--- /dev/null
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -0,0 +1,274 @@
+#include "resource_importer_layered_texture.h"
+
+#include "resource_importer_texture.h"
+
+#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
+#include "io/config_file.h"
+#include "io/image_loader.h"
+#include "scene/resources/texture.h"
+
+String ResourceImporterLayeredTexture::get_importer_name() const {
+
+ return is_3d ? "texture_3d" : "texture_array";
+}
+
+String ResourceImporterLayeredTexture::get_visible_name() const {
+
+ return is_3d ? "Texture3D" : "TextureArray";
+}
+void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
+
+ ImageLoader::get_recognized_extensions(p_extensions);
+}
+String ResourceImporterLayeredTexture::get_save_extension() const {
+ return is_3d ? "tex3d" : "texarr";
+}
+
+String ResourceImporterLayeredTexture::get_resource_type() const {
+
+ return is_3d ? "Texture3D" : "TextureArray";
+}
+
+bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterLayeredTexture::get_preset_count() const {
+ return 3;
+}
+String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
+
+ static const char *preset_names[] = {
+ "3D",
+ "2D",
+ "ColorCorrect"
+ };
+
+ return preset_names[p_idx];
+}
+
+void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_COLOR_CORRECT ? 0 : 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable"), p_preset == PRESET_3D ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/horizontal", PROPERTY_HINT_RANGE, "1,256,1"), p_preset == PRESET_COLOR_CORRECT ? 16 : 8));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/vertical", PROPERTY_HINT_RANGE, "1,256,1"), p_preset == PRESET_COLOR_CORRECT ? 1 : 8));
+}
+
+void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags) {
+
+ FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
+ f->store_8('G');
+ f->store_8('D');
+ if (is_3d) {
+ f->store_8('3');
+ } else {
+ f->store_8('A');
+ }
+ f->store_8('T'); //godot streamable texture
+
+ f->store_32(p_images[0]->get_width());
+ f->store_32(p_images[0]->get_height());
+ f->store_32(p_images.size()); //depth
+ f->store_32(p_texture_flags);
+ if (p_compress_mode != COMPRESS_VIDEO_RAM) {
+ //vram needs to do a first compression to tell what the format is, for the rest its ok
+ f->store_32(p_images[0]->get_format());
+ f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+ }
+
+ if ((p_compress_mode == COMPRESS_LOSSLESS) && p_images[0]->get_format() > Image::FORMAT_RGBA8) {
+ p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy
+ }
+
+ for (int i = 0; i < p_images.size(); i++) {
+
+ switch (p_compress_mode) {
+ case COMPRESS_LOSSLESS: {
+
+ Ref<Image> image = p_images[i]->duplicate();
+ if (p_mipmaps) {
+ image->generate_mipmaps();
+ } else {
+ image->clear_mipmaps();
+ }
+
+ int mmc = image->get_mipmap_count() + 1;
+ f->store_32(mmc);
+
+ for (int i = 0; i < mmc; i++) {
+
+ if (i > 0) {
+ image->shrink_x2();
+ }
+
+ PoolVector<uint8_t> data = Image::lossless_packer(image);
+ int data_len = data.size();
+ f->store_32(data_len);
+
+ PoolVector<uint8_t>::Read r = data.read();
+ f->store_buffer(r.ptr(), data_len);
+ }
+
+ } break;
+ case COMPRESS_VIDEO_RAM: {
+
+ Ref<Image> image = p_images[i]->duplicate();
+ image->generate_mipmaps(false);
+
+ Image::CompressSource csource = Image::COMPRESS_SOURCE_LAYERED;
+ image->compress(p_vram_compression, csource, 0.7);
+
+ if (i == 0) {
+ //hack so we can properly tell the format
+ f->store_32(image->get_format());
+ f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+ }
+
+ PoolVector<uint8_t> data = image->get_data();
+ int dl = data.size();
+
+ PoolVector<uint8_t>::Read r = data.read();
+ f->store_buffer(r.ptr(), dl);
+ } break;
+ case COMPRESS_UNCOMPRESSED: {
+
+ Ref<Image> image = p_images[i]->duplicate();
+
+ if (p_mipmaps) {
+ image->generate_mipmaps();
+ } else {
+ image->clear_mipmaps();
+ }
+
+ PoolVector<uint8_t> data = image->get_data();
+ int dl = data.size();
+
+ PoolVector<uint8_t>::Read r = data.read();
+
+ f->store_buffer(r.ptr(), dl);
+
+ } break;
+ }
+ }
+
+ memdelete(f);
+}
+
+Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+
+ int compress_mode = p_options["compress/mode"];
+ int repeat = p_options["flags/repeat"];
+ bool filter = p_options["flags/filter"];
+ bool mipmaps = p_options["flags/mipmaps"];
+ int srgb = p_options["flags/srgb"];
+ int hslices = p_options["slices/horizontal"];
+ int vslices = p_options["slices/vertical"];
+
+ Ref<Image> image;
+ image.instance();
+ Error err = ImageLoader::load_image(p_source_file, image, NULL, false, 1.0);
+ if (err != OK)
+ return err;
+
+ int tex_flags = 0;
+ if (repeat > 0)
+ tex_flags |= Texture::FLAG_REPEAT;
+ if (repeat == 2)
+ tex_flags |= Texture::FLAG_MIRRORED_REPEAT;
+ if (filter)
+ tex_flags |= Texture::FLAG_FILTER;
+ if (mipmaps || compress_mode == COMPRESS_VIDEO_RAM)
+ tex_flags |= Texture::FLAG_MIPMAPS;
+ if (srgb == 1)
+ tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
+
+ Vector<Ref<Image> > slices;
+
+ int slice_w = image->get_width() / hslices;
+ int slice_h = image->get_height() / vslices;
+
+ //optimize
+ if (compress_mode == COMPRESS_VIDEO_RAM) {
+ //if using video ram, optimize
+ if (srgb) {
+ //remove alpha if not needed, so compression is more efficient
+ if (image->get_format() == Image::FORMAT_RGBA8 && !image->detect_alpha()) {
+ image->convert(Image::FORMAT_RGB8);
+ }
+ } else {
+ image->optimize_channels();
+ }
+ }
+
+ for (int i = 0; i < vslices; i++) {
+ for (int j = 0; j < hslices; j++) {
+ int x = slice_w * j;
+ int y = slice_h * i;
+ Ref<Image> slice = image->get_rect(Rect2(x, y, slice_w, slice_h));
+ ERR_CONTINUE(slice.is_null() || slice->empty());
+ if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
+ slice->resize(slice_w, slice_h);
+ }
+ slices.push_back(slice);
+ }
+ }
+
+ String extension = get_save_extension();
+
+ if (compress_mode == COMPRESS_VIDEO_RAM) {
+ //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
+ //Android, GLES 2.x
+
+ bool ok_on_pc = false;
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
+
+ _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps, tex_flags);
+ r_platform_variants->push_back("s3tc");
+ ok_on_pc = true;
+ }
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
+
+ _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps, tex_flags);
+ r_platform_variants->push_back("etc2");
+ }
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
+ _save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps, tex_flags);
+ r_platform_variants->push_back("etc");
+ }
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
+
+ _save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps, tex_flags);
+ r_platform_variants->push_back("pvrtc");
+ }
+
+ if (!ok_on_pc) {
+ EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC.");
+ }
+ } else {
+ //import normally
+ _save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags);
+ }
+
+ return OK;
+}
+
+ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = NULL;
+
+ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() {
+
+ singleton = this;
+ is_3d = true;
+}
+
+ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() {
+}
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
new file mode 100644
index 0000000000..ec73b2624d
--- /dev/null
+++ b/editor/import/resource_importer_layered_texture.h
@@ -0,0 +1,57 @@
+#ifndef RESOURCE_IMPORTER_LAYERED_TEXTURE_H
+#define RESOURCE_IMPORTER_LAYERED_TEXTURE_H
+
+#include "image.h"
+#include "io/resource_import.h"
+
+class StreamTexture;
+
+class ResourceImporterLayeredTexture : public ResourceImporter {
+ GDCLASS(ResourceImporterLayeredTexture, ResourceImporter)
+
+ bool is_3d;
+
+protected:
+ static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
+
+ static ResourceImporterLayeredTexture *singleton;
+
+public:
+ static ResourceImporterLayeredTexture *get_singleton() { return singleton; }
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ enum Preset {
+ PRESET_3D,
+ PRESET_2D,
+ PRESET_COLOR_CORRECT,
+ };
+
+ enum CompressMode {
+ COMPRESS_LOSSLESS,
+ COMPRESS_VIDEO_RAM,
+ COMPRESS_UNCOMPRESSED
+ };
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags);
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+
+ void update_imports();
+
+ void set_3d(bool p_3d) { is_3d = p_3d; }
+ ResourceImporterLayeredTexture();
+ ~ResourceImporterLayeredTexture();
+};
+#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index b8dd4a87b7..5babf6419c 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -224,6 +224,13 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p
while (true) {
String l = f->get_line().strip_edges();
+ while (l.length() && l[l.length() - 1] == '\\') {
+ String add = f->get_line().strip_edges();
+ l += add;
+ if (add == String()) {
+ break;
+ }
+ }
if (l.begins_with("v ")) {
//vertex
@@ -264,10 +271,12 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p
face[0] = v[1].split("/");
face[1] = v[2].split("/");
ERR_FAIL_COND_V(face[0].size() == 0, ERR_FILE_CORRUPT);
+
ERR_FAIL_COND_V(face[0].size() != face[1].size(), ERR_FILE_CORRUPT);
for (int i = 2; i < v.size() - 1; i++) {
face[2] = v[i + 1].split("/");
+
ERR_FAIL_COND_V(face[0].size() != face[2].size(), ERR_FILE_CORRUPT);
for (int j = 0; j < 3; j++) {
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index a5ad34f377..b5e3466b12 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -750,7 +750,7 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
Vector<String> strings = p_text.split("\n");
for (int i = 0; i < strings.size(); i++) {
- strings[i] = strings[i].strip_edges();
+ strings.write[i] = strings[i].strip_edges();
}
List<StringName> anim_names;
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index debdeb1c4a..41f5a892eb 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -215,19 +215,19 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
for (int i = 0; i < frames * format_channels; i++) {
// 8 bit samples are UNSIGNED
- data[i] = int8_t(file->get_8() - 128) / 128.f;
+ data.write[i] = int8_t(file->get_8() - 128) / 128.f;
}
} else if (format_bits == 32 && compression_code == 3) {
for (int i = 0; i < frames * format_channels; i++) {
//32 bit IEEE Float
- data[i] = file->get_float();
+ data.write[i] = file->get_float();
}
} else if (format_bits == 16) {
for (int i = 0; i < frames * format_channels; i++) {
//16 bit SIGNED
- data[i] = int16_t(file->get_16()) / 32768.f;
+ data.write[i] = int16_t(file->get_16()) / 32768.f;
}
} else {
for (int i = 0; i < frames * format_channels; i++) {
@@ -241,7 +241,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
}
s <<= (32 - format_bits);
- data[i] = (int32_t(s) >> 16) / 32768.f;
+ data.write[i] = (int32_t(s) >> 16) / 32768.f;
}
}
@@ -335,7 +335,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
float res = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);
- new_data[i * format_channels + c] = res;
+ new_data.write[i * format_channels + c] = res;
// update position and always keep fractional part within ]0...1]
// in order to avoid 32bit floating point precision errors
@@ -374,7 +374,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
float mult = 1.0 / max;
for (int i = 0; i < data.size(); i++) {
- data[i] *= mult;
+ data.write[i] *= mult;
}
}
}
@@ -408,7 +408,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> new_data;
new_data.resize((last - first + 1) * format_channels);
for (int i = first * format_channels; i < (last + 1) * format_channels; i++) {
- new_data[i - first * format_channels] = data[i];
+ new_data.write[i - first * format_channels] = data[i];
}
data = new_data;
@@ -433,7 +433,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> new_data;
new_data.resize(data.size() / 2);
for (int i = 0; i < frames; i++) {
- new_data[i] = (data[i * 2 + 0] + data[i * 2 + 1]) / 2.0;
+ new_data.write[i] = (data[i * 2 + 0] + data[i * 2 + 1]) / 2.0;
}
data = new_data;
@@ -465,8 +465,8 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
right.resize(tframes);
for (int i = 0; i < tframes; i++) {
- left[i] = data[i * 2 + 0];
- right[i] = data[i * 2 + 1];
+ left.write[i] = data[i * 2 + 0];
+ right.write[i] = data[i * 2 + 1];
}
PoolVector<uint8_t> bleft;
@@ -526,119 +526,5 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
return OK;
}
-void ResourceImporterWAV::_compress_ima_adpcm(const Vector<float> &p_data, PoolVector<uint8_t> &dst_data) {
-
- /*p_sample_data->data = (void*)malloc(len);
- xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/
-
- static const int16_t _ima_adpcm_step_table[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
- };
-
- static const int8_t _ima_adpcm_index_table[16] = {
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8
- };
-
- int datalen = p_data.size();
- int datamax = datalen;
- if (datalen & 1)
- datalen++;
-
- dst_data.resize(datalen / 2 + 4);
- PoolVector<uint8_t>::Write w = dst_data.write();
-
- int i, step_idx = 0, prev = 0;
- uint8_t *out = w.ptr();
- //int16_t xm_prev=0;
- const float *in = p_data.ptr();
-
- /* initial value is zero */
- *(out++) = 0;
- *(out++) = 0;
- /* Table index initial value */
- *(out++) = 0;
- /* unused */
- *(out++) = 0;
-
- for (i = 0; i < datalen; i++) {
- int step, diff, vpdiff, mask;
- uint8_t nibble;
- int16_t xm_sample;
-
- if (i >= datamax)
- xm_sample = 0;
- else {
-
- xm_sample = CLAMP(in[i] * 32767.0, -32768, 32767);
- /*
- if (xm_sample==32767 || xm_sample==-32768)
- printf("clippy!\n",xm_sample);
- */
- }
-
- //xm_sample=xm_sample+xm_prev;
- //xm_prev=xm_sample;
-
- diff = (int)xm_sample - prev;
-
- nibble = 0;
- step = _ima_adpcm_step_table[step_idx];
- vpdiff = step >> 3;
- if (diff < 0) {
- nibble = 8;
- diff = -diff;
- }
- mask = 4;
- while (mask) {
-
- if (diff >= step) {
-
- nibble |= mask;
- diff -= step;
- vpdiff += step;
- }
-
- step >>= 1;
- mask >>= 1;
- };
-
- if (nibble & 8)
- prev -= vpdiff;
- else
- prev += vpdiff;
-
- if (prev > 32767) {
- //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev);
- prev = 32767;
- } else if (prev < -32768) {
- //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev);
- prev = -32768;
- }
-
- step_idx += _ima_adpcm_index_table[nibble];
- if (step_idx < 0)
- step_idx = 0;
- else if (step_idx > 88)
- step_idx = 88;
-
- if (i & 1) {
- *out |= nibble << 4;
- out++;
- } else {
- *out = nibble;
- }
- /*dataptr[i]=prev>>8;*/
- }
-}
-
ResourceImporterWAV::ResourceImporterWAV() {
}
diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h
index cfce5a31ee..f78ab09e9b 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -48,7 +48,118 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- void _compress_ima_adpcm(const Vector<float> &p_data, PoolVector<uint8_t> &dst_data);
+ static void _compress_ima_adpcm(const Vector<float> &p_data, PoolVector<uint8_t> &dst_data) {
+ /*p_sample_data->data = (void*)malloc(len);
+ xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/
+
+ static const int16_t _ima_adpcm_step_table[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+ };
+
+ static const int8_t _ima_adpcm_index_table[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+ };
+
+ int datalen = p_data.size();
+ int datamax = datalen;
+ if (datalen & 1)
+ datalen++;
+
+ dst_data.resize(datalen / 2 + 4);
+ PoolVector<uint8_t>::Write w = dst_data.write();
+
+ int i, step_idx = 0, prev = 0;
+ uint8_t *out = w.ptr();
+ //int16_t xm_prev=0;
+ const float *in = p_data.ptr();
+
+ /* initial value is zero */
+ *(out++) = 0;
+ *(out++) = 0;
+ /* Table index initial value */
+ *(out++) = 0;
+ /* unused */
+ *(out++) = 0;
+
+ for (i = 0; i < datalen; i++) {
+ int step, diff, vpdiff, mask;
+ uint8_t nibble;
+ int16_t xm_sample;
+
+ if (i >= datamax)
+ xm_sample = 0;
+ else {
+
+ xm_sample = CLAMP(in[i] * 32767.0, -32768, 32767);
+ /*
+ if (xm_sample==32767 || xm_sample==-32768)
+ printf("clippy!\n",xm_sample);
+ */
+ }
+
+ //xm_sample=xm_sample+xm_prev;
+ //xm_prev=xm_sample;
+
+ diff = (int)xm_sample - prev;
+
+ nibble = 0;
+ step = _ima_adpcm_step_table[step_idx];
+ vpdiff = step >> 3;
+ if (diff < 0) {
+ nibble = 8;
+ diff = -diff;
+ }
+ mask = 4;
+ while (mask) {
+
+ if (diff >= step) {
+
+ nibble |= mask;
+ diff -= step;
+ vpdiff += step;
+ }
+
+ step >>= 1;
+ mask >>= 1;
+ };
+
+ if (nibble & 8)
+ prev -= vpdiff;
+ else
+ prev += vpdiff;
+
+ if (prev > 32767) {
+ //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev);
+ prev = 32767;
+ } else if (prev < -32768) {
+ //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev);
+ prev = -32768;
+ }
+
+ step_idx += _ima_adpcm_index_table[nibble];
+ if (step_idx < 0)
+ step_idx = 0;
+ else if (step_idx > 88)
+ step_idx = 88;
+
+ if (i & 1) {
+ *out |= nibble << 4;
+ out++;
+ } else {
+ *out = nibble;
+ }
+ /*dataptr[i]=prev>>8;*/
+ }
+ }
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 0d0b12c911..43baabe2f5 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -140,6 +140,7 @@ void InspectorDock::_load_resource(const String &p_type) {
void InspectorDock::_resource_file_selected(String p_file) {
RES res = ResourceLoader::load(p_file);
+
if (res.is_null()) {
warning_dialog->get_ok()->set_text("Ugh");
warning_dialog->set_text(TTR("Failed to load resource."));
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 5052b69e24..2d341cdd93 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -345,7 +345,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
- vertices[edited_point.vertex] = edited_point.pos - _get_offset(edited_point.polygon);
+ vertices.write[edited_point.vertex] = edited_point.pos - _get_offset(edited_point.polygon);
undo_redo->create_action(TTR("Edit Poly"));
_action_set_polygon(edited_point.polygon, pre_move_edit, vertices);
@@ -445,7 +445,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
- vertices[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
+ vertices.write[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
_set_polygon(edited_point.polygon, vertices);
}
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 8d17062248..27df60f87a 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -414,7 +414,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
point *= s;
point.y = s.height - point.y;
- points[j] = point;
+ points.write[j] = point;
}
for (int j = 0; j < 3; j++) {
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 23eeef9f20..9ab5436de8 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -1333,7 +1333,7 @@ void AnimationPlayerEditor::_allocate_onion_layers() {
bool is_present = onion.differences_only && i == captures - 1;
// Each capture is a viewport with a canvas item attached that renders a full-size rect with the contents of the main viewport
- onion.captures[i] = VS::get_singleton()->viewport_create();
+ onion.captures.write[i] = VS::get_singleton()->viewport_create();
VS::get_singleton()->viewport_set_usage(onion.captures[i], VS::VIEWPORT_USAGE_2D);
VS::get_singleton()->viewport_set_size(onion.captures[i], capture_size.width, capture_size.height);
VS::get_singleton()->viewport_set_update_mode(onion.captures[i], VS::VIEWPORT_UPDATE_ALWAYS);
@@ -1473,7 +1473,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
float pos = cpos + step_off * anim->get_step();
bool valid = anim->has_loop() || (pos >= 0 && pos <= anim->get_length());
- onion.captures_valid[cidx] = valid;
+ onion.captures_valid.write[cidx] = valid;
if (valid) {
player->seek(pos, true);
get_tree()->flush_transform_notifications(); // Needed for transforms of Spatials
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 04bd5f0cec..ee450333c8 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -679,7 +679,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
Ref<StyleBox> sb = name == selected_node ? style_selected : style;
int strsize = font->get_string_size(name).width;
- NodeRect &nr = node_rects[i];
+ NodeRect &nr = node_rects.write[i];
Vector2 offset = nr.node.position;
int h = nr.node.size.height;
@@ -771,7 +771,7 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
if (idx == -1)
return;
- NodeRect &nr = node_rects[idx];
+ const NodeRect &nr = node_rects[idx];
Vector2 from;
from.x = nr.play.position.x;
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 505dd4ab76..e98dfceb90 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -197,7 +197,7 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
for (int i = 0; i < preview_images.size(); i++) {
if (preview_images[i].id == p_index) {
- preview_images[i].image = p_image;
+ preview_images.write[i].image = p_image;
if (preview_images[i].button->is_pressed()) {
_preview_click(p_index);
}
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index ddb03d0250..454a5d72f2 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -81,8 +81,8 @@ void AudioStreamEditor::_draw_preview() {
float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
int idx = i;
- lines[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
- lines[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
+ lines.write[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
+ lines.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
}
Vector<Color> color;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 1d20c63969..eed6b5a95c 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -533,7 +533,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
r_items.remove(i);
i--;
} else {
- r_items[i].item = canvas_item;
+ r_items.write[i].item = canvas_item;
}
}
}
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index e837359d0c..5109379add 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -276,7 +276,7 @@ bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<Inpu
//apply
ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos;
+ poly.write[edited_point] = edited_point_pos;
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node, "set_polygon", poly);
undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index b003664dca..9e052bb027 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -446,8 +446,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
float radius = shape->get_radius();
float height = shape->get_height() / 2;
- handles[0] = Point2(radius, -height);
- handles[1] = Point2(0, -(height + radius));
+ handles.write[0] = Point2(radius, -height);
+ handles.write[1] = Point2(0, -(height + radius));
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -458,7 +458,7 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<CircleShape2D> shape = node->get_shape();
handles.resize(1);
- handles[0] = Point2(shape->get_radius(), 0);
+ handles.write[0] = Point2(shape->get_radius(), 0);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
@@ -476,8 +476,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<LineShape2D> shape = node->get_shape();
handles.resize(2);
- handles[0] = shape->get_normal() * shape->get_d();
- handles[1] = shape->get_normal() * (shape->get_d() + 30.0);
+ handles.write[0] = shape->get_normal() * shape->get_d();
+ handles.write[1] = shape->get_normal() * (shape->get_d() + 30.0);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -488,7 +488,7 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<RayShape2D> shape = node->get_shape();
handles.resize(1);
- handles[0] = Point2(0, shape->get_length());
+ handles.write[0] = Point2(0, shape->get_length());
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
@@ -499,8 +499,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
handles.resize(2);
Vector2 ext = shape->get_extents();
- handles[0] = Point2(ext.x, 0);
- handles[1] = Point2(0, -ext.y);
+ handles.write[0] = Point2(ext.x, 0);
+ handles.write[1] = Point2(0, -ext.y);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -511,8 +511,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<SegmentShape2D> shape = node->get_shape();
handles.resize(2);
- handles[0] = shape->get_a();
- handles[1] = shape->get_b();
+ handles.write[0] = shape->get_a();
+ handles.write[1] = shape->get_b();
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 0d25b3685a..9acbceec92 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -78,7 +78,7 @@ bool EditorTexturePreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Texture");
}
-Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
Ref<Image> img;
Ref<AtlasTexture> atex = p_from;
@@ -138,12 +138,66 @@ EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() {
////////////////////////////////////////////////////////////////////////////
+bool EditorImagePreviewPlugin::handles(const String &p_type) const {
+
+ return p_type == "Image";
+}
+
+Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
+
+ Ref<Image> img = p_from;
+
+ if (img.is_null() || img->empty())
+ return Ref<Image>();
+
+ img = img->duplicate();
+ img->clear_mipmaps();
+
+ int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
+ thumbnail_size *= EDSCALE;
+ if (img->is_compressed()) {
+ if (img->decompress() != OK)
+ return Ref<Image>();
+ } else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
+ img->convert(Image::FORMAT_RGBA8);
+ }
+
+ int width, height;
+ if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
+
+ width = thumbnail_size;
+ height = img->get_height() * thumbnail_size / img->get_width();
+ } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
+
+ height = thumbnail_size;
+ width = img->get_width() * thumbnail_size / img->get_height();
+ } else {
+
+ width = img->get_width();
+ height = img->get_height();
+ }
+
+ img->resize(width, height);
+ post_process_preview(img);
+
+ Ref<ImageTexture> ptex;
+ ptex.instance();
+
+ ptex->create_from_image(img, 0);
+ return ptex;
+}
+
+EditorImagePreviewPlugin::EditorImagePreviewPlugin() {
+}
+
+////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////
bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "BitMap");
}
-Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
Ref<BitMap> bm = p_from;
@@ -215,12 +269,12 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "PackedScene");
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) const {
return generate_from_path(p_from->get_path());
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) const {
String temp_path = EditorSettings::get_singleton()->get_cache_dir();
String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text();
@@ -269,7 +323,7 @@ bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Material"); //any material
}
-Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const {
Ref<Material> material = p_from;
ERR_FAIL_COND_V(material.is_null(), Ref<Texture>());
@@ -281,7 +335,7 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) {
VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
preview_done = false;
- VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+ VS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant());
while (!preview_done) {
OS::get_singleton()->delay_usec(10);
@@ -436,7 +490,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Script");
}
-Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const {
Ref<Script> scr = p_from;
if (scr.is_null())
@@ -559,7 +613,7 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "AudioStream");
}
-Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) const {
Ref<AudioStream> stream = p_from;
ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>());
@@ -657,7 +711,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
}
-Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const {
Ref<Mesh> mesh = p_from;
ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>());
@@ -684,7 +738,7 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) {
VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
preview_done = false;
- VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+ VS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant());
while (!preview_done) {
OS::get_singleton()->delay_usec(10);
@@ -771,16 +825,7 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "DynamicFontData");
}
-Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) {
- if (canvas.is_valid()) {
- VS::get_singleton()->viewport_remove_canvas(viewport, canvas);
- }
-
- canvas = VS::get_singleton()->canvas_create();
- canvas_item = VS::get_singleton()->canvas_item_create();
-
- VS::get_singleton()->viewport_attach_canvas(viewport, canvas);
- VS::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
+Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) const {
Ref<DynamicFontData> SampledFont;
SampledFont.instance();
@@ -809,7 +854,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) {
VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
preview_done = false;
- VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+ VS::get_singleton()->request_frame_drawn_callback(const_cast<EditorFontPreviewPlugin *>(this), "_preview_done", Variant());
while (!preview_done) {
OS::get_singleton()->delay_usec(10);
@@ -829,7 +874,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) {
return ptex;
}
-Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) const {
return generate_from_path(p_from->get_path());
}
@@ -842,6 +887,12 @@ EditorFontPreviewPlugin::EditorFontPreviewPlugin() {
VS::get_singleton()->viewport_set_size(viewport, 128, 128);
VS::get_singleton()->viewport_set_active(viewport, true);
viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
+
+ canvas = VS::get_singleton()->canvas_create();
+ canvas_item = VS::get_singleton()->canvas_item_create();
+
+ VS::get_singleton()->viewport_attach_canvas(viewport, canvas);
+ VS::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
}
EditorFontPreviewPlugin::~EditorFontPreviewPlugin() {
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 140d9f849f..8bd7943383 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -39,16 +39,25 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorTexturePreviewPlugin();
};
+class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator {
+ GDCLASS(EditorImagePreviewPlugin, EditorResourcePreviewGenerator)
+public:
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from) const;
+
+ EditorImagePreviewPlugin();
+};
+
class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorBitmapPreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorBitmapPreviewPlugin();
};
@@ -57,8 +66,8 @@ class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
- virtual Ref<Texture> generate_from_path(const String &p_path);
+ virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path) const;
EditorPackedScenePreviewPlugin();
};
@@ -77,7 +86,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- volatile bool preview_done;
+ mutable volatile bool preview_done;
void _preview_done(const Variant &p_udata);
@@ -86,7 +95,7 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorMaterialPreviewPlugin();
~EditorMaterialPreviewPlugin();
@@ -95,7 +104,7 @@ public:
class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorScriptPreviewPlugin();
};
@@ -103,7 +112,7 @@ public:
class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorAudioStreamPreviewPlugin();
};
@@ -121,7 +130,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- volatile bool preview_done;
+ mutable volatile bool preview_done;
void _preview_done(const Variant &p_udata);
@@ -130,7 +139,7 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorMeshPreviewPlugin();
~EditorMeshPreviewPlugin();
@@ -144,7 +153,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator {
RID viewport_texture;
RID canvas;
RID canvas_item;
- volatile bool preview_done;
+ mutable volatile bool preview_done;
void _preview_done(const Variant &p_udata);
@@ -153,8 +162,8 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
- virtual Ref<Texture> generate_from_path(const String &p_path);
+ virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path) const;
EditorFontPreviewPlugin();
~EditorFontPreviewPlugin();
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index a3be10dc33..3351e5918f 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -255,7 +255,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
//apply
ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos;
+ poly.write[edited_point] = edited_point_pos;
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index 6d11079759..c2b17189ef 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -165,12 +165,12 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
if (emode == EMISSION_MODE_SOLID) {
if (capture_colors) {
- valid_colors[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
- valid_colors[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
- valid_colors[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
- valid_colors[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
+ valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
+ valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
+ valid_colors.write[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
+ valid_colors.write[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
}
- valid_positions[vpc++] = Point2(i, j);
+ valid_positions.write[vpc++] = Point2(i, j);
} else {
@@ -189,7 +189,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
}
if (on_border) {
- valid_positions[vpc] = Point2(i, j);
+ valid_positions.write[vpc] = Point2(i, j);
if (emode == EMISSION_MODE_BORDER_DIRECTED) {
Vector2 normal;
@@ -206,14 +206,14 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
}
normal.normalize();
- valid_normals[vpc] = normal;
+ valid_normals.write[vpc] = normal;
}
if (capture_colors) {
- valid_colors[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
- valid_colors[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
- valid_colors[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
- valid_colors[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
+ valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
+ valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
+ valid_colors.write[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
+ valid_colors.write[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
}
vpc++;
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index e0325702a8..1f5a4a8a36 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -40,7 +40,6 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
float area_accum = 0;
Map<float, int> triangle_area_map;
- print_line("geometry size: " + itos(geometry.size()));
for (int i = 0; i < geometry.size(); i++) {
@@ -300,6 +299,10 @@ void ParticlesEditor::_menu_option(int p_option) {
CPUParticles *cpu_particles = memnew(CPUParticles);
cpu_particles->convert_from_particles(node);
+ cpu_particles->set_name(node->get_name());
+ cpu_particles->set_transform(node->get_transform());
+ cpu_particles->set_visible(node->is_visible());
+ cpu_particles->set_pause_mode(node->get_pause_mode());
undo_redo->create_action("Replace Particles by CPUParticles");
undo_redo->add_do_method(node, "replace_by", cpu_particles);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 876da7f61a..6cc8f91e38 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -31,7 +31,6 @@
#include "script_editor_plugin.h"
#include "core/io/resource_loader.h"
-#include "core/io/resource_saver.h"
#include "core/os/file_access.h"
#include "core/os/input.h"
#include "core/os/keyboard.h"
@@ -283,7 +282,6 @@ void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se) {
-
continue;
}
@@ -344,11 +342,11 @@ void ScriptEditor::_save_history() {
if (Object::cast_to<ScriptEditorBase>(n)) {
- history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
- history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+ history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
}
@@ -375,11 +373,11 @@ void ScriptEditor::_go_to_tab(int p_idx) {
if (Object::cast_to<ScriptEditorBase>(n)) {
- history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
- history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+ history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
}
@@ -402,7 +400,10 @@ void ScriptEditor::_go_to_tab(int p_idx) {
if (is_visible_in_tree())
Object::cast_to<ScriptEditorBase>(c)->ensure_focus();
- notify_script_changed(Object::cast_to<ScriptEditorBase>(c)->get_edited_script());
+ Ref<Script> script = Object::cast_to<ScriptEditorBase>(c)->get_edited_resource();
+ if (script != NULL) {
+ notify_script_changed(script);
+ }
}
if (Object::cast_to<EditorHelp>(c)) {
@@ -482,12 +483,23 @@ void ScriptEditor::_open_recent_script(int p_idx) {
String path = rc[p_idx];
// if its not on disk its a help file or deleted
if (FileAccess::exists(path)) {
- Ref<Script> script = ResourceLoader::load(path);
- if (script.is_valid()) {
- edit(script, true);
- return;
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+
+ if (extensions.find(path.get_extension())) {
+ Ref<Script> script = ResourceLoader::load(path);
+ if (script.is_valid()) {
+ edit(script, true);
+ return;
+ }
}
+ Error err;
+ Ref<TextFile> text_file = _load_text_file(path, &err);
+ if (text_file.is_valid()) {
+ edit(text_file, true);
+ return;
+ }
// if it's a path then its most likely a deleted file not help
} else if (!path.is_resource_file()) {
_help_class_open(path);
@@ -513,12 +525,17 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
return;
Node *tselected = tab_container->get_child(selected);
+
ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected));
if (current) {
if (p_save) {
apply_scripts();
}
- notify_script_close(current->get_edited_script());
+
+ Ref<Script> script = current->get_edited_resource();
+ if (script != NULL) {
+ notify_script_close(script);
+ }
}
// roll back to previous tab
@@ -589,7 +606,7 @@ void ScriptEditor::_close_docs_tab() {
void ScriptEditor::_copy_script_path() {
ScriptEditorBase *se = _get_current_editor();
- Ref<Script> script = se->get_edited_script();
+ RES script = se->get_edited_resource();
OS::get_singleton()->set_clipboard(script->get_path());
}
@@ -655,7 +672,7 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
if (!se)
continue;
- Ref<Script> script = se->get_edited_script();
+ RES script = se->get_edited_resource();
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)
continue; //internal script, who cares
@@ -672,7 +689,14 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
}
}
- editor->save_resource(script);
+ Ref<TextFile> text_file = script;
+ if (text_file != NULL) {
+ se->apply_code();
+ _save_text_file(text_file, text_file->get_path());
+ break;
+ } else {
+ editor->save_resource(script);
+ }
se->tag_saved_version();
}
@@ -689,25 +713,37 @@ void ScriptEditor::_reload_scripts() {
continue;
}
- Ref<Script> script = se->get_edited_script();
+ RES edited_res = se->get_edited_resource();
- if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
+ if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) {
continue; //internal script, who cares
}
- uint64_t last_date = script->get_last_modified_time();
- uint64_t date = FileAccess::get_modified_time(script->get_path());
+ uint64_t last_date = edited_res->get_last_modified_time();
+ uint64_t date = FileAccess::get_modified_time(edited_res->get_path());
if (last_date == date) {
continue;
}
- Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
- ERR_CONTINUE(!rel_script.is_valid());
- script->set_source_code(rel_script->get_source_code());
- script->set_last_modified_time(rel_script->get_last_modified_time());
- script->reload();
+ Ref<Script> script = edited_res;
+ if (script != NULL) {
+ Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
+ ERR_CONTINUE(!rel_script.is_valid());
+ script->set_source_code(rel_script->get_source_code());
+ script->set_last_modified_time(rel_script->get_last_modified_time());
+ script->reload();
+ }
+
+ Ref<TextFile> text_file = edited_res;
+ if (text_file != NULL) {
+ Error err;
+ Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err);
+ ERR_CONTINUE(!rel_text_file.is_valid());
+ text_file->set_text(rel_text_file->get_text());
+ text_file->set_last_modified_time(rel_text_file->get_last_modified_time());
+ }
se->reload_text();
}
@@ -725,7 +761,7 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
continue;
}
- Ref<Script> script = se->get_edited_script();
+ RES script = se->get_edited_resource();
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
continue; //internal script, who cares
@@ -750,7 +786,7 @@ void ScriptEditor::_live_auto_reload_running_scripts() {
debugger->reload_scripts();
}
-bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) {
+bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
disk_changed_list->clear();
TreeItem *r = disk_changed_list->create_item();
@@ -765,21 +801,20 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
- Ref<Script> script = se->get_edited_script();
-
- if (p_for_script.is_valid() && p_for_script != script)
+ RES edited_res = se->get_edited_resource();
+ if (edited_res.is_valid() && p_for_script != edited_res)
continue;
- if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)
+ if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1)
continue; //internal script, who cares
- uint64_t last_date = script->get_last_modified_time();
- uint64_t date = FileAccess::get_modified_time(script->get_path());
+ uint64_t last_date = edited_res->get_last_modified_time();
+ uint64_t date = FileAccess::get_modified_time(edited_res->get_path());
if (last_date != date) {
TreeItem *ti = disk_changed_list->create_item(r);
- ti->set_text(0, script->get_path().get_file());
+ ti->set_text(0, edited_res->get_path().get_file());
if (!use_autoreload || se->is_unsaved()) {
need_ask = true;
@@ -804,6 +839,49 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) {
void ScriptEditor::_file_dialog_action(String p_file) {
switch (file_dialog_option) {
+ case FILE_OPEN: {
+
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ if (extensions.find(p_file.get_extension())) {
+ Ref<Script> scr = ResourceLoader::load(p_file);
+ if (!scr.is_valid()) {
+ editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
+ file_dialog_option = -1;
+ return;
+ }
+
+ edit(scr);
+ file_dialog_option = -1;
+ return;
+ }
+
+ Error error;
+ Ref<TextFile> text_file = _load_text_file(p_file, &error);
+ if (error != OK) {
+ editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
+ }
+
+ if (text_file.is_valid()) {
+ edit(text_file);
+ file_dialog_option = -1;
+ return;
+ }
+ }
+ case FILE_SAVE_AS: {
+ ScriptEditorBase *current = _get_current_editor();
+
+ String path = ProjectSettings::get_singleton()->localize_path(p_file);
+ Error err = _save_text_file(current->get_edited_resource(), path);
+
+ if (err != OK) {
+ editor->show_accept(TTR("Error saving file!"), TTR("OK"));
+ return;
+ }
+
+ ((Resource *)current->get_edited_resource().ptr())->set_path(path);
+ _update_script_names();
+ } break;
case THEME_SAVE_AS: {
if (!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) {
editor->show_warning(TTR("Error while saving theme"), TTR("Error saving"));
@@ -823,7 +901,8 @@ Ref<Script> ScriptEditor::_get_current_script() {
ScriptEditorBase *current = _get_current_editor();
if (current) {
- return current->get_edited_script();
+ Ref<Script> script = current->get_edited_resource();
+ return script != NULL ? script : NULL;
} else {
return NULL;
}
@@ -848,8 +927,19 @@ void ScriptEditor::_menu_option(int p_option) {
script_create_dialog->popup_centered(Size2(300, 300) * EDSCALE);
} break;
case FILE_OPEN: {
+ file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
+ file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ file_dialog_option = FILE_OPEN;
- editor->open_resource("Script");
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ file_dialog->clear_filters();
+ for (int i = 0; i < extensions.size(); i++) {
+ file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ }
+
+ file_dialog->popup_centered_ratio();
+ file_dialog->set_title(TTR("Open File"));
return;
} break;
case FILE_SAVE_ALL: {
@@ -929,7 +1019,14 @@ void ScriptEditor::_menu_option(int p_option) {
current->convert_indent_to_tabs();
}
}
- editor->save_resource(current->get_edited_script());
+
+ Ref<TextFile> text_file = current->get_edited_resource();
+ if (text_file != NULL) {
+ current->apply_code();
+ _save_text_file(text_file, text_file->get_path());
+ break;
+ }
+ editor->save_resource(current->get_edited_resource());
} break;
case FILE_SAVE_AS: {
@@ -943,8 +1040,25 @@ void ScriptEditor::_menu_option(int p_option) {
current->convert_indent_to_tabs();
}
}
- editor->push_item(Object::cast_to<Object>(current->get_edited_script().ptr()));
- editor->save_resource_as(current->get_edited_script());
+
+ Ref<TextFile> text_file = current->get_edited_resource();
+ if (text_file != NULL) {
+ file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+ file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ file_dialog_option = FILE_SAVE_AS;
+
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ file_dialog->clear_filters();
+ file_dialog->set_current_dir(text_file->get_path().get_base_dir());
+ file_dialog->set_current_file(text_file->get_path().get_file());
+ file_dialog->popup_centered_ratio();
+ file_dialog->set_title(TTR("Save File As..."));
+ break;
+ }
+
+ editor->push_item(Object::cast_to<Object>(current->get_edited_resource().ptr()));
+ editor->save_resource_as(current->get_edited_resource());
} break;
@@ -956,8 +1070,8 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case FILE_RUN: {
- Ref<Script> scr = current->get_edited_script();
- if (scr.is_null()) {
+ Ref<Script> scr = current->get_edited_resource();
+ if (scr == NULL || scr.is_null()) {
EditorNode::get_singleton()->show_warning("Can't obtain the script for running");
break;
}
@@ -1000,8 +1114,7 @@ void ScriptEditor::_menu_option(int p_option) {
_copy_script_path();
} break;
case SHOW_IN_FILE_SYSTEM: {
- ScriptEditorBase *se = _get_current_editor();
- Ref<Script> script = se->get_edited_script();
+ RES script = current->get_edited_resource();
FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock();
file_system_dock->navigate_to_path(script->get_path());
// Ensure that the FileSystem dock is visible.
@@ -1259,8 +1372,8 @@ void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
if (se) {
- Ref<Script> script = se->get_edited_script();
- if (!script.is_valid())
+ Ref<Script> script = se->get_edited_resource();
+ if (script == NULL || !script.is_valid())
continue;
if (script->get_path().find("::") != -1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
@@ -1307,9 +1420,13 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
if (!se)
continue;
+ Ref<Script> script = se->get_edited_resource();
+ if (script == NULL) {
+ continue;
+ }
+
List<int> bpoints;
se->get_breakpoints(&bpoints);
- Ref<Script> script = se->get_edited_script();
String base = script->get_path();
ERR_CONTINUE(base.begins_with("local://") || base == "");
@@ -1452,7 +1569,7 @@ void ScriptEditor::_update_members_overview() {
members_overview->set_item_metadata(i, functions[i].get_slice(":", 1).to_int() - 1);
}
- String path = se->get_edited_script()->get_path();
+ String path = se->get_edited_resource()->get_path();
bool built_in = !path.is_resource_file();
String name = built_in ? path.get_file() : se->get_name();
filename->set_text(name);
@@ -1570,7 +1687,7 @@ void ScriptEditor::_update_script_names() {
if (se) {
Ref<Texture> icon = se->get_icon();
- String path = se->get_edited_script()->get_path();
+ String path = se->get_edited_resource()->get_path();
bool built_in = !path.is_resource_file();
String name = built_in ? path.get_file() : se->get_name();
@@ -1579,7 +1696,7 @@ void ScriptEditor::_update_script_names() {
sd.name = name;
sd.tooltip = path;
sd.index = i;
- sd.used = used.has(se->get_edited_script());
+ sd.used = used.has(se->get_edited_resource());
sd.category = 0;
sd.ref = se;
@@ -1681,11 +1798,65 @@ void ScriptEditor::_update_script_names() {
_update_script_colors();
}
-bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus) {
+Ref<TextFile> ScriptEditor::_load_text_file(const String &p_path, Error *r_error) {
+ if (r_error) {
+ *r_error = ERR_FILE_CANT_OPEN;
+ }
+
+ String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ String path = ResourceLoader::path_remap(local_path);
+
+ TextFile *text_file = memnew(TextFile);
+ Ref<TextFile> text_res(text_file);
+ Error err = text_file->load_text(path);
+
+ if (err != OK) {
+ ERR_FAIL_COND_V(err != OK, RES());
+ }
+
+ text_file->set_file_path(local_path);
+ text_file->set_path(local_path, true);
+
+ if (r_error) {
+ *r_error = OK;
+ }
+
+ return text_res;
+}
+
+Error ScriptEditor::_save_text_file(Ref<TextFile> p_text_file, const String &p_path) {
+ Ref<TextFile> sqscr = p_text_file;
+ ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
+
+ String source = sqscr->get_text();
+
+ Error err;
+ FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
+
+ if (err) {
+
+ ERR_FAIL_COND_V(err, err);
+ }
+
+ file->store_string(source);
+ if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
+ memdelete(file);
+ return ERR_CANT_CREATE;
+ }
+ file->close();
+ memdelete(file);
+
+ _res_saved_callback(sqscr);
+ return OK;
+}
+
+bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus) {
- if (p_script.is_null())
+ if (p_resource.is_null())
return false;
+ Ref<Script> script = p_resource;
+
// refuse to open built-in if scene is not loaded
// see if already has it
@@ -1694,17 +1865,18 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
const bool should_open = open_dominant || !EditorNode::get_singleton()->is_changing_scene();
- if (p_script->get_language()->overrides_external_editor()) {
+ if (script != NULL && script->get_language()->overrides_external_editor()) {
if (should_open) {
- Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col);
+ Error err = script->get_language()->open_in_external_editor(script, p_line >= 0 ? p_line : 0, p_col);
if (err != OK)
ERR_PRINT("Couldn't open script in the overridden external text editor");
}
return false;
}
- if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) &&
- p_script->get_path().is_resource_file() &&
+ if ((debugger->get_dump_stack_script() != p_resource || debugger->get_debug_with_external_editor()) &&
+ p_resource->get_path().is_resource_file() &&
+ p_resource->get_class_name() != StringName("VisualScript") &&
bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path");
@@ -1714,7 +1886,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
if (flags.size()) {
String project_path = ProjectSettings::get_singleton()->get_resource_path();
- String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path());
+ String script_path = ProjectSettings::get_singleton()->globalize_path(p_resource->get_path());
flags = flags.replacen("{line}", itos(p_line > 0 ? p_line : 0));
flags = flags.replacen("{col}", itos(p_col));
@@ -1762,7 +1934,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
if (!se)
continue;
- if (se->get_edited_script() == p_script) {
+ if (se->get_edited_resource() == p_resource) {
if (should_open) {
if (tab_container->get_current_tab() != i) {
@@ -1784,7 +1956,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
ScriptEditorBase *se;
for (int i = script_editor_func_count - 1; i >= 0; i--) {
- se = script_editor_funcs[i](p_script);
+ se = script_editor_funcs[i](p_resource);
if (se)
break;
}
@@ -1795,9 +1967,9 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
SyntaxHighlighter *highlighter = syntax_highlighters_funcs[i]();
se->add_syntax_highlighter(highlighter);
- if (!highlighter_set) {
+ if (script != NULL && !highlighter_set) {
List<String> languages = highlighter->get_supported_languages();
- if (languages.find(p_script->get_language()->get_name())) {
+ if (languages.find(script->get_language()->get_name())) {
se->set_syntax_highlighter(highlighter);
highlighter_set = true;
}
@@ -1805,7 +1977,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
}
tab_container->add_child(se);
- se->set_edited_script(p_script);
+ se->set_edited_resource(p_resource);
se->set_tooltip_request_func("_get_debug_tooltip", this);
if (se->get_edit_menu()) {
se->get_edit_menu()->hide();
@@ -1829,14 +2001,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
//test for modification, maybe the script was not edited but was loaded
- _test_script_times_on_disk(p_script);
- _update_modified_scripts_for_external_editor(p_script);
+ _test_script_times_on_disk(p_resource);
+ _update_modified_scripts_for_external_editor(p_resource);
if (p_line >= 0)
se->goto_line(p_line - 1);
- notify_script_changed(p_script);
- _add_recent_script(p_script->get_path());
+ notify_script_changed(p_resource);
+ _add_recent_script(p_resource->get_path());
return true;
}
@@ -1863,12 +2035,19 @@ void ScriptEditor::save_all_scripts() {
if (!se->is_unsaved())
continue;
- Ref<Script> script = se->get_edited_script();
- if (script.is_valid())
+ RES edited_res = se->get_edited_resource();
+ if (edited_res.is_valid()) {
se->apply_code();
+ }
- if (script->get_path() != "" && script->get_path().find("local://") == -1 && script->get_path().find("::") == -1)
- editor->save_resource(script); //external script, save it
+ if (edited_res->get_path() != "" && edited_res->get_path().find("local://") == -1 && edited_res->get_path().find("::") == -1) {
+ Ref<TextFile> text_file = edited_res;
+ if (text_file != NULL) {
+ _save_text_file(text_file, text_file->get_path());
+ continue;
+ }
+ editor->save_resource(edited_res); //external script, save it
+ }
}
_update_script_names();
@@ -1938,7 +2117,7 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se)
continue;
- if (se->get_edited_script() != script)
+ if (se->get_edited_resource() != script)
continue;
se->add_callback(p_function, p_args);
@@ -2223,25 +2402,25 @@ void ScriptEditor::_make_script_list_context_menu() {
if (se) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save"), FILE_SAVE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save_as"), FILE_SAVE_AS);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_all"), CLOSE_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_other_tabs"), CLOSE_OTHER_TABS);
- context_menu->add_separator();
+ }
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_all"), CLOSE_ALL);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_other_tabs"), CLOSE_OTHER_TABS);
+ context_menu->add_separator();
+ if (se) {
+ Ref<Script> scr = se->get_edited_resource();
+ if (scr != NULL) {
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
+ if (!scr.is_null() && scr->is_tool()) {
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
+ context_menu->add_separator();
+ }
+ }
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/copy_path"), FILE_COPY_PATH);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/show_in_file_system"), SHOW_IN_FILE_SYSTEM);
- Ref<Script> scr = se->get_edited_script();
- if (!scr.is_null() && scr->is_tool()) {
- context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
- }
- } else {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
+ context_menu->add_separator();
}
- EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(selected));
-
- context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_move_up"), WINDOW_MOVE_UP);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_move_down"), WINDOW_MOVE_DOWN);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_sort"), WINDOW_SORT);
@@ -2268,14 +2447,28 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
restoring_layout = true;
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+
for (int i = 0; i < scripts.size(); i++) {
String path = scripts[i];
if (!FileAccess::exists(path))
continue;
- Ref<Script> scr = ResourceLoader::load(path);
- if (scr.is_valid()) {
- edit(scr);
+
+ if (extensions.find(path.get_extension())) {
+ Ref<Script> scr = ResourceLoader::load(path);
+ if (scr.is_valid()) {
+ edit(scr);
+ continue;
+ }
+ }
+
+ Error error;
+ Ref<TextFile> text_file = _load_text_file(path, &error);
+ if (error == OK && text_file.is_valid()) {
+ edit(text_file);
+ continue;
}
}
@@ -2311,7 +2504,7 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
- String path = se->get_edited_script()->get_path();
+ String path = se->get_edited_resource()->get_path();
if (!path.is_resource_file())
continue;
@@ -2419,11 +2612,11 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
if (Object::cast_to<ScriptEditorBase>(n)) {
- history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
- history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+ history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
history_pos = p_new_pos;
@@ -2436,7 +2629,10 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
Object::cast_to<ScriptEditorBase>(n)->set_edit_state(history[history_pos].state);
Object::cast_to<ScriptEditorBase>(n)->ensure_focus();
- notify_script_changed(Object::cast_to<ScriptEditorBase>(n)->get_edited_script());
+ Ref<Script> script = Object::cast_to<ScriptEditorBase>(n)->get_edited_resource();
+ if (script != NULL) {
+ notify_script_changed(script);
+ }
}
if (Object::cast_to<EditorHelp>(n)) {
@@ -2473,7 +2669,11 @@ Vector<Ref<Script> > ScriptEditor::get_open_scripts() const {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se)
continue;
- out_scripts.push_back(se->get_edited_script());
+
+ Ref<Script> script = se->get_edited_resource();
+ if (script != NULL) {
+ out_scripts.push_back(script);
+ }
}
return out_scripts;
@@ -2519,6 +2719,14 @@ void ScriptEditor::_open_script_request(const String &p_path) {
Ref<Script> script = ResourceLoader::load(p_path);
if (script.is_valid()) {
script_editor->edit(script, false);
+ return;
+ }
+
+ Error err;
+ Ref<TextFile> text_file = script_editor->_load_text_file(p_path, &err);
+ if (text_file.is_valid()) {
+ script_editor->edit(text_file, false);
+ return;
}
}
@@ -2552,7 +2760,7 @@ void ScriptEditor::_on_find_in_files_requested(String text) {
void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) {
- Ref<Resource> res = ResourceLoader::load(fpath);
+ RES res = ResourceLoader::load(fpath);
edit(res);
ScriptEditorBase *seb = _get_current_editor();
@@ -2693,6 +2901,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
context_menu = memnew(PopupMenu);
add_child(context_menu);
context_menu->connect("id_pressed", this, "_menu_option");
+ context_menu->set_hide_on_window_lose_focus(true);
overview_vbox = memnew(VBoxContainer);
overview_vbox->set_custom_minimum_size(Size2(0, 90));
@@ -2747,6 +2956,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu = memnew(MenuButton);
menu_hb->add_child(file_menu);
file_menu->set_text(TTR("File"));
+ file_menu->get_popup()->set_hide_on_window_lose_focus(true);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New")), FILE_NEW);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open")), FILE_OPEN);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
@@ -2796,6 +3006,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
script_search_menu = memnew(MenuButton);
menu_hb->add_child(script_search_menu);
script_search_menu->set_text(TTR("Search"));
+ script_search_menu->get_popup()->set_hide_on_window_lose_focus(true);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F), HELP_SEARCH_FIND);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), HELP_SEARCH_FIND_NEXT);
script_search_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -2804,6 +3015,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
debug_menu = memnew(MenuButton);
menu_hb->add_child(debug_menu);
debug_menu->set_text(TTR("Debug"));
+ debug_menu->get_popup()->set_hide_on_window_lose_focus(true);
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10), DEBUG_NEXT);
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_into", TTR("Step Into"), KEY_F11), DEBUG_STEP);
debug_menu->get_popup()->add_separator();
@@ -2968,14 +3180,21 @@ ScriptEditor::~ScriptEditor() {
void ScriptEditorPlugin::edit(Object *p_object) {
- if (!Object::cast_to<Script>(p_object))
- return;
+ if (Object::cast_to<Script>(p_object)) {
+ script_editor->edit(Object::cast_to<Script>(p_object));
+ }
- script_editor->edit(Object::cast_to<Script>(p_object));
+ if (Object::cast_to<TextFile>(p_object)) {
+ script_editor->edit(Object::cast_to<TextFile>(p_object));
+ }
}
bool ScriptEditorPlugin::handles(Object *p_object) const {
+ if (Object::cast_to<TextFile>(p_object)) {
+ return true;
+ }
+
if (Object::cast_to<Script>(p_object)) {
bool valid = _can_open_in_editor(Object::cast_to<Script>(p_object));
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index ad12add53f..186c80a5f9 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -43,6 +43,7 @@
#include "scene/gui/tool_button.h"
#include "scene/gui/tree.h"
#include "scene/main/timer.h"
+#include "scene/resources/text_file.h"
#include "script_language.h"
class ScriptEditorQuickOpen : public ConfirmationDialog {
@@ -74,7 +75,7 @@ class ScriptEditorDebugger;
class ScriptEditorBase : public VBoxContainer {
- GDCLASS(ScriptEditorBase, VBoxContainer);
+ GDCLASS(ScriptEditorBase, VBoxContainer)
protected:
static void _bind_methods();
@@ -84,9 +85,9 @@ public:
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter) = 0;
virtual void apply_code() = 0;
- virtual Ref<Script> get_edited_script() const = 0;
+ virtual RES get_edited_resource() const = 0;
virtual Vector<String> get_functions() = 0;
- virtual void set_edited_script(const Ref<Script> &p_script) = 0;
+ virtual void set_edited_resource(const RES &p_res) = 0;
virtual void reload_text() = 0;
virtual String get_name() = 0;
virtual Ref<Texture> get_icon() = 0;
@@ -99,7 +100,7 @@ public:
virtual void convert_indent_to_tabs() = 0;
virtual void ensure_focus() = 0;
virtual void tag_saved_version() = 0;
- virtual void reload(bool p_soft) = 0;
+ virtual void reload(bool p_soft) {}
virtual void get_breakpoints(List<int> *p_breakpoints) = 0;
virtual void add_callback(const String &p_function, PoolStringArray p_args) = 0;
virtual void update_settings() = 0;
@@ -116,7 +117,7 @@ public:
};
typedef SyntaxHighlighter *(*CreateSyntaxHighlighterFunc)();
-typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const Ref<Script> &p_script);
+typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const RES &p_resource);
class EditorScriptCodeCompletionCache;
class FindInFilesDialog;
@@ -268,7 +269,7 @@ class ScriptEditor : public PanelContainer {
void _resave_scripts(const String &p_str);
void _reload_scripts();
- bool _test_script_times_on_disk(Ref<Script> p_for_script = Ref<Script>());
+ bool _test_script_times_on_disk(RES p_for_script = Ref<Resource>());
void _add_recent_script(String p_path);
void _update_recent_scripts();
@@ -378,6 +379,9 @@ class ScriptEditor : public PanelContainer {
Ref<Script> _get_current_script();
Array _get_open_scripts() const;
+ Ref<TextFile> _load_text_file(const String &p_path, Error *r_error);
+ Error _save_text_file(Ref<TextFile> p_text_file, const String &p_path);
+
void _on_find_in_files_requested(String text);
void _on_find_in_files_result_selected(String fpath, int line_number, int begin, int end);
void _start_find_in_files(bool with_replace);
@@ -400,8 +404,8 @@ public:
void ensure_select_current();
- _FORCE_INLINE_ bool edit(const Ref<Script> &p_script, bool p_grab_focus = true) { return edit(p_script, -1, 0, p_grab_focus); }
- bool edit(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus = true);
+ _FORCE_INLINE_ bool edit(const RES &p_resource, bool p_grab_focus = true) { return edit(p_resource, -1, 0, p_grab_focus); }
+ bool edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus = true);
void get_breakpoints(List<String> *p_breakpoints);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 2263d782d9..0f48d42cf2 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -66,11 +66,24 @@ void ScriptTextEditor::apply_code() {
_update_member_keywords();
}
-Ref<Script> ScriptTextEditor::get_edited_script() const {
-
+RES ScriptTextEditor::get_edited_resource() const {
return script;
}
+void ScriptTextEditor::set_edited_resource(const RES &p_res) {
+ ERR_FAIL_COND(!script.is_null());
+
+ script = p_res;
+ _set_theme_for_script();
+
+ code_editor->get_text_edit()->set_text(script->get_source_code());
+ code_editor->get_text_edit()->clear_undo_history();
+ code_editor->get_text_edit()->tag_saved_version();
+
+ emit_signal("name_changed");
+ code_editor->update_line_and_column();
+}
+
void ScriptTextEditor::_update_member_keywords() {
member_keywords.clear();
code_editor->get_text_edit()->clear_member_keywords();
@@ -190,6 +203,7 @@ void ScriptTextEditor::_set_theme_for_script() {
List<String> keywords;
script->get_language()->get_reserved_words(&keywords);
+
for (List<String>::Element *E = keywords.front(); E; E = E->next()) {
text_edit->add_keyword_color(E->get(), colors_cache.keyword_color);
@@ -251,7 +265,6 @@ void ScriptTextEditor::_set_theme_for_script() {
//colorize strings
List<String> strings;
script->get_language()->get_string_delimiters(&strings);
-
for (List<String>::Element *E = strings.front(); E; E = E->next()) {
String string = E->get();
@@ -326,197 +339,32 @@ bool ScriptTextEditor::is_unsaved() {
Variant ScriptTextEditor::get_edit_state() {
- Dictionary state;
+ return code_editor->get_edit_state();
+}
- state["scroll_position"] = code_editor->get_text_edit()->get_v_scroll();
- state["column"] = code_editor->get_text_edit()->cursor_get_column();
- state["row"] = code_editor->get_text_edit()->cursor_get_line();
+void ScriptTextEditor::set_edit_state(const Variant &p_state) {
- return state;
+ code_editor->set_edit_state(p_state);
}
-void ScriptTextEditor::_convert_case(CaseStyle p_case) {
- TextEdit *te = code_editor->get_text_edit();
- Ref<Script> scr = get_edited_script();
- if (scr.is_null()) {
- return;
- }
-
- if (te->is_selection_active()) {
- te->begin_complex_operation();
-
- int begin = te->get_selection_from_line();
- int end = te->get_selection_to_line();
- int begin_col = te->get_selection_from_column();
- int end_col = te->get_selection_to_column();
-
- for (int i = begin; i <= end; i++) {
- int len = te->get_line(i).length();
- if (i == end)
- len -= len - end_col;
- if (i == begin)
- len -= begin_col;
- String new_line = te->get_line(i).substr(i == begin ? begin_col : 0, len);
-
- switch (p_case) {
- case UPPER: {
- new_line = new_line.to_upper();
- } break;
- case LOWER: {
- new_line = new_line.to_lower();
- } break;
- case CAPITALIZE: {
- new_line = new_line.capitalize();
- } break;
- }
+void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
- if (i == begin) {
- new_line = te->get_line(i).left(begin_col) + new_line;
- }
- if (i == end) {
- new_line = new_line + te->get_line(i).right(end_col);
- }
- te->set_line(i, new_line);
- }
- te->end_complex_operation();
- }
+ code_editor->convert_case(p_case);
}
void ScriptTextEditor::trim_trailing_whitespace() {
- TextEdit *tx = code_editor->get_text_edit();
-
- bool trimed_whitespace = false;
- for (int i = 0; i < tx->get_line_count(); i++) {
- String line = tx->get_line(i);
- if (line.ends_with(" ") || line.ends_with("\t")) {
-
- if (!trimed_whitespace) {
- tx->begin_complex_operation();
- trimed_whitespace = true;
- }
-
- int end = 0;
- for (int j = line.length() - 1; j > -1; j--) {
- if (line[j] != ' ' && line[j] != '\t') {
- end = j + 1;
- break;
- }
- }
- tx->set_line(i, line.substr(0, end));
- }
- }
- if (trimed_whitespace) {
- tx->end_complex_operation();
- tx->update();
- }
+ code_editor->trim_trailing_whitespace();
}
void ScriptTextEditor::convert_indent_to_spaces() {
- TextEdit *tx = code_editor->get_text_edit();
- Ref<Script> scr = get_edited_script();
-
- if (scr.is_null()) {
- return;
- }
-
- int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
- String indent = "";
-
- for (int i = 0; i < indent_size; i++) {
- indent += " ";
- }
-
- int cursor_line = tx->cursor_get_line();
- int cursor_column = tx->cursor_get_column();
-
- bool changed_indentation = false;
- for (int i = 0; i < tx->get_line_count(); i++) {
- String line = tx->get_line(i);
-
- if (line.length() <= 0) {
- continue;
- }
- int j = 0;
- while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
- if (line[j] == '\t') {
- if (!changed_indentation) {
- tx->begin_complex_operation();
- changed_indentation = true;
- }
- if (cursor_line == i && cursor_column > j) {
- cursor_column += indent_size - 1;
- }
- line = line.left(j) + indent + line.right(j + 1);
- }
- j++;
- }
- if (changed_indentation) {
- tx->set_line(i, line);
- }
- }
- if (changed_indentation) {
- tx->cursor_set_column(cursor_column);
- tx->end_complex_operation();
- tx->update();
- }
+ code_editor->convert_indent_to_spaces();
}
void ScriptTextEditor::convert_indent_to_tabs() {
- TextEdit *tx = code_editor->get_text_edit();
- Ref<Script> scr = get_edited_script();
-
- if (scr.is_null()) {
- return;
- }
-
- int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
- indent_size -= 1;
- int cursor_line = tx->cursor_get_line();
- int cursor_column = tx->cursor_get_column();
-
- bool changed_indentation = false;
- for (int i = 0; i < tx->get_line_count(); i++) {
- String line = tx->get_line(i);
-
- if (line.length() <= 0) {
- continue;
- }
-
- int j = 0;
- int space_count = -1;
- while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
- if (line[j] != '\t') {
- space_count++;
-
- if (space_count == indent_size) {
- if (!changed_indentation) {
- tx->begin_complex_operation();
- changed_indentation = true;
- }
- if (cursor_line == i && cursor_column > j) {
- cursor_column -= indent_size;
- }
- line = line.left(j - indent_size) + "\t" + line.right(j + 1);
- j = 0;
- space_count = -1;
- }
- } else {
- space_count = -1;
- }
- j++;
- }
- if (changed_indentation) {
- tx->set_line(i, line);
- }
- }
- if (changed_indentation) {
- tx->cursor_set_column(cursor_column);
- tx->end_complex_operation();
- tx->update();
- }
+ code_editor->convert_indent_to_tabs();
}
void ScriptTextEditor::tag_saved_version() {
@@ -525,31 +373,17 @@ void ScriptTextEditor::tag_saved_version() {
}
void ScriptTextEditor::goto_line(int p_line, bool p_with_error) {
- TextEdit *tx = code_editor->get_text_edit();
- tx->deselect();
- tx->unfold_line(p_line);
- tx->call_deferred("cursor_set_line", p_line);
-}
-void ScriptTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
- TextEdit *tx = code_editor->get_text_edit();
- tx->unfold_line(p_line);
- tx->call_deferred("cursor_set_line", p_line);
- tx->call_deferred("cursor_set_column", p_begin);
- tx->select(p_line, p_begin, p_line, p_end);
+ code_editor->goto_line(p_line);
}
-void ScriptTextEditor::ensure_focus() {
+void ScriptTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
- code_editor->get_text_edit()->grab_focus();
+ code_editor->goto_line_selection(p_line, p_begin, p_end);
}
-void ScriptTextEditor::set_edit_state(const Variant &p_state) {
+void ScriptTextEditor::ensure_focus() {
- Dictionary state = p_state;
- code_editor->get_text_edit()->cursor_set_column(state["column"]);
- code_editor->get_text_edit()->cursor_set_line(state["row"]);
- code_editor->get_text_edit()->set_v_scroll(state["scroll_position"]);
code_editor->get_text_edit()->grab_focus();
}
@@ -578,22 +412,6 @@ Ref<Texture> ScriptTextEditor::get_icon() {
return Ref<Texture>();
}
-void ScriptTextEditor::set_edited_script(const Ref<Script> &p_script) {
-
- ERR_FAIL_COND(!script.is_null());
-
- script = p_script;
- _set_theme_for_script();
-
- code_editor->get_text_edit()->set_text(script->get_source_code());
- code_editor->get_text_edit()->clear_undo_history();
- code_editor->get_text_edit()->tag_saved_version();
-
- emit_signal("name_changed");
- code_editor->update_line_and_column();
- call_deferred("_validate_script");
-}
-
void ScriptTextEditor::_validate_script() {
String errortxt;
@@ -878,98 +696,15 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_MOVE_LINE_UP: {
- Ref<Script> scr = script;
- if (scr.is_null())
- return;
-
- tx->begin_complex_operation();
- if (tx->is_selection_active()) {
- int from_line = tx->get_selection_from_line();
- int from_col = tx->get_selection_from_column();
- int to_line = tx->get_selection_to_line();
- int to_column = tx->get_selection_to_column();
-
- for (int i = from_line; i <= to_line; i++) {
- int line_id = i;
- int next_id = i - 1;
-
- if (line_id == 0 || next_id < 0)
- return;
-
- tx->unfold_line(line_id);
- tx->unfold_line(next_id);
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- int from_line_up = from_line > 0 ? from_line - 1 : from_line;
- int to_line_up = to_line > 0 ? to_line - 1 : to_line;
- tx->select(from_line_up, from_col, to_line_up, to_column);
- } else {
- int line_id = tx->cursor_get_line();
- int next_id = line_id - 1;
-
- if (line_id == 0 || next_id < 0)
- return;
-
- tx->unfold_line(line_id);
- tx->unfold_line(next_id);
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- tx->end_complex_operation();
- tx->update();
+ code_editor->move_lines_up();
} break;
case EDIT_MOVE_LINE_DOWN: {
- Ref<Script> scr = get_edited_script();
- if (scr.is_null())
- return;
-
- tx->begin_complex_operation();
- if (tx->is_selection_active()) {
- int from_line = tx->get_selection_from_line();
- int from_col = tx->get_selection_from_column();
- int to_line = tx->get_selection_to_line();
- int to_column = tx->get_selection_to_column();
-
- for (int i = to_line; i >= from_line; i--) {
- int line_id = i;
- int next_id = i + 1;
-
- if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
- return;
-
- tx->unfold_line(line_id);
- tx->unfold_line(next_id);
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- int from_line_down = from_line < tx->get_line_count() ? from_line + 1 : from_line;
- int to_line_down = to_line < tx->get_line_count() ? to_line + 1 : to_line;
- tx->select(from_line_down, from_col, to_line_down, to_column);
- } else {
- int line_id = tx->cursor_get_line();
- int next_id = line_id + 1;
-
- if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
- return;
-
- tx->unfold_line(line_id);
- tx->unfold_line(next_id);
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- tx->end_complex_operation();
- tx->update();
-
+ code_editor->move_lines_down();
} break;
case EDIT_INDENT_LEFT: {
- Ref<Script> scr = get_edited_script();
+ Ref<Script> scr = script;
if (scr.is_null())
return;
@@ -977,7 +712,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_INDENT_RIGHT: {
- Ref<Script> scr = get_edited_script();
+ Ref<Script> scr = script;
if (scr.is_null())
return;
@@ -985,72 +720,11 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_DELETE_LINE: {
- Ref<Script> scr = get_edited_script();
- if (scr.is_null())
- return;
- tx->begin_complex_operation();
- if (tx->is_selection_active()) {
- int to_line = tx->get_selection_to_line();
- int from_line = tx->get_selection_from_line();
- int count = Math::abs(to_line - from_line) + 1;
- while (count) {
- tx->set_line(tx->cursor_get_line(), "");
- tx->backspace_at_cursor();
- count--;
- if (count)
- tx->unfold_line(from_line);
- }
- tx->cursor_set_line(from_line - 1);
- tx->deselect();
- } else {
- int line = tx->cursor_get_line();
- tx->set_line(tx->cursor_get_line(), "");
- tx->backspace_at_cursor();
- tx->unfold_line(line);
- tx->cursor_set_line(line);
- }
- tx->end_complex_operation();
+ code_editor->delete_lines();
} break;
case EDIT_CLONE_DOWN: {
- Ref<Script> scr = get_edited_script();
- if (scr.is_null())
- return;
-
- int from_line = tx->cursor_get_line();
- int to_line = tx->cursor_get_line();
- int column = tx->cursor_get_column();
-
- if (tx->is_selection_active()) {
- from_line = tx->get_selection_from_line();
- to_line = tx->get_selection_to_line();
- column = tx->cursor_get_column();
- }
- int next_line = to_line + 1;
-
- if (to_line >= tx->get_line_count() - 1) {
- tx->set_line(to_line, tx->get_line(to_line) + "\n");
- }
-
- tx->begin_complex_operation();
- for (int i = from_line; i <= to_line; i++) {
-
- tx->unfold_line(i);
- if (i >= tx->get_line_count() - 1) {
- tx->set_line(i, tx->get_line(i) + "\n");
- }
- String line_clone = tx->get_line(i);
- tx->insert_at(line_clone, next_line);
- next_line++;
- }
-
- tx->cursor_set_column(column);
- if (tx->is_selection_active()) {
- tx->select(to_line + 1, tx->get_selection_from_column(), next_line - 1, tx->get_selection_to_column());
- }
-
- tx->end_complex_operation();
- tx->update();
+ code_editor->code_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
@@ -1069,7 +743,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_TOGGLE_COMMENT: {
- Ref<Script> scr = get_edited_script();
+ Ref<Script> scr = script;
if (scr.is_null())
return;
@@ -1137,7 +811,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
case EDIT_AUTO_INDENT: {
String text = tx->get_text();
- Ref<Script> scr = get_edited_script();
+ Ref<Script> scr = script;
if (scr.is_null())
return;
@@ -1180,15 +854,15 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_TO_UPPERCASE: {
- _convert_case(UPPER);
+ _convert_case(CodeTextEditor::UPPER);
} break;
case EDIT_TO_LOWERCASE: {
- _convert_case(LOWER);
+ _convert_case(CodeTextEditor::LOWER);
} break;
case EDIT_CAPITALIZE: {
- _convert_case(CAPITALIZE);
+ _convert_case(CodeTextEditor::CAPITALIZE);
} break;
case SEARCH_FIND: {
@@ -1228,7 +902,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
int line = tx->cursor_get_line();
bool dobreak = !tx->is_line_set_as_breakpoint(line);
tx->set_line_as_breakpoint(line, dobreak);
- ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
+ ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), line + 1, dobreak);
} break;
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
@@ -1239,7 +913,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
int line = E->get();
bool dobreak = !tx->is_line_set_as_breakpoint(line);
tx->set_line_as_breakpoint(line, dobreak);
- ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
+ ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), line + 1, dobreak);
}
}
case DEBUG_GOTO_NEXT_BREAKPOINT: {
@@ -1293,7 +967,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
}
} break;
-
case HELP_CONTEXTUAL: {
String text = tx->get_selection_text();
@@ -1303,6 +976,15 @@ void ScriptTextEditor::_edit_option(int p_op) {
emit_signal("request_help_search", text);
}
} break;
+ case LOOKUP_SYMBOL: {
+
+ String text = tx->get_word_under_cursor();
+ if (text == "")
+ text = tx->get_selection_text();
+ if (text != "") {
+ _lookup_symbol(text, tx->cursor_get_line(), tx->cursor_get_column());
+ }
+ } break;
}
}
@@ -1359,7 +1041,7 @@ void ScriptTextEditor::clear_edit_menu() {
void ScriptTextEditor::reload(bool p_soft) {
TextEdit *te = code_editor->get_text_edit();
- Ref<Script> scr = get_edited_script();
+ Ref<Script> scr = script;
if (scr.is_null())
return;
scr->set_source_code(te->get_text());
@@ -1508,19 +1190,13 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_RIGHT) {
-
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
int col, row;
TextEdit *tx = code_editor->get_text_edit();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
Vector2 mpos = mb->get_global_position() - tx->get_global_position();
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
- bool has_color = (tx->get_word_at_pos(mpos) == "Color");
- int fold_state = 0;
- bool can_fold = tx->can_fold(row);
- bool is_folded = tx->is_folded(row);
-
if (tx->is_right_click_moving_caret()) {
if (tx->is_selection_active()) {
@@ -1540,38 +1216,62 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
}
- if (!mb->is_pressed()) {
- if (has_color) {
- String line = tx->get_line(row);
- color_line = row;
- int begin = 0;
- int end = 0;
- bool valid = false;
- for (int i = col; i < line.length(); i++) {
- if (line[i] == '(') {
- begin = i;
- continue;
- } else if (line[i] == ')') {
- end = i + 1;
- valid = true;
- break;
- }
+ String word_at_mouse = tx->get_word_at_pos(mpos);
+ if (word_at_mouse == "")
+ word_at_mouse = tx->get_word_under_cursor();
+ if (word_at_mouse == "")
+ word_at_mouse = tx->get_selection_text();
+
+ bool has_color = (word_at_mouse == "Color");
+ int fold_state = 0;
+ bool foldable = tx->can_fold(row) || tx->is_folded(row);
+ bool open_docs = false;
+ bool goto_definition = false;
+
+ if (word_at_mouse.is_resource_file()) {
+ open_docs = true;
+ } else {
+
+ Node *base = get_tree()->get_edited_scene_root();
+ if (base) {
+ base = _find_node_for_script(base, base, script);
+ }
+ ScriptLanguage::LookupResult result;
+ if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), word_at_mouse, script->get_path().get_base_dir(), base, result) == OK) {
+ open_docs = true;
+ }
+ }
+
+ if (has_color) {
+ String line = tx->get_line(row);
+ color_line = row;
+ int begin = 0;
+ int end = 0;
+ bool valid = false;
+ for (int i = col; i < line.length(); i++) {
+ if (line[i] == '(') {
+ begin = i;
+ continue;
+ } else if (line[i] == ')') {
+ end = i + 1;
+ valid = true;
+ break;
}
- if (valid) {
- color_args = line.substr(begin, end - begin);
- String stripped = color_args.replace(" ", "").replace("(", "").replace(")", "");
- Vector<float> color = stripped.split_floats(",");
- if (color.size() > 2) {
- float alpha = color.size() > 3 ? color[3] : 1.0f;
- color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
- }
- color_panel->set_position(get_global_transform().xform(get_local_mouse_position()));
- } else {
- has_color = false;
+ }
+ if (valid) {
+ color_args = line.substr(begin, end - begin);
+ String stripped = color_args.replace(" ", "").replace("(", "").replace(")", "");
+ Vector<float> color = stripped.split_floats(",");
+ if (color.size() > 2) {
+ float alpha = color.size() > 3 ? color[3] : 1.0f;
+ color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
}
+ color_panel->set_position(get_global_transform().xform(get_local_mouse_position()));
+ } else {
+ has_color = false;
}
- _make_context_menu(tx->is_selection_active(), has_color, can_fold, is_folded);
}
+ _make_context_menu(tx->is_selection_active(), has_color, foldable, open_docs, goto_definition);
}
}
}
@@ -1590,7 +1290,7 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
code_editor->get_text_edit()->set_line(color_line, new_line);
}
-void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded) {
+void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
context_menu->clear();
if (p_selection) {
@@ -1613,13 +1313,17 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
}
- if (p_can_fold || p_is_folded)
+ if (p_foldable)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
- if (p_color) {
+ if (p_color || p_open_docs || p_goto_definition) {
context_menu->add_separator();
- context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
+ if (p_open_docs)
+ context_menu->add_item(TTR("Lookup Symbol"), LOOKUP_SYMBOL);
+ if (p_color)
+ context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
}
+
context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
context_menu->set_size(Vector2(1, 1));
context_menu->popup();
@@ -1653,6 +1357,7 @@ ScriptTextEditor::ScriptTextEditor() {
context_menu = memnew(PopupMenu);
add_child(context_menu);
context_menu->connect("id_pressed", this, "_edit_option");
+ context_menu->set_hide_on_window_lose_focus(true);
color_panel = memnew(PopupPanel);
add_child(color_panel);
@@ -1664,6 +1369,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu = memnew(MenuButton);
edit_menu->set_text(TTR("Edit"));
+ edit_menu->get_popup()->set_hide_on_window_lose_focus(true);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -1717,6 +1423,7 @@ ScriptTextEditor::ScriptTextEditor() {
search_menu = memnew(MenuButton);
edit_hb->add_child(search_menu);
search_menu->set_text(TTR("Search"));
+ search_menu->get_popup()->set_hide_on_window_lose_focus(true);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
@@ -1743,9 +1450,12 @@ ScriptTextEditor::ScriptTextEditor() {
code_editor->get_text_edit()->set_drag_forwarding(this);
}
-static ScriptEditorBase *create_editor(const Ref<Script> &p_script) {
+static ScriptEditorBase *create_editor(const RES &p_resource) {
- return memnew(ScriptTextEditor);
+ if (Object::cast_to<Script>(*p_resource)) {
+ return memnew(ScriptTextEditor);
+ }
+ return NULL;
}
void ScriptTextEditor::register_editor() {
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index a415f478e8..334d410dbe 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -112,6 +112,7 @@ class ScriptTextEditor : public ScriptEditorBase {
DEBUG_GOTO_NEXT_BREAKPOINT,
DEBUG_GOTO_PREV_BREAKPOINT,
HELP_CONTEXTUAL,
+ LOOKUP_SYMBOL,
};
protected:
@@ -131,19 +132,14 @@ protected:
void _change_syntax_highlighter(int p_idx);
void _edit_option(int p_op);
- void _make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded);
+ void _make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition);
void _text_edit_gui_input(const Ref<InputEvent> &ev);
void _color_changed(const Color &p_color);
void _goto_line(int p_line) { goto_line(p_line); }
void _lookup_symbol(const String &p_symbol, int p_row, int p_column);
- enum CaseStyle {
- UPPER,
- LOWER,
- CAPITALIZE,
- };
- void _convert_case(CaseStyle p_case);
+ void _convert_case(CodeTextEditor::CaseStyle p_case);
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
@@ -154,14 +150,13 @@ public:
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
virtual void apply_code();
- virtual Ref<Script> get_edited_script() const;
+ virtual RES get_edited_resource() const;
+ virtual void set_edited_resource(const RES &p_res);
virtual Vector<String> get_functions();
- virtual void set_edited_script(const Ref<Script> &p_script);
virtual void reload_text();
virtual String get_name();
virtual Ref<Texture> get_icon();
virtual bool is_unsaved();
-
virtual Variant get_edit_state();
virtual void set_edit_state(const Variant &p_state);
virtual void ensure_focus();
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 4b7f27c0c1..ea1876c27a 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -258,84 +258,10 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->get_text_edit()->select_all();
} break;
case EDIT_MOVE_LINE_UP: {
-
- TextEdit *tx = shader_editor->get_text_edit();
- if (shader.is_null())
- return;
-
- tx->begin_complex_operation();
- if (tx->is_selection_active()) {
- int from_line = tx->get_selection_from_line();
- int from_col = tx->get_selection_from_column();
- int to_line = tx->get_selection_to_line();
- int to_column = tx->get_selection_to_column();
-
- for (int i = from_line; i <= to_line; i++) {
- int line_id = i;
- int next_id = i - 1;
-
- if (line_id == 0 || next_id < 0)
- return;
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- int from_line_up = from_line > 0 ? from_line - 1 : from_line;
- int to_line_up = to_line > 0 ? to_line - 1 : to_line;
- tx->select(from_line_up, from_col, to_line_up, to_column);
- } else {
- int line_id = tx->cursor_get_line();
- int next_id = line_id - 1;
-
- if (line_id == 0 || next_id < 0)
- return;
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- tx->end_complex_operation();
- tx->update();
-
+ shader_editor->move_lines_up();
} break;
case EDIT_MOVE_LINE_DOWN: {
-
- TextEdit *tx = shader_editor->get_text_edit();
- if (shader.is_null())
- return;
-
- tx->begin_complex_operation();
- if (tx->is_selection_active()) {
- int from_line = tx->get_selection_from_line();
- int from_col = tx->get_selection_from_column();
- int to_line = tx->get_selection_to_line();
- int to_column = tx->get_selection_to_column();
-
- for (int i = to_line; i >= from_line; i--) {
- int line_id = i;
- int next_id = i + 1;
-
- if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
- return;
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- int from_line_down = from_line < tx->get_line_count() ? from_line + 1 : from_line;
- int to_line_down = to_line < tx->get_line_count() ? to_line + 1 : to_line;
- tx->select(from_line_down, from_col, to_line_down, to_column);
- } else {
- int line_id = tx->cursor_get_line();
- int next_id = line_id + 1;
-
- if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
- return;
-
- tx->swap_lines(line_id, next_id);
- tx->cursor_set_line(next_id);
- }
- tx->end_complex_operation();
- tx->update();
-
+ shader_editor->move_lines_down();
} break;
case EDIT_INDENT_LEFT: {
@@ -356,55 +282,10 @@ void ShaderEditor::_menu_option(int p_option) {
} break;
case EDIT_DELETE_LINE: {
-
- TextEdit *tx = shader_editor->get_text_edit();
- if (shader.is_null())
- return;
-
- tx->begin_complex_operation();
- int line = tx->cursor_get_line();
- tx->set_line(tx->cursor_get_line(), "");
- tx->backspace_at_cursor();
- tx->cursor_set_line(line);
- tx->end_complex_operation();
-
+ shader_editor->delete_lines();
} break;
case EDIT_CLONE_DOWN: {
-
- TextEdit *tx = shader_editor->get_text_edit();
- if (shader.is_null())
- return;
-
- int from_line = tx->cursor_get_line();
- int to_line = tx->cursor_get_line();
- int column = tx->cursor_get_column();
-
- if (tx->is_selection_active()) {
- from_line = tx->get_selection_from_line();
- to_line = tx->get_selection_to_line();
- column = tx->cursor_get_column();
- }
- int next_line = to_line + 1;
-
- tx->begin_complex_operation();
- for (int i = from_line; i <= to_line; i++) {
-
- if (i >= tx->get_line_count() - 1) {
- tx->set_line(i, tx->get_line(i) + "\n");
- }
- String line_clone = tx->get_line(i);
- tx->insert_at(line_clone, next_line);
- next_line++;
- }
-
- tx->cursor_set_column(column);
- if (tx->is_selection_active()) {
- tx->select(to_line + 1, tx->get_selection_from_column(), next_line - 1, tx->get_selection_to_column());
- }
-
- tx->end_complex_operation();
- tx->update();
-
+ shader_editor->code_lines_down();
} break;
case EDIT_TOGGLE_COMMENT: {
@@ -584,7 +465,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_RIGHT) {
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
int col, row;
TextEdit *tx = shader_editor->get_text_edit();
@@ -610,10 +491,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
tx->cursor_set_column(col);
}
}
-
- if (!mb->is_pressed()) {
- _make_context_menu(tx->is_selection_active());
- }
+ _make_context_menu(tx->is_selection_active());
}
}
}
@@ -665,6 +543,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
context_menu = memnew(PopupMenu);
add_child(context_menu);
context_menu->connect("id_pressed", this, "_menu_option");
+ context_menu->set_hide_on_window_lose_focus(true);
VBoxContainer *main_container = memnew(VBoxContainer);
HBoxContainer *hbc = memnew(HBoxContainer);
@@ -673,6 +552,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
//edit_menu->set_position(Point2(5, -1));
edit_menu->set_text(TTR("Edit"));
+ edit_menu->get_popup()->set_hide_on_window_lose_focus(true);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -697,7 +577,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
search_menu = memnew(MenuButton);
//search_menu->set_position(Point2(38, -1));
search_menu->set_text(TTR("Search"));
-
+ search_menu->get_popup()->set_hide_on_window_lose_focus(true);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp
index 40a696119e..fe7d1df50c 100644
--- a/editor/plugins/skeleton_editor_plugin.cpp
+++ b/editor/plugins/skeleton_editor_plugin.cpp
@@ -68,16 +68,16 @@ void SkeletonEditor::create_physical_skeleton() {
if (parent < 0) {
- bones_infos[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
+ bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
} else {
- bones_infos[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
+ bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
/// create physical bone on parent
if (!bones_infos[parent].physical_bone) {
- bones_infos[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
+ bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
ur->create_action(TTR("Create physical bones"));
ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
diff --git a/editor/plugins/skeleton_ik_editor_plugin.cpp b/editor/plugins/skeleton_ik_editor_plugin.cpp
new file mode 100644
index 0000000000..2d343d3edd
--- /dev/null
+++ b/editor/plugins/skeleton_ik_editor_plugin.cpp
@@ -0,0 +1,110 @@
+/*************************************************************************/
+/* skeleton_ik_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "skeleton_ik_editor_plugin.h"
+
+#include "scene/animation/skeleton_ik.h"
+
+void SkeletonIKEditorPlugin::_play() {
+
+ if (!skeleton_ik)
+ return;
+
+ if (!skeleton_ik->get_parent_skeleton())
+ return;
+
+ if (play_btn->is_pressed()) {
+
+ initial_bone_poses.resize(skeleton_ik->get_parent_skeleton()->get_bone_count());
+ for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) {
+ initial_bone_poses.write[i] = skeleton_ik->get_parent_skeleton()->get_bone_pose(i);
+ }
+
+ skeleton_ik->start();
+ } else {
+ skeleton_ik->stop();
+
+ if (initial_bone_poses.size() != skeleton_ik->get_parent_skeleton()->get_bone_count())
+ return;
+
+ for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) {
+ skeleton_ik->get_parent_skeleton()->set_bone_pose(i, initial_bone_poses[i]);
+ }
+ }
+}
+
+void SkeletonIKEditorPlugin::edit(Object *p_object) {
+
+ if (p_object != skeleton_ik) {
+ if (skeleton_ik) {
+ play_btn->set_pressed(false);
+ _play();
+ }
+ }
+
+ SkeletonIK *s = Object::cast_to<SkeletonIK>(p_object);
+ if (!s)
+ return;
+
+ skeleton_ik = s;
+}
+
+bool SkeletonIKEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("SkeletonIK");
+}
+
+void SkeletonIKEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible)
+ play_btn->show();
+ else
+ play_btn->hide();
+}
+
+void SkeletonIKEditorPlugin::_bind_methods() {
+
+ ClassDB::bind_method("_play", &SkeletonIKEditorPlugin::_play);
+}
+
+SkeletonIKEditorPlugin::SkeletonIKEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ play_btn = memnew(Button);
+ play_btn->set_icon(editor->get_gui_base()->get_icon("Play", "EditorIcons"));
+ play_btn->set_text(TTR("Play IK"));
+ play_btn->set_toggle_mode(true);
+ play_btn->hide();
+ play_btn->connect("pressed", this, "_play");
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, play_btn);
+ skeleton_ik = NULL;
+}
+
+SkeletonIKEditorPlugin::~SkeletonIKEditorPlugin() {}
diff --git a/editor/plugins/skeleton_ik_editor_plugin.h b/editor/plugins/skeleton_ik_editor_plugin.h
new file mode 100644
index 0000000000..e645bea39a
--- /dev/null
+++ b/editor/plugins/skeleton_ik_editor_plugin.h
@@ -0,0 +1,65 @@
+/*************************************************************************/
+/* skeleton_ik_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 SKELETON_IK_EDITOR_PLUGIN_H
+#define SKELETON_IK_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+
+class SkeletonIK;
+
+class SkeletonIKEditorPlugin : public EditorPlugin {
+
+ GDCLASS(SkeletonIKEditorPlugin, EditorPlugin);
+
+ SkeletonIK *skeleton_ik;
+
+ Button *play_btn;
+ EditorNode *editor;
+ Vector<Transform> initial_bone_poses;
+
+ void _play();
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_name() const { return "SkeletonIK"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual void make_visible(bool p_visible);
+
+ SkeletonIKEditorPlugin(EditorNode *p_node);
+ ~SkeletonIKEditorPlugin();
+};
+
+#endif // SKELETON_IK_EDITOR_PLUGIN_H
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 37b8562e96..eab1588a55 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -1928,6 +1928,11 @@ void SpatialEditorViewport::_nav_zoom(Ref<InputEventWithModifiers> p_event, cons
void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
+ if (lock_rotation) {
+ _nav_pan(p_event, p_relative);
+ return;
+ }
+
real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
@@ -2151,6 +2156,21 @@ void SpatialEditorViewport::_notification(int p_what) {
_update_freelook(delta);
+ Node *scene_root = editor->get_scene_tree_dock()->get_editor_data()->get_edited_scene_root();
+ if (previewing_cinema == true && scene_root != NULL) {
+ Camera *cam = scene_root->get_viewport()->get_camera();
+ if (cam != NULL && cam != previewing) {
+ //then switch the viewport's camera to the scene's viewport camera
+ if (previewing != NULL) {
+ previewing->disconnect("tree_exited", this, "_preview_exited_scene");
+ }
+ previewing = cam;
+ previewing->connect("tree_exited", this, "_preview_exited_scene");
+ VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera());
+ surface->update();
+ }
+ }
+
_update_camera(delta);
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -2256,6 +2276,13 @@ void SpatialEditorViewport::_notification(int p_what) {
text += TTR("FPS") + ": " + itos(temp_fps) + " (" + String::num(1000.0f / temp_fps, 2) + " ms)";
fps_label->set_text(text);
}
+
+ bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
+ cinema_label->set_visible(show_cinema);
+ if (show_cinema) {
+ float cinema_half_width = cinema_label->get_size().width / 2.0f;
+ cinema_label->set_anchor_and_margin(MARGIN_LEFT, 0.5f, -cinema_half_width);
+ }
}
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -2268,6 +2295,7 @@ void SpatialEditorViewport::_notification(int p_what) {
surface->connect("focus_exited", this, "_surface_focus_exit");
info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
preview_camera->set_icon(get_icon("Camera", "EditorIcons"));
_init_gizmo_instance(index);
}
@@ -2563,6 +2591,19 @@ void SpatialEditorViewport::_menu_option(int p_option) {
_update_name();
} break;
+ case VIEW_LOCK_ROTATION: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_LOCK_ROTATION);
+ bool current = view_menu->get_popup()->is_item_checked(idx);
+ lock_rotation = !current;
+ view_menu->get_popup()->set_item_checked(idx, !current);
+ if (lock_rotation) {
+ view_menu->set_icon(get_icon("Lock", "EditorIcons"));
+ } else {
+ view_menu->set_icon(Ref<Texture>());
+ }
+
+ } break;
case VIEW_AUDIO_LISTENER: {
int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER);
@@ -2581,6 +2622,22 @@ void SpatialEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(idx, current);
} break;
+ case VIEW_CINEMATIC_PREVIEW: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW);
+ bool current = view_menu->get_popup()->is_item_checked(idx);
+ current = !current;
+ view_menu->get_popup()->set_item_checked(idx, current);
+ previewing_cinema = true;
+ _toggle_cinema_preview(current);
+
+ if (current) {
+ preview_camera->hide();
+ } else {
+ if (previewing != NULL)
+ preview_camera->show();
+ }
+ } break;
case VIEW_GIZMOS: {
int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
@@ -2744,6 +2801,25 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
}
}
+void SpatialEditorViewport::_toggle_cinema_preview(bool p_activate) {
+ previewing_cinema = p_activate;
+ if (!previewing_cinema) {
+ if (previewing != NULL)
+ previewing->disconnect("tree_exited", this, "_preview_exited_scene");
+
+ previewing = NULL;
+ VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), camera->get_camera()); //restore
+ preview_camera->set_pressed(false);
+ if (!preview) {
+ preview_camera->hide();
+ } else {
+ preview_camera->show();
+ }
+ view_menu->show();
+ surface->update();
+ }
+}
+
void SpatialEditorViewport::_selection_result_pressed(int p_result) {
if (selection_results.size() <= p_result)
@@ -2768,7 +2844,7 @@ void SpatialEditorViewport::set_can_preview(Camera *p_preview) {
preview = p_preview;
- if (!preview_camera->is_pressed())
+ if (!preview_camera->is_pressed() && !previewing_cinema)
preview_camera->set_visible(p_preview);
}
@@ -2836,6 +2912,12 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
if (!view_menu->get_popup()->is_item_checked(idx))
_menu_option(display);
}
+ if (p_state.has("lock_rotation")) {
+ lock_rotation = p_state["lock_rotation"];
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_LOCK_ROTATION);
+ view_menu->get_popup()->set_item_checked(idx, lock_rotation);
+ }
if (p_state.has("use_environment")) {
bool env = p_state["use_environment"];
@@ -2883,6 +2965,12 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
int idx = view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION);
view_menu->get_popup()->set_item_checked(idx, half_res);
}
+ if (p_state.has("cinematic_preview")) {
+ previewing_cinema = p_state["cinematic_preview"];
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW);
+ view_menu->get_popup()->set_item_checked(idx, previewing_cinema);
+ }
if (p_state.has("previewing")) {
Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]);
@@ -2921,8 +3009,11 @@ Dictionary SpatialEditorViewport::get_state() const {
d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
d["fps"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
d["half_res"] = viewport_container->get_stretch_shrink() > 1;
+ d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
if (previewing)
d["previewing"] = EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing);
+ if (lock_rotation)
+ d["lock_rotation"] = lock_rotation;
return d;
}
@@ -2951,6 +3042,7 @@ void SpatialEditorViewport::_bind_methods() {
void SpatialEditorViewport::reset() {
orthogonal = false;
+ lock_rotation = false;
message_time = 0;
message = "";
last_message = "";
@@ -3377,6 +3469,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_radio_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true);
view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_lock_rotation", TTR("Lock View Rotation")), VIEW_LOCK_ROTATION);
+ view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL);
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME);
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW);
@@ -3396,6 +3490,9 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_cinematic_preview", TTR("Cinematic Preview")), VIEW_CINEMATIC_PREVIEW);
+
+ view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_origin"), VIEW_CENTER_TO_ORIGIN);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_selection"), VIEW_CENTER_TO_SELECTION);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_selection_with_view"), VIEW_ALIGN_SELECTION_WITH_VIEW);
@@ -3445,6 +3542,15 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
surface->add_child(fps_label);
fps_label->hide();
+ cinema_label = memnew(Label);
+ cinema_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
+ cinema_label->set_h_grow_direction(GROW_DIRECTION_END);
+ cinema_label->set_align(Label::ALIGN_CENTER);
+ surface->add_child(cinema_label);
+ cinema_label->set_text(TTR("Cinematic Preview"));
+ cinema_label->hide();
+ previewing_cinema = false;
+
accept = NULL;
freelook_active = false;
@@ -4241,6 +4347,9 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
} break;
+ case MENU_SNAP_TO_FLOOR: {
+ snap_selected_nodes_to_floor();
+ } break;
case MENU_LOCK_SELECTED: {
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -4641,9 +4750,7 @@ void SpatialEditor::_init_grid() {
Vector3 p2_dest = p2 * (-axis_n1 + axis_n2);
Color line_color = secondary_grid_color;
- if (j == 0) {
- continue;
- } else if (j % primary_grid_steps == 0) {
+ if (j % primary_grid_steps == 0) {
line_color = primary_grid_color;
}
@@ -4718,6 +4825,119 @@ void SpatialEditor::_refresh_menu_icons() {
tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
}
+template <typename T>
+Set<T *> _get_child_nodes(Node *parent_node) {
+ Set<T *> nodes = Set<T *>();
+ T *node = Node::cast_to<T>(parent_node);
+ if (node) {
+ nodes.insert(node);
+ }
+
+ for (int i = 0; i < parent_node->get_child_count(); i++) {
+ Node *child_node = parent_node->get_child(i);
+ Set<T *> child_nodes = _get_child_nodes<T>(child_node);
+ for (typename Set<T *>::Element *I = child_nodes.front(); I; I = I->next()) {
+ nodes.insert(I->get());
+ }
+ }
+
+ return nodes;
+}
+
+Set<RID> _get_physics_bodies_rid(Node *node) {
+ Set<RID> rids = Set<RID>();
+ PhysicsBody *pb = Node::cast_to<PhysicsBody>(node);
+ if (pb) {
+ rids.insert(pb->get_rid());
+ }
+ Set<PhysicsBody *> child_nodes = _get_child_nodes<PhysicsBody>(node);
+ for (Set<PhysicsBody *>::Element *I = child_nodes.front(); I; I = I->next()) {
+ rids.insert(I->get()->get_rid());
+ }
+
+ return rids;
+}
+
+void SpatialEditor::snap_selected_nodes_to_floor() {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ Dictionary snap_data;
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Spatial *sp = Object::cast_to<Spatial>(E->get());
+ if (sp) {
+ Vector3 from = Vector3();
+ Vector3 position_offset = Vector3();
+
+ // Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin
+ Set<VisualInstance *> vi = _get_child_nodes<VisualInstance>(sp);
+ Set<CollisionShape *> cs = _get_child_nodes<CollisionShape>(sp);
+
+ if (cs.size()) {
+ AABB aabb = sp->get_global_transform().xform(cs.front()->get()->get_shape()->get_debug_mesh()->get_aabb());
+ for (Set<CollisionShape *>::Element *I = cs.front(); I; I = I->next()) {
+ aabb.merge_with(sp->get_global_transform().xform(I->get()->get_shape()->get_debug_mesh()->get_aabb()));
+ }
+ Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
+ from = aabb.position + size;
+ position_offset.y = from.y - sp->get_global_transform().origin.y;
+ } else if (vi.size()) {
+ AABB aabb = vi.front()->get()->get_transformed_aabb();
+ for (Set<VisualInstance *>::Element *I = vi.front(); I; I = I->next()) {
+ aabb.merge_with(I->get()->get_transformed_aabb());
+ }
+ Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
+ from = aabb.position + size;
+ position_offset.y = from.y - sp->get_global_transform().origin.y;
+ } else {
+ from = sp->get_global_transform().origin;
+ }
+
+ // We add a bit of margin to the from position to avoid it from snapping
+ // when the spatial is already on a floor and there's another floor under
+ // it
+ from = from + Vector3(0.0, 0.1, 0.0);
+
+ Dictionary d;
+
+ d["from"] = from;
+ d["position_offset"] = position_offset;
+ snap_data[sp] = d;
+ }
+ }
+
+ PhysicsDirectSpaceState *ss = get_tree()->get_root()->get_world()->get_direct_space_state();
+ PhysicsDirectSpaceState::RayResult result;
+
+ Array keys = snap_data.keys();
+
+ if (keys.size()) {
+ undo_redo->create_action("Snap Nodes To Floor");
+
+ for (int i = 0; i < keys.size(); i++) {
+ Node *node = keys[i];
+ Spatial *sp = Object::cast_to<Spatial>(node);
+
+ Dictionary d = snap_data[node];
+ Vector3 from = d["from"];
+ Vector3 position_offset = d["position_offset"];
+
+ Vector3 to = from - Vector3(0.0, 10.0, 0.0);
+ Set<RID> excluded = _get_physics_bodies_rid(sp);
+
+ if (ss->intersect_ray(from, to, result, excluded)) {
+ Transform new_transform = sp->get_global_transform();
+ new_transform.origin.y = result.position.y;
+ new_transform.origin = new_transform.origin - position_offset;
+
+ undo_redo->add_do_method(sp, "set_global_transform", new_transform);
+ undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
+ }
+ }
+
+ undo_redo->commit_action();
+ }
+}
+
void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
@@ -4746,6 +4966,8 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event))
_menu_item_pressed(MENU_TOOL_SCALE);
+ else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event))
+ snap_selected_nodes_to_floor();
else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event))
if (are_local_coords_enabled()) {
@@ -5011,7 +5233,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
tool_button[TOOL_MODE_SELECT]->set_flat(true);
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
- button_binds[0] = MENU_TOOL_SELECT;
+ button_binds.write[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
@@ -5019,7 +5241,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
tool_button[TOOL_MODE_MOVE]->set_flat(true);
- button_binds[0] = MENU_TOOL_MOVE;
+ button_binds.write[0] = MENU_TOOL_MOVE;
tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
@@ -5027,7 +5249,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true);
tool_button[TOOL_MODE_ROTATE]->set_flat(true);
- button_binds[0] = MENU_TOOL_ROTATE;
+ button_binds.write[0] = MENU_TOOL_ROTATE;
tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
@@ -5035,7 +5257,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true);
tool_button[TOOL_MODE_SCALE]->set_flat(true);
- button_binds[0] = MENU_TOOL_SCALE;
+ button_binds.write[0] = MENU_TOOL_SCALE;
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
@@ -5043,19 +5265,19 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true);
- button_binds[0] = MENU_TOOL_LIST_SELECT;
+ button_binds.write[0] = MENU_TOOL_LIST_SELECT;
tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
- button_binds[0] = MENU_LOCK_SELECTED;
+ button_binds.write[0] = MENU_LOCK_SELECTED;
tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
- button_binds[0] = MENU_UNLOCK_SELECTED;
+ button_binds.write[0] = MENU_UNLOCK_SELECTED;
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
@@ -5066,7 +5288,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
- button_binds[0] = MENU_TOOL_LOCAL_COORDS;
+ button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
@@ -5076,7 +5298,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
- button_binds[0] = MENU_TOOL_USE_SNAP;
+ button_binds.write[0] = MENU_TOOL_USE_SNAP;
tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
@@ -5105,6 +5327,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W);
ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E);
ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R);
+ ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap To Floor"), KEY_PAGEDOWN);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
@@ -5115,6 +5338,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(transform_menu);
p = transform_menu->get_popup();
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap object to floor")), MENU_SNAP_TO_FLOOR);
p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog...")), MENU_TRANSFORM_DIALOG);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 637926a913..bd449a28df 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -60,6 +60,7 @@ public:
virtual Variant get_handle_value(int p_idx) const;
virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ virtual bool is_gizmo_handle_highlighted(int idx) const { return false; }
virtual bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum);
virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false);
@@ -93,7 +94,9 @@ class SpatialEditorViewport : public Control {
VIEW_DISPLAY_NORMAL,
VIEW_DISPLAY_WIREFRAME,
VIEW_DISPLAY_OVERDRAW,
- VIEW_DISPLAY_SHADELESS
+ VIEW_DISPLAY_SHADELESS,
+ VIEW_LOCK_ROTATION,
+ VIEW_CINEMATIC_PREVIEW
};
public:
@@ -107,7 +110,6 @@ private:
int index;
String name;
void _menu_option(int p_option);
-
Spatial *preview_node;
AABB *preview_bounds;
Vector<String> selected_files;
@@ -131,6 +133,7 @@ private:
Camera *camera;
bool transforming;
bool orthogonal;
+ bool lock_rotation;
float gizmo_scale;
bool freelook_active;
@@ -138,6 +141,7 @@ private:
Label *info_label;
Label *fps_label;
+ Label *cinema_label;
struct _RayResult {
@@ -286,8 +290,11 @@ private:
Camera *previewing;
Camera *preview;
+ bool previewing_cinema;
+
void _preview_exited_scene();
void _toggle_camera_preview(bool);
+ void _toggle_cinema_preview(bool);
void _init_gizmo_instance(int p_idx);
void _finish_gizmo_instances();
void _selection_result_pressed(int);
@@ -402,7 +409,6 @@ public:
TOOL_LOCK_SELECTED,
TOOL_UNLOCK_SELECTED,
TOOL_MAX
-
};
enum ToolOptions {
@@ -486,7 +492,8 @@ private:
MENU_VIEW_CAMERA_SETTINGS,
MENU_LOCK_SELECTED,
MENU_UNLOCK_SELECTED,
- MENU_VISIBILITY_SKELETON
+ MENU_VISIBILITY_SKELETON,
+ MENU_SNAP_TO_FLOOR
};
Button *tool_button[TOOL_MAX];
@@ -595,7 +602,7 @@ public:
void update_transform_gizmo();
void update_all_gizmos();
-
+ void snap_selected_nodes_to_floor();
void select_gizmo_highlight_axis(int p_axis);
void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp
index 66673cca00..9bf1178b58 100644
--- a/editor/plugins/sprite_editor_plugin.cpp
+++ b/editor/plugins/sprite_editor_plugin.cpp
@@ -169,7 +169,7 @@ void SpriteEditor::_update_mesh_data() {
Size2 img_size = Vector2(image->get_width(), image->get_height());
for (int j = 0; j < lines.size(); j++) {
- lines[j] = expand(lines[j], rect, epsilon);
+ lines.write[j] = expand(lines[j], rect, epsilon);
int index_ofs = computed_vertices.size();
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
new file mode 100644
index 0000000000..16c25f3074
--- /dev/null
+++ b/editor/plugins/text_editor.cpp
@@ -0,0 +1,607 @@
+/*************************************************************************/
+/* text_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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_editor.h"
+
+void TextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
+ highlighters[p_highlighter->get_name()] = p_highlighter;
+ highlighter_menu->add_radio_check_item(p_highlighter->get_name());
+}
+
+void TextEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
+ TextEdit *te = code_editor->get_text_edit();
+ te->_set_syntax_highlighting(p_highlighter);
+ if (p_highlighter != NULL) {
+ highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(p_highlighter->get_name()), true);
+ } else {
+ highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text("Standard"), true);
+ }
+
+ // little work around. GDScript highlighter goes through text_edit for colours,
+ // so to remove all colours we need to set and unset them here.
+ if (p_highlighter == NULL) { // standard
+ TextEdit *text_edit = code_editor->get_text_edit();
+ text_edit->add_color_override("number_color", colors_cache.font_color);
+ text_edit->add_color_override("function_color", colors_cache.font_color);
+ text_edit->add_color_override("number_color", colors_cache.font_color);
+ text_edit->add_color_override("member_variable_color", colors_cache.font_color);
+ } else {
+ _load_theme_settings();
+ }
+}
+
+void TextEditor::_change_syntax_highlighter(int p_idx) {
+ Map<String, SyntaxHighlighter *>::Element *el = highlighters.front();
+ while (el != NULL) {
+ highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(el->key()), false);
+ el = el->next();
+ }
+ set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]);
+}
+
+void TextEditor::_load_theme_settings() {
+
+ TextEdit *text_edit = code_editor->get_text_edit();
+ text_edit->clear_colors();
+
+ Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
+ Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color");
+ Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color");
+ Color completion_existing_color = EDITOR_GET("text_editor/highlighting/completion_existing_color");
+ Color completion_scroll_color = EDITOR_GET("text_editor/highlighting/completion_scroll_color");
+ Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color");
+ Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
+ Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color");
+ Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color");
+ Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color");
+ Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color");
+ Color selection_color = EDITOR_GET("text_editor/highlighting/selection_color");
+ Color brace_mismatch_color = EDITOR_GET("text_editor/highlighting/brace_mismatch_color");
+ Color current_line_color = EDITOR_GET("text_editor/highlighting/current_line_color");
+ Color line_length_guideline_color = EDITOR_GET("text_editor/highlighting/line_length_guideline_color");
+ Color word_highlighted_color = EDITOR_GET("text_editor/highlighting/word_highlighted_color");
+ Color number_color = EDITOR_GET("text_editor/highlighting/number_color");
+ Color function_color = EDITOR_GET("text_editor/highlighting/function_color");
+ Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color");
+ Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color");
+ Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color");
+ Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color");
+ Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color");
+ Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color");
+ Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
+ Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
+ Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color");
+ Color type_color = EDITOR_GET("text_editor/highlighting/engine_type_color");
+ Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
+ Color string_color = EDITOR_GET("text_editor/highlighting/string_color");
+
+ text_edit->add_color_override("background_color", background_color);
+ text_edit->add_color_override("completion_background_color", completion_background_color);
+ text_edit->add_color_override("completion_selected_color", completion_selected_color);
+ text_edit->add_color_override("completion_existing_color", completion_existing_color);
+ text_edit->add_color_override("completion_scroll_color", completion_scroll_color);
+ text_edit->add_color_override("completion_font_color", completion_font_color);
+ text_edit->add_color_override("font_color", text_color);
+ text_edit->add_color_override("line_number_color", line_number_color);
+ text_edit->add_color_override("caret_color", caret_color);
+ text_edit->add_color_override("caret_background_color", caret_background_color);
+ text_edit->add_color_override("font_selected_color", text_selected_color);
+ text_edit->add_color_override("selection_color", selection_color);
+ text_edit->add_color_override("brace_mismatch_color", brace_mismatch_color);
+ text_edit->add_color_override("current_line_color", current_line_color);
+ text_edit->add_color_override("line_length_guideline_color", line_length_guideline_color);
+ text_edit->add_color_override("word_highlighted_color", word_highlighted_color);
+ text_edit->add_color_override("number_color", number_color);
+ text_edit->add_color_override("function_color", function_color);
+ text_edit->add_color_override("member_variable_color", member_variable_color);
+ text_edit->add_color_override("breakpoint_color", breakpoint_color);
+ text_edit->add_color_override("mark_color", mark_color);
+ text_edit->add_color_override("code_folding_color", code_folding_color);
+ text_edit->add_color_override("search_result_color", search_result_color);
+ text_edit->add_color_override("search_result_border_color", search_result_border_color);
+ text_edit->add_color_override("symbol_color", symbol_color);
+
+ text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
+
+ colors_cache.font_color = text_color;
+ colors_cache.symbol_color = symbol_color;
+ colors_cache.keyword_color = keyword_color;
+ colors_cache.basetype_color = basetype_color;
+ colors_cache.type_color = type_color;
+ colors_cache.comment_color = comment_color;
+ colors_cache.string_color = string_color;
+}
+
+String TextEditor::get_name() {
+ String name;
+
+ if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
+ name = text_file->get_path().get_file();
+ if (is_unsaved()) {
+ name += "(*)";
+ }
+ } else if (text_file->get_name() != "") {
+ name = text_file->get_name();
+ } else {
+ name = text_file->get_class() + "(" + itos(text_file->get_instance_id()) + ")";
+ }
+
+ return name;
+}
+
+Ref<Texture> TextEditor::get_icon() {
+
+ if (get_parent_control() && get_parent_control()->has_icon(text_file->get_class(), "EditorIcons")) {
+ return get_parent_control()->get_icon(text_file->get_class(), "EditorIcons");
+ }
+ return Ref<Texture>();
+}
+
+RES TextEditor::get_edited_resource() const {
+ return text_file;
+}
+
+void TextEditor::set_edited_resource(const RES &p_res) {
+ ERR_FAIL_COND(!text_file.is_null());
+
+ text_file = p_res;
+
+ code_editor->get_text_edit()->set_text(text_file->get_text());
+ code_editor->get_text_edit()->clear_undo_history();
+ code_editor->get_text_edit()->tag_saved_version();
+
+ emit_signal("name_changed");
+ code_editor->update_line_and_column();
+}
+
+void TextEditor::add_callback(const String &p_function, PoolStringArray p_args) {
+}
+
+void TextEditor::set_debugger_active(bool p_active) {
+}
+
+void TextEditor::get_breakpoints(List<int> *p_breakpoints) {
+}
+
+void TextEditor::reload_text() {
+
+ ERR_FAIL_COND(text_file.is_null());
+
+ TextEdit *te = code_editor->get_text_edit();
+ int column = te->cursor_get_column();
+ int row = te->cursor_get_line();
+ int h = te->get_h_scroll();
+ int v = te->get_v_scroll();
+
+ te->set_text(text_file->get_text());
+ te->clear_undo_history();
+ te->cursor_set_line(row);
+ te->cursor_set_column(column);
+ te->set_h_scroll(h);
+ te->set_v_scroll(v);
+
+ te->tag_saved_version();
+
+ code_editor->update_line_and_column();
+}
+
+void TextEditor::_validate_script() {
+ emit_signal("name_changed");
+ emit_signal("edited_script_changed");
+}
+
+void TextEditor::apply_code() {
+ text_file->set_text(code_editor->get_text_edit()->get_text());
+}
+
+bool TextEditor::is_unsaved() {
+
+ return code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version();
+}
+
+Variant TextEditor::get_edit_state() {
+
+ return code_editor->get_edit_state();
+}
+
+void TextEditor::set_edit_state(const Variant &p_state) {
+
+ code_editor->set_edit_state(p_state);
+}
+
+void TextEditor::trim_trailing_whitespace() {
+
+ code_editor->trim_trailing_whitespace();
+}
+
+void TextEditor::convert_indent_to_spaces() {
+
+ code_editor->convert_indent_to_spaces();
+}
+
+void TextEditor::convert_indent_to_tabs() {
+
+ code_editor->convert_indent_to_tabs();
+}
+
+void TextEditor::tag_saved_version() {
+
+ code_editor->get_text_edit()->tag_saved_version();
+}
+
+void TextEditor::goto_line(int p_line, bool p_with_error) {
+
+ code_editor->goto_line(p_line);
+}
+
+void TextEditor::ensure_focus() {
+
+ code_editor->get_text_edit()->grab_focus();
+}
+
+Vector<String> TextEditor::get_functions() {
+
+ return Vector<String>();
+}
+
+bool TextEditor::show_members_overview() {
+ return true;
+}
+
+void TextEditor::update_settings() {
+
+ code_editor->update_editor_settings();
+}
+
+void TextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
+
+ code_editor->get_text_edit()->set_tooltip_request_func(p_obj, p_method, this);
+}
+
+Control *TextEditor::get_edit_menu() {
+
+ return edit_hb;
+}
+
+void TextEditor::clear_edit_menu() {
+ memdelete(edit_hb);
+}
+
+void TextEditor::_notification(int p_what) {
+
+ switch (p_what) {
+ case NOTIFICATION_READY:
+ _load_theme_settings();
+ set_syntax_highlighter(NULL);
+ break;
+ }
+}
+
+void TextEditor::_edit_option(int p_op) {
+ TextEdit *tx = code_editor->get_text_edit();
+
+ switch (p_op) {
+ case EDIT_UNDO: {
+
+ tx->undo();
+ tx->call_deferred("grab_focus");
+ } break;
+ case EDIT_REDO: {
+
+ tx->redo();
+ tx->call_deferred("grab_focus");
+ } break;
+ case EDIT_CUT: {
+
+ tx->cut();
+ tx->call_deferred("grab_focus");
+ } break;
+ case EDIT_COPY: {
+
+ tx->copy();
+ tx->call_deferred("grab_focus");
+ } break;
+ case EDIT_PASTE: {
+
+ tx->paste();
+ tx->call_deferred("grab_focus");
+ } break;
+ case EDIT_SELECT_ALL: {
+
+ tx->select_all();
+ tx->call_deferred("grab_focus");
+ } break;
+ case EDIT_MOVE_LINE_UP: {
+
+ code_editor->move_lines_up();
+ } break;
+ case EDIT_MOVE_LINE_DOWN: {
+
+ code_editor->move_lines_down();
+ } break;
+ case EDIT_INDENT_LEFT: {
+
+ tx->indent_left();
+ } break;
+ case EDIT_INDENT_RIGHT: {
+
+ tx->indent_right();
+ } break;
+ case EDIT_DELETE_LINE: {
+
+ code_editor->delete_lines();
+ } break;
+ case EDIT_CLONE_DOWN: {
+
+ code_editor->code_lines_down();
+ } break;
+ case EDIT_TOGGLE_FOLD_LINE: {
+
+ tx->toggle_fold_line(tx->cursor_get_line());
+ tx->update();
+ } break;
+ case EDIT_FOLD_ALL_LINES: {
+
+ tx->fold_all_lines();
+ tx->update();
+ } break;
+ case EDIT_UNFOLD_ALL_LINES: {
+
+ tx->unhide_all_lines();
+ tx->update();
+ } break;
+ case EDIT_TRIM_TRAILING_WHITESAPCE: {
+
+ trim_trailing_whitespace();
+ } break;
+ case EDIT_CONVERT_INDENT_TO_SPACES: {
+
+ convert_indent_to_spaces();
+ } break;
+ case EDIT_CONVERT_INDENT_TO_TABS: {
+
+ convert_indent_to_tabs();
+ } break;
+ case EDIT_TO_UPPERCASE: {
+
+ _convert_case(CodeTextEditor::UPPER);
+ } break;
+ case EDIT_TO_LOWERCASE: {
+
+ _convert_case(CodeTextEditor::LOWER);
+ } break;
+ case EDIT_CAPITALIZE: {
+
+ _convert_case(CodeTextEditor::CAPITALIZE);
+ } break;
+ case SEARCH_FIND: {
+
+ code_editor->get_find_replace_bar()->popup_search();
+ } break;
+ case SEARCH_FIND_NEXT: {
+
+ code_editor->get_find_replace_bar()->search_next();
+ } break;
+ case SEARCH_FIND_PREV: {
+
+ code_editor->get_find_replace_bar()->search_prev();
+ } break;
+ case SEARCH_REPLACE: {
+
+ code_editor->get_find_replace_bar()->popup_replace();
+ } break;
+ case SEARCH_GOTO_LINE: {
+
+ goto_line_dialog->popup_find_line(tx);
+ } break;
+ }
+}
+
+void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
+
+ code_editor->convert_case(p_case);
+}
+
+void TextEditor::_bind_methods() {
+
+ ClassDB::bind_method("_validate_script", &TextEditor::_validate_script);
+ ClassDB::bind_method("_load_theme_settings", &TextEditor::_load_theme_settings);
+ ClassDB::bind_method("_edit_option", &TextEditor::_edit_option);
+ ClassDB::bind_method("_change_syntax_highlighter", &TextEditor::_change_syntax_highlighter);
+ ClassDB::bind_method("_text_edit_gui_input", &TextEditor::_text_edit_gui_input);
+}
+
+static ScriptEditorBase *create_editor(const RES &p_resource) {
+
+ if (Object::cast_to<TextFile>(*p_resource)) {
+ return memnew(TextEditor);
+ }
+ return NULL;
+}
+
+void TextEditor::register_editor() {
+
+ ScriptEditor::register_create_script_editor_function(create_editor);
+}
+
+void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
+
+ Ref<InputEventMouseButton> mb = ev;
+
+ if (mb.is_valid()) {
+ if (mb->get_button_index() == BUTTON_RIGHT) {
+
+ int col, row;
+ TextEdit *tx = code_editor->get_text_edit();
+ tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
+
+ tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
+ bool can_fold = tx->can_fold(row);
+ bool is_folded = tx->is_folded(row);
+
+ if (tx->is_right_click_moving_caret()) {
+ if (tx->is_selection_active()) {
+
+ int from_line = tx->get_selection_from_line();
+ int to_line = tx->get_selection_to_line();
+ int from_column = tx->get_selection_from_column();
+ int to_column = tx->get_selection_to_column();
+
+ if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
+ // Right click is outside the seleted text
+ tx->deselect();
+ }
+ }
+ if (!tx->is_selection_active()) {
+ tx->cursor_set_line(row, true, false);
+ tx->cursor_set_column(col);
+ }
+ }
+
+ if (!mb->is_pressed()) {
+ _make_context_menu(tx->is_selection_active(), can_fold, is_folded);
+ }
+ }
+ }
+}
+
+void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded) {
+
+ context_menu->clear();
+ if (p_selection) {
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
+ }
+
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
+
+ if (p_selection) {
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
+ }
+ if (p_can_fold || p_is_folded)
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
+
+ context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ context_menu->set_size(Vector2(1, 1));
+ context_menu->popup();
+}
+
+TextEditor::TextEditor() {
+ code_editor = memnew(CodeTextEditor);
+ add_child(code_editor);
+ code_editor->add_constant_override("separation", 0);
+ code_editor->connect("load_theme_settings", this, "_load_theme_settings");
+ code_editor->connect("validate_script", this, "_validate_script");
+ code_editor->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ code_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
+ update_settings();
+
+ code_editor->get_text_edit()->set_context_menu_enabled(false);
+ code_editor->get_text_edit()->connect("gui_input", this, "_text_edit_gui_input");
+
+ context_menu = memnew(PopupMenu);
+ add_child(context_menu);
+ context_menu->connect("id_pressed", this, "_edit_option");
+
+ edit_hb = memnew(HBoxContainer);
+
+ search_menu = memnew(MenuButton);
+ edit_hb->add_child(search_menu);
+ search_menu->set_text(TTR("Search"));
+ search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
+ search_menu->get_popup()->add_separator();
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+
+ goto_line_dialog = memnew(GotoLineDialog);
+ add_child(goto_line_dialog);
+
+ edit_menu = memnew(MenuButton);
+ edit_menu->set_text(TTR("Edit"));
+ edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ edit_hb->add_child(edit_menu);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ edit_menu->get_popup()->add_separator();
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ edit_menu->get_popup()->add_separator();
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
+ edit_menu->get_popup()->add_separator();
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES);
+ edit_menu->get_popup()->add_separator();
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
+
+ edit_menu->get_popup()->add_separator();
+ PopupMenu *convert_case = memnew(PopupMenu);
+ convert_case->set_name("convert_case");
+ edit_menu->get_popup()->add_child(convert_case);
+ edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case");
+ convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase")), EDIT_TO_UPPERCASE);
+ convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase")), EDIT_TO_LOWERCASE);
+ convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize")), EDIT_CAPITALIZE);
+ convert_case->connect("id_pressed", this, "_edit_option");
+
+ highlighters["Standard"] = NULL;
+ highlighter_menu = memnew(PopupMenu);
+ highlighter_menu->set_name("highlighter_menu");
+ edit_menu->get_popup()->add_child(highlighter_menu);
+ edit_menu->get_popup()->add_submenu_item(TTR("Syntax Highlighter"), "highlighter_menu");
+ highlighter_menu->add_radio_check_item(TTR("Standard"));
+ highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
+
+ code_editor->get_text_edit()->set_drag_forwarding(this);
+}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
new file mode 100644
index 0000000000..8b1983d891
--- /dev/null
+++ b/editor/plugins/text_editor.h
@@ -0,0 +1,146 @@
+/*************************************************************************/
+/* text_editor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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_EDITOR_H
+#define TEXT_EDITOR_H
+
+#include "script_editor_plugin.h"
+
+class TextEditor : public ScriptEditorBase {
+
+ GDCLASS(TextEditor, ScriptEditorBase)
+
+private:
+ CodeTextEditor *code_editor;
+
+ Ref<TextFile> text_file;
+
+ HBoxContainer *edit_hb;
+ MenuButton *edit_menu;
+ PopupMenu *highlighter_menu;
+ MenuButton *search_menu;
+ PopupMenu *context_menu;
+
+ GotoLineDialog *goto_line_dialog;
+
+ struct ColorsCache {
+ Color font_color;
+ Color symbol_color;
+ Color keyword_color;
+ Color basetype_color;
+ Color type_color;
+ Color comment_color;
+ Color string_color;
+ } colors_cache;
+
+ enum {
+ EDIT_UNDO,
+ EDIT_REDO,
+ EDIT_CUT,
+ EDIT_COPY,
+ EDIT_PASTE,
+ EDIT_SELECT_ALL,
+ EDIT_TRIM_TRAILING_WHITESAPCE,
+ EDIT_CONVERT_INDENT_TO_SPACES,
+ EDIT_CONVERT_INDENT_TO_TABS,
+ EDIT_MOVE_LINE_UP,
+ EDIT_MOVE_LINE_DOWN,
+ EDIT_INDENT_RIGHT,
+ EDIT_INDENT_LEFT,
+ EDIT_DELETE_LINE,
+ EDIT_CLONE_DOWN,
+ EDIT_TO_UPPERCASE,
+ EDIT_TO_LOWERCASE,
+ EDIT_CAPITALIZE,
+ EDIT_TOGGLE_FOLD_LINE,
+ EDIT_FOLD_ALL_LINES,
+ EDIT_UNFOLD_ALL_LINES,
+ SEARCH_FIND,
+ SEARCH_FIND_NEXT,
+ SEARCH_FIND_PREV,
+ SEARCH_REPLACE,
+ SEARCH_GOTO_LINE,
+ };
+
+protected:
+ static void _bind_methods();
+
+ void _notification(int p_what);
+
+ void _edit_option(int p_op);
+ void _make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded);
+ void _text_edit_gui_input(const Ref<InputEvent> &ev);
+
+ Map<String, SyntaxHighlighter *> highlighters;
+ void _change_syntax_highlighter(int p_idx);
+ void _load_theme_settings();
+
+ void _convert_case(CodeTextEditor::CaseStyle p_case);
+
+ void _validate_script();
+
+public:
+ virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter);
+ virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
+
+ virtual String get_name();
+ virtual Ref<Texture> get_icon();
+ virtual RES get_edited_resource() const;
+ virtual void set_edited_resource(const RES &p_res);
+ void set_edited_file(const Ref<TextFile> &p_file);
+ virtual void reload_text();
+ virtual void apply_code();
+ virtual bool is_unsaved();
+ virtual Variant get_edit_state();
+ virtual void set_edit_state(const Variant &p_state);
+ virtual Vector<String> get_functions();
+ virtual void get_breakpoints(List<int> *p_breakpoints);
+ virtual void goto_line(int p_line, bool p_with_error = false);
+ virtual void trim_trailing_whitespace();
+ virtual void convert_indent_to_spaces();
+ virtual void convert_indent_to_tabs();
+ virtual void ensure_focus();
+ virtual void tag_saved_version();
+ virtual void update_settings();
+ virtual bool show_members_overview();
+ virtual bool can_lose_focus_on_node_selection() { return true; }
+ virtual void set_debugger_active(bool p_active);
+ virtual void set_tooltip_request_func(String p_method, Object *p_obj);
+ virtual void add_callback(const String &p_function, PoolStringArray p_args);
+
+ virtual Control *get_edit_menu();
+ virtual void clear_edit_menu();
+
+ static void register_editor();
+
+ TextEditor();
+};
+
+#endif // TEXT_EDITOR_H
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 19646f37b5..435ef229c5 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -196,7 +196,7 @@ Vector<int> TileMapEditor::get_selected_tiles() const {
}
for (int i = items.size() - 1; i >= 0; i--) {
- items[i] = palette->get_item_metadata(items[i]);
+ items.write[i] = palette->get_item_metadata(items[i]);
}
return items;
}
@@ -526,7 +526,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
if (!erase) {
ids = get_selected_tiles();
- if (ids.size() == 0 && ids[0] == TileMap::INVALID_CELL)
+ if (ids.size() == 0 || ids[0] == TileMap::INVALID_CELL)
return PoolVector<Vector2>();
} else if (prev_id == TileMap::INVALID_CELL) {
return PoolVector<Vector2>();
@@ -538,9 +538,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
}
}
- Rect2i r = node->_edit_get_rect();
- r.position = r.position / node->get_cell_size();
- r.size = r.size / node->get_cell_size();
+ Rect2i r = node->get_used_rect();
int area = r.get_area();
if (preview) {
@@ -985,7 +983,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
ids.push_back(0);
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- ids[0] = E->get().cell;
+ ids.write[0] = E->get().cell;
_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
_finish_undo();
@@ -1008,7 +1006,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- ids[0] = E->get().cell;
+ ids.write[0] = E->get().cell;
_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
_finish_undo();
@@ -1029,7 +1027,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (points.size() == 0)
return false;
- undo_redo->create_action(TTR("Bucket Fill"));
+ _start_undo(TTR("Bucket Fill"));
Dictionary op;
op["id"] = get_selected_tiles();
@@ -1039,7 +1037,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
_fill_points(points, op);
- undo_redo->commit_action();
+ _finish_undo();
// We want to keep the bucket-tool active
return true;
@@ -1230,7 +1228,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- tmp_cell[0] = E->get().idx;
+ tmp_cell.write[0] = E->get().idx;
_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
}
@@ -1267,7 +1265,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- tmp_cell[0] = E->get().idx;
+ tmp_cell.write[0] = E->get().idx;
_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
}
@@ -1752,7 +1750,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
bucket_cache_visited = 0;
invalid_cell.resize(1);
- invalid_cell[0] = TileMap::INVALID_CELL;
+ invalid_cell.write[0] = TileMap::INVALID_CELL;
ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE);
ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index b9b8b07a2e..9218fed907 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -190,7 +190,7 @@ void VisualShaderEditor::_update_graph() {
}
for (int i = 0; i < plugins.size(); i++) {
- custom_editor = plugins[i]->create_editor(vsnode);
+ custom_editor = plugins.write[i]->create_editor(vsnode);
if (custom_editor) {
break;
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 0d06b71420..95d39953cf 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -72,16 +72,26 @@ private:
MESSAGE_SUCCESS
};
+ enum InputType {
+ PROJECT_PATH,
+ INSTALL_PATH
+ };
+
Mode mode;
Button *browse;
+ Button *install_browse;
Button *create_dir;
Container *name_container;
Container *path_container;
+ Container *install_path_container;
Label *msg;
LineEdit *project_path;
LineEdit *project_name;
+ LineEdit *install_path;
TextureRect *status_rect;
+ TextureRect *install_status_rect;
FileDialog *fdialog;
+ FileDialog *fdialog_install;
String zip_path;
String zip_title;
AcceptDialog *dialog_error;
@@ -89,10 +99,11 @@ private:
String created_folder_path;
- void set_message(const String &p_msg, MessageType p_type = MESSAGE_SUCCESS) {
+ void set_message(const String &p_msg, MessageType p_type = MESSAGE_SUCCESS, InputType input_type = PROJECT_PATH) {
msg->set_text(p_msg);
- Ref<Texture> current_icon = status_rect->get_texture();
+ Ref<Texture> current_path_icon = status_rect->get_texture();
+ Ref<Texture> current_install_icon = install_status_rect->get_texture();
Ref<Texture> new_icon;
switch (p_type) {
@@ -119,8 +130,11 @@ private:
} break;
}
- if (current_icon != new_icon)
+ if (current_path_icon != new_icon && input_type == PROJECT_PATH) {
status_rect->set_texture(new_icon);
+ } else if (current_install_icon != new_icon && input_type == INSTALL_PATH) {
+ install_status_rect->set_texture(new_icon);
+ }
set_size(Size2(500, 0) * EDSCALE);
}
@@ -128,11 +142,19 @@ private:
String _test_path() {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- String valid_path;
+ String valid_path, valid_install_path;
if (d->change_dir(project_path->get_text()) == OK) {
valid_path = project_path->get_text();
} else if (d->change_dir(project_path->get_text().strip_edges()) == OK) {
valid_path = project_path->get_text().strip_edges();
+ } else if (project_path->get_text().ends_with(".zip")) {
+ if (d->file_exists(project_path->get_text())) {
+ valid_path = project_path->get_text();
+ }
+ } else if (project_path->get_text().strip_edges().ends_with(".zip")) {
+ if (d->file_exists(project_path->get_text().strip_edges())) {
+ valid_path = project_path->get_text().strip_edges();
+ }
}
if (valid_path == "") {
@@ -142,11 +164,94 @@ private:
return "";
}
+ if (mode == MODE_IMPORT && valid_path.ends_with(".zip")) {
+ if (d->change_dir(install_path->get_text()) == OK) {
+ valid_install_path = install_path->get_text();
+ } else if (d->change_dir(install_path->get_text().strip_edges()) == OK) {
+ valid_install_path = install_path->get_text().strip_edges();
+ }
+
+ if (valid_install_path == "") {
+ set_message(TTR("The path does not exist."), MESSAGE_ERROR, INSTALL_PATH);
+ memdelete(d);
+ get_ok()->set_disabled(true);
+ return "";
+ }
+ }
+
if (mode == MODE_IMPORT || mode == MODE_RENAME) {
if (valid_path != "" && !d->file_exists("project.godot")) {
- set_message(TTR("Please choose a 'project.godot' file."), MESSAGE_ERROR);
+ if (valid_path.ends_with(".zip")) {
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ unzFile pkg = unzOpen2(valid_path.utf8().get_data(), &io);
+ if (!pkg) {
+
+ set_message(TTR("Error opening package file, not in zip format."), MESSAGE_ERROR);
+ memdelete(d);
+ get_ok()->set_disabled(true);
+ unzClose(pkg);
+ return "";
+ }
+
+ int ret = unzGoToFirstFile(pkg);
+ while (ret == UNZ_OK) {
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
+
+ if (String(fname).ends_with("project.godot")) {
+ break;
+ }
+
+ ret = unzGoToNextFile(pkg);
+ }
+
+ if (ret == UNZ_END_OF_LIST_OF_FILE) {
+ set_message(TTR("Invalid '.zip' project file, does not contain a 'project.godot' file."), MESSAGE_ERROR);
+ memdelete(d);
+ get_ok()->set_disabled(true);
+ unzClose(pkg);
+ return "";
+ }
+
+ unzClose(pkg);
+
+ // check if the specified install folder is empty, even though this is not an error, it is good to check here
+ d->list_dir_begin();
+ bool is_empty = true;
+ String n = d->get_next();
+ while (n != String()) {
+ if (n != "." && n != "..") {
+ is_empty = false;
+ break;
+ }
+ n = d->get_next();
+ }
+ d->list_dir_end();
+
+ if (!is_empty) {
+
+ set_message(TTR("Please choose an empty folder."), MESSAGE_WARNING, INSTALL_PATH);
+ memdelete(d);
+ get_ok()->set_disabled(true);
+ return "";
+ }
+
+ } else {
+ set_message(TTR("Please choose a 'project.godot' or '.zip' file."), MESSAGE_ERROR);
+ memdelete(d);
+ install_path_container->hide();
+ get_ok()->set_disabled(true);
+ return "";
+ }
+
+ } else if (valid_path.ends_with("zip")) {
+
+ set_message(TTR("Directory already contains a Godot project."), MESSAGE_ERROR, INSTALL_PATH);
memdelete(d);
get_ok()->set_disabled(true);
return "";
@@ -159,7 +264,7 @@ private:
bool is_empty = true;
String n = d->get_next();
while (n != String()) {
- if (!n.begins_with(".")) { // i don't know if this is enough to guarantee an empty dir
+ if (n != "." && n != "..") { // i don't know if this is enough to guarantee an empty dir
is_empty = false;
break;
}
@@ -177,6 +282,7 @@ private:
}
set_message("");
+ set_message("", MESSAGE_SUCCESS, INSTALL_PATH);
memdelete(d);
get_ok()->set_disabled(false);
return valid_path;
@@ -214,9 +320,14 @@ private:
if (mode == MODE_IMPORT) {
if (p.ends_with("project.godot")) {
p = p.get_base_dir();
+ install_path_container->hide();
+ get_ok()->set_disabled(false);
+ } else if (p.ends_with(".zip")) {
+ install_path->set_text(p.get_base_dir());
+ install_path_container->show();
get_ok()->set_disabled(false);
} else {
- set_message(TTR("Please choose a 'project.godot' file."), MESSAGE_ERROR);
+ set_message(TTR("Please choose a 'project.godot' or '.zip' file."), MESSAGE_ERROR);
get_ok()->set_disabled(true);
return;
}
@@ -224,7 +335,11 @@ private:
String sp = p.simplify_path();
project_path->set_text(sp);
_path_text_changed(sp);
- get_ok()->call_deferred("grab_focus");
+ if (p.ends_with(".zip")) {
+ install_path->call_deferred("grab_focus");
+ } else {
+ get_ok()->call_deferred("grab_focus");
+ }
}
void _path_selected(const String &p_path) {
@@ -236,6 +351,14 @@ private:
get_ok()->call_deferred("grab_focus");
}
+ void _install_path_selected(const String &p_path) {
+ String p = p_path;
+ String sp = p.simplify_path();
+ install_path->set_text(sp);
+ _path_text_changed(sp);
+ get_ok()->call_deferred("grab_focus");
+ }
+
void _browse_path() {
fdialog->set_current_dir(project_path->get_text());
@@ -245,12 +368,19 @@ private:
fdialog->set_mode(FileDialog::MODE_OPEN_FILE);
fdialog->clear_filters();
fdialog->add_filter("project.godot ; " VERSION_NAME " Project");
+ fdialog->add_filter("*.zip ; Zip File");
} else {
fdialog->set_mode(FileDialog::MODE_OPEN_DIR);
}
fdialog->popup_centered_ratio();
}
+ void _browse_install_path() {
+ fdialog_install->set_current_dir(install_path->get_text());
+ fdialog_install->set_mode(FileDialog::MODE_OPEN_DIR);
+ fdialog_install->popup_centered_ratio();
+ }
+
void _create_folder() {
if (project_name->get_text() == "" || created_folder_path != "" || project_name->get_text().ends_with(".") || project_name->get_text().ends_with(" ")) {
@@ -328,7 +458,15 @@ private:
} else {
if (mode == MODE_IMPORT) {
- // nothing to do
+
+ if (project_path->get_text().ends_with(".zip")) {
+
+ mode = MODE_INSTALL;
+ ok_pressed();
+
+ return;
+ }
+
} else {
if (mode == MODE_NEW) {
@@ -357,6 +495,11 @@ private:
} else if (mode == MODE_INSTALL) {
+ if (project_path->get_text().ends_with(".zip")) {
+ dir = install_path->get_text();
+ zip_path = project_path->get_text();
+ }
+
FileAccess *src_f = NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -444,7 +587,7 @@ private:
dialog_error->set_text(msg);
dialog_error->popup_centered_minsize();
- } else {
+ } else if (!project_path->get_text().ends_with(".zip")) {
dialog_error->set_text(TTR("Package Installed Successfully!"));
dialog_error->popup_centered_minsize();
}
@@ -486,6 +629,9 @@ private:
if (status_rect->get_texture() == get_icon("StatusError", "EditorIcons"))
msg->show();
+
+ if (install_status_rect->get_texture() == get_icon("StatusError", "EditorIcons"))
+ msg->show();
}
void _notification(int p_what) {
@@ -503,6 +649,8 @@ protected:
ClassDB::bind_method("_path_text_changed", &ProjectDialog::_path_text_changed);
ClassDB::bind_method("_path_selected", &ProjectDialog::_path_selected);
ClassDB::bind_method("_file_selected", &ProjectDialog::_file_selected);
+ ClassDB::bind_method("_install_path_selected", &ProjectDialog::_install_path_selected);
+ ClassDB::bind_method("_browse_install_path", &ProjectDialog::_browse_install_path);
ADD_SIGNAL(MethodInfo("project_created"));
ADD_SIGNAL(MethodInfo("project_renamed"));
}
@@ -530,12 +678,15 @@ public:
project_path->set_editable(false);
browse->hide();
+ install_browse->hide();
set_title(TTR("Rename Project"));
get_ok()->set_text(TTR("Rename"));
name_container->show();
status_rect->hide();
msg->hide();
+ install_path_container->hide();
+ install_status_rect->hide();
get_ok()->set_disabled(false);
ProjectSettings *current = memnew(ProjectSettings);
@@ -575,14 +726,18 @@ public:
project_path->set_editable(true);
browse->set_disabled(false);
browse->show();
+ install_browse->set_disabled(false);
+ install_browse->show();
create_dir->show();
status_rect->show();
+ install_status_rect->show();
msg->show();
if (mode == MODE_IMPORT) {
set_title(TTR("Import Existing Project"));
get_ok()->set_text(TTR("Import & Edit"));
name_container->hide();
+ install_path_container->hide();
project_path->grab_focus();
} else if (mode == MODE_NEW) {
@@ -590,6 +745,7 @@ public:
set_title(TTR("Create New Project"));
get_ok()->set_text(TTR("Create & Edit"));
name_container->show();
+ install_path_container->hide();
project_name->grab_focus();
} else if (mode == MODE_INSTALL) {
@@ -597,6 +753,7 @@ public:
set_title(TTR("Install Project:") + " " + zip_title);
get_ok()->set_text(TTR("Install & Edit"));
name_container->hide();
+ install_path_container->hide();
project_path->grab_focus();
}
@@ -644,6 +801,20 @@ public:
project_path->set_h_size_flags(SIZE_EXPAND_FILL);
pphb->add_child(project_path);
+ install_path_container = memnew(VBoxContainer);
+ vb->add_child(install_path_container);
+
+ l = memnew(Label);
+ l->set_text(TTR("Project Installation Path:"));
+ install_path_container->add_child(l);
+
+ HBoxContainer *iphb = memnew(HBoxContainer);
+ install_path_container->add_child(iphb);
+
+ install_path = memnew(LineEdit);
+ install_path->set_h_size_flags(SIZE_EXPAND_FILL);
+ iphb->add_child(install_path);
+
// status icon
status_rect = memnew(TextureRect);
status_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
@@ -654,17 +825,33 @@ public:
browse->connect("pressed", this, "_browse_path");
pphb->add_child(browse);
+ // install status icon
+ install_status_rect = memnew(TextureRect);
+ install_status_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
+ iphb->add_child(install_status_rect);
+
+ install_browse = memnew(Button);
+ install_browse->set_text(TTR("Browse"));
+ install_browse->connect("pressed", this, "_browse_install_path");
+ iphb->add_child(install_browse);
+
msg = memnew(Label);
msg->set_align(Label::ALIGN_CENTER);
vb->add_child(msg);
fdialog = memnew(FileDialog);
fdialog->set_access(FileDialog::ACCESS_FILESYSTEM);
+ fdialog_install = memnew(FileDialog);
+ fdialog_install->set_access(FileDialog::ACCESS_FILESYSTEM);
add_child(fdialog);
+ add_child(fdialog_install);
project_name->connect("text_changed", this, "_text_changed");
project_path->connect("text_changed", this, "_path_text_changed");
+ install_path->connect("text_changed", this, "_path_text_changed");
fdialog->connect("dir_selected", this, "_path_selected");
fdialog->connect("file_selected", this, "_file_selected");
+ fdialog_install->connect("dir_selected", this, "_install_path_selected");
+ fdialog_install->connect("file_selected", this, "_install_path_selected");
set_hide_on_ok(false);
mode = MODE_NEW;
@@ -1594,8 +1781,8 @@ ProjectManager::ProjectManager() {
vb->add_constant_override("separation", 15 * EDSCALE);
String cp;
- cp.push_back(0xA9);
- cp.push_back(0);
+ cp += 0xA9;
+ cp += '0';
OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2018 Juan Linietsky, Ariel Manzur & Godot Contributors");
HBoxContainer *top_hb = memnew(HBoxContainer);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index e6ae2d64e7..2b2e03ce38 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -1462,7 +1462,7 @@ void ProjectSettingsEditor::_update_translations() {
t->set_editable(0, true);
t->set_tooltip(0, l);
t->set_checked(0, l_filter.has(l));
- translation_filter_treeitems[i] = t;
+ translation_filter_treeitems.write[i] = t;
}
} else {
for (int i = 0; i < s; i++) {
@@ -1502,7 +1502,7 @@ void ProjectSettingsEditor::_update_translations() {
if (langnames.length() > 0)
langnames += ",";
langnames += names[i];
- translation_locales_idxs_remap[l_idx] = i;
+ translation_locales_idxs_remap.write[l_idx] = i;
l_idx++;
}
}
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 7f46844f6c..b370a711e3 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -90,7 +90,7 @@ bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) co
return false;
}
-Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) {
+Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const {
if (get_script_instance())
return get_script_instance()->call("_convert", p_resource);
@@ -4394,7 +4394,7 @@ PropertyEditor::PropertyEditor() {
use_filter = false;
subsection_selectable = false;
property_selectable = false;
- show_type_icons = EDITOR_DEF("interface/editor/show_type_icons", false);
+ show_type_icons = false; // TODO: need to reimplement it to work with the new inspector
}
PropertyEditor::~PropertyEditor() {
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 56743822d2..7d8fa22f3f 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -64,7 +64,7 @@ protected:
public:
virtual String converts_to() const;
virtual bool handles(const Ref<Resource> &p_resource) const;
- virtual Ref<Resource> convert(const Ref<Resource> &p_resource);
+ virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
};
class CustomPropertyEditor : public Popup {
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 26dd931321..907bb50f7e 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -195,7 +195,7 @@ Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<Strin
Vector<float> scores;
scores.resize(list.size());
for (int i = 0; i < list.size(); i++)
- scores[i] = _path_cmp(search_text, list[i].first);
+ scores.write[i] = _path_cmp(search_text, list[i].first);
while (list.size() > 0) {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 2ffaa0ca12..73a9c8ac1a 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -349,21 +349,33 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
Ref<Script> existing = selected->get_script();
- if (existing.is_valid())
- editor->push_item(existing.ptr());
- else {
- String path = selected->get_filename();
- if (path == "") {
- String root_path = editor_data->get_edited_scene_root()->get_filename();
- if (root_path == "") {
- path = "res://" + selected->get_name();
- } else {
- path = root_path.get_base_dir() + "/" + selected->get_name();
+
+ String path = selected->get_filename();
+ if (path == "") {
+ String root_path = editor_data->get_edited_scene_root()->get_filename();
+ if (root_path == "") {
+ path = "res://" + selected->get_name();
+ } else {
+ path = root_path.get_base_dir() + "/" + selected->get_name();
+ }
+ }
+
+ String inherits = selected->get_class();
+ if (existing.is_valid()) {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptLanguage *l = ScriptServer::get_language(i);
+ if (l->get_type() == existing->get_class()) {
+ if (EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
+ String name = l->get_global_class_name(existing->get_path(), NULL);
+ inherits = editor->get_editor_data().script_class_get_base(name);
+ } else if (l->can_inherit_from_file()) {
+ inherits = "\"" + existing->get_path() + "\"";
+ }
}
}
- script_create_dialog->config(selected->get_class(), path);
- script_create_dialog->popup_centered();
}
+ script_create_dialog->config(inherits, path);
+ script_create_dialog->popup_centered();
} break;
case TOOL_CLEAR_SCRIPT: {
@@ -724,7 +736,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
} break;
- case TOOL_SCENE_CLEAR_INSTANCING: {
+ case TOOL_SCENE_MAKE_LOCAL: {
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
if (e) {
@@ -736,7 +748,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
ERR_FAIL_COND(node->get_filename() == String());
- undo_redo->create_action(TTR("Discard Instancing"));
+ undo_redo->create_action(TTR("Make Local"));
undo_redo->add_do_method(node, "set_filename", "");
undo_redo->add_undo_method(node, "set_filename", node->get_filename());
_node_replace_owner(node, node, root);
@@ -791,7 +803,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
switch (p_tool) {
case TOOL_CREATE_2D_SCENE: new_node = memnew(Node2D); break;
case TOOL_CREATE_3D_SCENE: new_node = memnew(Spatial); break;
- case TOOL_CREATE_USER_INTERFACE: new_node = memnew(Control); break;
+ case TOOL_CREATE_USER_INTERFACE: {
+ Control *node = memnew(Control);
+ node->set_anchors_and_margins_preset(PRESET_WIDE); //more useful for resizable UIs.
+ new_node = node;
+
+ } break;
}
editor_data->get_undo_redo().create_action("New Scene Root");
@@ -1426,13 +1443,9 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
}
- editor_data->get_undo_redo().add_do_method(editor, "push_item", p_script.operator->());
- editor_data->get_undo_redo().add_undo_method(editor, "push_item", (Script *)NULL);
-
- editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
- editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
-
editor_data->get_undo_redo().commit_action();
+
+ editor->push_item(p_script.operator->());
}
void SceneTreeDock::_delete_confirm() {
@@ -1521,16 +1534,9 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_update_script_button() {
if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) {
- if (EditorNode::get_singleton()->get_editor_selection()->get_selection().front()->key()->get_script().is_null()) {
- button_create_script->show();
- button_clear_script->hide();
- } else {
- button_create_script->hide();
- button_clear_script->show();
- }
+ button_create_script->show();
} else {
button_create_script->hide();
- button_clear_script->hide();
}
}
@@ -1984,6 +1990,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (selection.size() == 1) {
+ Node *selected = selection[0];
+
subresources.clear();
menu_subresources->clear();
menu_subresources->set_size(Size2(1, 1));
@@ -1994,18 +2002,23 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
menu->add_separator();
+
menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
- menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ Ref<Script> existing = selected->get_script();
+ if (existing.is_valid()) {
+ menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ }
menu->add_separator();
menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
- menu->add_separator();
- menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
- menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
- menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
- menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
-
+ if (scene_tree->get_selected() != edited_scene) {
+ menu->add_separator();
+ menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
+ menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
+ menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
+ menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
+ }
if (selection.size() == 1) {
menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
@@ -2028,7 +2041,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
bool placeholder = selection[0]->get_scene_instance_load_placeholder();
menu->add_check_item(TTR("Editable Children"), TOOL_SCENE_EDITABLE_CHILDREN);
menu->add_check_item(TTR("Load As Placeholder"), TOOL_SCENE_USE_PLACEHOLDER);
- menu->add_item(TTR("Discard Instancing"), TOOL_SCENE_CLEAR_INSTANCING);
+ menu->add_item(TTR("Make Local"), TOOL_SCENE_MAKE_LOCAL);
menu->add_icon_item(get_icon("Load", "EditorIcons"), TTR("Open in Editor"), TOOL_SCENE_OPEN);
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Editable Children")), editable);
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
@@ -2324,6 +2337,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
menu = memnew(PopupMenu);
add_child(menu);
menu->connect("id_pressed", this, "_tool_selected");
+ menu->set_hide_on_window_lose_focus(true);
menu_subresources = memnew(PopupMenu);
menu_subresources->set_name("Sub-Resources");
menu_subresources->connect("id_pressed", this, "_tool_selected");
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index fd74611bde..57f4759747 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -77,7 +77,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_BUTTON_MAX,
TOOL_SCENE_EDITABLE_CHILDREN,
TOOL_SCENE_USE_PLACEHOLDER,
- TOOL_SCENE_CLEAR_INSTANCING,
+ TOOL_SCENE_MAKE_LOCAL,
TOOL_SCENE_OPEN,
TOOL_SCENE_CLEAR_INHERITANCE,
TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM,
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 9ce0e973f7..e483fde4bc 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -658,7 +658,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
Vector<float> p;
p.resize(arr.size());
for (int i = 0; i < arr.size(); i++) {
- p[i] = arr[i];
+ p.write[i] = arr[i];
if (i < perf_items.size()) {
float v = p[i];
@@ -693,7 +693,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
perf_items[i]->set_text(1, vs);
perf_items[i]->set_tooltip(1, tt);
if (p[i] > perf_max[i])
- perf_max[i] = p[i];
+ perf_max.write[i] = p[i];
}
}
perf_history.push_front(p);
@@ -807,7 +807,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
item.signature = "categ::" + name + "::" + item.name;
item.name = item.name.capitalize();
c.total_time += item.total;
- c.items[i / 2] = item;
+ c.items.write[i / 2] = item;
}
metric.categories.push_back(c);
}
@@ -844,7 +844,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
item.calls = calls;
item.self = self;
item.total = total;
- funcs.items[i] = item;
+ funcs.items.write[i] = item;
}
metric.categories.push_back(funcs);
@@ -1193,7 +1193,7 @@ void ScriptEditorDebugger::start() {
perf_history.clear();
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
- perf_max[i] = 0;
+ perf_max.write[i] = 0;
}
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
@@ -2076,7 +2076,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
it->set_selectable(1, false);
it->set_text(0, name.capitalize());
perf_items.push_back(it);
- perf_max[i] = 0;
+ perf_max.write[i] = 0;
}
}
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index c45dea0df7..9970f434ce 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -33,6 +33,7 @@
#include "geometry.h"
#include "quick_hull.h"
#include "scene/3d/camera.h"
+#include "scene/3d/soft_body.h"
#include "scene/resources/box_shape.h"
#include "scene/resources/capsule_shape.h"
#include "scene/resources/convex_polygon_shape.h"
@@ -228,7 +229,7 @@ void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines)
collision_segments.resize(from + p_lines.size());
for (int i = 0; i < p_lines.size(); i++) {
- collision_segments[from + i] = p_lines[i];
+ collision_segments.write[from + i] = p_lines[i];
}
}
@@ -256,8 +257,12 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
for (int i = 0; i < p_handles.size(); i++) {
Color col(1, 1, 1, 1);
+ if (is_gizmo_handle_highlighted(i))
+ col = Color(0, 0, 1, 0.9);
+
if (SpatialEditor::get_singleton()->get_over_gizmo_handle() != i)
- col = Color(0.9, 0.9, 0.9, 0.9);
+ col.a = 0.8;
+
w[i] = col;
}
}
@@ -291,14 +296,14 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
int chs = handles.size();
handles.resize(chs + p_handles.size());
for (int i = 0; i < p_handles.size(); i++) {
- handles[i + chs] = p_handles[i];
+ handles.write[i + chs] = p_handles[i];
}
} else {
int chs = secondary_handles.size();
secondary_handles.resize(chs + p_handles.size());
for (int i = 0; i < p_handles.size(); i++) {
- secondary_handles[i + chs] = p_handles[i];
+ secondary_handles.write[i + chs] = p_handles[i];
}
}
}
@@ -592,7 +597,7 @@ void EditorSpatialGizmo::create() {
for (int i = 0; i < instances.size(); i++) {
- instances[i].create_instance(spatial_node);
+ instances.write[i].create_instance(spatial_node);
}
transform();
@@ -616,7 +621,7 @@ void EditorSpatialGizmo::free() {
if (instances[i].instance.is_valid())
VS::get_singleton()->free(instances[i].instance);
- instances[i].instance = RID();
+ instances.write[i].instance = RID();
}
valid = false;
@@ -1119,8 +1124,8 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() {
Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
- points[i * 2 + 0] = from;
- points[i * 2 + 1] = to;
+ points.write[i * 2 + 0] = from;
+ points.write[i * 2 + 1] = to;
}
for (int i = 0; i < 4; i++) {
@@ -1129,8 +1134,8 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() {
Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
- points[200 + i * 2 + 0] = from;
- points[200 + i * 2 + 1] = Vector3();
+ points.write[200 + i * 2 + 0] = from;
+ points.write[200 + i * 2 + 1] = Vector3();
}
add_lines(points, material);
@@ -1436,23 +1441,25 @@ void SkeletonSpatialGizmo::redraw() {
weights.resize(4);
for (int i = 0; i < 4; i++) {
- bones[i] = 0;
- weights[i] = 0;
+ bones.write[i] = 0;
+ weights.write[i] = 0;
}
- weights[0] = 1;
+ weights.write[0] = 1;
AABB aabb;
Color bonecolor = Color(1.0, 0.4, 0.4, 0.3);
Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
- for (int i = 0; i < skel->get_bone_count(); i++) {
+ for (int i_bone = 0; i_bone < skel->get_bone_count(); i_bone++) {
+
+ int i = skel->get_process_order(i_bone);
int parent = skel->get_bone_parent(i);
if (parent >= 0) {
- grests[i] = grests[parent] * skel->get_bone_rest(i);
+ grests.write[i] = grests[parent] * skel->get_bone_rest(i);
Vector3 v0 = grests[parent].origin;
Vector3 v1 = grests[i].origin;
@@ -1475,7 +1482,7 @@ void SkeletonSpatialGizmo::redraw() {
int pointidx = 0;
for (int j = 0; j < 3; j++) {
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(rootcolor);
@@ -1503,7 +1510,7 @@ void SkeletonSpatialGizmo::redraw() {
Vector3 point = v0 + d * dist * 0.2;
point += axis * dist * 0.1;
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
@@ -1513,12 +1520,12 @@ void SkeletonSpatialGizmo::redraw() {
surface_tool->add_color(bonecolor);
surface_tool->add_vertex(point);
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
surface_tool->add_vertex(point);
- bones[0] = i;
+ bones.write[0] = i;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
@@ -1530,7 +1537,7 @@ void SkeletonSpatialGizmo::redraw() {
SWAP(points[1], points[2]);
for (int j = 0; j < 4; j++) {
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
@@ -1555,8 +1562,8 @@ void SkeletonSpatialGizmo::redraw() {
*/
} else {
- grests[i] = skel->get_bone_rest(i);
- bones[0] = i;
+ grests.write[i] = skel->get_bone_rest(i);
+ bones.write[0] = i;
}
/*
Transform t = grests[i];
@@ -1914,6 +1921,100 @@ VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel) {
///////////
+void SoftBodySpatialGizmo::redraw() {
+ clear();
+
+ if (!soft_body || soft_body->get_mesh().is_null()) {
+ return;
+ }
+
+ // find mesh
+
+ Vector<Vector3> lines;
+
+ soft_body->get_mesh()->generate_debug_mesh_lines(lines);
+
+ if (!lines.size()) {
+ return;
+ }
+
+ Vector<Vector3> points;
+ soft_body->get_mesh()->generate_debug_mesh_indices(points);
+
+ soft_body->get_mesh()->clear_cache();
+
+ Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
+ Ref<Material> material = create_material("shape_material", gizmo_color);
+
+ add_lines(lines, material);
+ add_collision_segments(lines);
+ add_handles(points);
+}
+
+bool SoftBodySpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
+ return EditorSpatialGizmo::intersect_ray(p_camera, p_point, r_pos, r_normal, r_gizmo_handle, p_sec_first);
+
+ /* Perform a shape cast but doesn't work with softbody
+ PhysicsDirectSpaceState *space_state = PhysicsServer::get_singleton()->space_get_direct_state(SceneTree::get_singleton()->get_root()->get_world()->get_space());
+ if (!physics_sphere_shape.is_valid()) {
+ physics_sphere_shape = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE);
+ real_t radius = 0.02;
+ PhysicsServer::get_singleton()->shape_set_data(physics_sphere_shape, radius);
+ }
+
+ Vector3 sphere_motion(p_camera->project_ray_normal(p_point));
+ real_t closest_safe;
+ real_t closest_unsafe;
+ PhysicsDirectSpaceState::ShapeRestInfo result;
+ bool collided = space_state->cast_motion(
+ physics_sphere_shape,
+ p_camera->get_transform(),
+ sphere_motion * Vector3(1000, 1000, 1000),
+ 0.f,
+ closest_safe,
+ closest_unsafe,
+ Set<RID>(),
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ &result);
+
+ if (collided) {
+
+ if (result.collider_id == soft_body->get_instance_id()) {
+ print_line("Collided");
+ } else {
+ print_line("Collided but with wrong object: " + itos(result.collider_id));
+ }
+ } else {
+ print_line("Not collided, motion: x: " + rtos(sphere_motion[0]) + " y: " + rtos(sphere_motion[1]) + " z: " + rtos(sphere_motion[2]));
+ }
+ return false;
+ */
+}
+
+void SoftBodySpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+ soft_body->pin_point_toggle(p_idx);
+ redraw();
+}
+
+bool SoftBodySpatialGizmo::is_gizmo_handle_highlighted(int idx) const {
+ return soft_body->is_point_pinned(idx);
+}
+
+SoftBodySpatialGizmo::SoftBodySpatialGizmo(SoftBody *p_soft_physics_body) :
+ EditorSpatialGizmo(),
+ soft_body(p_soft_physics_body) {
+ set_spatial_node(p_soft_physics_body);
+}
+
+SoftBodySpatialGizmo::~SoftBodySpatialGizmo() {
+ //if (!physics_sphere_shape.is_valid()) {
+ // PhysicsServer::get_singleton()->free(physics_sphere_shape);
+ //}
+}
+
+///////////
+
String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const {
Ref<Shape> s = cs->get_shape();
@@ -2443,8 +2544,8 @@ void CollisionShapeSpatialGizmo::redraw() {
Vector<Vector3> points;
points.resize(md.edges.size() * 2);
for (int i = 0; i < md.edges.size(); i++) {
- points[i * 2 + 0] = md.vertices[md.edges[i].a];
- points[i * 2 + 1] = md.vertices[md.edges[i].b];
+ points.write[i * 2 + 0] = md.vertices[md.edges[i].a];
+ points.write[i * 2 + 1] = md.vertices[md.edges[i].b];
}
add_lines(points, material);
@@ -3272,10 +3373,10 @@ NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p
navmesh = p_navmesh;
}
-//////
-///
-///
-///
+ //////
+ ///
+ ///
+ ///
#define BODY_A_RADIUS 0.25
#define BODY_B_RADIUS 0.27
@@ -4051,6 +4152,12 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
return lsg;
}
+ if (Object::cast_to<SoftBody>(p_spatial)) {
+
+ Ref<SoftBodySpatialGizmo> misg = memnew(SoftBodySpatialGizmo(Object::cast_to<SoftBody>(p_spatial)));
+ return misg;
+ }
+
if (Object::cast_to<MeshInstance>(p_spatial)) {
Ref<MeshInstanceSpatialGizmo> misg = memnew(MeshInstanceSpatialGizmo(Object::cast_to<MeshInstance>(p_spatial)));
@@ -4081,6 +4188,7 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
return misg;
}
*/
+
if (Object::cast_to<CollisionShape>(p_spatial)) {
Ref<CollisionShapeSpatialGizmo> misg = memnew(CollisionShapeSpatialGizmo(Object::cast_to<CollisionShape>(p_spatial)));
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index 924f82dc16..198d028516 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -331,6 +331,23 @@ public:
BakedIndirectLightGizmo(BakedLightmap *p_baker = NULL);
};
+class SoftBodySpatialGizmo : public EditorSpatialGizmo {
+ GDCLASS(SoftBodySpatialGizmo, EditorSpatialGizmo);
+
+ class SoftBody *soft_body;
+ //RID physics_sphere_shape; // Used for raycast that doesn't work, in this moment, with softbody
+
+public:
+ void redraw();
+ virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false);
+ virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel);
+
+ virtual bool is_gizmo_handle_highlighted(int idx) const;
+
+ SoftBodySpatialGizmo(SoftBody *p_soft_physics_body = NULL);
+ ~SoftBodySpatialGizmo();
+};
+
class CollisionShapeSpatialGizmo : public EditorSpatialGizmo {
GDCLASS(CollisionShapeSpatialGizmo, EditorSpatialGizmo);
diff --git a/editor/translations/af.po b/editor/translations/af.po
index c5853bbb2f..d4c8bc26f4 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -7328,6 +7328,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index ccf2b97d9a..1535ccafb6 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Adel <dragonhunter250@gmail.com>, 2018.
# athomield <athomield@hotmail.com>, 2017.
# Basil Al-Khateeb <basil.y.alkhateeb@gmail.com>, 2017.
@@ -15,13 +14,12 @@
# omar anwar aglan <omar.aglan91@yahoo.com>, 2017-2018.
# OWs Tetra <owstetra@gmail.com>, 2017.
# Rached Noureddine <rached.noureddine@gmail.com>, 2018.
-# Rex_sa <asd1234567890m@gmail.com>, 2017.
+# Rex_sa <asd1234567890m@gmail.com>, 2017, 2018.
# Wajdi Feki <wajdi.feki@gmail.com>, 2017.
-#
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-28 18:34+0000\n"
+"PO-Revision-Date: 2018-07-15 19:34+0000\n"
"Last-Translator: Rached Noureddine <rached.noureddine@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
@@ -30,7 +28,7 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -4331,11 +4329,11 @@ msgstr "ولد رؤية AABB"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
-msgstr ""
+msgstr "إزالة نقطة من المنحنى"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Out-Control from Curve"
-msgstr ""
+msgstr "أزل Out-Control من المنحنى"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove In-Control from Curve"
@@ -7392,6 +7390,11 @@ msgstr "بناء المشروع"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "إظهار الملفات"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
@@ -8076,7 +8079,7 @@ msgstr ""
#: scene/resources/dynamic_font.cpp
msgid "Invalid font size."
-msgstr ""
+msgstr "حجم الخط غير صالح"
#~ msgid "Next"
#~ msgstr "التالي"
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 9f366b3d2f..71b9216b46 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -7383,6 +7383,11 @@ msgstr "Проект"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Преглед на файловете"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 3d00e3450c..aa36beefb6 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -7773,6 +7773,11 @@ msgstr "নতুন প্রকল্প"
msgid "Warnings"
msgstr "সতর্কতা"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "ফাইল"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index d2bffb0f84..085241296e 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -7438,6 +7438,11 @@ msgstr "Munta el Projecte"
msgid "Warnings"
msgstr "Avisos"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Visualitza Fitxers"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Final de la traça de la pila d'excepció interna"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 1066bbad94..b4cf176796 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -7372,6 +7372,11 @@ msgstr "Sestavit projekt"
msgid "Warnings"
msgstr "Varování"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Zobrazit soubory"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/da.po b/editor/translations/da.po
index 3b5854334a..fcfdb6d249 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -7445,6 +7445,11 @@ msgstr "Projekt"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vis filer"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/de.po b/editor/translations/de.po
index d5d63f654b..c61d78e37e 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -27,12 +27,15 @@
# Tim Schellenberg <smwleod@gmail.com>, 2017.
# Timo Schwarzer <account@timoschwarzer.com>, 2016-2018.
# viernullvier <hannes.breul+github@gmail.com>, 2016.
+# Arndt Heuvel <codeforpb@schatzkarten.net>, 2018.
+# Gordon <gkone@gmx.net>, 2018.
+# chillhelm <wilhelm@neubert.online>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-19 19:38+0000\n"
-"Last-Translator: nimradium <nimra242001@gmail.com>\n"
+"PO-Revision-Date: 2018-07-05 12:38+0000\n"
+"Last-Translator: So Wieso <sowieso@dukun.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -40,7 +43,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -331,8 +334,7 @@ msgstr "Optimieren"
#: editor/animation_editor.cpp
msgid "Select an AnimationPlayer from the Scene Tree to edit animations."
msgstr ""
-"Wählen Sie einen AnimationPlayer aus dem Szenenbaum aus, um Animationen zu "
-"bearbeiten."
+"AnimationPlayer aus dem Szenenbaum auswählen um Animationen zu bearbeiten."
#: editor/animation_editor.cpp
msgid "Key"
@@ -1948,7 +1950,7 @@ msgstr "Umwandeln zu..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr "MeshLibrary..."
+msgstr "Mesh-Bibliothek..."
#: editor/editor_node.cpp
msgid "TileSet..."
@@ -2483,7 +2485,7 @@ msgstr "Mirrors werden geladen, bitte warten..."
#: editor/export_template_manager.cpp
msgid "Remove template version '%s'?"
-msgstr "Template-Version '%s' entfernen?"
+msgstr "Template-Version ‚%s‘ entfernen?"
#: editor/export_template_manager.cpp
msgid "Can't open export templates zip."
@@ -6048,8 +6050,8 @@ msgid ""
"Couldn't load project.godot in project path (error %d). It may be missing or "
"corrupted."
msgstr ""
-"Konnte project.godot im Projektpfad nicht laden (Fehler %d). Sie könnte "
-"fehlen oder beschädigt worden sein."
+"Die Datei project.godot im Projektpfad konnte nicht geladen werden (Fehler "
+"%d). Sie könnte fehlen oder beschädigt sein."
#: editor/project_manager.cpp
msgid "Couldn't edit project.godot in project path."
@@ -7490,6 +7492,11 @@ msgstr "Projekt bauen"
msgid "Warnings"
msgstr "Warnungen"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Dateien anzeigen"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Ende des inneren Exception-Stack-Traces"
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index 26f824bc4b..7d11a9d09f 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -7424,6 +7424,11 @@ msgstr "Projektname:"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Datei(en) öffnen"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 1cb31e0ee9..d0f1d04a10 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -7265,6 +7265,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index b3275b4647..4a9560e602 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -2,13 +2,11 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# George Tsiamasiotis <gtsiam@windowslive.com>, 2017-2018.
-#
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-20 09:37+0000\n"
+"PO-Revision-Date: 2018-07-21 22:38+0000\n"
"Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
@@ -16,7 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -1135,7 +1133,7 @@ msgstr "Εμφάνιση στη διαχείριση αρχείων"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
-msgstr "Νέος φάκελος"
+msgstr "Νέος φάκελος..."
#: editor/editor_file_dialog.cpp
msgid "Refresh"
@@ -2698,7 +2696,7 @@ msgstr "Μετονομασία..."
#: editor/filesystem_dock.cpp
msgid "Move To..."
-msgstr "Μετακίνηση σε"
+msgstr "Μετακίνηση σε..."
#: editor/filesystem_dock.cpp
msgid "Open Scene(s)"
@@ -2710,15 +2708,15 @@ msgstr "Στιγμιότυπο"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
-msgstr "Επεξεργασία εξαρτήσεων"
+msgstr "Επεξεργασία εξαρτήσεων..."
#: editor/filesystem_dock.cpp
msgid "View Owners..."
-msgstr "Προβολή ιδιοκτητών"
+msgstr "Προβολή ιδιοκτητών..."
#: editor/filesystem_dock.cpp
msgid "Duplicate..."
-msgstr "Αναπαραγωγή"
+msgstr "Αναπαραγωγή..."
#: editor/filesystem_dock.cpp
msgid "Previous Directory"
@@ -4031,7 +4029,7 @@ msgstr "Δημιουργία περιγράμματος"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Πλέγμα"
+msgstr "Πλέγμα..."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5712,9 +5710,8 @@ msgid "Options"
msgstr "Επιλογές"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Has,Many,Options"
-msgstr "Έχει,Πάρα,Πολλές,Επιλογές!"
+msgstr "Έχει,Πολλές,Επιλογές"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -6001,9 +5998,8 @@ msgid "Imported Project"
msgstr "Εισαγμένο έργο"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "Όνομα έργου:"
+msgstr "Άκυρο όνομα έργου."
#: editor/project_manager.cpp
msgid "Couldn't create folder."
@@ -6207,13 +6203,12 @@ msgid "Mouse Button"
msgstr "Κουμπί ποντικιού"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid ""
"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'."
msgstr ""
"Άκυρο όνομα ενέργειας. Δεν μπορεί να είναι άδειο ή να περιέχει '/', ':', "
-"'=', '\\' ή '\"'"
+"'=', '\\' ή '\"'."
#: editor/project_settings_editor.cpp
msgid "Action '%s' already exists!"
@@ -7474,6 +7469,11 @@ msgstr "Δόμηση έργου"
msgid "Warnings"
msgstr "Προειδοποιήσεις"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Προβολή αρχείων"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Τέλος ιχνηλάτησης στοίβας εσωτερικής εξαίρεσης"
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 89118d2501..8e1f0b13c9 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -29,12 +29,13 @@
# Swyter <swyterzone@gmail.com>, 2016-2017.
# Vazquinhos <vazquinhos@gmail.com>, 2018.
# Yovani Damián <blackblex@gmail.com>, 2018.
+# Andrus Diaz German <andrusdiazaleman@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-22 08:31+0000\n"
-"Last-Translator: R. Joshua Seville <rjoshua@protonmail.com>\n"
+"PO-Revision-Date: 2018-07-20 16:43+0000\n"
+"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -54,19 +55,19 @@ msgstr "Toda la Selección"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr "Cambiar el tiempo del Fotograma Clave de Animación"
+msgstr "Cambiar el Tiempo del Fotograma Clave de Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
-msgstr "Cambiar Transición de Animación"
+msgstr "Cambiar la Transición de Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Transform"
-msgstr "Cambiar transformación de animación"
+msgstr "Cambiar la Transformación de la Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Cambiar valor del Fotograma Clave de Animación"
+msgstr "Cambiar valor de la Clave de Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Call"
@@ -114,7 +115,7 @@ msgstr "Cambiar Modo de Ciclo de Pista de Animación"
#: editor/animation_editor.cpp
msgid "Edit Node Curve"
-msgstr "Editar Nodo de Curva"
+msgstr "Editar Curva del Nodo"
#: editor/animation_editor.cpp
msgid "Edit Selection Curve"
@@ -163,7 +164,7 @@ msgstr "Escalar Selección"
#: editor/animation_editor.cpp
msgid "Scale From Cursor"
-msgstr "Escalar desde cursor"
+msgstr "Escalar Desde Cursor"
#: editor/animation_editor.cpp
msgid "Goto Next Step"
@@ -212,11 +213,11 @@ msgstr "Limpiar Animación"
#: editor/animation_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr "¿Quieres crear una NUEVA pista para %s e insertar clave?"
+msgstr "¿Crear NUEVA pista para %s e insertar clave?"
#: editor/animation_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr "¿Quieres crear %d NUEVAS pistas e insertar claves?"
+msgstr "¿Crear %d NUEVAS pistas e insertar claves?"
#: editor/animation_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/plugins/abstract_polygon_2d_editor.cpp
@@ -288,7 +289,7 @@ msgstr "Activar/Desactivar Bucle de Animación."
#: editor/animation_editor.cpp
msgid "Add new tracks."
-msgstr "Añadir Nuevas Pistas."
+msgstr "Añadir nuevas pistas."
#: editor/animation_editor.cpp
msgid "Move current track up."
@@ -308,7 +309,7 @@ msgstr "Herramientas de pistas"
#: editor/animation_editor.cpp
msgid "Enable editing of individual keys by clicking them."
-msgstr "Habilitar la edición de claves individuales al hacer clic."
+msgstr "Habilitar la edición de claves individuales haciendo clic en ellas."
#: editor/animation_editor.cpp
msgid "Anim. Optimizer"
@@ -366,7 +367,7 @@ msgstr "Limpiar todas las animaciones"
#: editor/animation_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr "Limpiar todas las animaciones (IRREVERSIBLE)"
+msgstr "Limpiar las Animación(es) (¡IRREVERSIBLE!)"
#: editor/animation_editor.cpp
msgid "Clean-Up"
@@ -374,39 +375,39 @@ msgstr "Limpiar"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr "Redimensionar «array»"
+msgstr "Redimensionar Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr "Cambiar tipo de valor del «array»"
+msgstr "Cambiar Tipo de Valor del Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr "Cambiar valor del «array»"
+msgstr "Cambiar Valor del Array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr "Ir a línea"
+msgstr "Ir a Línea"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr "Número de línea:"
+msgstr "Número de Línea:"
#: editor/code_editor.cpp
msgid "No Matches"
-msgstr "Sin coincidencias"
+msgstr "Sin Coincidencias"
#: editor/code_editor.cpp
msgid "Replaced %d occurrence(s)."
-msgstr "%d ocurrencia/s reemplazadas."
+msgstr "%d Ocurrencia(s) Reemplazada(s)."
#: editor/code_editor.cpp
msgid "Match Case"
-msgstr "Coincidir mayús/minúsculas"
+msgstr "Coincidir Mayús/Minúsculas"
#: editor/code_editor.cpp
msgid "Whole Words"
-msgstr "Palabras completas"
+msgstr "Palabras Completas"
#: editor/code_editor.cpp
msgid "Replace"
@@ -414,11 +415,11 @@ msgstr "Reemplazar"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr "Reemplazar todo"
+msgstr "Reemplazar Todo"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr "Sólo selección"
+msgstr "Sólo Selección"
#: editor/code_editor.cpp
msgid "Zoom In"
@@ -430,7 +431,7 @@ msgstr "Alejar"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Restablecer zoom"
+msgstr "Restablecer Zoom"
#: editor/code_editor.cpp editor/script_editor_debugger.cpp
msgid "Line:"
@@ -449,8 +450,8 @@ msgid ""
"Target method not found! Specify a valid method or attach a script to target "
"Node."
msgstr ""
-"No se encontró el método del objetivo! Especifica un método válido o adjunta "
-"un script al Nodo objetivo."
+"¡Método objetivo no encontrado! Especifica un método válido o añade un "
+"script al Nodo objetivo."
#: editor/connections_dialog.cpp
msgid "Connect To Node:"
@@ -471,11 +472,11 @@ msgstr "Quitar"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "Añadir argumento extra de llamada:"
+msgstr "Añadir Argumento Extra de Llamada:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr "Argumentos extras de llamada:"
+msgstr "Argumentos Extras de Llamada:"
#: editor/connections_dialog.cpp
msgid "Path to Node:"
@@ -483,7 +484,7 @@ msgstr "Ruta al Nodo:"
#: editor/connections_dialog.cpp
msgid "Make Function"
-msgstr "Crear función"
+msgstr "Crear Función"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -538,7 +539,7 @@ msgstr "Señales"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr "Cambiar el tipo de %s"
+msgstr "Cambiar el Tipo de %s"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -579,11 +580,11 @@ msgstr "Descripción:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
-msgstr "Buscar reemplazo para:"
+msgstr "Buscar Reemplazo Para:"
#: editor/dependency_editor.cpp
msgid "Dependencies For:"
-msgstr "Dependencias para:"
+msgstr "Dependencias Para:"
#: editor/dependency_editor.cpp
msgid ""
@@ -622,7 +623,7 @@ msgstr "Dependencias:"
#: editor/dependency_editor.cpp
msgid "Fix Broken"
-msgstr "Arreglar rota(s)"
+msgstr "Arreglar Rota(s)"
#: editor/dependency_editor.cpp
msgid "Dependency Editor"
@@ -630,7 +631,7 @@ msgstr "Editor de Dependencias"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr "Buscar recurso de reemplazo:"
+msgstr "Buscar Recurso de Reemplazo:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help.cpp editor/editor_node.cpp editor/filesystem_dock.cpp
@@ -641,13 +642,11 @@ msgstr "Abrir"
#: editor/dependency_editor.cpp
msgid "Owners Of:"
-msgstr "Dueños de:"
+msgstr "Dueños De:"
#: editor/dependency_editor.cpp
msgid "Remove selected files from the project? (no undo)"
-msgstr ""
-"¿Quieres quitar los archivos seleccionados del proyecto? (No puedes "
-"deshacerlo)"
+msgstr "¿Quitar los archivos seleccionados del proyecto? (irreversible)"
#: editor/dependency_editor.cpp
msgid ""
@@ -657,7 +656,7 @@ msgid ""
msgstr ""
"Otros recursos necesitan los archivos que estás intentando quitar para "
"funcionar.\n"
-"¿Seguro que quieres quitarlos? (No puedes deshacerlo)"
+"¿Quitarlos de todos modos? (irreversible)"
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -673,7 +672,7 @@ msgstr "La escena no se pudo cargar porque faltan las siguientes dependencias:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
-msgstr "Abrir de todos modos"
+msgstr "Abrir de Todos Modos"
#: editor/dependency_editor.cpp
msgid "Which action should be taken?"
@@ -689,23 +688,23 @@ msgstr "¡Hubo errores al cargar!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "¿Quieres eliminar permanentemente %d elementos? (Irreversible)"
+msgstr "¿Eliminar permanentemente %d elemento(s)? (¡Irreversible!)"
#: editor/dependency_editor.cpp
msgid "Owns"
-msgstr "Es dueño de"
+msgstr "Dueño de"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr "Recursos sin propietario explícito:"
+msgstr "Recursos Sin Propietario Explícito:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Orphan Resource Explorer"
-msgstr "Explorador de recursos huérfanos"
+msgstr "Explorador de Recursos Huérfanos"
#: editor/dependency_editor.cpp
msgid "Delete selected files?"
-msgstr "¿Quieres eliminar los archivos seleccionados?"
+msgstr "¿Eliminar los archivos seleccionados?"
#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
@@ -745,7 +744,7 @@ msgstr "Desarrollador Principal"
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Administrador de proyectos "
+msgstr "Administrador de Proyectos "
#: editor/editor_about.cpp
msgid "Developers"
@@ -757,11 +756,11 @@ msgstr "Autores"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr "Patrocinadores Platinum"
+msgstr "Patrocinadores de Platino"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr "Patrocinadores Gold"
+msgstr "Patrocinadores de Oro"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
@@ -769,11 +768,11 @@ msgstr "Mini Patrocinadores"
#: editor/editor_about.cpp
msgid "Gold Donors"
-msgstr "Donantes Gold"
+msgstr "Donantes de Oro"
#: editor/editor_about.cpp
msgid "Silver Donors"
-msgstr "Donantes Silver"
+msgstr "Donantes de Plata"
#: editor/editor_about.cpp
msgid "Bronze Donors"
@@ -825,7 +824,7 @@ msgstr "Descomprimiendo Assets"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package Installed Successfully!"
-msgstr "¡El paquete se ha instalado correctamente!"
+msgstr "¡Paquete Instalado Exitosamente!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -859,19 +858,19 @@ msgstr "Cambiar Volumen de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
-msgstr "Act./Desact. Solo de Bus de Audio"
+msgstr "Alternar Solo de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr "Alternar Mute del Bus de Audio"
+msgstr "Alternar Silencio de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
-msgstr "Alternar puenteado de efectos en Bus de Audio"
+msgstr "Alternar Puenteado de Efectos de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr "Seleccionar Envío de Audio Bus"
+msgstr "Seleccionar Envío de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
@@ -928,7 +927,7 @@ msgstr "Añadir Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr "¡No se puede borrar el Bus Maestro!"
+msgstr "¡No se puede borrar el bus maestro!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
@@ -940,7 +939,7 @@ msgstr "Duplicar Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr "Restablecer Volumen del Bus"
+msgstr "Restablecer Volumen de Bus"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
@@ -948,7 +947,7 @@ msgstr "Mover Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr "Guardar configuración de los Buses de Audio como..."
+msgstr "Guardar Configuración de Bus de Audio Como..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
@@ -956,7 +955,7 @@ msgstr "Ubicación para Nueva Configuración..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr "Abrir configuración de Bus de Audio"
+msgstr "Abrir Configuración de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "There is no 'res://default_bus_layout.tres' file."
@@ -1002,7 +1001,7 @@ msgstr "Cargar configuración de Bus por defecto."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
-msgstr "El nombre no es correcto."
+msgstr "Nombre inválido."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1011,24 +1010,24 @@ msgstr "Letras válidas:"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing engine class name."
msgstr ""
-"El nombre no es correcto. No puede coincidir con el nombre de una clase que "
-"ya exista en el motor gráfico."
+"Nombre inválido. No debe coincidir con el nombre de una clase que ya exista "
+"en el motor gráfico."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing buit-in type name."
msgstr ""
-"El nombre no es correcto. No puede coincidir con un nombre de tipo que ya "
-"esté integrado en el motor gráfico."
+"Nombre inválido. No debe coincidir con un nombre de tipo que ya esté "
+"integrado en el motor gráfico."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing global constant name."
msgstr ""
-"El nombre no es correcto. No puede coincidir con un nombre de constante "
-"global ya existente en el motor gráfico."
+"Nombre inválido. No debe coincidir con un nombre de constante global ya "
+"existente en el motor gráfico."
#: editor/editor_autoload_settings.cpp
msgid "Invalid Path."
-msgstr "Ruta incorrecta."
+msgstr "Ruta Inválida."
#: editor/editor_autoload_settings.cpp
msgid "File does not exist."
@@ -1052,7 +1051,7 @@ msgstr "Renombrar Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
-msgstr "Des/Activar Globales de Autoload"
+msgstr "Alternar Globales de Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
@@ -1106,7 +1105,7 @@ msgstr "[vacío]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr "[no guardado]"
+msgstr "[sin guardar]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first"
@@ -1114,12 +1113,12 @@ msgstr "Por favor, selecciona primero un directorio base"
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
-msgstr "Elige una carpeta"
+msgstr "Elige un Directorio"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
msgid "Create Folder"
-msgstr "Crear carpeta"
+msgstr "Crear Carpeta"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
@@ -1139,7 +1138,7 @@ msgstr "Elegir"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr "Archivo de almacenamiento:"
+msgstr "Archivo de Almacenamiento:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1147,11 +1146,11 @@ msgstr "Empaquetando"
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
-msgstr "No se encontró archivo de plantilla:"
+msgstr "Archivo de plantilla no encontrado:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File Exists, Overwrite?"
-msgstr "El archivo ya existe, ¿quieres sobreescribirlo?"
+msgstr "El Archivo ya Existe, ¿Quieres Sobreescribirlo?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1159,15 +1158,15 @@ msgstr "Seleccionar Carpeta Actual"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr "Copiar ruta"
+msgstr "Copiar Ruta"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Show In File Manager"
-msgstr "Mostrar en el navegador de archivos"
+msgstr "Mostrar en el Navegador de Archivos"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
-msgstr "Nueva carpeta..."
+msgstr "Nueva Carpeta..."
#: editor/editor_file_dialog.cpp
msgid "Refresh"
@@ -1183,19 +1182,19 @@ msgstr "Todos los archivos (*)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
-msgstr "Abrir un archivo"
+msgstr "Abrir un Archivo"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
-msgstr "Abrir archivo/s"
+msgstr "Abrir Archivo(s)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a Directory"
-msgstr "Abrir una carpeta"
+msgstr "Abrir un Directorio"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File or Directory"
-msgstr "Abrir un archivo o carpeta"
+msgstr "Abrir un Archivo o Directorio"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1205,7 +1204,7 @@ msgstr "Guardar"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr "Guardar un archivo"
+msgstr "Guardar un Archivo"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -1221,27 +1220,27 @@ msgstr "Subir"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr "Ver/ocultar archivos ocultos"
+msgstr "Ver/ocultar Archivos Ocultos"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr "Añadir/quitar favorito"
+msgstr "Añadir/quitar Favorito"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr "Cambiar modo"
+msgstr "Cambiar Modo"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr "Seleccionar ruta"
+msgstr "Seleccionar Ruta"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr "Subir favorito"
+msgstr "Subir Favorito"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr "Bajar favorito"
+msgstr "Bajar Favorito"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder"
@@ -1249,7 +1248,7 @@ msgstr "Ir a la carpeta principal"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
-msgstr "Carpetas y archivos:"
+msgstr "Directorios y Archivos:"
#: editor/editor_file_dialog.cpp
msgid "Preview:"
@@ -1266,7 +1265,7 @@ msgstr "Debe tener una extensión válida."
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr "Analizando fuentes"
+msgstr "Analizando Fuentes"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -1275,15 +1274,15 @@ msgstr "(Re)Importando Assets"
#: editor/editor_help.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "Ayuda de búsqueda"
+msgstr "Ayuda de Búsqueda"
#: editor/editor_help.cpp
msgid "Class List:"
-msgstr "Lista de clases:"
+msgstr "Lista de Clases:"
#: editor/editor_help.cpp
msgid "Search Classes"
-msgstr "Buscar clases"
+msgstr "Buscar Clases"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
@@ -1303,7 +1302,7 @@ msgstr "Heredada por:"
#: editor/editor_help.cpp
msgid "Brief Description:"
-msgstr "Descripción breve:"
+msgstr "Descripción Breve:"
#: editor/editor_help.cpp
msgid "Members"
@@ -1323,11 +1322,11 @@ msgstr "Métodos públicos:"
#: editor/editor_help.cpp
msgid "GUI Theme Items"
-msgstr "Elementos del Tema de GUI"
+msgstr "Elementos del Tema de Interfaz"
#: editor/editor_help.cpp
msgid "GUI Theme Items:"
-msgstr "Elementos de tema de interfaz:"
+msgstr "Elementos del Tema de Interfaz:"
#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
@@ -1359,7 +1358,7 @@ msgstr "Descripción"
#: editor/editor_help.cpp
msgid "Online Tutorials:"
-msgstr "Tutoriales en línea:"
+msgstr "Tutoriales en Línea:"
#: editor/editor_help.cpp
msgid ""
@@ -1367,8 +1366,8 @@ msgid ""
"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
"url][/color]."
msgstr ""
-"De momento no hay tutoriales para esta clase, puedes [color=$color][url="
-"$url]añadir uno[/url][/color] o [color=$color][url=$url2]pedir uno[color="
+"Actualmente no hay tutoriales para esta clase, puedes [color=$color][url="
+"$url]aportar uno[/url][/color] o [color=$color][url=$url2]pedir uno[color="
"$color][url=$url2]."
#: editor/editor_help.cpp
@@ -1393,7 +1392,7 @@ msgstr "Métodos"
#: editor/editor_help.cpp
msgid "Method Description:"
-msgstr "Descripción de métodos:"
+msgstr "Descripción del Método:"
#: editor/editor_help.cpp
msgid ""
@@ -1405,11 +1404,11 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Search Text"
-msgstr "Texto de búsqueda"
+msgstr "Texto de Búsqueda"
#: editor/editor_help.cpp
msgid "Find"
-msgstr "Búsqueda"
+msgstr "Buscar"
#: editor/editor_log.cpp
msgid "Output:"
@@ -1420,11 +1419,11 @@ msgstr "Salida:"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr "Borrar todo"
+msgstr "Borrar Todo"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr "Borrar salida"
+msgstr "Borrar Salida"
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
@@ -1432,7 +1431,7 @@ msgstr "La exportación del proyecto falló con el código de error %d."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr "¡Hubo un error al guardar el recurso!"
+msgstr "¡Error al guardar el recurso!"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -1485,7 +1484,7 @@ msgstr "Analizando"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr "Creando miniatura"
+msgstr "Creando Miniatura"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
@@ -1501,7 +1500,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Failed to load resource."
-msgstr "Hubo un problema al cargar el recurso."
+msgstr "Error al cargar el recurso."
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
@@ -1529,7 +1528,7 @@ msgstr "Se han sobrescrito los ajustes predeterminados del editor."
#: editor/editor_node.cpp
msgid "Layout name not found!"
-msgstr "¡No se encuentra el nombre del ajuste!"
+msgstr "¡Nombre del ajuste no encontrado!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
@@ -1594,23 +1593,23 @@ msgstr "Ocultar todas las propiedades"
#: editor/editor_node.cpp
msgid "Copy Params"
-msgstr "Copiar parámetros"
+msgstr "Copiar Parámetros"
#: editor/editor_node.cpp
msgid "Paste Params"
-msgstr "Pegar parámetros"
+msgstr "Pegar Parámetros"
#: editor/editor_node.cpp editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Paste Resource"
-msgstr "Pegar recurso"
+msgstr "Pegar Recurso"
#: editor/editor_node.cpp
msgid "Copy Resource"
-msgstr "Copiar recurso"
+msgstr "Copiar Recurso"
#: editor/editor_node.cpp
msgid "Make Built-In"
-msgstr "Convertirlo en integrado"
+msgstr "Convertirlo en Integrado"
#: editor/editor_node.cpp
msgid "Make Sub-Resources Unique"
@@ -1618,7 +1617,7 @@ msgstr "Creación de Subrecursos Únicos"
#: editor/editor_node.cpp
msgid "Open in Help"
-msgstr "Abrir en la ayuda"
+msgstr "Abrir en la Ayuda"
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
@@ -1711,11 +1710,11 @@ msgstr "Esta operación no puede realizarse sin una escena."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr "Exportar biblioteca de mallas"
+msgstr "Exportar Librería de Mallas"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr "Esta operación no puede realizarse sin un Nodo Raíz."
+msgstr "Esta operación no puede realizarse sin un nodo raíz."
#: editor/editor_node.cpp
msgid "Export Tile Set"
@@ -1727,7 +1726,7 @@ msgstr "Esta operación no puede realizarse sin un nodo seleccionado."
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr "La escena actual no se ha guardado. ¿Quieres abrirla de todos modos?"
+msgstr "Escena actual no guardada ¿Abrir de todos modos?"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
@@ -2320,7 +2319,7 @@ msgstr "Abrir Editor anterior"
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr "Creando vistas previas de las mallas"
+msgstr "Creación de Vistas Previas de Malla"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
@@ -2851,7 +2850,7 @@ msgstr "Generando \"Lightmaps\""
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr "Generando para modelo: "
+msgstr "Generando para Malla: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
@@ -3122,7 +3121,7 @@ msgstr "Posterior"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
-msgstr "Profundidad"
+msgstr "Depth"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
@@ -3996,7 +3995,7 @@ msgstr "Clic derecho: Borrar punto."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh is empty!"
-msgstr "¡La malla está vacía!"
+msgstr "¡La Malla está vacía!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
@@ -4020,11 +4019,11 @@ msgstr "Crear forma convexa"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
-msgstr "Crear malla de navegación"
+msgstr "Crear Malla de Navegación"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Contained Mesh is not of type ArrayMesh."
-msgstr "La malla que contiene no es del tipo ArrayMesh."
+msgstr "La Malla contenedora no es del tipo ArrayMesh."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Unwrap failed, mesh may not be manifold?"
@@ -4042,7 +4041,7 @@ msgstr "El modelo no tiene UV en esta capa"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "MeshInstance lacks a Mesh!"
-msgstr "¡MeshInstance no tiene malla!"
+msgstr "¡MeshInstance no tiene Malla!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh has not surface to create outlines from!"
@@ -4050,7 +4049,7 @@ msgstr "¡La malla no tiene superficie de la que crear contornos!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
-msgstr "El tipo de la malla primitiva no es PRIMITIVE_TRIANGLES!"
+msgstr "¡El tipo primitivo de malla no es PRIMITIVE_TRIANGLES!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Could not create outline!"
@@ -4098,7 +4097,7 @@ msgstr "Desenvuelva UV2 para Lightmap/AO"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh"
-msgstr "Crear contorno de malla"
+msgstr "Crear Contorno de Malla"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Outline Size:"
@@ -4107,12 +4106,14 @@ msgstr "Tamaño del contorno:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
msgstr ""
-"No se especificó malla de origen (y no hay MultiMesh establecido en el nodo)."
+"No se ha especificado ninguna malla de origen (y no hay MultiMesh "
+"establecido en el nodo)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and MultiMesh contains no Mesh)."
msgstr ""
-"No se especificó malla de origen (y MultiMesh no contiene ningún Mesh)."
+"No se ha especificado ninguna malla de origen (y MultiMesh no contiene "
+"ninguna Mesh)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
@@ -4120,11 +4121,11 @@ msgstr "El origen de la malla es inválido (ruta inválida)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (not a MeshInstance)."
-msgstr "La malla elegida no es correcta (no es un MeshInstance)."
+msgstr "El origen de la malla es inválido (no es un MeshInstance)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (contains no Mesh resource)."
-msgstr "La malla elegida no es correcta (no contiene ningún recurso Mesh)."
+msgstr "El origen de la malla es inválido (no contiene ningún recurso Mesh)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No surface source specified."
@@ -4152,7 +4153,7 @@ msgstr "No se pudo mapear el área."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
-msgstr "Elige un origen de malla:"
+msgstr "Elige un origen de Malla:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Target Surface:"
@@ -4172,7 +4173,7 @@ msgstr "Superficie objetivo:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Source Mesh:"
-msgstr "Modelo 3D elegido:"
+msgstr "Malla de origen:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "X-Axis"
@@ -4212,11 +4213,11 @@ msgstr "¡Calcular!"
#: editor/plugins/navigation_mesh_editor_plugin.cpp
msgid "Bake the navigation mesh."
-msgstr "Pre-calcular la malla de navegación 3D."
+msgstr "Pre-calcular la malla de navegación."
#: editor/plugins/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr "Vaciar malla de navegación 3D."
+msgstr "Vaciar malla de navegación."
#: editor/plugins/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
@@ -4501,7 +4502,7 @@ msgstr "Crear mapa UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Transform UV Map"
-msgstr "Transformar mapa UV"
+msgstr "Transformar Mapa UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
@@ -5416,11 +5417,11 @@ msgstr "Activar Vista Libre"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform"
-msgstr "Transform"
+msgstr "Transformar"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
-msgstr "Ventana de transformación..."
+msgstr "Dialogo de Transformación..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
@@ -5497,7 +5498,7 @@ msgstr "Profundidad máxima de vista:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Change"
-msgstr "Transformar"
+msgstr "Cambio de Transformación"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate:"
@@ -6644,7 +6645,7 @@ msgstr "Reemparentar ubicación (selecciona un nuevo padre):"
#: editor/reparent_dialog.cpp
msgid "Keep Global Transform"
-msgstr "Mantener transformación global"
+msgstr "Mantener Transformación Global"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent"
@@ -7498,6 +7499,11 @@ msgstr "Compilar Proyecto"
msgid "Warnings"
msgstr "Advertencias"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Archivos"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fin del reporte de la pila de excepciones"
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 64ee2404f1..bea184b813 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -7464,6 +7464,11 @@ msgstr "Construir Proyecto"
msgid "Warnings"
msgstr "Advertencias"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Archivos"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fin del stack trace de excepción interna"
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index f674ef99cc..eb192ececb 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -2,26 +2,25 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# alabd14313 <alabd14313@yahoo.com>, 2016.
# Dante Marshal <Marshal.Devilhunter@gmail.com>, 2018.
# hamed nasib <cghamed752@chmail.ir>, 2016.
# Hasan Hejdari Nasab <hsn6@openmailbox.org>, 2017.
# rezapouya <r.pouya@chmail.ir>, 2016.
# sayyed hamed nasib <cghamed752@chmail.ir>, 2017.
-#
+# Behrooz Kashani <bkashani@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-04-29 05:39+0000\n"
-"Last-Translator: Dante Marshal <Marshal.Devilhunter@gmail.com>\n"
+"PO-Revision-Date: 2018-07-24 19:42+0000\n"
+"Last-Translator: Behrooz Kashani <bkashani@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -636,9 +635,8 @@ msgstr ""
"آیا در هر صورت حذف شوند؟(بدون برگشت)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Cannot remove:"
-msgstr "ناتوانی در حذف :"
+msgstr "امکان حذف وجود ندارد :"
#: editor/dependency_editor.cpp
msgid "Error loading:"
@@ -743,9 +741,8 @@ msgid "Gold Sponsors"
msgstr "اسپانسر‌های درجه ۲"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Mini Sponsors"
-msgstr "اسپانسر‌های دیگر"
+msgstr "اسپانسر‌های کوچک"
#: editor/editor_about.cpp
msgid "Gold Donors"
@@ -789,7 +786,7 @@ msgstr "اجزا"
#: editor/editor_about.cpp
msgid "Licenses"
-msgstr ""
+msgstr "گواهینامه"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Error opening package file, not in zip format."
@@ -7420,6 +7417,11 @@ msgstr "پروژه"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "نمایش پرونده ها"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index f80efffd42..11f9bb51c7 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -12,7 +12,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-14 20:37+0000\n"
+"PO-Revision-Date: 2018-07-19 10:36+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -2128,7 +2128,7 @@ msgstr "Käynnistä muokattavana oleva skene."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "Toista skene"
+msgstr "Pelaa skeneä"
#: editor/editor_node.cpp
msgid "Play custom scene"
@@ -2414,7 +2414,7 @@ msgstr "Lataa uudelleen"
#: editor/export_template_manager.cpp
msgid "Uninstall"
-msgstr "Poista"
+msgstr "Poista asennus"
#: editor/export_template_manager.cpp
msgid "(Installed)"
@@ -2475,7 +2475,7 @@ msgstr ""
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't resolve."
-msgstr "Yhdistäminen epäonnistui."
+msgstr "Yhdeydenselvitys epäonnistui."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -2520,11 +2520,11 @@ msgstr "Yhteys katkaistu"
#: editor/export_template_manager.cpp
msgid "Resolving"
-msgstr "Selvitetään"
+msgstr "Selvitetään yhteyttä"
#: editor/export_template_manager.cpp
msgid "Can't Resolve"
-msgstr "Yhdistäminen epäonnistui"
+msgstr "Yhteyden selvittäminen epäonnistui"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -2809,7 +2809,7 @@ msgstr "Luodaan meshille: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr "Suorita valitsemasi skripti..."
+msgstr "Suoritetaan mukautettua skriptiä..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
@@ -2940,7 +2940,7 @@ msgstr "VIRHE: Virheellinen animaation nimi!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "ERROR: Animation name already exists!"
-msgstr "VIrhe: Samanniminen animaatio on jo olemassa!"
+msgstr "VIRHE: Samanniminen animaatio on jo olemassa!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -3316,7 +3316,8 @@ msgstr "Pyyntö epäonnistui, liikaa uudelleenohjauksia"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
-msgstr "Latauksessa väärä hash, oletetaan että tiedostoa on näpelöity."
+msgstr ""
+"Latauksessa väärä hajautuskoodi, oletetaan että tiedostoa on näpelöity."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Expected:"
@@ -3328,7 +3329,7 @@ msgstr "Saatiin:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed sha256 hash check"
-msgstr "sha256 hash-tarkistus epäonnistui"
+msgstr "sha256-hajautusarvon tarkistus epäonnistui"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -3442,7 +3443,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
-"Lightmap-kuvien luonti epäonnistui, varmista, että polku on "
+"Lightmap-kuvien luonti epäonnistui. Varmista, että polku on "
"kirjoituskelpoinen."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5301,11 +5302,11 @@ msgstr "Tarttumisen tila (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
-msgstr "Pohjanäkymä"
+msgstr "Alanäkymä"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View"
-msgstr "Huippunäkymä"
+msgstr "Ylänäkymä"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
@@ -7110,7 +7111,7 @@ msgstr "Aseta puusta"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
-msgstr "Pikakuvakkeet"
+msgstr "Pikanäppäimet"
#: editor/settings_config_dialog.cpp
msgid "Binding"
@@ -7435,6 +7436,11 @@ msgstr "Käännä projekti"
msgid "Warnings"
msgstr "Varoitukset"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Näytä tiedostot"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Sisemmän poikkeuksen kutsupinon loppu"
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index ee1d7b2cad..5c28d84a90 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -40,12 +40,14 @@
# Tommy Melançon-Roy <tommel1234@hotmail.com>, 2017-2018.
# Willow <theotimefd@aol.com>, 2018.
# Xananax <xananax@yelostudio.com>, 2017-2018.
+# Perrier Mathis <mathis.perrier73@gmail.com>, 2018.
+# Ewan Lehnebach <ewan.lehnebach@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-12 16:38+0000\n"
-"Last-Translator: Philippe Gervaise <blah@malvese.org>\n"
+"PO-Revision-Date: 2018-07-21 12:37+0000\n"
+"Last-Translator: Perrier Mathis <mathis.perrier73@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -53,7 +55,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -65,11 +67,11 @@ msgstr "Toute la sélection"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr "Changer l'heure de l'animation des images clés"
+msgstr "Animation Changer l'heure de l'image clé"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
-msgstr "Transition du changement d'animation"
+msgstr "Animation Changer la transition"
#: editor/animation_editor.cpp
msgid "Anim Change Transform"
@@ -77,7 +79,7 @@ msgstr "Animation Changer la transformation"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Changer la valeur de l'animation des images clés"
+msgstr "Animation Changer la valeur de l'image clé"
#: editor/animation_editor.cpp
msgid "Anim Change Call"
@@ -4076,7 +4078,7 @@ msgstr "Créer le contour"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Maillage"
+msgstr "Maillages"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -6512,7 +6514,7 @@ msgstr "Remaps par langue :"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr "Langue"
+msgstr "Localisation"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -7513,6 +7515,11 @@ msgstr "Compiler le projet"
msgid "Warnings"
msgstr "Avertissements"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Voir Fichiers"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fin de la trace d'appel (stack trace) intrinsèque"
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 0f1881211f..6dfd0ab3a5 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -7294,6 +7294,10 @@ msgstr ""
msgid "Warnings"
msgstr "אזהרות"
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 3340f13471..606da1d118 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -7327,6 +7327,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index b04dd073df..84c64138dc 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -7405,6 +7405,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Fájlok Megtekintése"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 3956378ce7..a0356b8178 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -10,7 +10,7 @@
# Fajar Ru <kzofajar@gmail.com>, 2018.
# Khairul Hidayat <khairulcyber4rt@gmail.com>, 2016.
# Reza Hidayat Bayu Prabowo <rh.bayu.prabowo@gmail.com>, 2018.
-# Romi Kusuma Bakti <romikusumab@gmail.com>, 2017.
+# Romi Kusuma Bakti <romikusumab@gmail.com>, 2017, 2018.
# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018.
# Tito <ijavadroid@gmail.com>, 2018.
# Tom My <tom.asadinawan@gmail.com>, 2017.
@@ -18,8 +18,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-22 08:30+0000\n"
-"Last-Translator: Fajar Ru <kzofajar@gmail.com>\n"
+"PO-Revision-Date: 2018-07-15 12:38+0000\n"
+"Last-Translator: Romi Kusuma Bakti <romikusumab@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -917,9 +917,8 @@ msgid "Delete Audio Bus"
msgstr "Hapus Bus Audio"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Duplicate Audio Bus"
-msgstr "Duplikat Audio Bus"
+msgstr "Duplikatkan Bus Audio"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
@@ -976,9 +975,8 @@ msgid "Save this Bus Layout to a file."
msgstr "Simpan Layout Bus ke berkas."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
-#, fuzzy
msgid "Load Default"
-msgstr "Muat Konfigurasi Bawaan"
+msgstr "Muat Default"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
@@ -1294,18 +1292,16 @@ msgid "Members:"
msgstr "Member-member:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Public Methods"
-msgstr "Fungsi Publik"
+msgstr "Metode Publik"
#: editor/editor_help.cpp
msgid "Public Methods:"
msgstr "Metode Publik:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "GUI Theme Items"
-msgstr "Item-item Tema GUI:"
+msgstr "Item Tema GUI"
#: editor/editor_help.cpp
msgid "GUI Theme Items:"
@@ -1422,9 +1418,8 @@ msgstr "Simpan Resource Sebagai..."
#: editor/editor_node.cpp editor/plugins/spatial_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "I see..."
-msgstr "Aku tahu..."
+msgstr "Mengerti..."
#: editor/editor_node.cpp
msgid "Can't open file for writing:"
@@ -1471,9 +1466,8 @@ msgid "Creating Thumbnail"
msgstr "Membuat Thumbnail"
#: editor/editor_node.cpp
-#, fuzzy
msgid "This operation can't be done without a tree root."
-msgstr "Tindakan ini tidak bisa dilakukan tanpa \"tree root\""
+msgstr "Operasi ini tidak dapat diselesaikan tanpa root pohon."
#: editor/editor_node.cpp
msgid ""
@@ -2712,7 +2706,7 @@ msgstr "Buka Scene"
#: editor/filesystem_dock.cpp
msgid "Instance"
-msgstr ""
+msgstr "Instance"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
@@ -2821,18 +2815,16 @@ msgid "Importing Scene..."
msgstr "Mengimpor scene..."
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Generating Lightmaps"
-msgstr "Sedang Membuat Pemetaan Cahaya"
+msgstr "Membuat Pemetaan Cahaya"
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
msgstr ""
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Running Custom Script..."
-msgstr "Menjalankan Skrip Buatan..."
+msgstr "Menjalankan Script Khusus..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
@@ -2868,7 +2860,7 @@ msgstr "Impor sebagai:"
#: editor/import_dock.cpp editor/property_editor.cpp
msgid "Preset..."
-msgstr ""
+msgstr "Prasetel..."
#: editor/import_dock.cpp
msgid "Reimport"
@@ -7563,6 +7555,11 @@ msgstr "Proyek"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "File:"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 98a376edca..0d6200fba1 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -7301,6 +7301,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 2d566fe163..afb8c5cfb8 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Alessio Corridori <alessiocorridori@hotmail.com>, 2018.
# Dario Bonfanti <bonfi.96@hotmail.it>, 2016-2017.
# Dario D'Ambra <legione0@gmail.com>, 2017.
@@ -15,13 +14,13 @@
# RealAquilus <JamesHeller@live.it>, 2017.
# Samuele Zolfanelli <samdazel@gmail.com>, 2018.
# Sean Bone <seanbone@zumguy.com>, 2017.
-#
+# Red Pill <redpill902@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-05-18 16:39+0000\n"
-"Last-Translator: Alessio Corridori <alessiocorridori@hotmail.com>\n"
+"PO-Revision-Date: 2018-06-25 18:40+0000\n"
+"Last-Translator: Red Pill <redpill902@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -29,7 +28,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -40,9 +39,8 @@ msgid "All Selection"
msgstr "Seleziona Tutto"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
-msgstr "Anim Cambia Valore"
+msgstr "Anim Cambia Tempo di Keyframe"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
@@ -7640,6 +7638,11 @@ msgstr "Progetto"
msgid "Warnings"
msgstr "Avvertimento"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vedi Files"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 5ce73d0442..d7e2c07ac2 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -8251,6 +8251,11 @@ msgstr "プロジェクト"
msgid "Warnings"
msgstr "警告"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "ビューファイル:"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index be6b540a9a..197a11efa2 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -14,8 +14,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-07 16:40+0000\n"
-"Last-Translator: pgyage3263 <pgyage3263@naver.com>\n"
+"PO-Revision-Date: 2018-07-21 04:38+0000\n"
+"Last-Translator: 송태섭 <xotjq237@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -23,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -4003,7 +4003,7 @@ msgstr "외곽선 만들기"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "메시"
+msgstr "Mesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -7412,6 +7412,11 @@ msgstr "프로젝트 빌드"
msgid "Warnings"
msgstr "경고"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "파일 보기"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "내부 예외 스택 추적의 끝"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index bf4443627a..639e086d4c 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -7295,6 +7295,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 19d8b6b7d8..09c7b39e08 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -2,22 +2,21 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Sam Vanguard <syafz119@gmail.com>, 2018.
# Shaqir Rafiq <moshamoradev@gmail.com>, 2018.
-#
+# Syaz Amirin <amirin123z@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-05 19:27+0000\n"
-"Last-Translator: Shaqir Rafiq <moshamoradev@gmail.com>\n"
+"PO-Revision-Date: 2018-06-30 09:40+0000\n"
+"Last-Translator: Syaz Amirin <amirin123z@gmail.com>\n"
"Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/"
"ms/>\n"
"Language: ms\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -2014,11 +2013,11 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr ""
+msgstr "Komuniti"
#: editor/editor_node.cpp
msgid "About"
-msgstr ""
+msgstr "Tentang"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -6244,7 +6243,7 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr ""
+msgstr "Am"
#: editor/project_settings_editor.cpp editor/property_editor.cpp
msgid "Property:"
@@ -7273,6 +7272,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index e76053150c..abc026771d 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -14,8 +14,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-22 08:31+0000\n"
-"Last-Translator: Frank T. Rambol <frank@d-fect.com>\n"
+"PO-Revision-Date: 2018-06-28 14:40+0000\n"
+"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb/>\n"
"Language: nb\n"
@@ -1756,7 +1756,9 @@ msgstr "Velg en HovedScene"
#: editor/editor_node.cpp
#, fuzzy
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
-msgstr "Kan ikke aktivere addon-plugin på: '%s' parsing av konfig feilet."
+msgstr ""
+"Kan ikke aktivere tilleggs-programtillegg på: \"%s\" tolking av oppsett "
+"mislyktes."
#: editor/editor_node.cpp
msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
@@ -1912,9 +1914,8 @@ msgid "MeshLibrary..."
msgstr "MeshBibliotek..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "TileSet..."
-msgstr "TileSet…"
+msgstr "Flissett…"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -7495,6 +7496,11 @@ msgstr "Prosjekt"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vis Filer"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index bfedf322b3..240d99182f 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# aelspire <aelspire@gmail.com>, 2017.
# Aram Nap <xyphex.aram@gmail.com>, 2017.
# Arjan219 <arjannugteren1@gmail.com>, 2017-2018.
@@ -24,19 +23,19 @@
# Willem <studiebolmail@gmail.com>, 2018.
# Wout Standaert <wout@blobkat.com>, 2017.
# Zatherz <zatherz@linux.pl>, 2017.
-#
+# Tahar Meijs <tntmeijs@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-21 18:36+0000\n"
-"Last-Translator: Johannes Smit <smitjohannes96@gmail.com>\n"
+"PO-Revision-Date: 2018-06-30 15:36+0000\n"
+"Last-Translator: Tahar Meijs <tntmeijs@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
"Language: nl\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -6427,7 +6426,7 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr ""
+msgstr "Algemeen"
#: editor/project_settings_editor.cpp editor/property_editor.cpp
msgid "Property:"
@@ -7492,6 +7491,11 @@ msgstr "Project"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Bekijk Bestanden"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 5ca2760249..a133a4d8d5 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -27,7 +27,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-22 08:31+0000\n"
+"PO-Revision-Date: 2018-07-14 08:42+0000\n"
"Last-Translator: RM <synaptykq@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
@@ -1975,7 +1975,7 @@ msgstr "Wyjdź do Listy Projektów"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Debug"
-msgstr "Debuguj"
+msgstr "Debugowanie"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -3093,7 +3093,7 @@ msgstr "Poprzednie"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr "Następne"
+msgstr "Przyszłość"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
@@ -3154,7 +3154,7 @@ msgstr "Czas Przejścia Między Animacjami"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Animation"
-msgstr "Animacja"
+msgstr "Animacje"
#: editor/plugins/animation_tree_editor_plugin.cpp
msgid "New name:"
@@ -6514,7 +6514,7 @@ msgstr "Mapowanie w zależności od lokalizacji:"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr "Lokalizacja"
+msgstr "Języki"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -7137,7 +7137,7 @@ msgstr "Monitor"
#: editor/script_editor_debugger.cpp
msgid "Value"
-msgstr "Wartość"
+msgstr "Value"
#: editor/script_editor_debugger.cpp
msgid "Monitors"
@@ -7525,6 +7525,11 @@ msgstr "Zbuduj projekt"
msgid "Warnings"
msgstr "Ostrzeżenia"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Pokaż pliki"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
@@ -7672,11 +7677,11 @@ msgstr "Dodaj węzeł(y) z drzewa"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Getter Property"
-msgstr ""
+msgstr "Dodaj właściwość Gettera"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Setter Property"
-msgstr ""
+msgstr "Dodaj właściwość Settera"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Base Type"
@@ -7712,7 +7717,7 @@ msgstr "Iterator"
#: modules/visual_script/visual_script_editor.cpp
msgid "While"
-msgstr ""
+msgstr "While"
#: modules/visual_script/visual_script_editor.cpp
msgid "Return"
@@ -8045,7 +8050,7 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVRCamera must have an ARVROrigin node as its parent"
-msgstr "ARVRCamera musi dziedziczyć po ARVROrigin node"
+msgstr "ARVRCamera musi dziedziczyć po węźle ARVROrigin"
#: scene/3d/arvr_nodes.cpp
#, fuzzy
@@ -8073,11 +8078,11 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVROrigin requires an ARVRCamera child node"
-msgstr "ARVROrigin wymaga by ARVRCamera dziedziczyła po node"
+msgstr "ARVROrigin wymaga dziedziczącego po nim ARVRCamera"
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
-msgstr ""
+msgstr "%d%%"
#: scene/3d/baked_lightmap.cpp
msgid "(Time Left: %d:%02d s)"
@@ -8106,6 +8111,10 @@ msgid ""
"Consider adding CollisionShape or CollisionPolygon children nodes to define "
"its shape."
msgstr ""
+"Ten węzeł nie posiada podwezła, który definiowałby jego kształt, więc nie "
+"może wchodzić w interakcje z przestrzenią.\n"
+"Powinieneś dodać węzeł \"CollisionShape2D\" lub \"CollisionPolygon2D\" jako "
+"jego podwęzeł aby zdefiniować jego kształt."
#: scene/3d/collision_polygon.cpp
msgid ""
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 0c085024e0..ee30748cee 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -7350,6 +7350,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 6d26cbc500..472fb1e7bc 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -23,12 +23,13 @@
# Renato Rotenberg <renato.rotenberg@gmail.com>, 2017.
# Rodolfo R Gomes <rodolforg@gmail.com>, 2017-2018.
# Tiago Almeida <thyagoeap@gmail.com>, 2017.
+# Mauricio Luan Carneiro deSouza <newmailmlcs@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2018-06-16 18:43+0000\n"
-"Last-Translator: Rodolfo R Gomes <rodolforg@gmail.com>\n"
+"PO-Revision-Date: 2018-07-26 09:14+0000\n"
+"Last-Translator: Mauricio Luan Carneiro deSouza <newmailmlcs@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -36,7 +37,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -4036,7 +4037,7 @@ msgstr "Criar Contorno"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Mesh"
+msgstr "Malha"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5100,7 +5101,7 @@ msgstr "Transformação do Eixo-Z."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Plane Transform."
-msgstr "Visualizar Transformação do Plano."
+msgstr "Transformação do Plano de Visão."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scaling: "
@@ -5236,7 +5237,7 @@ msgstr "Visualizar Gizmos"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
-msgstr "VIsualizar Informação"
+msgstr "Visualizar Informações"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View FPS"
@@ -7049,7 +7050,7 @@ msgstr "Processo Filho Conectado"
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
-msgstr "Erro ao Copiar"
+msgstr "Copiar Erro"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -7463,6 +7464,11 @@ msgstr "Compilar Projeto"
msgid "Warnings"
msgstr "Avisos"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Arquivos"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fim da pilha de rastreamento de exceção interna"
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index 71275cd19a..d111d1dd4b 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -7442,6 +7442,11 @@ msgstr "Construir Projeto"
msgid "Warnings"
msgstr "Avisos"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Ficheiros"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fim do stack trace de exceção interna"
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index eaf931092a..c5a4e35903 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -7400,6 +7400,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vizualizează Fișierele"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 97c7284404..1c888d3330 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -17,12 +17,15 @@
# Sergey <maligin.serega2010@yandex.ru>, 2018.
# Sergey Agarkov <zorgsoft@gmail.com>, 2017.
# teriva <spirin.cos@yandex.ru>, 2018.
+# Aleksey Terentyev <terentjew.alexey@ya.ru>, 2018.
+# Игорь Д <protorian.di@gmail.com>, 2018.
+# Егор Бураков <fend.q@mail.ru>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-18 19:42+0000\n"
-"Last-Translator: ijet <my-ijet@mail.ru>\n"
+"PO-Revision-Date: 2018-07-22 04:43+0000\n"
+"Last-Translator: Егор Бураков <fend.q@mail.ru>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -31,7 +34,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -2347,7 +2350,7 @@ msgstr "Кадр %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr "Физический шаг %"
+msgstr "Кадр физики %"
#: editor/editor_profiler.cpp editor/script_editor_debugger.cpp
msgid "Time:"
@@ -2359,7 +2362,7 @@ msgstr "Включительно"
#: editor/editor_profiler.cpp
msgid "Self"
-msgstr ""
+msgstr "Субъект"
#: editor/editor_profiler.cpp
msgid "Frame #:"
@@ -4029,7 +4032,7 @@ msgstr "Создать контур"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Полисетка"
+msgstr "Массив"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5561,7 +5564,7 @@ msgstr "Предпросмотр StyleBox:"
#: editor/plugins/style_box_editor_plugin.cpp
msgid "StyleBox"
-msgstr ""
+msgstr "StyleBox"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
@@ -5684,14 +5687,12 @@ msgid "Checked Item"
msgstr "Отмеченный элемент"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Radio Item"
-msgstr "Добавить элемент"
+msgstr "Переключатель"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Checked Radio Item"
-msgstr "Отмеченный элемент"
+msgstr "Отмеченный переключатель"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
@@ -7233,7 +7234,7 @@ msgstr "Библиотеки: "
#: modules/gdnative/register_types.cpp
msgid "GDNative"
-msgstr ""
+msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -7450,6 +7451,11 @@ msgstr "Собрать проект"
msgid "Warnings"
msgstr "Предупреждения"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Просмотр Файлов"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Конец трассировки внутреннего стека исключений"
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 9716dee696..94b6c137d0 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -7354,6 +7354,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Súbor:"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 0fe619654f..66e3c43bee 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -10,7 +10,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-10 08:44+0000\n"
+"PO-Revision-Date: 2018-06-27 13:43+0000\n"
"Last-Translator: matevž lapajne <sivar.lapajne@gmail.com>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/"
"godot/sl/>\n"
@@ -19,7 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3;\n"
-"X-Generator: Weblate 3.0.1-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -3340,23 +3340,23 @@ msgstr "Razreševanje..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Error making request"
-msgstr ""
+msgstr "Napaka pri izdelavi zahteve"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Idle"
-msgstr ""
+msgstr "Nedejaven"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
-msgstr ""
+msgstr "Ponovi"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download Error"
-msgstr ""
+msgstr "Napaka Pri Prenosu"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download for this asset is already in progress!"
-msgstr ""
+msgstr "Prenos za ta dodatek je že v teku!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "first"
@@ -3382,7 +3382,7 @@ msgstr "Vse"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
msgid "Plugins"
-msgstr ""
+msgstr "Vtičniki"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Sort:"
@@ -3390,7 +3390,7 @@ msgstr "Razvrsti:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Reverse"
-msgstr ""
+msgstr "Obrni"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -3407,15 +3407,15 @@ msgstr "Podpora..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
-msgstr ""
+msgstr "Uradno"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Testing"
-msgstr ""
+msgstr "Preskušanje"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
-msgstr ""
+msgstr "Dodatki v ZIP Datoteki"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -3423,6 +3423,9 @@ msgid ""
"Save your scene (for images to be saved in the same dir), or pick a save "
"path from the BakedLightmap properties."
msgstr ""
+"Ni mogoče določiti poti shranjevanja slik svetlobnih kart.\n"
+"Shrani prizor (za slike, da bodo shranjene v isti mapi), ali izberi pot za "
+"shranitev iz lastnosti Zapečene Svetlobne karte."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -3435,53 +3438,54 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
+"Napaka pri izdelavi slik, svetlobnih kart. Poskrbite, da je pot zapisljiva."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr ""
+msgstr "Zapeči Svetlobne karte"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
-msgstr ""
+msgstr "Predogled"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
-msgstr ""
+msgstr "Nastavi Zaskok"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr ""
+msgstr "Mrežni Zamik:"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step:"
-msgstr ""
+msgstr "Mrežni Korak:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
-msgstr ""
+msgstr "Rotacijski Odmik:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
-msgstr ""
+msgstr "Rotacijski Korak:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move Pivot"
-msgstr ""
+msgstr "Premakni Točko"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move Action"
-msgstr ""
+msgstr "Premakni Dejanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move vertical guide"
-msgstr ""
+msgstr "Premakni navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create new vertical guide"
-msgstr ""
+msgstr "Ustvari nov navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Remove vertical guide"
@@ -3489,59 +3493,61 @@ msgstr "Odstranite navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move horizontal guide"
-msgstr ""
+msgstr "Premakni vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create new horizontal guide"
-msgstr ""
+msgstr "Ustvari nov vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Remove horizontal guide"
-msgstr "Odstrani vodoravno vodilo"
+msgstr "Odstrani vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create new horizontal and vertical guides"
-msgstr ""
+msgstr "Ustvari nov vodoravni in navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Edit IK Chain"
-msgstr ""
+msgstr "Uredi Verigo IK"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Edit CanvasItem"
-msgstr ""
+msgstr "Uredi Platno Stvari"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
-msgstr ""
+msgstr "Samo Sidrišča"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors and Margins"
-msgstr ""
+msgstr "Spremeni Sidrišča in Robove"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors"
-msgstr ""
+msgstr "Spremeni Sidrišča"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
-msgstr ""
+msgstr "Prilepi Pozicijo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Select Mode"
-msgstr "Izberite Način"
+msgstr "Izberi Način"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
-msgstr "Povlecite: Zavrti"
+msgstr "Povleci: Vrtenje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+Drag: Move"
-msgstr ""
+msgstr "Alt+Drag: Premakni"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
msgstr ""
+"Pritisni 'v' za Spremembo Točke in 'Shift+v' za Vleko Točke (med "
+"premikanjem)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
@@ -3561,16 +3567,16 @@ msgid ""
"Show a list of all objects at the position clicked\n"
"(same as Alt+RMB in select mode)."
msgstr ""
-"Ob kliku prikaži seznam vseh objektov na tem mestu.\n"
+"Ob kliku prikaži seznam vseh objektov na tem mestu\n"
"(isto kot Alt+RMB v načinu izbire)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Click to change object's rotation pivot."
-msgstr ""
+msgstr "Klikni, če želiš spremeniti rotacijsko točko objekta."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan Mode"
-msgstr ""
+msgstr "Način Plošče"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggles snapping"
@@ -3578,66 +3584,66 @@ msgstr "Preklopi pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Snap"
-msgstr ""
+msgstr "Uporabi Pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snapping options"
-msgstr ""
+msgstr "Možnosti pripenjanja"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to grid"
-msgstr ""
+msgstr "Pripni na mrežo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
-msgstr ""
+msgstr "Uporabi Rotacijsko Pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Configure Snap..."
-msgstr "Preoblikuj Zaskok..."
+msgstr "Nastavi Pripenjanje..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
-msgstr ""
+msgstr "Pripni Relativno"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Pixel Snap"
-msgstr ""
+msgstr "Uporabi Pripenjanje Pikslov"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Smart snapping"
-msgstr ""
+msgstr "Pametno pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to parent"
-msgstr ""
+msgstr "Pripni na Predhodnika"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to node anchor"
-msgstr ""
+msgstr "Pripni na gradnik vodilo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to node sides"
-msgstr ""
+msgstr "Pripni na gradnik strani"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to other nodes"
-msgstr ""
+msgstr "Pripni na druge gradnike"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to guides"
-msgstr ""
+msgstr "Pripni na vodnike"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock the selected object in place (can't be moved)."
-msgstr "Izbrani predmet zaklenite na svoje mesto (ga ni mogoče premakniti)."
+msgstr "Izbrani predmet zakleni na svoje mesto (ni ga mogoče premakniti)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock the selected object (can be moved)."
-msgstr "Odklenite izbrani predmet (ga lahko premaknete)."
+msgstr "Odkleni izbrani predmet (lahko ga premaknete)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Makes sure the object's children are not selectable."
@@ -5945,9 +5951,8 @@ msgid "Imported Project"
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "Ime Projekta:"
+msgstr "Neveljavno Ime Projekta."
#: editor/project_manager.cpp
msgid "Couldn't create folder."
@@ -7374,6 +7379,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ogled datotek"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index c838174131..9998a16e3a 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -7461,6 +7461,11 @@ msgstr "Пројекат"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Погледај датотеке"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 975418d4fb..4d293a592d 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -7272,6 +7272,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index 9ec654128a..f9e65bb600 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -2,24 +2,24 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# bergmarklund <davemcgroin@gmail.com>, 2017, 2018.
# Christoffer Sundbom <christoffer_karlsson@live.se>, 2017.
# Jakob Sinclair <sinclair.jakob@mailbox.org>, 2018.
# . <grenoscar@gmail.com>, 2018.
-#
+# Kristoffer Grundström <kristoffer.grundstrom1983@gmail.com>, 2018.
+# Magnus Helander <helander@fastmail.net>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-07 11:42+0000\n"
-"Last-Translator: anonymous <>\n"
+"PO-Revision-Date: 2018-07-24 12:44+0000\n"
+"Last-Translator: Magnus Helander <helander@fastmail.net>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/"
"godot/sv/>\n"
"Language: sv\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -30,9 +30,8 @@ msgid "All Selection"
msgstr "Alla urval"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
-msgstr "Anim Ändra Värde"
+msgstr "Anim Ändra Nyckelram Tid"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
@@ -88,16 +87,15 @@ msgstr "Ändra Anim Spårets Värde Läge"
#: editor/animation_editor.cpp
msgid "Anim Track Change Wrap Mode"
-msgstr ""
+msgstr "Anim Spåra Ändra Linda om Läge"
#: editor/animation_editor.cpp
msgid "Edit Node Curve"
msgstr "Redigera Nodkurva"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Edit Selection Curve"
-msgstr "Redigera Urval Kurva"
+msgstr "Redigera Urvalsurva"
#: editor/animation_editor.cpp
msgid "Anim Delete Keys"
@@ -7903,6 +7901,11 @@ msgstr "Projekt"
msgid "Warnings"
msgstr "Varning"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Visa Filer"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index d7910c2c87..d3d80facc3 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -7274,6 +7274,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 4db8459f1b..2393ca98a9 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -7359,6 +7359,11 @@ msgstr "Build โปรเจกต์"
msgid "Warnings"
msgstr "คำเตือน"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "ดูไฟล์"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "สิ้นสุดสแตคข้อผิดพลาดภายใน"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 292cec4063..abe7d485fa 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -17,18 +17,19 @@
# razah <icnikerazah@gmail.com>, 2017-2018.
# stnmycri <satenmeycri@gmail.com>, 2017-2018.
# Yavuz Günay <yavuzgunay@gmail.com>, 2017.
+# Onur Sanır <onursanir@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-10 09:46+0000\n"
-"Last-Translator: Aykut YILDIRIM <aykutyildirim@windowslive.com>\n"
+"PO-Revision-Date: 2018-07-07 20:42+0000\n"
+"Last-Translator: Onur Sanır <onursanir@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0.1-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -5696,9 +5697,8 @@ msgid "Options"
msgstr "Seçenekler"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Has,Many,Options"
-msgstr "Bir Çok,Seçenek,Var!"
+msgstr "Birçok,Seçenek,Var"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -7438,6 +7438,11 @@ msgstr "Projeyi İnşa et"
msgid "Warnings"
msgstr "Uyarılar"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Dosyaları Görüntüle"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "İç özel durum yığını izlemesinin sonu"
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 067c7be724..d940561131 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -7447,6 +7447,11 @@ msgstr "Зібрати проект"
msgid "Warnings"
msgstr "Попередження"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Перегляд файлів"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Кінець трасування стека для внутрішнього виключення"
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 0162eb0788..3857bff9b0 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -7331,6 +7331,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 6651bd170c..faf77300b8 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -2,25 +2,24 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# 01lifeleft <01lifeleft@gmail.com>, 2018.
# Dlean Jeans <dleanjeans@gmail.com>, 2018.
# Hai Le <dark.hades.1102@gmail.com>, 2017.
# Nguyễn Tuấn Anh <anhnt.fami@gmail.com>, 2017.
# Tung Le <tungkradle@gmail.com>, 2017.
-#
+# 38569459 <xxx38569459@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-04-18 15:44+0000\n"
-"Last-Translator: 01lifeleft <01lifeleft@gmail.com>\n"
+"PO-Revision-Date: 2018-07-22 06:42+0000\n"
+"Last-Translator: 38569459 <xxx38569459@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/"
"godot/vi/>\n"
"Language: vi\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -141,24 +140,24 @@ msgstr "Chọn Scale"
#: editor/animation_editor.cpp
msgid "Scale From Cursor"
-msgstr ""
+msgstr "Scale từ trỏ chuột"
#: editor/animation_editor.cpp
msgid "Goto Next Step"
-msgstr ""
+msgstr "Đến Step tiếp theo"
#: editor/animation_editor.cpp
msgid "Goto Prev Step"
-msgstr ""
+msgstr "Đến Step trước đó"
#: editor/animation_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
msgid "Linear"
-msgstr ""
+msgstr "Tuyến"
#: editor/animation_editor.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
-msgstr ""
+msgstr "Cố định"
#: editor/animation_editor.cpp
msgid "In"
@@ -178,11 +177,11 @@ msgstr "Ngoài-Trong"
#: editor/animation_editor.cpp
msgid "Transitions"
-msgstr ""
+msgstr "Chuyển tiếp"
#: editor/animation_editor.cpp
msgid "Optimize Animation"
-msgstr ""
+msgstr "Tối ưu Animation"
#: editor/animation_editor.cpp
msgid "Clean-Up Animation"
@@ -190,11 +189,11 @@ msgstr "Dọn dẹp Animation"
#: editor/animation_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr ""
+msgstr "Tạo track mới cho %s và chèn key?"
#: editor/animation_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr ""
+msgstr "Tạo %d track mới và chèn key?"
#: editor/animation_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/plugins/abstract_polygon_2d_editor.cpp
@@ -210,15 +209,15 @@ msgstr "Tạo & Chèn Anim"
#: editor/animation_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr ""
+msgstr "Chèn Track & Key Anim"
#: editor/animation_editor.cpp
msgid "Anim Insert Key"
-msgstr ""
+msgstr "Chèn Key Anim"
#: editor/animation_editor.cpp
msgid "Change Anim Len"
-msgstr ""
+msgstr "Đổi độ dài Anim"
#: editor/animation_editor.cpp
msgid "Change Anim Loop"
@@ -226,23 +225,25 @@ msgstr "Đổi vòng lặp Anim"
#: editor/animation_editor.cpp
msgid "Anim Create Typed Value Key"
-msgstr ""
+msgstr "Tạo Key để nhập giá trị Anim"
#: editor/animation_editor.cpp
msgid "Anim Insert"
msgstr "Chèn Anim"
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Anim Scale Keys"
-msgstr ""
+msgstr "Anim Scale Keys"
#: editor/animation_editor.cpp
msgid "Anim Add Call Track"
msgstr "Thêm Track Gọi Function"
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Animation zoom."
-msgstr ""
+msgstr "Phóng Animation."
#: editor/animation_editor.cpp
msgid "Length (s):"
@@ -266,27 +267,27 @@ msgstr "Mở/Tắt lặp animation."
#: editor/animation_editor.cpp
msgid "Add new tracks."
-msgstr ""
+msgstr "Thêm track mới."
#: editor/animation_editor.cpp
msgid "Move current track up."
-msgstr ""
+msgstr "Di chuyển track lên."
#: editor/animation_editor.cpp
msgid "Move current track down."
-msgstr ""
+msgstr "Di chuyển track xuống."
#: editor/animation_editor.cpp
msgid "Remove selected track."
-msgstr ""
+msgstr "Bỏ track đang chọn."
#: editor/animation_editor.cpp
msgid "Track tools"
-msgstr ""
+msgstr "Công cụ Track"
#: editor/animation_editor.cpp
msgid "Enable editing of individual keys by clicking them."
-msgstr ""
+msgstr "Cho phép chỉnh sửa từng key riêng bằng cách chọn chúng."
#: editor/animation_editor.cpp
msgid "Anim. Optimizer"
@@ -306,162 +307,171 @@ msgstr ""
#: editor/animation_editor.cpp
msgid "Optimize"
-msgstr ""
+msgstr "Tối ưu"
#: editor/animation_editor.cpp
msgid "Select an AnimationPlayer from the Scene Tree to edit animations."
msgstr "Chọn một AnimationPlayer từ Scene Tree để chỉnh sửa animation."
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Key"
-msgstr ""
+msgstr "Mã"
#: editor/animation_editor.cpp
msgid "Transition"
-msgstr ""
+msgstr "Chuyển tiếp"
#: editor/animation_editor.cpp
msgid "Scale Ratio:"
-msgstr ""
+msgstr "Tỉ lệ Scale:"
#: editor/animation_editor.cpp
msgid "Call Functions in Which Node?"
-msgstr ""
+msgstr "Gọi Function từ Node nào?"
#: editor/animation_editor.cpp
msgid "Remove invalid keys"
-msgstr ""
+msgstr "Hủy key không đúng chuẩn"
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "Gỡ bỏ track trống và không tìm thấy"
#: editor/animation_editor.cpp
msgid "Clean-up all animations"
-msgstr ""
+msgstr "Dọn dẹp tất cả animations"
#: editor/animation_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr ""
+msgstr "Dọn dẹp tất cả Animation (KHÔNG THỂ HỒI LẠI)"
#: editor/animation_editor.cpp
msgid "Clean-Up"
-msgstr ""
+msgstr "Dọn dẹp"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr ""
+msgstr "Đổi lại size Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr ""
+msgstr "Đổi loại giá trị Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr ""
+msgstr "Đổi giá trị Array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr ""
+msgstr "Đến Dòng"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr ""
+msgstr "Dòng số:"
#: editor/code_editor.cpp
msgid "No Matches"
-msgstr ""
+msgstr "Không tìm thấy"
#: editor/code_editor.cpp
msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp
+#, fuzzy
msgid "Match Case"
-msgstr ""
+msgstr "Trùng khớp"
#: editor/code_editor.cpp
msgid "Whole Words"
-msgstr ""
+msgstr "Cả từ"
#: editor/code_editor.cpp
msgid "Replace"
-msgstr ""
+msgstr "Thay thế"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr ""
+msgstr "Thay thế tất cả"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr ""
+msgstr "Chỉ lựa chọn"
#: editor/code_editor.cpp
msgid "Zoom In"
-msgstr ""
+msgstr "Phóng to"
#: editor/code_editor.cpp
msgid "Zoom Out"
-msgstr ""
+msgstr "Thu nhỏ"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr ""
+msgstr "Đặt lại phóng"
#: editor/code_editor.cpp editor/script_editor_debugger.cpp
msgid "Line:"
-msgstr ""
+msgstr "Dòng:"
#: editor/code_editor.cpp
+#, fuzzy
msgid "Col:"
-msgstr ""
+msgstr "Col:"
#: editor/connections_dialog.cpp
msgid "Method in target Node must be specified!"
-msgstr ""
+msgstr "Cách thức trong Node được chọn phải được ghi rõ!"
#: editor/connections_dialog.cpp
msgid ""
"Target method not found! Specify a valid method or attach a script to target "
"Node."
msgstr ""
+"Cách thức của đối tượng không tìm thấy! ghi rõ một cách thức hợp lệ hoặc "
+"đính kèm một script cho đối tượng Node."
#: editor/connections_dialog.cpp
msgid "Connect To Node:"
-msgstr ""
+msgstr "Kết nối đến Node:"
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
msgid "Add"
-msgstr ""
+msgstr "Thêm"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
-msgstr ""
+msgstr "Xóa"
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Add Extra Call Argument:"
-msgstr ""
+msgstr "Thêm đối số:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
msgstr ""
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Path to Node:"
-msgstr ""
+msgstr "Đường đến Node:"
#: editor/connections_dialog.cpp
msgid "Make Function"
-msgstr ""
+msgstr "Tạo Function"
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Deferred"
-msgstr ""
+msgstr "Hoãn lại"
#: editor/connections_dialog.cpp
msgid "Oneshot"
@@ -479,45 +489,45 @@ msgstr ""
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr ""
+msgstr "Tắt"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr ""
+msgstr "Kết nối"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr ""
+msgstr "Kết nối '%s' đến '%s'"
#: editor/connections_dialog.cpp
msgid "Connecting Signal:"
-msgstr ""
+msgstr "Đang kết nối Signal:"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr ""
+msgstr "Hủy kết nối '%s' từ '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
-msgstr ""
+msgstr "Kết nối..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_editor_plugin.cpp
msgid "Disconnect"
-msgstr ""
+msgstr "Hủy kết nối"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr ""
+msgstr "Tín hiệu"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr ""
+msgstr "Đổi %s Type"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Change"
-msgstr ""
+msgstr "Đổi"
#: editor/create_dialog.cpp
msgid "Create New %s"
@@ -526,38 +536,39 @@ msgstr "Tạo %s Mới"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
msgid "Favorites:"
-msgstr ""
+msgstr "Ưa thích:"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
msgid "Recent:"
-msgstr ""
+msgstr "Gần đây:"
#: editor/create_dialog.cpp editor/editor_node.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp
#: editor/quick_open.cpp
msgid "Search:"
-msgstr ""
+msgstr "Tìm kiếm:"
#: editor/create_dialog.cpp editor/editor_help.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp
#: editor/quick_open.cpp
msgid "Matches:"
-msgstr ""
+msgstr "Phù hợp:"
#: editor/create_dialog.cpp editor/editor_help.cpp
#: editor/plugins/asset_library_editor_plugin.cpp editor/property_selector.cpp
#: editor/script_editor_debugger.cpp
msgid "Description:"
-msgstr ""
+msgstr "Mô tả:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
-msgstr ""
+msgstr "Tìm kiếm thay thế cho:"
#: editor/dependency_editor.cpp
+#, fuzzy
msgid "Dependencies For:"
-msgstr ""
+msgstr "Phần phụ thuộc cho:"
#: editor/dependency_editor.cpp
msgid ""
@@ -2017,12 +2028,14 @@ msgid "Issue Tracker"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Community"
-msgstr ""
+msgstr "Cộng đồng"
#: editor/editor_node.cpp
+#, fuzzy
msgid "About"
-msgstr ""
+msgstr "Thông tin"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -4223,7 +4236,7 @@ msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
msgid "Volume"
-msgstr ""
+msgstr "Âm lượng"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Emission Source: "
@@ -4265,7 +4278,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Select Points"
-msgstr ""
+msgstr "Chọn Points"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -4275,12 +4288,12 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Click: Add Point"
-msgstr ""
+msgstr "Nhấp: Tạo Point"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Right Click: Delete Point"
-msgstr ""
+msgstr "Nhấp chuột phải: Xóa Point"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Select Control Points (Shift+Drag)"
@@ -4299,7 +4312,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Delete Point"
-msgstr ""
+msgstr "Xóa Point"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -4562,27 +4575,27 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme"
-msgstr ""
+msgstr "Lưu Theme"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As"
-msgstr ""
+msgstr "Lưu Theme thành"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close Docs"
-msgstr ""
+msgstr "Đóng Docs"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
-msgstr ""
+msgstr "Đóng tất cả"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
-msgstr ""
+msgstr "Đóng tất cả Tab"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
-msgstr ""
+msgstr "Chạy"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
@@ -4591,12 +4604,12 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find..."
-msgstr ""
+msgstr "Tìm..."
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr ""
+msgstr "Tìm tiếp theo"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
@@ -4613,7 +4626,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr ""
+msgstr "Tiếp tục"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
@@ -4645,11 +4658,11 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Discard"
-msgstr ""
+msgstr "Hủy"
#: editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
-msgstr ""
+msgstr "Tạo Script"
#: editor/plugins/script_editor_plugin.cpp
msgid ""
@@ -4680,7 +4693,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "Pick Color"
-msgstr ""
+msgstr "Chọn màu"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Case"
@@ -4701,13 +4714,13 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Cut"
-msgstr ""
+msgstr "Cắt"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
-msgstr ""
+msgstr "Copy"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6252,8 +6265,9 @@ msgid "Project Settings (project.godot)"
msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+#, fuzzy
msgid "General"
-msgstr ""
+msgstr "Tổng quan"
#: editor/project_settings_editor.cpp editor/property_editor.cpp
msgid "Property:"
@@ -7283,6 +7297,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 48e30ceab3..51e0181fc8 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -7372,6 +7372,11 @@ msgstr "构建项目"
msgid "Warnings"
msgstr "警告"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "查看文件"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "内部异常堆栈追朔结束"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index 568390a7a8..de03512af1 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -7589,6 +7589,11 @@ msgstr "專案"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "檔案"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 38b565a37f..df0c474322 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Allen H <w84miracle@gmail.com>, 2017.
# Billy SU <g4691821@gmail.com>, 2018.
# Chao Yu <casd82@gmail.com>, 2017.
@@ -12,19 +11,18 @@
# popcade <popcade@gmail.com>, 2016.
# Qing <icinriiq@gmail.com>, 2018.
# Sam Pan <sampan66@gmail.com>, 2016.
-#
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-04-24 09:35+0000\n"
-"Last-Translator: Qing <icinriiq@gmail.com>\n"
+"PO-Revision-Date: 2018-07-15 16:35+0000\n"
+"Last-Translator: Kisaragi Hiu <mail@kisaragi-hiu.com>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
"Language: zh_TW\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -35,9 +33,8 @@ msgid "All Selection"
msgstr "所有的選擇"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
-msgstr "動畫更改座標"
+msgstr "動畫更改關鍵幀時間"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
@@ -52,9 +49,8 @@ msgid "Anim Change Keyframe Value"
msgstr "動畫更改關鍵幀數值"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Call"
-msgstr "動畫改變呼叫"
+msgstr "動畫更改呼叫"
#: editor/animation_editor.cpp
msgid "Anim Add Track"
@@ -345,7 +341,7 @@ msgstr "移除無效按鍵"
#: editor/animation_editor.cpp
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "刪除未解決或是空的軌道"
#: editor/animation_editor.cpp
msgid "Clean-up all animations"
@@ -523,9 +519,8 @@ msgid "Signals"
msgstr "信號"
#: editor/create_dialog.cpp
-#, fuzzy
msgid "Change %s Type"
-msgstr "變更鏡頭尺寸"
+msgstr "變更 %s 尺寸"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -533,9 +528,8 @@ msgid "Change"
msgstr "更換"
#: editor/create_dialog.cpp
-#, fuzzy
msgid "Create New %s"
-msgstr "新增"
+msgstr "新增 %s"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
@@ -618,7 +612,7 @@ msgstr "相依性編輯器"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr ""
+msgstr "搜尋替代資源:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help.cpp editor/editor_node.cpp editor/filesystem_dock.cpp
@@ -670,7 +664,7 @@ msgstr "修復相依性"
#: editor/dependency_editor.cpp
msgid "Errors loading!"
-msgstr ""
+msgstr "載入錯誤!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
@@ -682,7 +676,7 @@ msgstr "擁有"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr ""
+msgstr "沒有明定擁有者的資源:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Orphan Resource Explorer"
@@ -701,16 +695,19 @@ msgid "Delete"
msgstr "刪除"
#: editor/dictionary_property_edit.cpp
+#, fuzzy
msgid "Change Dictionary Key"
-msgstr ""
+msgstr "改變字典 key"
#: editor/dictionary_property_edit.cpp
+#, fuzzy
msgid "Change Dictionary Value"
-msgstr ""
+msgstr "改變字典 value"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Thanks from the Godot community!"
-msgstr ""
+msgstr "Godot 社群感謝你!"
#: editor/editor_about.cpp
msgid "Thanks!"
@@ -718,7 +715,7 @@ msgstr "謝謝!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
-msgstr ""
+msgstr "Godot Engine 貢獻者"
#: editor/editor_about.cpp
msgid "Project Founders"
@@ -726,12 +723,11 @@ msgstr "專案創始人"
#: editor/editor_about.cpp
msgid "Lead Developer"
-msgstr ""
+msgstr "主開發者"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Project Manager "
-msgstr "專案創始人"
+msgstr "專案管理人 "
#: editor/editor_about.cpp
msgid "Developers"
@@ -739,35 +735,38 @@ msgstr "開發者"
#: editor/editor_about.cpp
msgid "Authors"
-msgstr ""
+msgstr "作者"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr ""
+msgstr "白金贊助"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr ""
+msgstr "黃金贊助"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Mini Sponsors"
-msgstr ""
+msgstr "迷你贊助"
#: editor/editor_about.cpp
msgid "Gold Donors"
-msgstr ""
+msgstr "黃金捐贈者"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Silver Donors"
-msgstr ""
+msgstr "白銀捐贈者"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Bronze Donors"
-msgstr ""
+msgstr "紅銅捐贈者"
#: editor/editor_about.cpp
msgid "Donors"
-msgstr ""
+msgstr "捐贈者"
#: editor/editor_about.cpp
msgid "License"
@@ -775,7 +774,7 @@ msgstr "授權"
#: editor/editor_about.cpp
msgid "Thirdparty License"
-msgstr ""
+msgstr "第三方授權條款"
#: editor/editor_about.cpp
msgid ""
@@ -784,14 +783,16 @@ msgid ""
"is an exhaustive list of all such thirdparty components with their "
"respective copyright statements and license terms."
msgstr ""
+"Godot Engine 依賴著許多與 MIT 授權條款相容、自由開源的第三方函式庫。以下是這"
+"些第三方元件的完整列表,附有它們各自的著作權宣示與授權條款。"
#: editor/editor_about.cpp
msgid "All Components"
-msgstr ""
+msgstr "所有元件"
#: editor/editor_about.cpp
msgid "Components"
-msgstr ""
+msgstr "元件"
#: editor/editor_about.cpp
msgid "Licenses"
@@ -799,21 +800,20 @@ msgstr "授權"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Error opening package file, not in zip format."
-msgstr ""
+msgstr "開啟套件檔案出錯,非 zip 格式。"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Uncompressing Assets"
-msgstr "(重新)載入素材"
+msgstr "正在解壓縮素材"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package Installed Successfully!"
-msgstr ""
+msgstr "套件安裝成功!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr ""
+msgstr "成功!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -821,147 +821,148 @@ msgid "Install"
msgstr "安裝"
#: editor/editor_asset_installer.cpp
+#, fuzzy
msgid "Package Installer"
-msgstr ""
+msgstr "套件安裝"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
-msgstr ""
+msgstr "喇叭"
#: editor/editor_audio_buses.cpp
msgid "Add Effect"
-msgstr ""
+msgstr "新增效果"
#: editor/editor_audio_buses.cpp
msgid "Rename Audio Bus"
-msgstr ""
+msgstr "重新命名 Audio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Change Audio Bus Volume"
-msgstr "重設縮放大小"
+msgstr "變更 Audio Bus 音量"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Toggle Audio Bus Solo"
-msgstr ""
+msgstr "切換 Audio Bus 的 Solo"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Toggle Audio Bus Mute"
-msgstr ""
+msgstr "切換 Audio Bus 的 Mute"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Toggle Audio Bus Bypass Effects"
-msgstr ""
+msgstr "切換 Audio Bus 忽略效果"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr ""
+msgstr "選擇 Audio Bus 輸出地點"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr ""
+msgstr "新增 Audio Bus 效果"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr ""
+msgstr "移動 Bus 效果"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr ""
+msgstr "刪除 Bus 效果"
#: editor/editor_audio_buses.cpp
msgid "Audio Bus, Drag and Drop to rearrange."
-msgstr ""
+msgstr "Audio Bus。拖放以重新排列。"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Solo"
-msgstr ""
+msgstr "Solo"
#: editor/editor_audio_buses.cpp
msgid "Mute"
msgstr "靜音"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Bypass"
-msgstr ""
+msgstr "忽略效果 (Bypass)"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Bus options"
-msgstr "除錯選項"
+msgstr "Bus 選項"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr ""
+msgstr "製作複本"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Reset Volume"
-msgstr "重設縮放大小"
+msgstr "重設音量"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Delete Effect"
-msgstr "刪除"
+msgstr "刪除效果"
#: editor/editor_audio_buses.cpp
msgid "Audio"
-msgstr ""
+msgstr "聲音"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "新增 Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "Master Bus 不能被刪除!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr ""
+msgstr "刪除 Audio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Duplicate Audio Bus"
-msgstr "複製所選"
+msgstr "製作 Audio Bus 的複本"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Reset Bus Volume"
-msgstr "重設縮放大小"
+msgstr "重設 Bus 音量"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr ""
+msgstr "移動 Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr ""
+msgstr "另存 Audio Bus 配置為..."
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Location for New Layout..."
-msgstr ""
+msgstr "新配置的位置..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr ""
+msgstr "開啟 Audio Bus 配置"
#: editor/editor_audio_buses.cpp
msgid "There is no 'res://default_bus_layout.tres' file."
-msgstr ""
+msgstr "「res://default_bus_layout.tres」檔案不存在。"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr ""
+msgstr "檔案格式不正確,不是 Audio Bus 配置檔。"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr ""
+msgstr "新增 Bus"
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr ""
+msgstr "建立新的 Bus 配置。"
#: editor/editor_audio_buses.cpp editor/property_editor.cpp
#: editor/script_create_dialog.cpp
@@ -970,7 +971,7 @@ msgstr "載入"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr ""
+msgstr "讀取現存的 Bus 配置。"
#: editor/editor_audio_buses.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -979,7 +980,7 @@ msgstr "另存新檔"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr ""
+msgstr "儲存目前的 Bus 配置到檔案裡。"
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -987,7 +988,7 @@ msgstr "載入預設值"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr ""
+msgstr "載入預設的 Bus 配置。"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -999,7 +1000,7 @@ msgstr "合法字元:"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing engine class name."
-msgstr ""
+msgstr "不正確的名字。名字不能與現有的 engine class 名衝突。"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing buit-in type name."
@@ -1022,16 +1023,19 @@ msgid "Not in resource path."
msgstr "在資源路徑中找不到"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Add AutoLoad"
-msgstr ""
+msgstr "新增 AutoLoad"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Autoload '%s' already exists!"
-msgstr ""
+msgstr "Autoload「%s」已經存在!"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Rename Autoload"
-msgstr ""
+msgstr "重新命名 Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
@@ -1039,19 +1043,21 @@ msgstr ""
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
-msgstr ""
+msgstr "移動 Autoload"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Remove Autoload"
-msgstr ""
+msgstr "刪除 Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Enable"
msgstr "啟用"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Rearrange Autoloads"
-msgstr ""
+msgstr "重新排列 Autoload"
#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
#: scene/gui/file_dialog.cpp
@@ -1084,16 +1090,18 @@ msgid "Updating scene..."
msgstr "更新場景中..."
#: editor/editor_data.cpp
+#, fuzzy
msgid "[empty]"
-msgstr ""
+msgstr "(空)"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr ""
+msgstr "(未儲存)"
#: editor/editor_dir_dialog.cpp
+#, fuzzy
msgid "Please select a base directory first"
-msgstr ""
+msgstr "請先選擇一個基底的資料夾"
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1122,7 +1130,7 @@ msgstr "選擇"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr ""
+msgstr "儲存檔案:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1137,22 +1145,20 @@ msgid "File Exists, Overwrite?"
msgstr "檔案已經存在, 要覆寫嗎?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select Current Folder"
-msgstr "新增資料夾"
+msgstr "選擇目前的資料夾"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr ""
+msgstr "複製路徑"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Show In File Manager"
-msgstr ""
+msgstr "在檔案管理員內顯示"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Folder..."
-msgstr "新增資料夾"
+msgstr "新增資料夾..."
#: editor/editor_file_dialog.cpp
msgid "Refresh"
@@ -1160,7 +1166,7 @@ msgstr "重新整理"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr ""
+msgstr "可認得全部"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
@@ -1168,7 +1174,7 @@ msgstr "所有類型檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
-msgstr ""
+msgstr "開啟檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
@@ -1190,7 +1196,7 @@ msgstr "儲存"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr ""
+msgstr "儲存檔案"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -1209,12 +1215,13 @@ msgid "Toggle Hidden Files"
msgstr "切換顯示隱藏檔案"
#: editor/editor_file_dialog.cpp
+#, fuzzy
msgid "Toggle Favorite"
-msgstr ""
+msgstr "切換最愛"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr ""
+msgstr "切換模式"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
@@ -1247,8 +1254,9 @@ msgid "File:"
msgstr "檔案:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
msgid "Must use a valid extension."
-msgstr ""
+msgstr "必須使用有效的副檔名。"
#: editor/editor_file_system.cpp
msgid "ScanSources"
@@ -1261,27 +1269,28 @@ msgstr "(重新)載入素材"
#: editor/editor_help.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr ""
+msgstr "搜尋幫助"
#: editor/editor_help.cpp
msgid "Class List:"
-msgstr ""
+msgstr "Class 列表:"
#: editor/editor_help.cpp
msgid "Search Classes"
-msgstr ""
+msgstr "搜尋 Class"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Top"
-msgstr ""
+msgstr "上面"
#: editor/editor_help.cpp editor/property_editor.cpp
msgid "Class:"
-msgstr ""
+msgstr "Class:"
#: editor/editor_help.cpp editor/scene_tree_editor.cpp
msgid "Inherits:"
-msgstr ""
+msgstr "繼承:"
#: editor/editor_help.cpp
msgid "Inherited by:"
@@ -1305,19 +1314,19 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Public Methods:"
-msgstr ""
+msgstr "公開 method:"
#: editor/editor_help.cpp
msgid "GUI Theme Items"
-msgstr ""
+msgstr "介面主題項目"
#: editor/editor_help.cpp
msgid "GUI Theme Items:"
-msgstr ""
+msgstr "介面主題項目:"
#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
-msgstr ""
+msgstr "訊號:"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -1333,11 +1342,11 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Constants"
-msgstr ""
+msgstr "定數"
#: editor/editor_help.cpp
msgid "Constants:"
-msgstr ""
+msgstr "定數:"
#: editor/editor_help.cpp
msgid "Description"
@@ -1345,7 +1354,7 @@ msgstr "描述:"
#: editor/editor_help.cpp
msgid "Online Tutorials:"
-msgstr ""
+msgstr "線上教學:"
#: editor/editor_help.cpp
msgid ""
@@ -1353,20 +1362,25 @@ msgid ""
"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
"url][/color]."
msgstr ""
+"目前沒有這個 class 的教學,你可以[color=$color][url=$url]貢獻一個[/url][/"
+"color]或[color=$color][url=$url2]要求一個[/url][/color]。"
#: editor/editor_help.cpp
msgid "Properties"
msgstr ""
#: editor/editor_help.cpp
+#, fuzzy
msgid "Property Description:"
-msgstr ""
+msgstr "Property 說明:"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this property. Please help us by "
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"目前沒有這個 property 的說明。請幫我們[color=$color][url=$url]貢獻[/url][/"
+"color]一個!"
#: editor/editor_help.cpp
msgid "Methods"
@@ -1374,13 +1388,15 @@ msgstr "方法"
#: editor/editor_help.cpp
msgid "Method Description:"
-msgstr ""
+msgstr "Method 說明:"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this method. Please help us by [color="
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"目前沒有這個 method 的說明。請幫我們[color=$color][url=$url]貢獻[/url][/"
+"color]一個!"
#: editor/editor_help.cpp
msgid "Search Text"
@@ -1408,15 +1424,15 @@ msgstr "輸出:"
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
-msgstr ""
+msgstr "專案輸出失敗,錯誤代碼是 %d。"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr ""
+msgstr "儲存資源錯誤!"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
-msgstr ""
+msgstr "另存資源為..."
#: editor/editor_node.cpp editor/plugins/spatial_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
@@ -1424,16 +1440,17 @@ msgid "I see..."
msgstr "我知道了"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Can't open file for writing:"
-msgstr ""
+msgstr "無法以寫入模式開啟檔案:"
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr ""
+msgstr "要求了不明的檔案格式:"
#: editor/editor_node.cpp
msgid "Error while saving."
-msgstr ""
+msgstr "儲存中發生了錯誤。"
#: editor/editor_node.cpp
msgid "Can't open '%s'."
@@ -1445,11 +1462,12 @@ msgstr "分析 \"%s\" 時發生錯誤。"
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr ""
+msgstr "意料外的檔案結尾 (EOF) '%s'。"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "缺失 '%s' 或它的依存。"
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
@@ -1457,7 +1475,7 @@ msgstr "載入 \"%s\" 時發生錯誤。"
#: editor/editor_node.cpp
msgid "Saving Scene"
-msgstr ""
+msgstr "正在儲存場景"
#: editor/editor_node.cpp
msgid "Analyzing"
@@ -7424,6 +7442,11 @@ msgstr "專案設定"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "過濾檔案..."
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""