summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/connections_dialog.cpp4
-rw-r--r--editor/editor_node.cpp1
-rw-r--r--editor/editor_settings.cpp3
-rw-r--r--editor/editor_themes.cpp5
-rw-r--r--editor/filesystem_dock.cpp26
-rw-r--r--editor/filesystem_dock.h7
-rw-r--r--editor/icons/icon_soft_body.svg56
-rw-r--r--editor/plugins/particles_editor_plugin.cpp5
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp21
-rw-r--r--editor/plugins/spatial_editor_plugin.h1
-rw-r--r--editor/project_manager.cpp207
-rw-r--r--editor/script_editor_debugger.cpp3
-rw-r--r--editor/spatial_editor_gizmos.cpp108
-rw-r--r--editor/spatial_editor_gizmos.h17
15 files changed, 445 insertions, 21 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 8933fd7fe8..c4f4e28fec 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -820,7 +820,9 @@ void ConnectionsDock::update_tree() {
if (i > 0)
signaldesc += ", ";
String tname = "var";
- if (pi.type != Variant::NIL) {
+ if (pi.type == Variant::OBJECT && pi.class_name != StringName()) {
+ tname = pi.class_name.operator String();
+ } else if (pi.type != Variant::NIL) {
tname = Variant::get_type_name(pi.type);
}
signaldesc += tname + " " + (pi.name == "" ? String("arg " + itos(i)) : pi.name);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ff97878e71..a68a0779c5 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -156,7 +156,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) {
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 4cfdb6f6d3..466b12157d 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -364,6 +364,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/highlighting/highlight_all_occurrences", true);
_initial_set("text_editor/highlighting/highlight_current_line", true);
+ _initial_set("text_editor/highlighting/highlight_type_safe_lines", true);
_initial_set("text_editor/cursor/scroll_past_end_of_file", false);
_initial_set("text_editor/indent/type", 0);
@@ -404,6 +405,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/completion/callhint_tooltip_offset", Vector2());
_initial_set("text_editor/files/restore_scripts_on_load", true);
_initial_set("text_editor/completion/complete_file_paths", true);
+ _initial_set("text_editor/completion/add_type_hints", false);
_initial_set("docks/scene_tree/start_create_dialog_fully_expanded", false);
_initial_set("docks/scene_tree/draw_relationship_lines", false);
@@ -592,6 +594,7 @@ void EditorSettings::_load_default_text_editor_theme() {
_initial_set("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"));
_initial_set("text_editor/highlighting/text_color", Color::html("aaaaaa"));
_initial_set("text_editor/highlighting/line_number_color", Color::html("66aaaaaa"));
+ _initial_set("text_editor/highlighting/safe_line_number_color", Color::html("99aac8aa"));
_initial_set("text_editor/highlighting/caret_color", Color::html("aaaaaa"));
_initial_set("text_editor/highlighting/caret_background_color", Color::html("000000"));
_initial_set("text_editor/highlighting/text_selected_color", Color::html("000000"));
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 084caff083..18cc52a5c6 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);
@@ -1089,6 +1086,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color completion_font_color = font_color;
const Color text_color = font_color;
const Color line_number_color = dim_color;
+ const Color safe_line_number_color = dim_color * Color(1, 1.2, 1, 1.5);
const Color caret_color = mono_color;
const Color caret_background_color = mono_color.inverted();
const Color text_selected_color = dark_color_3;
@@ -1123,6 +1121,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
setting->set_initial_value("text_editor/highlighting/completion_font_color", completion_font_color, true);
setting->set_initial_value("text_editor/highlighting/text_color", text_color, true);
setting->set_initial_value("text_editor/highlighting/line_number_color", line_number_color, true);
+ setting->set_initial_value("text_editor/highlighting/safe_line_number_color", safe_line_number_color, true);
setting->set_initial_value("text_editor/highlighting/caret_color", caret_color, true);
setting->set_initial_value("text_editor/highlighting/caret_background_color", caret_background_color, true);
setting->set_initial_value("text_editor/highlighting/text_selected_color", text_selected_color, true);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index f65fb5365b..37f86cc912 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);
@@ -2087,6 +2108,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/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/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..de57a4ad51 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2239,8 +2239,6 @@ void ScriptEditor::_make_script_list_context_menu() {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
}
- 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);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index ffc2203475..2263d782d9 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -116,6 +116,7 @@ void ScriptTextEditor::_load_theme_settings() {
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 safe_line_number_color = EDITOR_GET("text_editor/highlighting/safe_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");
@@ -147,6 +148,7 @@ void ScriptTextEditor::_load_theme_settings() {
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("safe_line_number_color", safe_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);
@@ -589,6 +591,7 @@ void ScriptTextEditor::set_edited_script(const Ref<Script> &p_script) {
emit_signal("name_changed");
code_editor->update_line_and_column();
+ call_deferred("_validate_script");
}
void ScriptTextEditor::_validate_script() {
@@ -599,8 +602,9 @@ void ScriptTextEditor::_validate_script() {
String text = te->get_text();
List<String> fnc;
+ Set<int> safe_lines;
- if (!script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc)) {
+ if (!script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc, &safe_lines)) {
String error_text = "error(" + itos(line) + "," + itos(col) + "): " + errortxt;
code_editor->set_error(error_text);
} else {
@@ -621,8 +625,23 @@ void ScriptTextEditor::_validate_script() {
}
line--;
+ bool highlight_safe = EDITOR_DEF("text_editor/highlighting/highlight_type_safe_lines", true);
+ bool last_is_safe = false;
for (int i = 0; i < te->get_line_count(); i++) {
te->set_line_as_marked(i, line == i);
+ if (highlight_safe) {
+ if (safe_lines.has(i + 1)) {
+ te->set_line_as_safe(i, true);
+ last_is_safe = true;
+ } else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().empty())) {
+ te->set_line_as_safe(i, true);
+ } else {
+ te->set_line_as_safe(i, false);
+ last_is_safe = false;
+ }
+ } else {
+ te->set_line_as_safe(i, false);
+ }
}
emit_signal("name_changed");
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 637926a913..af882f6e05 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);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 0d06b71420..af7c4bb379 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;
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 62848a6035..9ce0e973f7 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -1249,6 +1249,9 @@ void ScriptEditorDebugger::stop() {
EditorNode::get_singleton()->get_scene_tree_dock()->hide_remote_tree();
EditorNode::get_singleton()->get_scene_tree_dock()->hide_tab_buttons();
+ Node *node = editor->get_scene_tree_dock()->get_tree_editor()->get_selected();
+ editor->push_item(node);
+
if (hide_on_stop) {
if (is_visible_in_tree())
EditorNode::get_singleton()->hide_bottom_panel();
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index c45dea0df7..35544f711b 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"
@@ -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;
}
}
@@ -1914,6 +1919,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();
@@ -4051,6 +4150,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 +4186,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);