summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/animation_editor.cpp18
-rw-r--r--editor/editor_export.cpp143
-rw-r--r--editor/editor_export.h5
-rw-r--r--editor/editor_node.cpp33
-rw-r--r--editor/editor_node.h3
-rw-r--r--editor/editor_settings.cpp5
-rw-r--r--editor/import/resource_importer_obj.cpp7
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp4
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp434
-rw-r--r--editor/plugins/spatial_editor_plugin.h22
-rw-r--r--editor/project_export.cpp2
-rw-r--r--editor/scene_tree_dock.cpp3
-rw-r--r--editor/script_create_dialog.cpp519
-rw-r--r--editor/script_create_dialog.h18
-rw-r--r--editor/script_editor_debugger.cpp32
-rw-r--r--editor/translations/ar.po3
-rw-r--r--editor/translations/bg.po3
-rw-r--r--editor/translations/bn.po3
-rw-r--r--editor/translations/ca.po3
-rw-r--r--editor/translations/cs.po3
-rw-r--r--editor/translations/da.po3
-rw-r--r--editor/translations/de.po3
-rw-r--r--editor/translations/de_CH.po3
-rw-r--r--editor/translations/editor.pot3
-rw-r--r--editor/translations/el.po3
-rw-r--r--editor/translations/es.po3
-rw-r--r--editor/translations/es_AR.po3
-rwxr-xr-xeditor/translations/extract.py3
-rw-r--r--editor/translations/fa.po3
-rw-r--r--editor/translations/fr.po3
-rw-r--r--editor/translations/hu.po3
-rw-r--r--editor/translations/id.po3
-rw-r--r--editor/translations/it.po3
-rw-r--r--editor/translations/ja.po3
-rw-r--r--editor/translations/ko.po3
-rw-r--r--editor/translations/nb.po3
-rw-r--r--editor/translations/nl.po3
-rw-r--r--editor/translations/pl.po3
-rw-r--r--editor/translations/pr.po3
-rw-r--r--editor/translations/pt_BR.po3
-rw-r--r--editor/translations/pt_PT.po3
-rw-r--r--editor/translations/ru.po3
-rw-r--r--editor/translations/sk.po3
-rw-r--r--editor/translations/sl.po3
-rw-r--r--editor/translations/th.po3
-rw-r--r--editor/translations/tr.po3
-rw-r--r--editor/translations/ur_PK.po3
-rw-r--r--editor/translations/zh_CN.po3
-rw-r--r--editor/translations/zh_HK.po3
-rw-r--r--editor/translations/zh_TW.po3
51 files changed, 894 insertions, 463 deletions
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp
index 63ed27e60c..1e6562fcf2 100644
--- a/editor/animation_editor.cpp
+++ b/editor/animation_editor.cpp
@@ -1871,21 +1871,35 @@ void AnimationKeyEditor::_track_editor_gui_input(const InputEvent &p_input) {
if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) {
if (mb.mod.command) {
+
zoom->set_value(zoom->get_value() + zoom->get_step());
} else {
- v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8);
+
+ v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * mb.factor / 8);
}
}
if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) {
if (mb.mod.command) {
+
zoom->set_value(zoom->get_value() - zoom->get_step());
} else {
- v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8);
+
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb.factor / 8);
}
}
+ if (mb.button_index == BUTTON_WHEEL_RIGHT && mb.pressed) {
+
+ h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * mb.factor / 8);
+ }
+
+ if (mb.button_index == BUTTON_WHEEL_LEFT && mb.pressed) {
+
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb.factor / 8);
+ }
+
if (mb.button_index == BUTTON_RIGHT && mb.pressed) {
Point2 mpos = Point2(mb.x, mb.y) - ofs;
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 4796640a3d..3774c8d4c3 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -321,7 +321,7 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat
return OK;
}
-String EditorExportPlatform::find_export_template(String template_file_name) const {
+String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
String base_name = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + _MKSTR(VERSION_STATUS) + "/" + template_file_name;
String user_file = EditorSettings::get_singleton()->get_settings_path() + "/templates/" + base_name;
@@ -342,9 +342,20 @@ String EditorExportPlatform::find_export_template(String template_file_name) con
return system_file;
}
}
- print_line("none,sorry");
- return String(); //not found
+ // Not found
+ if (err) {
+ *err += "No export template found at \"" + user_file + "\"";
+ if (has_system_path)
+ *err += "\n or \"" + system_file + "\".";
+ else
+ *err += ".";
+ }
+ return String(); // not found
+}
+
+bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const {
+ return find_export_template(template_file_name, err) != "";
}
Ref<EditorExportPreset> EditorExportPlatform::create_preset() {
@@ -925,19 +936,47 @@ Ref<Texture> EditorExportPlatformPC::get_logo() const {
bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
- r_missing_templates = false;
+ String err;
+ bool valid = true;
+
+ if (use64 && (!exists_export_template(debug_file_64, &err) || !exists_export_template(release_file_64, &err))) {
+ valid = false;
+ }
+
+ if (!use64 && (!exists_export_template(debug_file_32, &err) || !exists_export_template(release_file_32, &err))) {
+ valid = false;
+ }
+
+ String custom_debug_binary = p_preset->get("custom_template/debug");
+ String custom_release_binary = p_preset->get("custom_template/release");
+
+ if (custom_debug_binary == "" && custom_release_binary == "") {
+ if (!err.empty())
+ r_error = err;
+ return valid;
+ }
+
+ bool dvalid = true;
+ bool rvalid = true;
+
+ if (!FileAccess::exists(custom_debug_binary)) {
+ dvalid = false;
+ err = "Custom debug binary not found.\n";
+ }
- if (find_export_template(release_file_32) == String()) {
- r_missing_templates = true;
- } else if (find_export_template(debug_file_32) == String()) {
- r_missing_templates = true;
- } else if (find_export_template(release_file_64) == String()) {
- r_missing_templates = true;
- } else if (find_export_template(debug_file_64) == String()) {
- r_missing_templates = true;
+ if (!FileAccess::exists(custom_release_binary)) {
+ rvalid = false;
+ err += "Custom release binary not found.\n";
}
- return !r_missing_templates;
+ if (dvalid || rvalid)
+ valid = true;
+ else
+ valid = false;
+
+ if (!err.empty())
+ r_error = err;
+ return valid;
}
String EditorExportPlatformPC::get_binary_extension() const {
@@ -1497,40 +1536,6 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
}
-String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
- String user_file = EditorSettings::get_singleton()->get_settings_path()
- +"/templates/"+template_file_name;
- String system_file=OS::get_singleton()->get_installed_templates_path();
- bool has_system_path=(system_file!="");
- system_file+=template_file_name;
-
- // Prefer user file
- if (FileAccess::exists(user_file)) {
- return user_file;
- }
-
- // Now check system file
- if (has_system_path) {
- if (FileAccess::exists(system_file)) {
- return system_file;
- }
- }
-
- // Not found
- if (err) {
- *err+="No export template found at \""+user_file+"\"";
- if (has_system_path)
- *err+="\n or \""+system_file+"\".";
- else
- *err+=".";
- }
- return "";
-}
-
-bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const {
- return find_export_template(template_file_name,err)!="";
-}
-
///////////////////////////////////////
@@ -2430,50 +2435,6 @@ void EditorExportPlatformPC::set_binary_extension(const String& p_extension) {
binary_extension=p_extension;
}
-bool EditorExportPlatformPC::can_export(String *r_error) const {
-
- String err;
- bool valid=true;
-
- if (use64 && (!exists_export_template(debug_binary64) || !exists_export_template(release_binary64))) {
- valid=false;
- err="No 64 bits export templates found.\nDownload and install export templates.\n";
- }
-
- if (!use64 && (!exists_export_template(debug_binary32) || !exists_export_template(release_binary32))) {
- valid=false;
- err="No 32 bits export templates found.\nDownload and install export templates.\n";
- }
-
- if(custom_debug_binary=="" && custom_release_binary=="") {
- if (r_error) *r_error=err;
- return valid;
- }
-
- bool dvalid = true;
- bool rvalid = true;
-
- if(!FileAccess::exists(custom_debug_binary)) {
- dvalid = false;
- err = "Custom debug binary not found.\n";
- }
-
- if(!FileAccess::exists(custom_release_binary)) {
- rvalid = false;
- err = "Custom release binary not found.\n";
- }
-
- if (dvalid || rvalid)
- valid = true;
- else
- valid = false;
-
- if (r_error)
- *r_error=err;
- return valid;
-}
-
-
EditorExportPlatformPC::EditorExportPlatformPC() {
export_mode=EXPORT_PACK;
diff --git a/editor/editor_export.h b/editor/editor_export.h
index a78762ad80..740f05174b 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -154,7 +154,8 @@ private:
protected:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0;
- String find_export_template(String template_file_name) const;
+ bool exists_export_template(String template_file_name, String *err) const;
+ String find_export_template(String template_file_name, String *err = NULL) const;
void gen_export_flags(Vector<String> &r_flags, int p_flags);
public:
@@ -258,6 +259,8 @@ class EditorExportPlatformPC : public EditorExportPlatform {
String debug_file_32;
String debug_file_64;
+ bool use64;
+
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6b23a02275..698066f188 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1651,7 +1651,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
current_option = -1;
//accept->get_cancel()->hide();
- pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in later in \"Project Settings\" under the 'application' category."));
+ pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category."));
pick_main_scene->popup_centered_minsize();
return;
}
@@ -2689,6 +2689,14 @@ void EditorNode::_editor_select(int p_which) {
editor_plugin_screen = new_editor;
editor_plugin_screen->make_visible(true);
editor_plugin_screen->selected_notify();
+
+ if (EditorSettings::get_singleton()->get("interface/separate_distraction_mode")) {
+ if (p_which == EDITOR_SCRIPT) {
+ set_distraction_free_mode(script_distraction);
+ } else {
+ set_distraction_free_mode(scene_distraction);
+ }
+ }
}
void EditorNode::add_editor_plugin(EditorPlugin *p_editor) {
@@ -4382,7 +4390,25 @@ bool EditorNode::get_docks_visible() const {
void EditorNode::_toggle_distraction_free_mode() {
- set_distraction_free_mode(distraction_free->is_pressed());
+ if (EditorSettings::get_singleton()->get("interface/separate_distraction_mode")) {
+ int screen = -1;
+ for (int i = 0; i < editor_table.size(); i++) {
+ if (editor_plugin_screen == editor_table[i]) {
+ screen = i;
+ break;
+ }
+ }
+
+ if (screen == EDITOR_SCRIPT) {
+ script_distraction = !script_distraction;
+ set_distraction_free_mode(script_distraction);
+ } else {
+ scene_distraction = !scene_distraction;
+ set_distraction_free_mode(scene_distraction);
+ }
+ } else {
+ set_distraction_free_mode(distraction_free->is_pressed());
+ }
}
void EditorNode::set_distraction_free_mode(bool p_enter) {
@@ -4806,6 +4832,9 @@ EditorNode::EditorNode() {
_initializing_addons = false;
docks_visible = true;
+ scene_distraction = false;
+ script_distraction = false;
+
FileAccess::set_backup_save(true);
TranslationServer::get_singleton()->set_enabled(false);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 7de713eae9..fc107bb505 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -357,6 +357,9 @@ private:
bool docks_visible;
ToolButton *distraction_free;
+ bool scene_distraction;
+ bool script_distraction;
+
String _tmp_import_path;
EditorExport *editor_export;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 1b4f77419b..9fd76590a6 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -509,6 +509,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("interface/dim_transition_time", 0.08f);
hints["interface/dim_transition_time"] = PropertyInfo(Variant::REAL, "interface/dim_transition_time", PROPERTY_HINT_RANGE, "0,1,0.001", PROPERTY_USAGE_DEFAULT);
+ set("interface/separate_distraction_mode", false);
+
set("filesystem/directories/autoscan_project_path", "");
hints["filesystem/directories/autoscan_project_path"] = PropertyInfo(Variant::STRING, "filesystem/directories/autoscan_project_path", PROPERTY_HINT_GLOBAL_DIR);
set("filesystem/directories/default_project_path", "");
@@ -589,6 +591,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("editors/3d/emulate_3_button_mouse", false);
set("editors/3d/warped_mouse_panning", true);
+ set("editors/3d/freelook_base_speed", 1);
+ set("editors/3d/freelook_modifier_speed_factor", 5.0);
+
set("editors/2d/bone_width", 5);
set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9));
set("editors/2d/bone_color2", Color(0.75, 0.75, 0.75, 0.9));
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 19fd1208b9..21c2ae6eb3 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -168,18 +168,23 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
if (face[idx].size() == 3) {
int norm = face[idx][2].to_int() - 1;
+ if (norm < 0)
+ norm += normals.size() + 1;
ERR_FAIL_INDEX_V(norm, normals.size(), ERR_PARSE_ERROR);
surf_tool->add_normal(normals[norm]);
}
if (face[idx].size() >= 2 && face[idx][1] != String()) {
-
int uv = face[idx][1].to_int() - 1;
+ if (uv < 0)
+ uv += uvs.size() + 1;
ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_PARSE_ERROR);
surf_tool->add_uv(uvs[uv]);
}
int vtx = face[idx][0].to_int() - 1;
+ if (vtx < 0)
+ vtx += vertices.size() + 1;
ERR_FAIL_INDEX_V(vtx, vertices.size(), ERR_PARSE_ERROR);
Vector3 vertex = vertices[vtx];
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 430a5adeb1..27be6ea8f0 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1049,7 +1049,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
return;
float prev_zoom = zoom;
- zoom = zoom * 0.95;
+ zoom = zoom * (1 - (0.05 * b.factor));
{
Point2 ofs(b.x, b.y);
ofs = ofs / prev_zoom - ofs / zoom;
@@ -1067,7 +1067,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
return;
float prev_zoom = zoom;
- zoom = zoom * (1.0 / 0.95);
+ zoom = zoom * ((0.95 + (0.05 * b.factor)) / 0.95);
{
Point2 ofs(b.x, b.y);
ofs = ofs / prev_zoom - ofs / zoom;
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index e84e782580..896a26c8e8 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -522,10 +522,10 @@ void Polygon2DEditor::_uv_input(const InputEvent &p_input) {
} else if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) {
- uv_zoom->set_value(uv_zoom->get_value() / 0.9);
+ uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * mb.factor)));
} else if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) {
- uv_zoom->set_value(uv_zoom->get_value() * 0.9);
+ uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * mb.factor)));
}
} else if (p_input.type == InputEvent::MOUSE_MOTION) {
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index d73349f773..0bd4d7d6d2 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -51,6 +51,12 @@
//#define GIZMO_SCALE_DEFAULT 0.28
#define GIZMO_SCALE_DEFAULT 0.15
+#define ZOOM_MIN_DISTANCE 0.001
+#define ZOOM_MULTIPLIER 1.08
+#define ZOOM_INDICATOR_DELAY_S 1.5
+
+#define FREELOOK_MIN_SPEED 0.1
+
void SpatialEditorViewport::_update_camera() {
if (orthogonal) {
//camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar());
@@ -58,20 +64,26 @@ void SpatialEditorViewport::_update_camera() {
} else
camera->set_perspective(get_fov(), get_znear(), get_zfar());
+ Transform camera_transform = to_camera_transform(cursor);
+
+ if (camera->get_global_transform() != camera_transform) {
+ camera->set_global_transform(camera_transform);
+ update_transform_gizmo_view();
+ }
+}
+
+Transform SpatialEditorViewport::to_camera_transform(const Cursor &p_cursor) const {
Transform camera_transform;
- camera_transform.translate(cursor.pos);
- camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
- camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
+ camera_transform.translate(p_cursor.pos);
+ camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot);
+ camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot);
if (orthogonal)
camera_transform.translate(0, 0, 4096);
else
- camera_transform.translate(0, 0, cursor.distance);
+ camera_transform.translate(0, 0, p_cursor.distance);
- if (camera->get_global_transform() != camera_transform) {
- camera->set_global_transform(camera_transform);
- update_transform_gizmo_view();
- }
+ return camera_transform;
}
String SpatialEditorGizmo::get_handle_name(int p_idx) const {
@@ -669,8 +681,7 @@ void SpatialEditorViewport::_list_select(InputEventMouseButton b) {
selection_menu->add_item(spat->get_name());
selection_menu->set_item_icon(i, icon);
selection_menu->set_item_metadata(i, node_path);
- selection_menu->set_item_tooltip(i, String(spat->get_name()) +
- "\nType: " + spat->get_class() + "\nPath: " + node_path);
+ selection_menu->set_item_tooltip(i, String(spat->get_name()) + "\nType: " + spat->get_class() + "\nPath: " + node_path);
}
selection_menu->set_global_position(Vector2(b.global_x, b.global_y));
@@ -704,19 +715,13 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
switch (b.button_index) {
case BUTTON_WHEEL_UP: {
-
- cursor.distance /= 1.08;
- if (cursor.distance < 0.001)
- cursor.distance = 0.001;
-
+ scale_cursor_distance(is_freelook_active() ? ZOOM_MULTIPLIER : 1.0 / ZOOM_MULTIPLIER);
} break;
- case BUTTON_WHEEL_DOWN: {
-
- if (cursor.distance < 0.001)
- cursor.distance = 0.001;
- cursor.distance *= 1.08;
+ case BUTTON_WHEEL_DOWN: {
+ scale_cursor_distance(is_freelook_active() ? 1.0 / ZOOM_MULTIPLIER : ZOOM_MULTIPLIER);
} break;
+
case BUTTON_RIGHT: {
NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
@@ -729,76 +734,6 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
if (_edit.mode == TRANSFORM_NONE && b.pressed) {
- Plane cursor_plane(cursor.cursor_pos, _get_camera_normal());
-
- Vector3 ray_origin = _get_ray_pos(Vector2(b.x, b.y));
- Vector3 ray_dir = _get_ray(Vector2(b.x, b.y));
-
- //gizmo modify
-
- if (b.mod.control) {
-
- Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(ray_origin, ray_dir, get_tree()->get_root()->get_world()->get_scenario());
-
- Plane p(ray_origin, _get_camera_normal());
-
- float min_d = 1e10;
- bool found = false;
-
- for (int i = 0; i < instances.size(); i++) {
-
- Object *obj = ObjectDB::get_instance(instances[i]);
-
- if (!obj)
- continue;
-
- VisualInstance *vi = obj->cast_to<VisualInstance>();
- if (!vi)
- continue;
-
- //optimize by checking AABB (although should pre sort by distance)
- Rect3 aabb = vi->get_global_transform().xform(vi->get_aabb());
- if (p.distance_to(aabb.get_support(-ray_dir)) > min_d)
- continue;
-
- PoolVector<Face3> faces = vi->get_faces(VisualInstance::FACES_SOLID);
- int c = faces.size();
- if (c > 0) {
- PoolVector<Face3>::Read r = faces.read();
-
- for (int j = 0; j < c; j++) {
-
- Vector3 inters;
- if (r[j].intersects_ray(ray_origin, ray_dir, &inters)) {
-
- float d = p.distance_to(inters);
- if (d < 0)
- continue;
-
- if (d < min_d) {
- min_d = d;
- found = true;
- }
- }
- }
- }
- }
-
- if (found) {
-
- //cursor.cursor_pos=ray_origin+ray_dir*min_d;
- //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos));
- }
-
- } else {
- Vector3 new_pos;
- if (cursor_plane.intersects_ray(ray_origin, ray_dir, &new_pos)) {
-
- //cursor.cursor_pos=new_pos;
- //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos));
- }
- }
-
if (b.mod.alt) {
if (nav_scheme == NAVIGATION_MAYA)
@@ -832,6 +767,9 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
//VisualServer::get_singleton()->poly_clear(indicators);
set_message(TTR("Transform Aborted."), 3);
}
+
+ freelook_active = b.pressed;
+
} break;
case BUTTON_MIDDLE: {
@@ -1043,6 +981,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
surface->update();
}
+
} break;
}
} break;
@@ -1090,7 +1029,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle);
set_message(n + ": " + String(v));
- } else if (m.button_mask & 1) {
+ } else if (m.button_mask & BUTTON_MASK_LEFT) {
if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) {
nav_mode = NAVIGATION_ORBIT;
@@ -1340,13 +1279,15 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
}
}
- } else if (m.button_mask & 2) {
+ } else if (m.button_mask & BUTTON_MASK_RIGHT) {
if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) {
nav_mode = NAVIGATION_ZOOM;
+ } else {
+ nav_mode = NAVIGATION_LOOK;
}
- } else if (m.button_mask & 4) {
+ } else if (m.button_mask & BUTTON_MASK_MIDDLE) {
if (nav_scheme == NAVIGATION_GODOT) {
@@ -1402,12 +1343,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
if (nav_scheme == NAVIGATION_MAYA && m.mod.shift)
pan_speed *= pan_speed_modifier;
- Point2i relative;
- if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) {
- relative = Input::get_singleton()->warp_mouse_motion(m, surface->get_global_rect());
- } else {
- relative = Point2i(m.relative_x, m.relative_y);
- }
+ Point2i relative = _get_warped_mouse_motion(m);
Transform camera_transform;
@@ -1430,21 +1366,22 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int();
if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) {
if (m.relative_x > 0)
- cursor.distance *= 1 - m.relative_x * zoom_speed;
+ scale_cursor_distance(1 - m.relative_x * zoom_speed);
else if (m.relative_x < 0)
- cursor.distance /= 1 + m.relative_x * zoom_speed;
+ scale_cursor_distance(1.0 / (1 + m.relative_x * zoom_speed));
} else {
if (m.relative_y > 0)
- cursor.distance *= 1 + m.relative_y * zoom_speed;
+ scale_cursor_distance(1 + m.relative_y * zoom_speed);
else if (m.relative_y < 0)
- cursor.distance /= 1 - m.relative_y * zoom_speed;
+ scale_cursor_distance(1.0 / (1 - m.relative_y * zoom_speed));
}
} break;
case NAVIGATION_ORBIT: {
- cursor.x_rot += m.relative_y / 80.0;
- cursor.y_rot += m.relative_x / 80.0;
+ Point2i relative = _get_warped_mouse_motion(m);
+ cursor.x_rot += relative.y / 80.0;
+ cursor.y_rot += relative.x / 80.0;
if (cursor.x_rot > Math_PI / 2.0)
cursor.x_rot = Math_PI / 2.0;
if (cursor.x_rot < -Math_PI / 2.0)
@@ -1453,6 +1390,30 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
_update_name();
} break;
+ case NAVIGATION_LOOK: {
+ // Freelook only works properly in perspective.
+ // It technically works too in ortho, but it's awful for a user due to fov being near zero
+ if (!orthogonal) {
+ Point2i relative = _get_warped_mouse_motion(m);
+ cursor.x_rot += relative.y / 120.0;
+ cursor.y_rot += relative.x / 120.0;
+ if (cursor.x_rot > Math_PI / 2.0)
+ cursor.x_rot = Math_PI / 2.0;
+ if (cursor.x_rot < -Math_PI / 2.0)
+ cursor.x_rot = -Math_PI / 2.0;
+
+ // Look is like Orbit, except the cursor translates, not the camera
+ Transform camera_transform = to_camera_transform(cursor);
+ Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 diff = camera->get_translation() - pos;
+ cursor.pos += diff;
+
+ name = "";
+ _update_name();
+ }
+
+ } break;
+
default: {}
}
} break;
@@ -1543,6 +1504,104 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
}
}
+void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
+
+ // Prevents zero distance which would short-circuit any scaling
+ if (cursor.distance < ZOOM_MIN_DISTANCE)
+ cursor.distance = ZOOM_MIN_DISTANCE;
+
+ real_t prev_distance = cursor.distance;
+ cursor.distance *= scale;
+
+ if (cursor.distance < ZOOM_MIN_DISTANCE)
+ cursor.distance = ZOOM_MIN_DISTANCE;
+
+ if (is_freelook_active()) {
+ // In freelook mode, cursor reference is reversed so it needs to be adjusted
+ Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ cursor.pos += (cursor.distance - prev_distance) * forward;
+ }
+
+ zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
+ surface->update();
+}
+
+Point2i SpatialEditorViewport::_get_warped_mouse_motion(const InputEventMouseMotion &p_ev_mouse_motion) const {
+ Point2i relative;
+ if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) {
+ relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
+ } else {
+ relative = Point2i(p_ev_mouse_motion.relative_x, p_ev_mouse_motion.relative_y);
+ }
+ return relative;
+}
+
+void SpatialEditorViewport::_update_freelook(real_t delta) {
+
+ if (!is_freelook_active())
+ return;
+
+ Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0));
+ Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0));
+
+ int key_left = ED_SHORTCUT("spatial_editor/freelook_left", TTR("Freelook Left"), KEY_A)->get_shortcut().key.scancode;
+ int key_right = ED_SHORTCUT("spatial_editor/freelook_right", TTR("Freelook Right"), KEY_D)->get_shortcut().key.scancode;
+ int key_forward = ED_SHORTCUT("spatial_editor/freelook_forward", TTR("Freelook Forward"), KEY_W)->get_shortcut().key.scancode;
+ int key_backwards = ED_SHORTCUT("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), KEY_S)->get_shortcut().key.scancode;
+ int key_up = ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), KEY_Q)->get_shortcut().key.scancode;
+ int key_down = ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_E)->get_shortcut().key.scancode;
+ int key_speed_modifier = ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT)->get_shortcut().key.scancode;
+
+ Vector3 velocity;
+ bool pressed = false;
+ bool speed_modifier = false;
+
+ const Input &input = *Input::get_singleton();
+
+ if (input.is_key_pressed(key_left)) {
+ velocity -= right;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_right)) {
+ velocity += right;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_forward)) {
+ velocity += forward;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_backwards)) {
+ velocity -= forward;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_up)) {
+ velocity += up;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_down)) {
+ velocity -= up;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_speed_modifier)) {
+ speed_modifier = true;
+ }
+
+ if (pressed) {
+ const EditorSettings &s = *EditorSettings::get_singleton();
+ const real_t base_speed = s.get("editors/3d/freelook_base_speed");
+ const real_t modifier_speed_factor = s.get("editors/3d/freelook_modifier_speed_factor");
+
+ real_t speed = base_speed * cursor.distance;
+ if (speed_modifier)
+ speed *= modifier_speed_factor;
+
+ velocity.normalize();
+
+ cursor.pos += velocity * (speed * delta);
+ }
+}
+
void SpatialEditorViewport::set_message(String p_message, float p_time) {
message = p_message;
@@ -1579,6 +1638,17 @@ void SpatialEditorViewport::_notification(int p_what) {
}
*/
+ real_t delta = get_tree()->get_idle_process_time();
+
+ if (zoom_indicator_delay > 0) {
+ zoom_indicator_delay -= delta;
+ if (zoom_indicator_delay <= 0) {
+ surface->update();
+ }
+ }
+
+ _update_freelook(delta);
+
_update_camera();
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -1674,6 +1744,23 @@ void SpatialEditorViewport::_notification(int p_what) {
}
}
+// TODO That should be part of the drawing API...
+static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width = 1.0) {
+
+ // a---b
+ // | |
+ // c---d
+ Vector2 a(rect.pos);
+ Vector2 b(rect.pos.x + rect.size.x, rect.pos.y);
+ Vector2 c(rect.pos.x, rect.pos.y + rect.size.y);
+ Vector2 d(rect.pos + rect.size);
+
+ ci->draw_line(a, b, color, width);
+ ci->draw_line(b, d, color, width);
+ ci->draw_line(d, c, color, width);
+ ci->draw_line(c, a, color, width);
+}
+
void SpatialEditorViewport::_draw() {
if (surface->has_focus()) {
@@ -1730,10 +1817,37 @@ void SpatialEditorViewport::_draw() {
draw_rect = Rect2(Vector2(), s).clip(draw_rect);
- surface->draw_line(draw_rect.pos, draw_rect.pos + Vector2(draw_rect.size.x, 0), Color(0.6, 0.6, 0.1, 0.5), 2.0);
- surface->draw_line(draw_rect.pos + Vector2(draw_rect.size.x, 0), draw_rect.pos + draw_rect.size, Color(0.6, 0.6, 0.1, 0.5), 2.0);
- surface->draw_line(draw_rect.pos + draw_rect.size, draw_rect.pos + Vector2(0, draw_rect.size.y), Color(0.6, 0.6, 0.1, 0.5), 2.0);
- surface->draw_line(draw_rect.pos, draw_rect.pos + Vector2(0, draw_rect.size.y), Color(0.6, 0.6, 0.1, 0.5), 2.0);
+ stroke_rect(surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0);
+
+ } else {
+
+ if (zoom_indicator_delay > 0.0) {
+ // Show indicative zoom factor
+
+ real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
+ real_t max_distance = camera->get_zfar();
+ real_t scale_length = (max_distance - min_distance);
+
+ if (Math::abs(scale_length) > CMP_EPSILON) {
+ real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
+
+ // There is no real maximum distance so that factor can become negative,
+ // Let's make it look asymptotic instead (will decrease slower and slower).
+ if (logscale_t < 0.25)
+ logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+
+ Vector2 surface_size = surface->get_size();
+ real_t h = surface_size.y / 2.0;
+ real_t y = (surface_size.y - h) / 2.0;
+
+ Rect2 r(10, y, 6, h);
+ real_t sy = r.size.y * logscale_t;
+
+ surface->draw_rect(r, Color(1, 1, 1, 0.2));
+ surface->draw_rect(Rect2(r.pos.x, r.pos.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6));
+ stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7));
+ }
+ }
}
}
@@ -2143,6 +2257,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
clicked_includes_current = false;
orthogonal = false;
message_time = 0;
+ zoom_indicator_delay = 0.0;
spatial_editor = p_spatial_editor;
ViewportContainer *c = memnew(ViewportContainer);
@@ -2205,6 +2320,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
preview = NULL;
gizmo_scale = 1.0;
+ freelook_active = false;
+
selection_menu = memnew(PopupMenu);
add_child(selection_menu);
selection_menu->set_custom_minimum_size(Vector2(100, 0));
@@ -2278,7 +2395,7 @@ void SpatialEditor::update_transform_gizmo() {
gizmo.transform.origin = pcenter;
gizmo.transform.basis = gizmo_basis;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->update_transform_gizmo_view();
}
}
@@ -2434,7 +2551,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
Array vp = d["viewports"];
ERR_FAIL_COND(vp.size() > 4);
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->set_state(vp[i]);
}
}
@@ -2726,7 +2843,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_3_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 1; i < VIEWPORTS_COUNT; i++) {
if (i == 1)
viewports[i]->hide();
@@ -2752,7 +2869,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_3_VIEWPORTS_ALT: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 1; i < VIEWPORTS_COUNT; i++) {
if (i == 1)
viewports[i]->hide();
@@ -2778,7 +2895,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_4_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 1; i < VIEWPORTS_COUNT; i++) {
viewports[i]->show();
}
@@ -3149,34 +3266,12 @@ void SpatialEditor::_finish_indicators() {
VisualServer::get_singleton()->free(cursor_mesh);
}
-void SpatialEditor::_instance_scene() {
-#if 0
- EditorNode *en = get_scene()->get_root_node()->cast_to<EditorNode>();
- ERR_FAIL_COND(!en);
- String path = en->get_filesystem_dock()->get_selected_path();
- if (path=="") {
- set_message(TTR("No scene selected to instance!"));
- return;
- }
-
- undo_redo->create_action(TTR("Instance at Cursor"));
-
- Node* scene = en->request_instance_scene(path);
-
- if (!scene) {
- set_message(TTR("Could not instance scene!"));
- undo_redo->commit_action(); //bleh
- return;
- }
-
- Spatial *s = scene->cast_to<Spatial>();
- if (s) {
-
- undo_redo->add_do_method(s,"set_global_transform",Transform(Matrix3(),cursor.cursor_pos));
+bool SpatialEditor::is_any_freelook_active() const {
+ for (unsigned int i = 0; i < VIEWPORTS_COUNT; ++i) {
+ if (viewports[i]->is_freelook_active())
+ return true;
}
-
- undo_redo->commit_action();
-#endif
+ return false;
}
void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
@@ -3203,19 +3298,27 @@ void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
case InputEvent::KEY: {
- const InputEventKey &k = p_event.key;
+ // Note: need to check is_echo because first person movement keys might still be held
+ if (!is_any_freelook_active() && !p_event.is_echo()) {
- if (!k.pressed)
- break;
+ const InputEventKey &k = p_event.key;
+
+ if (!k.pressed)
+ break;
+
+ if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event))
+ _menu_item_pressed(MENU_TOOL_SELECT);
+
+ else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event))
+ _menu_item_pressed(MENU_TOOL_MOVE);
- switch (k.scancode) {
+ else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event))
+ _menu_item_pressed(MENU_TOOL_ROTATE);
- case KEY_Q: _menu_item_pressed(MENU_TOOL_SELECT); break;
- case KEY_W: _menu_item_pressed(MENU_TOOL_MOVE); break;
- case KEY_E: _menu_item_pressed(MENU_TOOL_ROTATE); break;
- case KEY_R: _menu_item_pressed(MENU_TOOL_SCALE); break;
+ else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event))
+ _menu_item_pressed(MENU_TOOL_SCALE);
- case KEY_Z: {
+ else if (ED_IS_SHORTCUT("spatial_editor/display_wireframe", p_event)) {
if (k.mod.shift || k.mod.control || k.mod.command)
break;
@@ -3224,10 +3327,7 @@ void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
} else {
_menu_item_pressed(MENU_VIEW_DISPLAY_WIREFRAME);
}
- } break;
-
-#if 0
-#endif
+ }
}
} break;
@@ -3242,8 +3342,6 @@ void SpatialEditor::_notification(int p_what) {
tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons"));
- instance_button->set_icon(get_icon("SpatialAdd", "EditorIcons"));
- instance_button->hide();
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
@@ -3344,7 +3442,7 @@ void SpatialEditor::_toggle_maximize_view(Object *p_viewport) {
if (!maximized) {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
if (i == index)
viewports[i]->set_area_as_parent_rect();
else
@@ -3352,7 +3450,7 @@ void SpatialEditor::_toggle_maximize_view(Object *p_viewport) {
}
} else {
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < VIEWPORTS_COUNT; i++)
viewports[i]->show();
if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT)))
@@ -3383,7 +3481,6 @@ void SpatialEditor::_bind_methods() {
ClassDB::bind_method("_node_removed", &SpatialEditor::_node_removed);
ClassDB::bind_method("_menu_item_pressed", &SpatialEditor::_menu_item_pressed);
ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action);
- ClassDB::bind_method("_instance_scene", &SpatialEditor::_instance_scene);
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
ClassDB::bind_method("_default_light_angle_input", &SpatialEditor::_default_light_angle_input);
@@ -3399,7 +3496,7 @@ void SpatialEditor::clear() {
settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near", 0.1));
settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far", 1500.0));
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->reset();
}
@@ -3415,7 +3512,7 @@ void SpatialEditor::clear() {
}
}
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER), i == 0);
viewports[i]->viewport->set_as_audio_listener(i == 0);
@@ -3520,12 +3617,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
- instance_button = memnew(Button);
- hbc_menu->add_child(instance_button);
- instance_button->set_flat(true);
- instance_button->connect("pressed", this, "_instance_scene");
- instance_button->hide();
-
VSeparator *vs = memnew(VSeparator);
hbc_menu->add_child(vs);
@@ -3553,6 +3644,13 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F);
ED_SHORTCUT("spatial_editor/align_selection_with_view", TTR("Align Selection With View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
+ ED_SHORTCUT("spatial_editor/tool_select", TTR("Tool Select"), KEY_Q);
+ 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/display_wireframe", TTR("Display Wireframe"), KEY_Z);
+
PopupMenu *p;
transform_menu = memnew(MenuButton);
@@ -3618,7 +3716,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
viewport_base = memnew(Control);
shader_split->add_child(viewport_base);
viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i] = memnew(SpatialEditorViewport(this, editor, i));
viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view");
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 4302927426..01435028ac 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -114,6 +114,8 @@ private:
bool orthogonal;
float gizmo_scale;
+ bool freelook_active;
+
struct _RayResult {
Spatial *item;
@@ -168,7 +170,8 @@ private:
NAVIGATION_NONE,
NAVIGATION_PAN,
NAVIGATION_ZOOM,
- NAVIGATION_ORBIT
+ NAVIGATION_ORBIT,
+ NAVIGATION_LOOK
};
enum TransformMode {
TRANSFORM_NONE,
@@ -203,8 +206,6 @@ private:
struct Cursor {
- Vector3 cursor_pos;
-
Vector3 pos;
float x_rot, y_rot, distance;
bool region_select;
@@ -217,6 +218,10 @@ private:
}
} cursor;
+ void scale_cursor_distance(real_t scale);
+
+ real_t zoom_indicator_delay;
+
RID move_gizmo_instance[3], rotate_gizmo_instance[3];
String last_message;
@@ -227,10 +232,12 @@ private:
//
void _update_camera();
+ Transform to_camera_transform(const Cursor &p_cursor) const;
void _draw();
void _smouseenter();
void _sinput(const InputEvent &p_ie);
+ void _update_freelook(real_t delta);
SpatialEditor *spatial_editor;
Camera *previewing;
@@ -243,6 +250,7 @@ private:
void _selection_result_pressed(int);
void _selection_menu_hide();
void _list_select(InputEventMouseButton b);
+ Point2i _get_warped_mouse_motion(const InputEventMouseMotion &p_ev_mouse_motion) const;
protected:
void _notification(int p_what);
@@ -255,6 +263,7 @@ public:
void set_state(const Dictionary &p_state);
Dictionary get_state() const;
void reset();
+ bool is_freelook_active() const { return freelook_active; }
void focus_selection();
@@ -295,11 +304,13 @@ public:
};
private:
+ static const unsigned int VIEWPORTS_COUNT = 4;
+
EditorNode *editor;
EditorSelection *editor_selection;
Control *viewport_base;
- SpatialEditorViewport *viewports[4];
+ SpatialEditorViewport *viewports[VIEWPORTS_COUNT];
VSplitContainer *shader_split;
HSplitContainer *palette_split;
@@ -385,7 +396,6 @@ private:
};
Button *tool_button[TOOL_MAX];
- Button *instance_button;
MenuButton *transform_menu;
MenuButton *view_menu;
@@ -456,6 +466,8 @@ private:
void _update_default_light_angle();
void _default_light_angle_input(const InputEvent &p_event);
+ bool is_any_freelook_active() const;
+
protected:
void _notification(int p_what);
//void _gui_input(InputEvent p_event);
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 90db23d236..40ffb8e246 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -229,6 +229,8 @@ void ProjectExportDialog::_edit_preset(int p_index) {
}
if (needs_templates)
export_templates_error->show();
+ else
+ export_templates_error->hide();
export_button->set_disabled(true);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 901b259960..835243e401 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -362,8 +362,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
else {
String path = selected->get_filename();
script_create_dialog->config(selected->get_class(), path);
- script_create_dialog->popup_centered(Size2(300, 290));
- //script_create_dialog->popup_centered_minsize();
+ script_create_dialog->popup_centered();
}
} break;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 15c540e132..1e86d8db4b 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -29,12 +29,23 @@
/*************************************************************************/
#include "script_create_dialog.h"
+#include "editor/editor_scale.h"
#include "editor_file_system.h"
#include "global_config.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
#include "script_language.h"
+void ScriptCreateDialog::_notification(int p_what) {
+
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ path_button->set_icon(get_icon("Folder", "EditorIcons"));
+ parent_browse_button->set_icon(get_icon("Folder", "EditorIcons"));
+ }
+ }
+}
+
void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path) {
class_name->set_text("");
@@ -46,6 +57,8 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
initial_bp = "";
file_path->set_text("");
}
+ _lang_changed(current_language);
+ _parent_name_changed(parent_name->get_text());
_class_name_changed("");
_path_changed(file_path->get_text());
}
@@ -85,54 +98,40 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
void ScriptCreateDialog::_class_name_changed(const String &p_name) {
- if (!_validate(parent_name->get_text())) {
- error_label->set_text(TTR("Invalid parent class name or path"));
- error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
- } else if (class_name->is_editable()) {
- if (class_name->get_text() == "") {
- error_label->set_text(TTR("Valid chars:") + " a-z A-Z 0-9 _");
- error_label->add_color_override("font_color", Color(1, 1, 1, 0.6));
- } else if (!_validate(class_name->get_text())) {
- error_label->set_text(TTR("Invalid class name"));
- error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
- } else {
- error_label->set_text(TTR("Valid name"));
- error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
- }
+ if (_validate(class_name->get_text())) {
+ is_class_name_valid = true;
} else {
+ is_class_name_valid = false;
+ }
+ _update_dialog();
+}
- error_label->set_text(TTR("N/A"));
- error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
+
+ if (_validate(parent_name->get_text())) {
+ is_parent_name_valid = true;
+ } else {
+ is_parent_name_valid = false;
}
+ _update_dialog();
}
void ScriptCreateDialog::ok_pressed() {
- if (create_new) {
+ if (is_new_script_created) {
_create_new();
} else {
_load_exist();
}
- create_new = true;
- _update_controls();
+ is_new_script_created = true;
+ _update_dialog();
}
void ScriptCreateDialog::_create_new() {
- if (class_name->is_editable() && !_validate(class_name->get_text())) {
- alert->set_text(TTR("Class name is invalid!"));
- alert->popup_centered_minsize();
- return;
- }
- if (!_validate(parent_name->get_text())) {
- alert->set_text(TTR("Parent class name is invalid!"));
- alert->popup_centered_minsize();
- return;
- }
-
String cname;
- if (class_name->is_editable())
+ if (has_named_classes)
cname = class_name->get_text();
Ref<Script> scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
@@ -143,18 +142,13 @@ void ScriptCreateDialog::_create_new() {
if (cname != "")
scr->set_name(cname);
- if (!internal->is_pressed()) {
+ if (!is_built_in) {
String lpath = GlobalConfig::get_singleton()->localize_path(file_path->get_text());
scr->set_path(lpath);
- if (!path_valid) {
- alert->set_text(TTR("Invalid path!"));
- alert->popup_centered_minsize();
- return;
- }
Error err = ResourceSaver::save(lpath, scr, ResourceSaver::FLAG_CHANGE_PATH);
if (err != OK) {
- alert->set_text(TTR("Could not create script in filesystem."));
- alert->popup_centered_minsize();
+ alert->set_text(TTR("Error - Could not create script in filesystem."));
+ alert->popup_centered();
return;
}
}
@@ -168,9 +162,9 @@ void ScriptCreateDialog::_load_exist() {
String path = file_path->get_text();
RES p_script = ResourceLoader::load(path, "Script");
if (p_script.is_null()) {
- alert->get_ok()->set_text(TTR("Ugh"));
+ alert->get_ok()->set_text(TTR("OK"));
alert->set_text(vformat(TTR("Error loading script from %s"), path));
- alert->popup_centered_minsize();
+ alert->popup_centered();
return;
}
@@ -182,55 +176,59 @@ void ScriptCreateDialog::_lang_changed(int l) {
l = language_menu->get_selected();
if (ScriptServer::get_language(l)->has_named_classes()) {
- class_name->set_editable(true);
+ has_named_classes = true;
} else {
- class_name->set_editable(false);
+ has_named_classes = false;
}
if (ScriptServer::get_language(l)->can_inherit_from_file()) {
- parent_browse_button->show();
+ can_inherit_from_file = true;
} else {
- parent_browse_button->hide();
+ can_inherit_from_file = false;
}
String selected_ext = "." + ScriptServer::get_language(l)->get_extension();
String path = file_path->get_text();
String extension = "";
- if (path.find(".") >= 0) {
- extension = path.get_extension();
- }
-
- if (extension.length() == 0) {
- // add extension if none
- path += selected_ext;
- _path_changed(path);
- } else {
- // change extension by selected language
- List<String> extensions;
- // get all possible extensions for script
- for (int l = 0; l < language_menu->get_item_count(); l++) {
- ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
+ if (path != "") {
+ if (path.find(".") >= 0) {
+ extension = path.get_extension();
}
- for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
- if (E->get().nocasecmp_to(extension) == 0) {
- path = path.get_basename() + selected_ext;
- _path_changed(path);
- break;
+ if (extension.length() == 0) {
+ // add extension if none
+ path += selected_ext;
+ _path_changed(path);
+ } else {
+ // change extension by selected language
+ List<String> extensions;
+ // get all possible extensions for script
+ for (int l = 0; l < language_menu->get_item_count(); l++) {
+ ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
+ }
+
+ for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
+ if (E->get().nocasecmp_to(extension) == 0) {
+ path = path.get_basename() + selected_ext;
+ _path_changed(path);
+ break;
+ }
}
}
+ file_path->set_text(path);
}
- file_path->set_text(path);
- _class_name_changed(class_name->get_text());
+
+ _update_dialog();
}
void ScriptCreateDialog::_built_in_pressed() {
if (internal->is_pressed()) {
- path_vb->hide();
+ is_built_in = true;
} else {
- path_vb->show();
+ is_built_in = false;
}
+ _update_dialog();
}
void ScriptCreateDialog::_browse_path(bool browse_parent) {
@@ -269,40 +267,45 @@ void ScriptCreateDialog::_file_selected(const String &p_file) {
void ScriptCreateDialog::_path_changed(const String &p_path) {
- path_valid = false;
+ is_path_valid = false;
+ is_new_script_created = true;
String p = p_path;
if (p == "") {
-
- path_error_label->set_text(TTR("Path is empty"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Path is empty"));
+ _update_dialog();
return;
}
p = GlobalConfig::get_singleton()->localize_path(p);
if (!p.begins_with("res://")) {
-
- path_error_label->set_text(TTR("Path is not local"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Path is not local"));
+ _update_dialog();
return;
}
if (p.find("/") || p.find("\\")) {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-
if (d->change_dir(p.get_base_dir()) != OK) {
-
- path_error_label->set_text(TTR("Invalid base path"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Invalid base path"));
memdelete(d);
+ _update_dialog();
return;
}
memdelete(d);
}
- FileAccess *f = FileAccess::create(FileAccess::ACCESS_RESOURCES);
- create_new = !f->file_exists(p);
+ /* Does file already exist */
+
+ DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (f->file_exists(p) && !(f->current_is_dir())) {
+ is_new_script_created = false;
+ is_path_valid = true;
+ }
memdelete(f);
+ _update_dialog();
+
+ /* Check file extension */
String extension = p.get_extension();
List<String> extensions;
@@ -313,45 +316,156 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
}
bool found = false;
+ bool match = false;
int index = 0;
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(extension) == 0) {
- language_menu->select(index); // change Language option by extension
+ //FIXME (?) - changing language this way doesn't update controls, needs rework
+ //language_menu->select(index); // change Language option by extension
found = true;
+ if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
+ match = true;
+ }
break;
}
index++;
}
if (!found) {
- path_error_label->set_text(TTR("Invalid extension"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Invalid extension"));
+ _update_dialog();
+ return;
+ }
+
+ if (!match) {
+ _msg_path_valid(false, TTR("Wrong extension chosen"));
+ _update_dialog();
return;
}
- _update_controls();
+ /* All checks passed */
+
+ is_path_valid = true;
+ _update_dialog();
+}
+
+void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
+
+ error_label->set_text(TTR(p_msg));
+ if (valid) {
+ error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ } else {
+ error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
+ }
+}
- path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
- path_valid = true;
+ path_error_label->set_text(TTR(p_msg));
+ if (valid) {
+ path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ } else {
+ path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ }
}
-void ScriptCreateDialog::_update_controls() {
+void ScriptCreateDialog::_update_dialog() {
+
+ bool script_ok = true;
+
+ /* "Add Script Dialog" gui logic and script checks */
+
+ // Is Script Valid (order from top to bottom)
+ get_ok()->set_disabled(true);
+ if (!is_built_in) {
+ if (!is_path_valid) {
+ _msg_script_valid(false, TTR("Invalid Path"));
+ script_ok = false;
+ }
+ }
+ if (has_named_classes && (!is_class_name_valid)) {
+ _msg_script_valid(false, TTR("Invalid class name"));
+ script_ok = false;
+ }
+ if (!is_parent_name_valid) {
+ _msg_script_valid(false, TTR("Invalid inherited parent name or path"));
+ script_ok = false;
+ }
+ if (script_ok) {
+ _msg_script_valid(true, TTR("Script valid"));
+ get_ok()->set_disabled(false);
+ }
+
+ /* Does script have named classes */
- if (create_new) {
- path_error_label->set_text(TTR("Create new script"));
+ if (has_named_classes) {
+ if (is_new_script_created) {
+ class_name->set_editable(true);
+ class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9 and _"));
+ class_name->set_placeholder_alpha(0.3);
+ } else {
+ class_name->set_editable(false);
+ }
+ } else {
+ class_name->set_editable(false);
+ class_name->set_placeholder(TTR("N/A"));
+ class_name->set_placeholder_alpha(1);
+ }
+
+ /* Can script inherit from a file */
+
+ if (can_inherit_from_file) {
+ parent_browse_button->set_disabled(false);
+ } else {
+ parent_browse_button->set_disabled(true);
+ }
+
+ /* Is script Built-in */
+
+ if (is_built_in) {
+ file_path->set_editable(false);
+ path_button->set_disabled(true);
+ re_check_path = true;
+ } else {
+ file_path->set_editable(true);
+ path_button->set_disabled(false);
+ if (re_check_path) {
+ re_check_path = false;
+ _path_changed(file_path->get_text());
+ }
+ }
+
+ /* Is Script created or loaded from existing file */
+
+ if (is_new_script_created) {
+ // New Script Created
get_ok()->set_text(TTR("Create"));
+ parent_name->set_editable(true);
+ parent_browse_button->set_disabled(false);
+ internal->set_disabled(false);
+ if (is_built_in) {
+ _msg_path_valid(true, TTR("Built-in script (into scene file)"));
+ } else {
+ if (script_ok) {
+ _msg_path_valid(true, TTR("Create new script file"));
+ }
+ }
} else {
- path_error_label->set_text(TTR("Load existing script"));
+ // Script Loaded
get_ok()->set_text(TTR("Load"));
+ parent_name->set_editable(false);
+ parent_browse_button->set_disabled(true);
+ internal->set_disabled(true);
+ if (script_ok) {
+ _msg_path_valid(true, TTR("Load existing script file"));
+ }
}
- parent_name->set_editable(create_new);
- internal->set_disabled(!create_new);
}
void ScriptCreateDialog::_bind_methods() {
ClassDB::bind_method("_class_name_changed", &ScriptCreateDialog::_class_name_changed);
+ ClassDB::bind_method("_parent_name_changed", &ScriptCreateDialog::_parent_name_changed);
ClassDB::bind_method("_lang_changed", &ScriptCreateDialog::_lang_changed);
ClassDB::bind_method("_built_in_pressed", &ScriptCreateDialog::_built_in_pressed);
ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
@@ -362,37 +476,100 @@ void ScriptCreateDialog::_bind_methods() {
ScriptCreateDialog::ScriptCreateDialog() {
- /* SNAP DIALOG */
+ editor_settings = EditorSettings::get_singleton();
+ GridContainer *gc = memnew(GridContainer);
VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
- //set_child_rect(vb);
+ HBoxContainer *hb = memnew(HBoxContainer);
+ Label *l = memnew(Label);
+ Control *empty = memnew(Control);
+ Control *empty_h = memnew(Control);
+ Control *empty_v = memnew(Control);
+ PanelContainer *pc = memnew(PanelContainer);
- class_name = memnew(LineEdit);
- VBoxContainer *vb2 = memnew(VBoxContainer);
- vb2->add_child(class_name);
- class_name->connect("text_changed", this, "_class_name_changed");
- error_label = memnew(Label);
- error_label->set_text("valid chars: a-z A-Z 0-9 _");
- error_label->set_align(Label::ALIGN_CENTER);
- vb2->add_child(error_label);
- vb->add_margin_child(TTR("Class Name:"), vb2);
+ /* DIALOG */
- HBoxContainer *hb1 = memnew(HBoxContainer);
- parent_name = memnew(LineEdit);
- parent_name->connect("text_changed", this, "_class_name_changed");
- parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
- hb1->add_child(parent_name);
- parent_browse_button = memnew(Button);
- parent_browse_button->set_text(" .. ");
- parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
- hb1->add_child(parent_browse_button);
- parent_browse_button->hide();
- vb->add_margin_child(TTR("Inherits:"), hb1);
- is_browsing_parent = false;
+ /* Main Controls */
+
+ gc = memnew(GridContainer);
+ gc->set_columns(2);
+
+ /* Error Stylebox Background */
+
+ StyleBoxFlat *sb = memnew(StyleBoxFlat);
+ sb->set_bg_color(Color(0, 0, 0, 0.05));
+ sb->set_light_color(Color(1, 1, 1, 0.05));
+ sb->set_dark_color(Color(1, 1, 1, 0.05));
+ sb->set_border_blend(false);
+ sb->set_border_size(1);
+ sb->set_default_margin(MARGIN_TOP, 10.0 * EDSCALE);
+ sb->set_default_margin(MARGIN_BOTTOM, 10.0 * EDSCALE);
+ sb->set_default_margin(MARGIN_LEFT, 10.0 * EDSCALE);
+ sb->set_default_margin(MARGIN_RIGHT, 10.0 * EDSCALE);
+
+ /* Error Messages Field */
+
+ vb = memnew(VBoxContainer);
+
+ hb = memnew(HBoxContainer);
+ l = memnew(Label);
+ l->set_text(" - ");
+ hb->add_child(l);
+ error_label = memnew(Label);
+ error_label->set_text(TTR("Error!"));
+ error_label->set_align(Label::ALIGN_LEFT);
+ hb->add_child(error_label);
+ vb->add_child(hb);
+
+ hb = memnew(HBoxContainer);
+ l = memnew(Label);
+ l->set_text(" - ");
+ hb->add_child(l);
+ path_error_label = memnew(Label);
+ path_error_label->set_text(TTR("Error!"));
+ path_error_label->set_align(Label::ALIGN_LEFT);
+ hb->add_child(path_error_label);
+ vb->add_child(hb);
+
+ pc = memnew(PanelContainer);
+ pc->set_h_size_flags(Control::SIZE_FILL);
+ pc->add_style_override("panel", sb);
+ pc->add_child(vb);
+
+ /* Margins */
+
+ empty_h = memnew(Control);
+ empty_h->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_h->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_h->set_custom_minimum_size(Size2(0, 10 * EDSCALE));
+ empty_v = memnew(Control);
+ empty_v->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_v->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_v->set_custom_minimum_size(Size2(10, 0 * EDSCALE));
+
+ vb = memnew(VBoxContainer);
+ vb->add_child(empty_h->duplicate());
+ vb->add_child(gc);
+ vb->add_child(empty_h->duplicate());
+ vb->add_child(pc);
+ vb->add_child(empty_h->duplicate());
+ hb = memnew(HBoxContainer);
+ hb->add_child(empty_v->duplicate());
+ hb->add_child(vb);
+ hb->add_child(empty_v->duplicate());
+
+ add_child(hb);
+
+ /* Language */
language_menu = memnew(OptionButton);
- vb->add_margin_child(TTR("Language"), language_menu);
+ language_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE);
+ language_menu->set_h_size_flags(SIZE_EXPAND_FILL);
+ l = memnew(Label);
+ l->set_text(TTR("Language"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(language_menu);
int default_lang = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -404,60 +581,108 @@ ScriptCreateDialog::ScriptCreateDialog() {
}
}
- editor_settings = EditorSettings::get_singleton();
String last_selected_language = editor_settings->get_project_metadata("script_setup", "last_selected_language", "");
if (last_selected_language != "") {
for (int i = 0; i < language_menu->get_item_count(); i++) {
if (language_menu->get_item_text(i) == last_selected_language) {
language_menu->select(i);
+ current_language = i;
break;
}
}
} else {
language_menu->select(default_lang);
+ current_language = default_lang;
}
language_menu->connect("item_selected", this, "_lang_changed");
- //parent_name->set_text();
+ /* Inherits */
- vb2 = memnew(VBoxContainer);
- path_vb = memnew(VBoxContainer);
- vb2->add_child(path_vb);
+ hb = memnew(HBoxContainer);
+ hb->set_h_size_flags(SIZE_EXPAND_FILL);
+ parent_name = memnew(LineEdit);
+ parent_name->connect("text_changed", this, "_parent_name_changed");
+ parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ hb->add_child(parent_name);
+ parent_browse_button = memnew(Button);
+ parent_browse_button->set_flat(true);
+ parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
+ hb->add_child(parent_browse_button);
+ l = memnew(Label);
+ l->set_text(TTR("Inherits"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(hb);
+ is_browsing_parent = false;
- HBoxContainer *hbc = memnew(HBoxContainer);
- file_path = memnew(LineEdit);
- file_path->connect("text_changed", this, "_path_changed");
- hbc->add_child(file_path);
- file_path->set_h_size_flags(SIZE_EXPAND_FILL);
- Button *b = memnew(Button);
- b->set_text(" .. ");
- b->connect("pressed", this, "_browse_path", varray(false));
- hbc->add_child(b);
- path_vb->add_child(hbc);
- path_error_label = memnew(Label);
- path_vb->add_child(path_error_label);
- path_error_label->set_text(TTR("Error!"));
- path_error_label->set_align(Label::ALIGN_CENTER);
+ /* Class Name */
- internal = memnew(CheckButton);
- internal->set_text(TTR("Built-In Script"));
- vb2->add_child(internal);
- internal->connect("pressed", this, "_built_in_pressed");
+ class_name = memnew(LineEdit);
+ class_name->connect("text_changed", this, "_class_name_changed");
+ class_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ l = memnew(Label);
+ l->set_text(TTR("Class Name"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(class_name);
- vb->add_margin_child(TTR("Path:"), vb2);
+ /* Built-in Script */
- set_size(Size2(200, 150));
- set_hide_on_ok(false);
- set_title(TTR("Attach Node Script"));
+ internal = memnew(CheckButton);
+ internal->connect("pressed", this, "_built_in_pressed");
+ hb = memnew(HBoxContainer);
+ empty = memnew(Control);
+ hb->add_child(internal);
+ hb->add_child(empty);
+ l = memnew(Label);
+ l->set_text(TTR("Built-in Script"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(hb);
+
+ /* Path */
+
+ hb = memnew(HBoxContainer);
+ file_path = memnew(LineEdit);
+ file_path->connect("text_changed", this, "_path_changed");
+ file_path->set_h_size_flags(SIZE_EXPAND_FILL);
+ hb->add_child(file_path);
+ path_button = memnew(Button);
+ path_button->set_flat(true);
+ path_button->connect("pressed", this, "_browse_path", varray(false));
+ hb->add_child(path_button);
+ l = memnew(Label);
+ l->set_text(TTR("Path"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(hb);
+
+ /* Dialog Setup */
file_browse = memnew(EditorFileDialog);
file_browse->connect("file_selected", this, "_file_selected");
add_child(file_browse);
get_ok()->set_text(TTR("Create"));
alert = memnew(AcceptDialog);
+ alert->set_as_minsize();
+ alert->get_label()->set_autowrap(true);
+ alert->get_label()->set_align(Label::ALIGN_CENTER);
+ alert->get_label()->set_valign(Label::VALIGN_CENTER);
+ alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
add_child(alert);
- _lang_changed(0);
- create_new = true;
+ set_as_minsize();
+ set_hide_on_ok(false);
+ set_title(TTR("Attach Node Script"));
+
+ is_parent_name_valid = false;
+ is_class_name_valid = false;
+ is_path_valid = false;
+
+ has_named_classes = false;
+ can_inherit_from_file = false;
+ is_built_in = false;
+
+ is_new_script_created = true;
}
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 113d4a468c..862d4f88f2 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -34,8 +34,10 @@
#include "editor/editor_settings.h"
#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
+#include "scene/gui/grid_container.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
+#include "scene/gui/panel_container.h"
class ScriptCreateDialog : public ConfirmationDialog {
GDCLASS(ScriptCreateDialog, ConfirmationDialog);
@@ -47,6 +49,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
Button *parent_browse_button;
OptionButton *language_menu;
LineEdit *file_path;
+ Button *path_button;
EditorFileDialog *file_browse;
CheckButton *internal;
VBoxContainer *path_vb;
@@ -56,20 +59,33 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool is_browsing_parent;
String initial_bp;
EditorSettings *editor_settings;
+ bool is_new_script_created;
+ bool is_path_valid;
+ bool has_named_classes;
+ bool can_inherit_from_file;
+ bool is_parent_name_valid;
+ bool is_class_name_valid;
+ bool is_built_in;
+ int current_language;
+ bool re_check_path;
void _path_changed(const String &p_path = String());
void _lang_changed(int l = 0);
void _built_in_pressed();
bool _validate(const String &p_strin);
void _class_name_changed(const String &p_name);
+ void _parent_name_changed(const String &p_parent);
void _browse_path(bool browse_parent);
void _file_selected(const String &p_file);
virtual void ok_pressed();
void _create_new();
void _load_exist();
- void _update_controls();
+ void _msg_script_valid(bool valid, const String &p_msg = String());
+ void _msg_path_valid(bool valid, const String &p_msg = String());
+ void _update_dialog();
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 2bc00c62fb..ebf4b1cf3a 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -90,11 +90,13 @@ public:
return "";
}
- void add_property(const String &p_name, const Variant &p_value) {
+ void add_property(const String &p_name, const Variant &p_value, const PropertyHint &p_hint, const String p_hint_string) {
PropertyInfo pinfo;
pinfo.name = p_name;
pinfo.type = p_value.get_type();
+ pinfo.hint = p_hint;
+ pinfo.hint_string = p_hint_string;
props.push_back(pinfo);
values[p_name] = p_value;
}
@@ -437,7 +439,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
inspected_object->last_edited_id = id;
- inspect_properties->edit(inspected_object);
+ if (tabs->get_current_tab() == 2) {
+ inspect_properties->edit(inspected_object);
+ } else {
+ editor->push_item(inspected_object);
+ }
} else if (p_msg == "message:video_mem") {
@@ -499,13 +505,20 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String n = p_data[ofs + i * 2 + 0];
Variant v = p_data[ofs + i * 2 + 1];
+ PropertyHint h = PROPERTY_HINT_NONE;
+ String hs = String();
if (n.begins_with("*")) {
n = n.substr(1, n.length());
+ h = PROPERTY_HINT_OBJECT_ID;
+ String s = v;
+ s = s.replace("[", "");
+ hs = s.get_slice(":", 0);
+ v = s.get_slice(":", 1).to_int();
}
- variables->add_property("members/" + n, v);
+ variables->add_property("members/" + n, v, h, hs);
}
ofs += mcount * 2;
@@ -516,13 +529,20 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String n = p_data[ofs + i * 2 + 0];
Variant v = p_data[ofs + i * 2 + 1];
+ PropertyHint h = PROPERTY_HINT_NONE;
+ String hs = String();
if (n.begins_with("*")) {
n = n.substr(1, n.length());
+ h = PROPERTY_HINT_OBJECT_ID;
+ String s = v;
+ s = s.replace("[", "");
+ hs = s.get_slice(":", 0);
+ v = s.get_slice(":", 1).to_int();
}
- variables->add_property("locals/" + n, v);
+ variables->add_property("locals/" + n, v, h, hs);
}
variables->update();
@@ -1056,6 +1076,9 @@ void ScriptEditorDebugger::stop() {
EditorNode::get_singleton()->get_pause_button()->set_pressed(false);
EditorNode::get_singleton()->get_pause_button()->set_disabled(true);
+ //avoid confusion when stopped debugging but an object is still edited
+ EditorNode::get_singleton()->push_item(NULL);
+
if (hide_on_stop) {
if (is_visible_in_tree())
EditorNode::get_singleton()->hide_bottom_panel();
@@ -1636,6 +1659,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
inspector->get_scene_tree()->set_column_title(0, TTR("Variable"));
inspector->set_enable_capitalize_paths(false);
inspector->set_read_only(true);
+ inspector->connect("object_id_selected", this, "_scene_tree_property_select_object");
sc->add_child(inspector);
server = TCP_Server::create_ref();
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 766d8f9676..867302b657 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -1,5 +1,6 @@
# Arabic translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# athomield <athomield@hotmail.com>, 2017.
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index b23fa3a8fb..f884b33773 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -1,5 +1,6 @@
# Bulgarian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Bojidar Marinov <bojidar.marinov.bg@gmail.com>, 2016.
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 224c00cf5d..3e4dec7656 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -1,5 +1,6 @@
# Bengali translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Abu Md. Maruf Sarker <maruf.webdev@gmail.com>, 2016-2017.
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 581e862716..6d7b245e58 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -1,5 +1,6 @@
# Catalan translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Roger BR <drai_kin@hotmail.com>, 2016.
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 89d88a234f..4643a9ac21 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -1,5 +1,6 @@
# Czech translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Jan 'spl!te' Kondelík <j.kondelik@centrum.cz>, 2016.
diff --git a/editor/translations/da.po b/editor/translations/da.po
index b84be76247..ba9d018e5a 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -1,5 +1,6 @@
# Danish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# David Lamhauge <davidlamhauge@gmail.com>, 2016.
diff --git a/editor/translations/de.po b/editor/translations/de.po
index ba6805d1f1..a10eaefa29 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -1,5 +1,6 @@
# German translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Alexander Mahr <alex.mahr@gmail.com>, 2016.
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index aeae6a5537..183f09e9a6 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -1,5 +1,6 @@
# Swiss High German translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Christian Fisch <christian.fiesel@gmail.com>, 2016.
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 5b62f132fa..5f50c159b8 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -1,5 +1,6 @@
# LANGUAGE translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 292c5a6fd3..0879b693ff 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -1,5 +1,6 @@
# Greek translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# gtsiam <gtsiam@windowslive.com>, 2017.
diff --git a/editor/translations/es.po b/editor/translations/es.po
index a7b9553892..f01c84718b 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -1,5 +1,6 @@
# Spanish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Alejandro Alvarez <eliluminado00@gmail.com>, 2017.
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 6c9579916f..f826517b27 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -1,5 +1,6 @@
# Spanish (Argentina) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017.
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index 616fec17a0..5e6c894936 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -38,7 +38,8 @@ unique_str = []
unique_loc = {}
main_po = """
# LANGUAGE translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index 2ec9b18d78..e8402fcb25 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -1,5 +1,6 @@
# Persian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# alabd14313 <alabd14313@yahoo.com>, 2016.
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 1418e6f493..8db0cf2555 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -1,5 +1,6 @@
# French translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Brice <bbric@free.fr>, 2016.
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 8cb6c2caf1..2d1b36d2ea 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -1,5 +1,6 @@
# Hungarian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Varga Dániel <danikah.danikah@gmail.com>, 2016.
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 2126d324dd..2abf4090c8 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -1,5 +1,6 @@
# Indonesian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Abdul Aziz Muslim Alqudsy <abdul.aziz.muslim.alqudsy@gmail.com>, 2016.
diff --git a/editor/translations/it.po b/editor/translations/it.po
index e055c6996a..08d04d296b 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -1,5 +1,6 @@
# Italian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Dario Bonfanti <bonfi.96@hotmail.it>, 2016-2017.
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index f34e0d118b..beeaf264a2 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -1,5 +1,6 @@
# Japanese translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# akirakido <achts.y@gmail.com>, 2016.
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 769089b860..08b10d2f7a 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -1,5 +1,6 @@
# Korean translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# 박한얼 (volzhs) <volzhs@gmail.com>, 2016-2017.
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index e7a64f501a..7ce577ebfa 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -1,5 +1,6 @@
# Norwegian Bokmål translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Anonymous <GentleSaucepan@protonmail.com>, 2017.
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 55407145d2..f0d54ebd9d 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -1,5 +1,6 @@
# Dutch translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Aram Nap <xyphex.aram@gmail.com>, 2017
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 8eb2e9c884..ccee170c57 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -1,5 +1,6 @@
# Polish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# 8-bit Pixel <dawdejw@gmail.com>, 2016.
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 4df9c04664..4629c24f45 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -1,5 +1,6 @@
# Pirate translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Zion Nimchuk <zionnimchuk@gmail.com>, 2016-2017.
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 75be59068c..25055a0b7b 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -1,5 +1,6 @@
# Portuguese (Brazil) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Allyson Souza <allyson_as@outlook.com>, 2017.
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index 913455b999..fa4629c5c1 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -1,5 +1,6 @@
# Portuguese (Portugal) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# António Sarmento <antonio.luis.sarmento@gmail.com>, 2016.
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 9f7aa6e26a..0c4a29fb63 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -1,5 +1,6 @@
# Russian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# DimOkGamer <dimokgamer@gmail.com>, 2016-2017.
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 697def1043..b0bee6aa6f 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -1,5 +1,6 @@
# Slovak translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# J08nY <johnenter@gmail.com>, 2016.
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index fad12d7f13..ea634658ce 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -1,5 +1,6 @@
# Slovenian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# matevž lapajne <sivar.lapajne@gmail.com>, 2016.
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 79cdaf6b10..b31532f3bf 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -1,5 +1,6 @@
# Thai translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Poommetee Ketson <poommetee@protonmail.com>, 2017.
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 20a794b34a..b4d8975649 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -1,5 +1,6 @@
# Turkish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Aprın Çor Tigin <kabusturk38@gmail.com>, 2016-2017.
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 651aa62001..ef3e3b30ca 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -1,5 +1,6 @@
# Urdu (Pakistan) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Muhammad Ali <ali@codeonion.com>, 2016.
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 87ca113ce2..f3afcab79d 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -1,5 +1,6 @@
# Chinese (China) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# 纯洁的坏蛋 <tqj.zyy@gmail.com>, 2016.
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index dfac75ecab..e49582e901 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -1,5 +1,6 @@
# Chinese (Honk Kong) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Wesley (zx-wt) <ZX_WT@ymail.com>, 2016.
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 48b76484e0..7836cd2f76 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -1,5 +1,6 @@
# Chinese (Taiwan) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# popcade <popcade@gmail.com>, 2016.