diff options
34 files changed, 338 insertions, 161 deletions
diff --git a/core/os/dir_access.h b/core/os/dir_access.h index 704eedae5b..3c0528112b 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -97,6 +97,18 @@ public: virtual Error rename(String p_from, String p_to) = 0; virtual Error remove(String p_name) = 0; + // Meant for editor code when we want to quickly remove a file without custom + // handling (e.g. removing a cache file). + static void remove_file_or_error(String p_path) { + DirAccess *da = create(ACCESS_FILESYSTEM); + if (da->file_exists(p_path)) { + if (da->remove(p_path) != OK) { + ERR_FAIL_MSG("Cannot remove file or directory: " + p_path); + } + } + memdelete(da); + } + virtual String get_filesystem_type() const = 0; static String get_full_path(const String &p_path, AccessType p_access); static DirAccess *create_for_path(const String &p_path); diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 5f01e043c4..6dd9054aaa 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -601,9 +601,19 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) { } } } + if (Node *node = Object::cast_to<Node>(obj)) { - PropertyInfo pi(Variant::NODE_PATH, String("Node/path")); - properties.push_front(PropertyDesc(pi, node->get_path())); + // in some cases node will not be in tree here + // for instance where it created as variable and not yet added to tree + // in such cases we can't ask for it's path + if (node->is_inside_tree()) { + PropertyInfo pi(Variant::NODE_PATH, String("Node/path")); + properties.push_front(PropertyDesc(pi, node->get_path())); + } else { + PropertyInfo pi(Variant::STRING, String("Node/path")); + properties.push_front(PropertyDesc(pi, "[Orphan]")); + } + } else if (Resource *res = Object::cast_to<Resource>(obj)) { if (Script *s = Object::cast_to<Script>(res)) { Map<StringName, Variant> constants; diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index 6f82b103db..2d3ceebed5 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -32,12 +32,6 @@ Adds an [AudioEffect] effect to the bus [code]bus_idx[/code] at [code]at_position[/code]. </description> </method> - <method name="capture_get_device"> - <return type="String"> - </return> - <description> - </description> - </method> <method name="capture_get_device_list"> <return type="Array"> </return> @@ -45,14 +39,6 @@ Returns the names of all audio input devices detected on the system. </description> </method> - <method name="capture_set_device"> - <return type="void"> - </return> - <argument index="0" name="name" type="String"> - </argument> - <description> - </description> - </method> <method name="capture_start"> <return type="int" enum="Error"> </return> @@ -423,17 +409,25 @@ <member name="bus_count" type="int" setter="set_bus_count" getter="get_bus_count" default="1"> Number of available audio buses. </member> + <member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default=""""> + Name of the current device for audio input (see [method capture_get_device_list]). + </member> <member name="device" type="String" setter="set_device" getter="get_device" default=""Default""> Name of the current device for audio output (see [method get_device_list]). </member> - <member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default=""Default""> - Name of the current device for audio input (see [method capture_get_device_list]). - </member> <member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale" default="1.0"> Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast). </member> </members> <signals> + <signal name="audio_mix_callback"> + <description> + </description> + </signal> + <signal name="audio_update_callback"> + <description> + </description> + </signal> <signal name="bus_layout_changed"> <description> Emitted when the [AudioBusLayout] changes. diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 4d5c76a75c..df9438e695 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -208,5 +208,13 @@ </member> </members> <constants> + <constant name="IDENTITY" value="Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 )"> + </constant> + <constant name="FLIP_X" value="Basis( -1, 0, 0, 0, 1, 0, 0, 0, 1 )"> + </constant> + <constant name="FLIP_Y" value="Basis( 1, 0, 0, 0, -1, 0, 0, 0, 1 )"> + </constant> + <constant name="FLIP_Z" value="Basis( 1, 0, 0, 0, 1, 0, 0, 0, -1 )"> + </constant> </constants> </class> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index f524a02934..16fb483249 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -110,7 +110,7 @@ <member name="drag_margin_bottom" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2"> Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen. </member> - <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="true"> + <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="false"> If [code]true[/code], the camera only moves when reaching the horizontal drag margins. If [code]false[/code], the camera moves horizontally regardless of margins. </member> <member name="drag_margin_left" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2"> @@ -122,7 +122,7 @@ <member name="drag_margin_top" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2"> Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen. </member> - <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="true"> + <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="false"> If [code]true[/code], the camera only moves when reaching the vertical drag margins. If [code]false[/code], the camera moves vertically regardless of margins. </member> <member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled" default="false"> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 6c3cf66c20..acceffb3bf 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -229,7 +229,7 @@ [codeblock] func _ready(): modulate = get_color("font_color", "Button") #get the color defined for button fonts - [/codeblock] + [/codeblock] </description> </method> <method name="get_combined_minimum_size" qualifiers="const"> diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index d55e810c9e..4f7a6d89a9 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -169,6 +169,22 @@ Selects the file, with the path provided by [code]file[/code], in the FileSystem dock. </description> </method> + <method name="set_distraction_free_mode"> + <return type="void"> + </return> + <argument index="0" name="enter" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_main_screen_editor"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> <method name="set_plugin_enabled"> <return type="void"> </return> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index fddc5e9d36..89e2f0580b 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -128,7 +128,7 @@ <argument index="3" name="ud" type="Variant" default="null"> </argument> <description> - Adds a custom menu to [b]Project > Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it. + Adds a custom menu item to [b]Project > Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it. </description> </method> <method name="add_tool_submenu_item"> @@ -139,7 +139,7 @@ <argument index="1" name="submenu" type="Object"> </argument> <description> - Like [method add_tool_menu_item] but adds the [code]submenu[/code] item inside the [code]name[/code] menu. + Adds a custom submenu under [b]Project > Tools >[/b] [code]name[/code]. [code]submenu[/code] should be an object of class [PopupMenu]. This submenu should be cleaned up using [code]remove_tool_menu_item(name)[/code]. </description> </method> <method name="apply_changes" qualifiers="virtual"> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index a4df0d5c19..10be66feb8 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -406,24 +406,24 @@ <description> </description> </method> - <method name="save_png" qualifiers="const"> + <method name="save_exr" qualifiers="const"> <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> + <argument index="1" name="grayscale" type="bool" default="false"> + </argument> <description> - Saves the image as a PNG file to [code]path[/code]. + Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitely as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module. </description> </method> - <method name="save_exr" qualifiers="const"> + <method name="save_png" qualifiers="const"> <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> - <argument index="1" name="grayscale" type="bool" default="false"> - </argument> <description> - Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitely as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module. + Saves the image as a PNG file to [code]path[/code]. </description> </method> <method name="set_pixel"> diff --git a/doc/classes/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml new file mode 100644 index 0000000000..d83c2e7d44 --- /dev/null +++ b/doc/classes/VisualShaderNodeVectorScalarMix.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" category="Core" version="3.2"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index ed262d9c4f..e1f2635275 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -35,6 +35,7 @@ #include "core/io/resource_saver.h" #include "core/io/zip_io.h" #include "core/math/crypto_core.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/project_settings.h" #include "core/script_language.h" @@ -884,6 +885,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file); ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list); Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); + DirAccess::remove_file_or_error(engine_cfb); p_func(p_udata, "res://" + config_file, data, idx, total); @@ -916,8 +918,10 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c memdelete(ftmp); //close tmp file - if (err) + if (err != OK) { + DirAccess::remove_file_or_error(tmppath); return err; + } pd.file_ofs.sort(); //do sort, so we can do binary search later @@ -926,11 +930,17 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c if (!p_embed) { // Regular output to separate PCK file f = FileAccess::open(p_path, FileAccess::WRITE); - ERR_FAIL_COND_V(!f, ERR_CANT_CREATE); + if (!f) { + DirAccess::remove_file_or_error(tmppath); + ERR_FAIL_V(ERR_CANT_CREATE); + } } else { // Append to executable f = FileAccess::open(p_path, FileAccess::READ_WRITE); - ERR_FAIL_COND_V(!f, ERR_FILE_CANT_OPEN); + if (!f) { + DirAccess::remove_file_or_error(tmppath); + ERR_FAIL_V(ERR_FILE_CANT_OPEN); + } f->seek_end(); embed_pos = f->get_position(); @@ -995,13 +1005,13 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c f->store_8(0); } - //save the rest of the data + // Save the rest of the data. ftmp = FileAccess::open(tmppath, FileAccess::READ); if (!ftmp) { memdelete(f); - ERR_EXPLAIN("Can't open file to read from path: " + String(tmppath)); - ERR_FAIL_V(ERR_CANT_CREATE); + DirAccess::remove_file_or_error(tmppath); + ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't open file to read from path: " + String(tmppath)); } const int bufsize = 16384; @@ -1035,6 +1045,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c } memdelete(f); + DirAccess::remove_file_or_error(tmppath); return OK; } @@ -1043,8 +1054,6 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co EditorProgress ep("savezip", TTR("Packing"), 102, true); - //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); - FileAccess *src_f; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io); @@ -1694,11 +1703,18 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export"); if (!convert) return; - String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("file.res"); + String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); - ERR_FAIL_COND(err != OK); + if (err != OK) { + DirAccess::remove_file_or_error(tmp_path); + ERR_FAIL(); + } Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); - ERR_FAIL_COND(data.size() == 0); + if (data.size() == 0) { + DirAccess::remove_file_or_error(tmp_path); + ERR_FAIL(); + } + DirAccess::remove_file_or_error(tmp_path); add_file(p_path + ".converted.res", data, true); } diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 9966394025..379b8a2980 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -347,6 +347,11 @@ void EditorSpinSlider::_value_input_closed() { //focus_exited signal void EditorSpinSlider::_value_focus_exited() { + + // discontinue because the focus_exit was caused by right-click context menu + if (value_input->get_menu()->is_visible()) + return; + _evaluate_input_text(); // focus is not on the same element after the vlalue_input was exited // -> focus is on next element diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 41ca2d566b..72a4b43737 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -435,14 +435,16 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int String path = download_templates->get_download_file(); template_list_state->set_text(TTR("Download Complete.")); template_downloader->hide(); - int ret = _install_from_file(path, false); + bool ret = _install_from_file(path, false); if (ret) { - Error err = OS::get_singleton()->move_to_trash(path); + // Clean up downloaded file. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Error err = da->remove(path); if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + path + "\n"); + EditorNode::get_singleton()->add_io_error(TTR("Cannot remove temporary file:") + "\n" + path + "\n"); } } else { - WARN_PRINTS(vformat(TTR("Templates installation failed. The problematic templates archives can be found at '%s'."), path)); + EditorNode::get_singleton()->add_io_error(vformat(TTR("Templates installation failed.\nThe problematic templates archives can be found at '%s'."), path)); } } } break; @@ -471,7 +473,7 @@ void ExportTemplateManager::_begin_template_download(const String &p_url) { Error err = download_templates->request(p_url); if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Error requesting url: ") + p_url); + EditorNode::get_singleton()->show_warning(TTR("Error requesting URL:") + " " + p_url); return; } diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 4a2295fab2..5679426eb5 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -354,16 +354,16 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int } break; case HTTPRequest::RESULT_REQUEST_FAILED: { error_text = TTR("Request failed, return code:") + " " + itos(p_code); - status->set_text(TTR("Request Failed.")); + status->set_text(TTR("Request failed.")); } break; case HTTPRequest::RESULT_DOWNLOAD_FILE_CANT_OPEN: case HTTPRequest::RESULT_DOWNLOAD_FILE_WRITE_ERROR: { - error_text = TTR("Cannot save response to") + " " + download->get_download_file(); + error_text = TTR("Cannot save response to:") + " " + download->get_download_file(); status->set_text(TTR("Write error.")); } break; case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: { error_text = TTR("Request failed, too many redirects"); - status->set_text(TTR("Redirect Loop.")); + status->set_text(TTR("Redirect loop.")); } break; case HTTPRequest::RESULT_TIMEOUT: { error_text = TTR("Request failed, timeout"); @@ -472,9 +472,8 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { } void EditorAssetLibraryItemDownload::_close() { - DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->remove(download->get_download_file()); //clean up removed file - memdelete(da); + // Clean up downloaded file. + DirAccess::remove_file_or_error(download->get_download_file()); queue_delete(); } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index ec391186c3..1072c3cad1 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1072,6 +1072,7 @@ void ScriptEditor::_menu_option(int p_option) { save_all_scripts(); } break; case SEARCH_IN_FILES: { + _on_find_in_files_requested(""); } break; case SEARCH_HELP: { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 98e0edd581..87248c53b1 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1197,7 +1197,6 @@ void ScriptTextEditor::_edit_option(int p_op) { // Yep, because it doesn't make sense to instance this dialog for every single script open... // So this will be delegated to the ScriptEditor. emit_signal("search_in_files_requested", selected_text); - } break; case SEARCH_LOCATE_FUNCTION: { diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index eb0794ba77..89e419ede8 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -482,6 +482,14 @@ void TextEditor::_edit_option(int p_op) { code_editor->get_find_replace_bar()->popup_replace(); } break; + case SEARCH_IN_FILES: { + + String selected_text = code_editor->get_text_edit()->get_selection_text(); + + // Yep, because it doesn't make sense to instance this dialog for every single script open... + // So this will be delegated to the ScriptEditor. + emit_signal("search_in_files_requested", selected_text); + } break; case SEARCH_GOTO_LINE: { goto_line_dialog->popup_find_line(tx); @@ -558,7 +566,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int to_column = tx->get_selection_to_column(); if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) { - // Right click is outside the selected text + // Right click is outside the selected text. tx->deselect(); } } @@ -636,13 +644,15 @@ TextEditor::TextEditor() { search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES); edit_menu = memnew(MenuButton); + edit_hb->add_child(edit_menu); edit_menu->set_text(TTR("Edit")); edit_menu->set_switch_on_hover(true); edit_menu->get_popup()->connect("id_pressed", this, "_edit_option"); - edit_hb->add_child(edit_menu); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index c69e1672c5..c8b49a61e0 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -87,6 +87,7 @@ private: SEARCH_FIND_NEXT, SEARCH_FIND_PREV, SEARCH_REPLACE, + SEARCH_IN_FILES, SEARCH_GOTO_LINE, BOOKMARK_TOGGLE, BOOKMARK_GOTO_NEXT, diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp index 84cd6da3d9..7cdd900d25 100644 --- a/editor/pvrtc_compress.cpp +++ b/editor/pvrtc_compress.cpp @@ -32,6 +32,7 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" #include "editor_settings.h" @@ -52,57 +53,75 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) { _base_image_compress_pvrtc2_func(p_image); else if (_base_image_compress_pvrtc4_func) _base_image_compress_pvrtc4_func(p_image); - break; case Image::COMPRESS_PVRTC4: if (_base_image_compress_pvrtc4_func) _base_image_compress_pvrtc4_func(p_image); - break; - default: ERR_FAIL(); + default: + ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module."); } return; } - String tmppath = EditorSettings::get_singleton()->get_cache_dir(); - - List<String> args; + String tmppath = EditorSettings::get_singleton()->get_cache_dir(); String src_img = tmppath.plus_file("_tmp_src_img.png"); String dst_img = tmppath.plus_file("_tmp_dst_img.pvr"); + List<String> args; args.push_back("-i"); args.push_back(src_img); args.push_back("-o"); args.push_back(dst_img); args.push_back("-f"); - switch (p_mode) { - case Image::COMPRESS_PVRTC2: args.push_back("PVRTC2"); break; - case Image::COMPRESS_PVRTC4: args.push_back("PVRTC4"); break; - case Image::COMPRESS_ETC: args.push_back("ETC"); break; - default: ERR_FAIL(); + switch (p_mode) { + case Image::COMPRESS_PVRTC2: + args.push_back("PVRTC2"); + break; + case Image::COMPRESS_PVRTC4: + args.push_back("PVRTC4"); + break; + case Image::COMPRESS_ETC: + args.push_back("ETC"); + break; + default: + ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module."); } if (EditorSettings::get_singleton()->get("filesystem/import/pvrtc_fast_conversion").operator bool()) { args.push_back("-pvrtcfast"); } - if (p_image->has_mipmaps()) + if (p_image->has_mipmaps()) { args.push_back("-m"); + } + // Save source PNG. Ref<ImageTexture> t = memnew(ImageTexture); t->create_from_image(Ref<Image>(p_image), 0); ResourceSaver::save(src_img, t); Error err = OS::get_singleton()->execute(ttpath, args, true); - ERR_EXPLAIN(TTR("Could not execute PVRTC tool:") + " " + ttpath); - ERR_FAIL_COND(err != OK); + if (err != OK) { + // Clean up generated files. + DirAccess::remove_file_or_error(src_img); + DirAccess::remove_file_or_error(dst_img); + ERR_FAIL_MSG("Could not execute PVRTC tool: " + ttpath); + } t = ResourceLoader::load(dst_img, "Texture"); - - ERR_EXPLAIN(TTR("Can't load back converted image using PVRTC tool:") + " " + dst_img); - ERR_FAIL_COND(t.is_null()); + if (t.is_null()) { + // Clean up generated files. + DirAccess::remove_file_or_error(src_img); + DirAccess::remove_file_or_error(dst_img); + ERR_FAIL_MSG("Can't load back converted image using PVRTC tool."); + } p_image->copy_internals_from(t->get_data()); + + // Clean up generated files. + DirAccess::remove_file_or_error(src_img); + DirAccess::remove_file_or_error(dst_img); } static void _compress_pvrtc2(Image *p_image) { diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index ed9a24311d..7d0f40fe91 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -44,6 +44,23 @@ void ScriptCreateDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + String lang = ScriptServer::get_language(i)->get_name(); + Ref<Texture> lang_icon = get_icon(lang, "EditorIcons"); + if (lang_icon.is_valid()) { + language_menu->set_item_icon(i, lang_icon); + } + } + String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", ""); + Ref<Texture> last_lang_icon; + if (!last_lang.empty()) { + last_lang_icon = get_icon(last_lang, "EditorIcons"); + } else { + last_lang_icon = language_menu->get_item_icon(default_language); + } + if (last_lang_icon.is_valid()) { + language_menu->set_icon(last_lang_icon); + } path_button->set_icon(get_icon("Folder", "EditorIcons")); parent_browse_button->set_icon(get_icon("Folder", "EditorIcons")); parent_search_button->set_icon(get_icon("ClassList", "EditorIcons")); @@ -671,13 +688,13 @@ ScriptCreateDialog::ScriptCreateDialog() { gc->add_child(l); gc->add_child(language_menu); - int default_lang = 0; + default_language = 0; for (int i = 0; i < ScriptServer::get_language_count(); i++) { String lang = ScriptServer::get_language(i)->get_name(); language_menu->add_item(lang); if (lang == "GDScript") { - default_lang = i; + default_language = i; } } @@ -691,8 +708,8 @@ ScriptCreateDialog::ScriptCreateDialog() { } } } else { - language_menu->select(default_lang); - current_language = default_lang; + language_menu->select(default_language); + current_language = default_language; } language_menu->connect("item_selected", this, "_lang_changed"); diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index 288b8f604b..202846fd3c 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -76,6 +76,7 @@ class ScriptCreateDialog : public ConfirmationDialog { bool is_built_in; bool built_in_enabled; int current_language; + int default_language; bool re_check_path; String script_template; Vector<String> template_list; diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index b8a13ed91b..62117dcaf3 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -32,6 +32,7 @@ #include "core/io/file_access_encrypted.h" #include "core/io/resource_loader.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "editor/gdscript_highlighter.h" #include "gdscript.h" @@ -117,6 +118,9 @@ public: file = FileAccess::get_file_as_array(tmp_path); add_file(p_path.get_basename() + ".gde", file, true); + // Clean up temporary file. + DirAccess::remove_file_or_error(tmp_path); + } else { add_file(p_path.get_basename() + ".gdc", file, true); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 5a21833ffa..9712f2b5e7 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -863,19 +863,21 @@ void GridMapEditor::_icon_size_changed(float p_value) { void GridMapEditor::update_palette() { int selected = mesh_library_palette->get_current(); + float min_size = EDITOR_DEF("editors/grid_map/preview_size", 64); + min_size *= EDSCALE; + mesh_library_palette->clear(); if (display_mode == DISPLAY_THUMBNAIL) { mesh_library_palette->set_max_columns(0); mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_TOP); + mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5)); } else if (display_mode == DISPLAY_LIST) { mesh_library_palette->set_max_columns(1); mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_LEFT); + mesh_library_palette->set_fixed_column_width(0); } - float min_size = EDITOR_DEF("editors/grid_map/preview_size", 64); - min_size *= EDSCALE; mesh_library_palette->set_fixed_icon_size(Size2(min_size, min_size)); - mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5)); mesh_library_palette->set_max_text_lines(2); Ref<MeshLibrary> mesh_library = node->get_mesh_library(); diff --git a/modules/mono/.gitignore b/modules/mono/.gitignore new file mode 100644 index 0000000000..fa6d00cbbb --- /dev/null +++ b/modules/mono/.gitignore @@ -0,0 +1,2 @@ +# Do not ignore solution files inside the mono module. Overrides Godot's global gitignore. +!*.sln diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 9f0eb58896..f751719531 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -113,8 +113,8 @@ def configure(env, env_mono): else: env.Append(LINKFLAGS=os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix)) - env.Append(LIBS='psapi') - env.Append(LIBS='version') + env.Append(LIBS=['psapi']) + env.Append(LIBS=['version']) else: mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib') @@ -124,7 +124,7 @@ def configure(env, env_mono): if env.msvc: env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX']) else: - env.Append(LIBS=mono_lib_name) + env.Append(LIBS=[mono_lib_name]) mono_bin_path = os.path.join(mono_root, 'bin') diff --git a/modules/mono/icons/icon_c_#.svg b/modules/mono/icons/icon_c_#.svg new file mode 100644 index 0000000000..69664ca553 --- /dev/null +++ b/modules/mono/icons/icon_c_#.svg @@ -0,0 +1,5 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g transform="translate(0 -1036.4)"> +<path d="m6 1046.4c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h1v-2h-1c-0.55228 0-1-0.4478-1-1 0-0.5523 0.44772-1 1-1h1v-2zm1-9-0.56445 2.2578c-0.23643 0.076-0.46689 0.1692-0.68945 0.2793l-1.9883-1.1933-1.4141 1.414 1.1953 1.9942c-0.11191 0.2211-0.20723 0.4502-0.28516 0.6855l-2.2539 0.5625v2h5.2715c-0.17677-0.3037-0.27041-0.6486-0.27148-1 9.6e-6 -1.1046 0.89543-2 2-2s2 0.8954 2 2c-4.817e-4 0.3512-0.093442 0.6961-0.26953 1h5.2695v-2l-2.2578-0.5645c-0.07594-0.2357-0.1693-0.4655-0.2793-0.6875l1.1934-1.9902-1.4141-1.414-1.9941 1.1953c-0.22113-0.1119-0.45028-0.2073-0.68555-0.2852l-0.5625-2.2539zm4 9c-0.71466-1e-4 -1.3751 0.3811-1.7324 1-0.35727 0.6188-0.35727 1.3812 0 2 0.35733 0.6189 1.0178 1.0001 1.7324 1h-2v2h2c0.71466 1e-4 1.3751-0.3811 1.7324-1 0.35727-0.6188 0.35727-1.3812 0-2-0.35733-0.6189-1.0178-1.0001-1.7324-1h2v-2z" fill="#e0e0e0"/> +</g> +</svg> diff --git a/platform/SCsub b/platform/SCsub index 20c89ae8c6..38bab59d74 100644 --- a/platform/SCsub +++ b/platform/SCsub @@ -29,4 +29,4 @@ with open_utf8('register_platform_apis.gen.cpp', 'w') as f: env.add_source_files(env.platform_sources, 'register_platform_apis.gen.cpp') lib = env.add_library('platform', env.platform_sources) -env.Prepend(LIBS=lib) +env.Prepend(LIBS=[lib]) diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index dc0a63d171..16e49e8a38 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -32,6 +32,7 @@ #include "core/io/marshalls.h" #include "core/io/zip_io.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" #include "core/project_settings.h" @@ -1398,8 +1399,9 @@ public: return ERR_UNCONFIGURED; } - //export_temp + // Export_temp APK. if (ep.step("Exporting APK", 0)) { + device_lock->unlock(); return ERR_SKIP; } @@ -1409,11 +1411,20 @@ public: if (use_reverse) p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST; - String export_to = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk"); - Error err = export_project(p_preset, true, export_to, p_debug_flags); - if (err) { - device_lock->unlock(); - return err; + String tmp_export_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk"); + +#define CLEANUP_AND_RETURN(m_err) \ + { \ + DirAccess::remove_file_or_error(tmp_export_path); \ + device_lock->unlock(); \ + return m_err; \ + } + + // Export to temporary APK before sending to device. + Error err = export_project(p_preset, true, tmp_export_path, p_debug_flags); + + if (err != OK) { + CLEANUP_AND_RETURN(err); } List<String> args; @@ -1425,7 +1436,7 @@ public: if (remove_prev) { if (ep.step("Uninstalling...", 1)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } print_line("Uninstalling previous version: " + devices[p_device].name); @@ -1440,7 +1451,7 @@ public: print_line("Installing to device (please wait...): " + devices[p_device].name); if (ep.step("Installing to device (please wait...)", 2)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } args.clear(); @@ -1448,13 +1459,12 @@ public: args.push_back(devices[p_device].id); args.push_back("install"); args.push_back("-r"); - args.push_back(export_to); + args.push_back(tmp_export_path); err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); if (err || rv != 0) { EditorNode::add_io_error("Could not install to device."); - device_lock->unlock(); - return ERR_CANT_CREATE; + CLEANUP_AND_RETURN(ERR_CANT_CREATE); } if (use_remote) { @@ -1508,7 +1518,7 @@ public: } if (ep.step("Running on Device...", 3)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } args.clear(); args.push_back("-s"); @@ -1528,11 +1538,11 @@ public: err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); if (err || rv != 0) { EditorNode::add_io_error("Could not execute on device."); - device_lock->unlock(); - return ERR_CANT_CREATE; + CLEANUP_AND_RETURN(ERR_CANT_CREATE); } - device_lock->unlock(); - return OK; + + CLEANUP_AND_RETURN(OK); +#undef CLEANUP_AND_RETURN } virtual Ref<Texture> get_run_icon() const { @@ -2023,8 +2033,16 @@ public: zlib_filefunc_def io2 = io; FileAccess *dst_f = NULL; io2.opaque = &dst_f; - String unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk"); - zipFile unaligned_apk = zipOpen2(unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); + + String tmp_unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk"); + +#define CLEANUP_AND_RETURN(m_err) \ + { \ + DirAccess::remove_file_or_error(tmp_unaligned_path); \ + return m_err; \ + } + + zipFile unaligned_apk = zipOpen2(tmp_unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer"); bool immersive = p_preset->get("screen/immersive_mode"); @@ -2152,7 +2170,7 @@ public: } if (ep.step("Adding Files...", 1)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } Error err = OK; Vector<String> cl = cmdline.strip_edges().split(" "); @@ -2184,7 +2202,7 @@ public: unzClose(pkg); EditorNode::add_io_error("Could not write expansion package file: " + apkfname); - return OK; + CLEANUP_AND_RETURN(ERR_SKIP); } cl.push_back("--use_apk_expansion"); @@ -2271,8 +2289,8 @@ public: zipClose(unaligned_apk, NULL); unzClose(pkg); - if (err) { - return err; + if (err != OK) { + CLEANUP_AND_RETURN(err); } if (_signed) { @@ -2280,7 +2298,7 @@ public: String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner"); if (!FileAccess::exists(jarsigner)) { EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the Editor Settings.\nThe resulting APK is unsigned."); - return OK; + CLEANUP_AND_RETURN(OK); } String keystore; @@ -2300,7 +2318,7 @@ public: } if (ep.step("Signing debug APK...", 103)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } } else { @@ -2309,13 +2327,13 @@ public: user = release_username; if (ep.step("Signing release APK...", 103)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } } if (!FileAccess::exists(keystore)) { EditorNode::add_io_error("Could not find keystore, unable to export."); - return ERR_FILE_CANT_OPEN; + CLEANUP_AND_RETURN(ERR_FILE_CANT_OPEN); } List<String> args; @@ -2333,30 +2351,30 @@ public: args.push_back(keystore); args.push_back("-storepass"); args.push_back(password); - args.push_back(unaligned_path); + args.push_back(tmp_unaligned_path); args.push_back(user); int retval; OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval); if (retval) { EditorNode::add_io_error("'jarsigner' returned with error #" + itos(retval)); - return ERR_CANT_CREATE; + CLEANUP_AND_RETURN(ERR_CANT_CREATE); } if (ep.step("Verifying APK...", 104)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } args.clear(); args.push_back("-verify"); args.push_back("-keystore"); args.push_back(keystore); - args.push_back(unaligned_path); + args.push_back(tmp_unaligned_path); args.push_back("-verbose"); OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval); if (retval) { EditorNode::add_io_error("'jarsigner' verification of APK failed. Make sure to use a jarsigner from OpenJDK 8."); - return ERR_CANT_CREATE; + CLEANUP_AND_RETURN(ERR_CANT_CREATE); } } @@ -2365,14 +2383,14 @@ public: static const int ZIP_ALIGNMENT = 4; if (ep.step("Aligning APK...", 105)) { - return ERR_SKIP; + CLEANUP_AND_RETURN(ERR_SKIP); } - unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io); + unzFile tmp_unaligned = unzOpen2(tmp_unaligned_path.utf8().get_data(), &io); if (!tmp_unaligned) { - EditorNode::add_io_error("Could not find temp unaligned APK."); - return ERR_FILE_NOT_FOUND; + EditorNode::add_io_error("Could not unzip temporary unaligned APK."); + CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND); } ret = unzGoToFirstFile(tmp_unaligned); @@ -2442,7 +2460,7 @@ public: zipClose(final_apk, NULL); unzClose(tmp_unaligned); - return OK; + CLEANUP_AND_RETURN(OK); } virtual void get_platform_features(List<String> *r_features) { diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index ac43392700..a0d6ac9214 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -141,3 +141,6 @@ def configure(env): # TODO: Reevaluate usage of this setting now that engine.js manages engine runtime. env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1']) + + #adding flag due to issue with emscripten 1.38.41 callMain method https://github.com/emscripten-core/emscripten/blob/incoming/ChangeLog.md#v13841-08072019 + env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["callMain"]']) diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index c68b420c61..69dd038709 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -362,12 +362,21 @@ int EditorExportPlatformJavaScript::get_device_count() const { Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { - String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_export.html"); + String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); + String path = basepath + ".html"; Error err = export_project(p_preset, true, path, p_debug_flags); - if (err) { + if (err != OK) { + // Export generates several files, clean them up on failure. + DirAccess::remove_file_or_error(basepath + ".html"); + DirAccess::remove_file_or_error(basepath + ".js"); + DirAccess::remove_file_or_error(basepath + ".pck"); + DirAccess::remove_file_or_error(basepath + ".png"); + DirAccess::remove_file_or_error(basepath + ".wasm"); return err; } OS::get_singleton()->shell_open(String("file://") + path); + // FIXME: Find out how to clean up export files after running the successfully + // exported game. Might not be trivial. return OK; } diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 8cabc45250..56b0a44dbc 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -29,9 +29,11 @@ /*************************************************************************/ #include "export.h" + #include "core/io/marshalls.h" #include "core/io/resource_saver.h" #include "core/io/zip_io.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" #include "core/project_settings.h" @@ -244,13 +246,17 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ copy->resize(icon_infos[i].size, icon_infos[i].size); if (icon_infos[i].is_png) { - //encode png icon + // Encode PNG icon. it->create_from_image(copy); String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png"); ResourceSaver::save(path, it); FileAccess *f = FileAccess::open(path, FileAccess::READ); - ERR_FAIL_COND(!f); + if (!f) { + // Clean up generated file. + DirAccess::remove_file_or_error(path); + ERR_FAIL(); + } int ofs = data.size(); uint32_t len = f->get_len(); @@ -261,6 +267,10 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ len = BSWAP32(len); copymem(&data.write[ofs], icon_infos[i].name, 4); encode_uint32(len, &data.write[ofs + 4]); + + // Clean up generated file. + DirAccess::remove_file_or_error(path); + } else { PoolVector<uint8_t> src_data = copy->get_data(); @@ -561,7 +571,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } } } - //bleh? } if (data.size() > 0) { @@ -687,7 +696,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p // Clean up temporary .app dir OS::get_singleton()->move_to_trash(tmp_app_path_name); - } else { + + } else { // pck String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck"); @@ -747,6 +757,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p zipCloseFileInZip(dst_pkg_zip); } } + + // Clean up generated file. + DirAccess::remove_file_or_error(pack_path); } } diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 024e7f1916..662ee49935 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -34,6 +34,7 @@ #include "core/io/zip_io.h" #include "core/math/crypto_core.h" #include "core/object.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/project_settings.h" #include "core/version.h" @@ -133,8 +134,6 @@ class AppxPackager { String progress_task; FileAccess *package; - String tmp_blockmap_file_path; - String tmp_content_types_file_path; Set<String> mime_types; @@ -146,8 +145,8 @@ class AppxPackager { String hash_block(const uint8_t *p_block_data, size_t p_block_len); - void make_block_map(); - void make_content_types(); + void make_block_map(const String &p_path); + void make_content_types(const String &p_path); _FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t *p_buf) { for (int i = 0; i < 2; i++) { @@ -208,9 +207,9 @@ String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) return String(base64); } -void AppxPackager::make_block_map() { +void AppxPackager::make_block_map(const String &p_path) { - FileAccess *tmp_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::WRITE); + FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE); tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">"); @@ -253,9 +252,9 @@ String AppxPackager::content_type(String p_extension) { return "application/octet-stream"; } -void AppxPackager::make_content_types() { +void AppxPackager::make_content_types(const String &p_path) { - FileAccess *tmp_file = FileAccess::open(tmp_content_types_file_path, FileAccess::WRITE); + FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE); tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); tmp_file->store_string("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">"); @@ -458,8 +457,6 @@ void AppxPackager::init(FileAccess *p_fa) { package = p_fa; central_dir_offset = 0; end_of_central_dir_offset = 0; - tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); - tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); } Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) { @@ -591,7 +588,9 @@ void AppxPackager::finish() { // Create and add block map file EditorNode::progress_task_step("export", "Creating block map...", 4); - make_block_map(); + const String &tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); + make_block_map(tmp_blockmap_file_path); + FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ); Vector<uint8_t> blockmap_buffer; blockmap_buffer.resize(blockmap_file->get_len()); @@ -604,8 +603,11 @@ void AppxPackager::finish() { memdelete(blockmap_file); // Add content types + EditorNode::progress_task_step("export", "Setting content types...", 5); - make_content_types(); + + const String &tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); + make_content_types(tmp_content_types_file_path); FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ); Vector<uint8_t> types_buffer; @@ -618,6 +620,10 @@ void AppxPackager::finish() { types_file->close(); memdelete(types_file); + // Cleanup generated files. + DirAccess::remove_file_or_error(tmp_blockmap_file_path); + DirAccess::remove_file_or_error(tmp_content_types_file_path); + // Pre-process central directory before signing for (int i = 0; i < file_metadata.size(); i++) { store_central_dir_header(file_metadata[i]); @@ -909,7 +915,8 @@ class EditorExportPlatformUWP : public EditorExportPlatform { if (err != OK) { String err_string = "Couldn't open temp logo file."; - + // Cleanup generated file. + DirAccess::remove_file_or_error(tmp_path); EditorNode::add_io_error(err_string); ERR_FAIL_V_MSG(data, err_string); } @@ -919,29 +926,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform { f->close(); memdelete(f); - - // Delete temp file - DirAccess *dir = DirAccess::open(tmp_path.get_base_dir(), &err); - - if (err != OK) { - - String err_string = "Couldn't open temp path to remove temp logo file."; - - EditorNode::add_io_error(err_string); - ERR_FAIL_V_MSG(data, err_string); - } - - err = dir->remove(tmp_path); - - memdelete(dir); - - if (err != OK) { - - String err_string = "Couldn't remove temp logo file."; - - EditorNode::add_io_error(err_string); - ERR_FAIL_V_MSG(data, err_string); - } + DirAccess::remove_file_or_error(tmp_path); return data; } diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index db277d3705..6ada0cba97 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -170,6 +170,10 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { void SpinBox::_line_edit_focus_exit() { + // discontinue because the focus_exit was caused by right-click context menu + if (line_edit->get_menu()->is_visible()) + return; + _text_entered(line_edit->get_text()); } diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 5f39d3ff49..c0b503c323 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -4022,6 +4022,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui _set_error("Expected array initialization"); return ERR_PARSE_ERROR; } + if (is_const) { + _set_error("Expected initialization of constant"); + return ERR_PARSE_ERROR; + } } node->declarations.push_back(decl); @@ -4051,6 +4055,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); node->declarations.push_back(decl); } else { + if (is_const) { + _set_error("Expected initialization of constant"); + return ERR_PARSE_ERROR; + } + VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); node->datatype = type; node->precision = precision; |