diff options
Diffstat (limited to 'editor')
| -rw-r--r-- | editor/connections_dialog.cpp | 4 | ||||
| -rw-r--r-- | editor/editor_node.cpp | 1 | ||||
| -rw-r--r-- | editor/editor_settings.cpp | 3 | ||||
| -rw-r--r-- | editor/editor_themes.cpp | 5 | ||||
| -rw-r--r-- | editor/filesystem_dock.cpp | 26 | ||||
| -rw-r--r-- | editor/filesystem_dock.h | 7 | ||||
| -rw-r--r-- | editor/icons/icon_soft_body.svg | 56 | ||||
| -rw-r--r-- | editor/plugins/particles_editor_plugin.cpp | 5 | ||||
| -rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 2 | ||||
| -rw-r--r-- | editor/plugins/script_text_editor.cpp | 21 | ||||
| -rw-r--r-- | editor/plugins/spatial_editor_plugin.h | 1 | ||||
| -rw-r--r-- | editor/project_manager.cpp | 207 | ||||
| -rw-r--r-- | editor/script_editor_debugger.cpp | 3 | ||||
| -rw-r--r-- | editor/spatial_editor_gizmos.cpp | 108 | ||||
| -rw-r--r-- | editor/spatial_editor_gizmos.h | 17 |
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); |