From a720bdb87ca8d6740ed442d0c1252ad565117b80 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 11 Mar 2025 22:09:10 -0300 Subject: [PATCH 01/23] feat: add desktop integration This commit adds desktop integration for linux by moving the executable to .local/godots.app and creating a desktop file in .local/share/applications. This way we can have a system shortcut to easily launch the application --- project.godot | 2 +- src/main/main.gd | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/project.godot b/project.godot index 015d2f34..c02892c1 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/expand-region/plugin.cfg", "res://addons/find-everywhere/plugin.cfg", "res://addons/previous-tab/plugin.cfg", "res://addons/script-tabs/plugin.cfg", "res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/use-context/plugin.cfg") [filesystem] diff --git a/src/main/main.gd b/src/main/main.gd index c4bcf327..2b087a1c 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -1,11 +1,24 @@ extends Node +const DESKTOP_ENTRY_FOLDER = ".local/share/applications" +const GVM_APP_FOLDER = ".local/godots.app" +const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" + @export_file() var gui_scene_path: String + + func _ready() -> void: var args := OS.get_cmdline_args() var user_args := OS.get_cmdline_user_args() + # Check if running as Flatpak by checking for the .flatpak-info file + var is_flatpak := FileAccess.file_exists("/.flatpak-info") + + # Check and create GVM desktop entry if needed + if OS.get_name() == "Linux" and not is_flatpak: + _ensure_desktop_entry() + if _is_cli_mode(args): Output.push("Run cli mode") var adjusted_args := args.slice(1) if OS.has_feature("editor") else args @@ -23,5 +36,61 @@ func _is_cli_mode(args: PackedStringArray) -> bool: return true return false +func _ensure_desktop_entry() -> void: + var home := OS.get_environment("HOME") + var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) + var gvm_app_path := home.path_join(GVM_APP_FOLDER) + + # Create gvm.app folder and copy executable + var dir := DirAccess.open("user://") + if FileAccess.file_exists(gvm_app_path): + return + else: + dir.make_dir_recursive(gvm_app_path) + + # Copy the current executable to gvm.app folder + var current_exe := OS.get_executable_path() + var new_exe_path := gvm_app_path.path_join("godots.x86_64") + if DirAccess.copy_absolute(current_exe, new_exe_path) == OK: + # Make it executable + OS.execute("chmod", ["+x", new_exe_path]) + + # Create desktop entry + # Copy and save the icon + var icon_path := gvm_app_path.path_join("icon.png") + var icon := load("res://icon.svg") as Texture2D + var image := icon.get_image() + image.save_png(icon_path) + + # Create desktop entry + var desktop_entry := _create_desktop_entry(new_exe_path, icon_path) + var file := FileAccess.open(desktop_entry_path, FileAccess.WRITE) + if file: + file.store_string(desktop_entry) + file.close() + # Make desktop entry executable + OS.execute("chmod", ["+x", desktop_entry_path]) + else: + printerr("Failed to create desktop entry") + else: + printerr("Failed to copy executable") + + +func _create_desktop_entry(exe_path: String, icon_path: String) -> String: + return """[Desktop Entry] + Name=Godots +GenericName=Libre game engine version manager +Comment=Ultimate go-to hub for managing your Godot versions and projects! +Exec="{exe}" %f +Icon={icon} +Terminal=false +PrefersNonDefaultGPU=true +Type=Application +Categories=Development;IDE; +StartupWMClass=Godot +""".format( + {"exe": exe_path, "icon": icon_path} + ) + func _exit() -> void: get_tree().quit() From be959ccb5dd62e9d3d84d348130700caffc2eed1 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Wed, 12 Mar 2025 22:44:19 -0300 Subject: [PATCH 02/23] chore: fix several erros and warnings The changes focus on adding proper type annotations and fixing various static typing issues throughout the codebase. The commit handles type safety improvements and GDScript best practices. I have also commented some unused or unreachable code, fixed narrowing conversion warnings by explicitly converting them, and added some annotations to ignore warnings from code I can't find a way to fix (for example, the await calls from some async functions. If I leave the await keyword, I get a warning saying it is redundant, but if I remove it, I get an error saying I have to add it... wtf) Also, we have some formatting because I have enabled gdformat to run automatically when I save a file. I think I will make a commit just with formatting to the rest of the files. --- plug.gd | 5 +- project.godot | 2 +- .../asset_lib_item_details.gd | 19 +- .../asset_lib_projects/asset_lib_projects.gd | 51 ++-- .../asset_list_item/asset_list_item.gd | 8 +- .../asset_lib_projects/assets_container.gd | 2 +- .../category_option_button.gd | 20 +- .../pagination_container.gd | 18 +- .../version_option_button.gd | 22 +- .../command_viewer/command_viewer.gd | 101 +++---- .../local/editor_item/show_owners_dialog.gd | 32 +-- .../local/editors_list/editors_list.gd | 3 +- .../editors/local_remote_editors_switch.gd | 6 +- .../remote_editor_install.gd | 18 +- .../remote_editors_tree.gd | 55 ++-- .../remote_editors_tree/sources/github.gd | 256 +++++++++++------- .../godots_releases/godots_releases.gd | 24 +- .../new_project_dialog/new_project_dialog.gd | 71 ++--- .../projects/project_item/project_item.gd | 74 ++--- src/components/projects/projects.gd | 32 +-- .../projects/projects_list/projects_list.gd | 3 +- src/components/settings/settings_window.gd | 120 ++++---- src/components/title_bar/title_bar.gd | 16 +- src/extensions/zip.gd | 22 +- src/http_client.gd | 24 +- src/main/gui/auto_updates.gd | 13 +- src/main/gui/gui_main.gd | 70 ++--- src/objects/node_component/comp_scene.gd | 4 +- src/services/godots_recent_releases.gd | 30 +- src/services/godots_releases.gd | 127 +++++---- src/services/local_editors.gd | 116 ++++---- src/services/projects.gd | 170 ++++++------ src/services/remote_image_src.gd | 52 ++-- src/utils.gd | 52 ++-- tests/cases/cli/parser/parser_not_ok.gd | 30 +- tests/cases/cli/parser/parser_ok.gd | 18 +- tests/cases/cli/parser/test_grammar.gd | 2 +- .../list_dir_recursive/list_dir_test.gd | 23 +- tests/cases/services/local_editor_tests.gd | 6 +- theme/fill_icons_registry.gd | 8 +- 40 files changed, 913 insertions(+), 812 deletions(-) diff --git a/plug.gd b/plug.gd index 6c722928..8d8e42bc 100644 --- a/plug.gd +++ b/plug.gd @@ -1,10 +1,11 @@ +@tool extends "res://addons/gd-plug/plug.gd" -func _plugging(): +func _plugging() -> void: plug("MikeSchulze/gdUnit4", {"commit": "8226bc34faaa9fde7829b065fa51b63a8fe140c4"}) plug("MakovWait/godot-use-context") - + if "--include-editor" in OS.get_cmdline_args(): plug("MakovWait/godot-expand-region", {"exclude": ["addons/gdUnit4"]}) plug("MakovWait/godot-find-everywhere") diff --git a/project.godot b/project.godot index c02892c1..b3a381b6 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg", "res://addons/use-context/plugin.cfg") [filesystem] diff --git a/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd b/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd index 7da925c0..a1c85073 100644 --- a/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd +++ b/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd @@ -26,7 +26,8 @@ func _ready() -> void: _preview.custom_minimum_size = Vector2(640, 345) * Config.EDSCALE _preview_bg.custom_minimum_size = Vector2(640, 101) * Config.EDSCALE - + + @warning_ignore("redundant_await") var item := await _asset_lib.async_fetch_one(_item_id) _configure(item) @@ -40,7 +41,8 @@ func _configure(item: AssetLib.Item) -> void: title = item.title var first_preview_selected := false for preview in item.previews: - var btn := add_preview(preview) + @warning_ignore("redundant_await") + var btn := await add_preview(preview) if not first_preview_selected and not preview.is_video: first_preview_selected = true _handle_btn_pressed.bind(preview, btn).call_deferred() @@ -52,10 +54,11 @@ func add_preview(item: AssetLib.ItemPreview) -> Button: btn.toggle_mode = true btn.pressed.connect(_handle_btn_pressed.bind(item, btn)) _previews_container.add_child(btn) - _images_src.async_load_img(item.thumbnail, func(tex: Texture2D) -> void: + @warning_ignore("redundant_await") + await _images_src.async_load_img(item.thumbnail, func(tex: Texture2D) -> void: if not item.is_video: if tex is ImageTexture: - utils.fit_height(85 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(85 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: (tex as ImageTexture).set_size_override(new_size) ) btn.icon = tex @@ -64,13 +67,13 @@ func add_preview(item: AssetLib.ItemPreview) -> Button: var tex_image: Image = tex.get_image() if tex_image == null: tex_image = get_theme_icon("FileBrokenBigThumb", "EditorIcons").get_image() - utils.fit_height(85 * Config.EDSCALE, tex_image.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(85 * Config.EDSCALE, tex_image.get_size(), func(new_size: Vector2i) -> void: tex_image.resize(new_size.x, new_size.y, Image.INTERPOLATE_LANCZOS) ) var thumbnail := tex_image.duplicate() as Image var overlay_pos := Vector2i( - (thumbnail.get_width() - overlay.get_width()) / 2, - (thumbnail.get_height() - overlay.get_height()) / 2 + int((thumbnail.get_width() - overlay.get_width()) / 2.0), + int((thumbnail.get_height() - overlay.get_height()) / 2.0) ) thumbnail.convert(Image.FORMAT_RGBA8) thumbnail.blend_rect(overlay, overlay.get_used_rect(), overlay_pos) @@ -89,7 +92,7 @@ func _handle_btn_pressed(item: AssetLib.ItemPreview, btn: Button) -> void: else: _images_src.async_load_img(item.link, func(tex: Texture2D) -> void: if tex is ImageTexture: - utils.fit_height(397 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(397 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: (tex as ImageTexture).set_size_override(new_size) ) _preview.texture = tex diff --git a/src/components/asset_lib_projects/asset_lib_projects.gd b/src/components/asset_lib_projects/asset_lib_projects.gd index d9d2c0c0..e38e9e9c 100644 --- a/src/components/asset_lib_projects/asset_lib_projects.gd +++ b/src/components/asset_lib_projects/asset_lib_projects.gd @@ -10,7 +10,7 @@ signal download_requested(item: AssetLib.Item, icon: Texture2D) @onready var _assets_container := %AssetsContainer as AssetsContainer @onready var _filter_edit := %FilterEdit as LineEdit @onready var _version_option_button := %VersionOptionButton as GodotVersionOptionButton -@onready var _sort_option_button := %SortOptionButton as OptionButton +#@onready var _sort_option_button := %SortOptionButton as OptionButton @onready var _category_option_button := %CategoryOptionButton as AssetCategoryOptionButton @onready var _site_option_button := %SiteOptionButton as AssetLibProjectsSiteOptionButton @onready var _support_menu_button := %SupportMenuButton as AssetLibProjectsSupportMenuButton @@ -23,8 +23,8 @@ var _params_sources_composed: ParamSources var _asset_lib_factory: AssetLib.Factory var _current_page := 0 -var _top_pages: HBoxContainer -var _bottom_pages: HBoxContainer +#var _top_pages: HBoxContainer +#var _bottom_pages: HBoxContainer var _versions_loaded := false var _config_loaded := false var _initial_fetch := false @@ -33,7 +33,7 @@ var _next_fetch_queued := false func init( - asset_lib_factory: AssetLib.Factory, + asset_lib_factory: AssetLib.Factory, category_src: AssetCategoryOptionButton.Src, version_src: GodotVersionOptionButton.Src, images_src: RemoteImageSrc.I @@ -41,20 +41,20 @@ func init( _category_option_button.init(category_src) _version_option_button.init(version_src) _asset_lib_factory = asset_lib_factory - + _assets_container.init(images_src) _assets_container.title_pressed.connect(func(item: AssetLib.Item) -> void: var asset_lib := _get_asset_lib() var item_details: AssetLibItemDetailsDialog = _item_details_scene.instantiate() - item_details.download_requested.connect(func(item: AssetLib.Item, icon: Texture2D) -> void: + item_details.download_requested.connect(func(asset: AssetLib.Item, icon: Texture2D) -> void: download_requested.emit(item, icon) ) item_details.init(item.id as String, asset_lib, images_src) add_child(item_details) item_details.popup_centered() ) - _assets_container.category_pressed.connect(func(item: AssetLib.Item) -> void: - _category_option_button.force_select_by_label(item.category) + _assets_container.category_pressed.connect(func(asset: AssetLib.Item) -> void: + _category_option_button.force_select_by_label(asset.category) ) if is_visible_in_tree(): @@ -72,23 +72,23 @@ func _init() -> void: func _ready() -> void: _params_sources_composed = ParamSources.new(_params_sources) - - (%LibVb as Control).add_theme_constant_override("separation", 20 * Config.EDSCALE) + + (%LibVb as Control).add_theme_constant_override("separation", int(20 * Config.EDSCALE)) _filter_edit.placeholder_text = tr("Search Templates, Projects, and Demos") - - _assets_container.add_theme_constant_override("h_separation", 10 * Config.EDSCALE) - _assets_container.add_theme_constant_override("v_separation", 10 * Config.EDSCALE) - + + _assets_container.add_theme_constant_override("h_separation", int(10 * Config.EDSCALE)) + _assets_container.add_theme_constant_override("v_separation", int(10 * Config.EDSCALE)) + _params_sources_composed.connect_changed(func() -> void: _current_page = 0 _async_fetch() ) - + _site_option_button.site_selected.connect(func() -> void: _config_loaded = false _async_fetch() ) - + (%TopPagesContainer as PaginationContainer).page_changed.connect(_change_page) (%BotPagesContainer as PaginationContainer).page_changed.connect(_change_page) @@ -102,17 +102,19 @@ func _async_fetch() -> void: _next_fetch_queued = false if not _versions_loaded: + @warning_ignore("redundant_await") var version_error := await __async_load_versions_list() if version_error: return - + if not _config_loaded: var config_error := await __async_load_configuration() if config_error: return - + + @warning_ignore("redundant_await") await __async_fetch_assets() - + _fetching = false if _next_fetch_queued: _async_fetch() @@ -126,6 +128,7 @@ func __async_load_versions_list() -> Error: _assets_container.clear() _clear_pages() + @warning_ignore("redundant_await") var versions_load_errors := await _version_option_button.async_load_versions() var return_error: Error if len(versions_load_errors) > 0: @@ -153,6 +156,7 @@ func __async_load_configuration() -> Error: _scroll_container.dim() _error_container.hide() + @warning_ignore("redundant_await") var config_load_errors := await _category_option_button.async_load_items( _site_option_button.get_selected_site() ) @@ -181,6 +185,7 @@ func __async_fetch_assets() -> void: var asset_lib := _get_asset_lib() var params := _get_asset_lib_params() var errors: Array[String] = [] + @warning_ignore("redundant_await") var items := await asset_lib.async_fetch(params, errors) if len(errors) > 0: @@ -253,15 +258,15 @@ func _set_status(text: String) -> void: class ParamSources: var _elements: Array - + func _init(elements: Array) -> void: _elements = elements - + func enable() -> void: for x: Object in _elements: if x.has_method("_on_fetch_enable"): x.call("_on_fetch_enable") - + func disable() -> void: for x: Object in _elements: if x.has_method("_on_fetch_disable"): @@ -271,7 +276,7 @@ class ParamSources: for x: Object in _elements: if x.has_signal("changed"): x.connect("changed", callback) - + func fill_params(params: AssetLib.Params) -> void: for x: Object in _elements: if x.has_method("fill_params"): diff --git a/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd b/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd index 3fffe404..c1369b7d 100644 --- a/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd +++ b/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd @@ -19,7 +19,7 @@ var _original_title_text: String func _init() -> void: custom_minimum_size = Vector2i(DEFAULT_MIN_SIZE_X, 100) * Config.EDSCALE - add_theme_constant_override("separation", 15 * Config.EDSCALE) + add_theme_constant_override("separation", int(15 * Config.EDSCALE)) func _ready() -> void: @@ -34,9 +34,9 @@ func init(item: AssetLib.Item, images: RemoteImageSrc.I) -> void: _category.text = item.category _author.text = item.author _cost.text = item.cost - + _original_title_text = item.title - + _title.pressed.connect(func() -> void: title_pressed.emit(item) ) @@ -69,5 +69,5 @@ func clamp_width(max_width: int) -> void: if text_pixel_width > max_width: # Truncate title text to within the current column width. var max_length := max_width / (text_pixel_width / full_text.length()) - var truncated_text := full_text.left(max_length - 3) + "..." + var truncated_text := full_text.left(int(max_length - 3)) + "..." _title.text = truncated_text diff --git a/src/components/asset_lib_projects/assets_container.gd b/src/components/asset_lib_projects/assets_container.gd index 81e452e9..11612f09 100644 --- a/src/components/asset_lib_projects/assets_container.gd +++ b/src/components/asset_lib_projects/assets_container.gd @@ -45,7 +45,7 @@ func _update_columns() -> void: new_columns = max(1, new_columns) # prints(size.x, new_columns, (size.x / new_columns) - (100 * Config.EDSCALE)) if new_columns != columns: - columns = new_columns + columns = int(new_columns) # for c in get_children(): # if c.has_method('clamp_width'): # c.clamp_width((size.x / new_columns) - (100 * Config.EDSCALE)) diff --git a/src/components/asset_lib_projects/category_option_button.gd b/src/components/asset_lib_projects/category_option_button.gd index e04ee764..53c74451 100644 --- a/src/components/asset_lib_projects/category_option_button.gd +++ b/src/components/asset_lib_projects/category_option_button.gd @@ -1,10 +1,8 @@ class_name AssetCategoryOptionButton extends OptionButton - signal changed - var _src: Src @@ -19,8 +17,10 @@ func _init() -> void: func async_load_items(url: String) -> Array[String]: clear() - add_item(tr("All"), 0) + @warning_ignore("redundant_await") + await add_item(tr("All"), 0) var errors: Array[String] = [] + @warning_ignore("redundant_await") var json := await _src.async_load(url, errors) for category: Dictionary in json.get("categories", []): add_item(tr(category.name as String), category.id as int) @@ -51,15 +51,17 @@ func force_select_by_label(opt_label: String) -> void: class Src: - func async_load(url: String, errors: Array[String]=[]) -> Dictionary: + func async_load(url: String, errors: Array[String] = []) -> Dictionary: return {} -class SrcRemote extends Src: - func async_load(url: String, errors: Array[String]=[]) -> Dictionary: - var response := HttpClient.Response.new(await HttpClient.async_http_get( - url.path_join("configure?type=project") - )) +class SrcRemote: + extends Src + + func async_load(url: String, errors: Array[String] = []) -> Dictionary: + var response := HttpClient.Response.new( + await HttpClient.async_http_get(url.path_join("configure?type=project")) + ) var info := response.to_response_info(url) if info.error_text: errors.append(info.error_text) diff --git a/src/components/asset_lib_projects/pagination_container.gd b/src/components/asset_lib_projects/pagination_container.gd index 1d7d3c52..e8afab5d 100644 --- a/src/components/asset_lib_projects/pagination_container.gd +++ b/src/components/asset_lib_projects/pagination_container.gd @@ -22,25 +22,25 @@ func clear() -> void: func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> HBoxContainer: var hbc := HBoxContainer.new() hbc.alignment = HBoxContainer.ALIGNMENT_CENTER - + if page_count < 2: return hbc - + var from := page - (5 / Config.EDSCALE) if from < 0: from = 0 var to := from + (10 / Config.EDSCALE) if to > page_count: to = page_count - + hbc.add_spacer(false) - hbc.add_theme_constant_override("separation", 5 * Config.EDSCALE) - + hbc.add_theme_constant_override("separation", int(5 * Config.EDSCALE)) + var trigger_search := func(btn: Button, p: int) -> void: btn.pressed.connect(func() -> void: page_changed.emit(p) ) - + var first := Button.new() first.text = tr("First", "Pagination") if page != 0: @@ -49,7 +49,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> first.set_disabled(true) first.set_focus_mode(Control.FOCUS_NONE) hbc.add_child(first) - + var prev := Button.new() prev.text = tr("Previous", "Pagination") if page > 0: @@ -59,7 +59,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> prev.set_focus_mode(Control.FOCUS_NONE) hbc.add_child(prev) hbc.add_child(VSeparator.new()) - + for i in range(from, to): if i == page: var current := Button.new() @@ -76,7 +76,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> trigger_search.call(current, i) hbc.add_child(current) - + var next := Button.new() next.set_text(tr("Next", "Pagination")) if page < page_count - 1: diff --git a/src/components/asset_lib_projects/version_option_button.gd b/src/components/asset_lib_projects/version_option_button.gd index 90a15390..5f6f0de6 100644 --- a/src/components/asset_lib_projects/version_option_button.gd +++ b/src/components/asset_lib_projects/version_option_button.gd @@ -17,6 +17,7 @@ func init(src: Src) -> void: func async_load_versions() -> Array[String]: clear() var errors: Array[String] = [] + @warning_ignore("redundant_await") var versions := await _src.async_fetch(errors) for i in range(len(versions)): add_item(versions[i]) @@ -29,28 +30,31 @@ func fill_params(params: AssetLib.Params) -> void: class Src: - func async_fetch(errors: Array[String]=[]) -> PackedStringArray: + func async_fetch(errors: Array[String] = []) -> PackedStringArray: return [] -class SrcMock extends Src: +class SrcMock: + extends Src var _data: PackedStringArray - + func _init(data: PackedStringArray) -> void: _data = data - - func async_fetch(errors: Array[String]=[]) -> PackedStringArray: + + func async_fetch(errors: Array[String] = []) -> PackedStringArray: return _data -class SrcGithubYml extends Src: +class SrcGithubYml: + extends Src var _yml_src: RemoteEditorsTreeDataSourceGithub.YmlSource var _name_regex := RegEx.create_from_string('(?m)\\sname:\\s"(?[^"]+)"$') - + func _init(yml_src: RemoteEditorsTreeDataSourceGithub.YmlSource) -> void: _yml_src = yml_src - - func async_fetch(errors: Array[String]=[]) -> PackedStringArray: + + func async_fetch(errors: Array[String] = []) -> PackedStringArray: + @warning_ignore("redundant_await") var yml := await _yml_src.async_load(errors) var versions := _name_regex.search_all(yml) var result: PackedStringArray = [] diff --git a/src/components/command_viewer/command_viewer.gd b/src/components/command_viewer/command_viewer.gd index d25477d1..7ad7b533 100644 --- a/src/components/command_viewer/command_viewer.gd +++ b/src/components/command_viewer/command_viewer.gd @@ -22,16 +22,16 @@ func _ready() -> void: if not visible: _commands = null ) - + var help := add_button(tr("Help")) help.pressed.connect(func() -> void: OS.shell_open("https://github.com/MakovWait/godots/blob/main/.github/assets/FEATURES.md#edit-commands") ) help.icon = get_theme_icon("ExternalLink", "EditorIcons") - + _create_new_command_btn = add_button(tr("New Command")) _create_new_command_btn.pressed.connect(func() -> void: - _popup_new_command_dialog("", "", [], "Terminal", false, + _popup_new_command_dialog("", "", [], "Terminal", false, func(cmd_name: String, cmd_path: String, cmd_args: PackedStringArray, cmd_icon: String, is_local: bool) -> void: if _commands: var command := _commands.add( @@ -60,7 +60,7 @@ func _update_view(commands: Commands, command_creation_allowed:=false) -> void: if c.has_method("hide"): c.call("hide") c.queue_free() - + for command in commands.all(): _add_view(command, commands) @@ -98,7 +98,7 @@ func _add_view(command: Command, commands: Commands) -> void: var output_text := "" if len(output) > 0: output_text = output[0] - + var rich_text_label := %OutputLabel as RichTextLabel rich_text_label.custom_minimum_size = Vector2i(0, 100) * Config.EDSCALE rich_text_label.clear() @@ -125,8 +125,8 @@ func _add_view(command: Command, commands: Commands) -> void: func _set_text_to_command_view(command: Command, command_view: CommandTextView) -> void: var local_badge := tr("Local") if command.is_local() else tr("Global") command_view.set_text( - "%s (%s):" % [command.name(), local_badge], - "", + "%s (%s):" % [command.name(), local_badge], + "", str(command), command.icon() ) @@ -155,14 +155,14 @@ class Command: var _icon: String var _process_src: OSProcessSchema.Source var _allowed_actions: PackedStringArray - + func _init( name: String, path: String, args: PackedStringArray, icon: String, - is_local: bool, - process_src: OSProcessSchema.Source, + is_local: bool, + process_src: OSProcessSchema.Source, allowed_actions: PackedStringArray ) -> void: _icon = icon @@ -172,36 +172,36 @@ class Command: _is_local = is_local _process_src = process_src _allowed_actions = allowed_actions - + func icon() -> String: return _icon - + func is_local() -> bool: return _is_local - + func is_action_allowed(action: String) -> bool: return action in _allowed_actions - + func args() -> PackedStringArray: return _args - + func path() -> String: return _path - + func name() -> String: return _name - + func execute(output:=[]) -> int: return _process_src.get_os_process_schema(_path, _args).execute( output, true, true ) - + func create_process() -> void: _process_src.get_os_process_schema(_path, _args).create_process(true) - + func remove_from(commands: Commands) -> void: commands.remove(_name, _is_local) - + func _to_string() -> String: return str(_process_src.get_os_process_schema(_path, _args)) @@ -209,11 +209,11 @@ class Command: class Commands: func all() -> Array[Command]: return [] - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: - assert(true, "Not implemented") + # assert(true, "Not implemented") <- Why??? assert true is redundant return null - + func remove(name: String, is_local: bool) -> void: pass @@ -222,10 +222,10 @@ class CustomCommandsSource: var custom_commands: Array: get: return _get_custom_commands() set(value): _set_custom_commands(value) - + func _get_custom_commands() -> Array: return [] - + func _set_custom_commands(value: Array) -> void: pass @@ -248,28 +248,28 @@ class CommandsInMemory extends CommandsWrap: class CustomCommandsSourceArray extends CustomCommandsSource: var _data: Array[Dictionary] = [] - + func _init(data: Array[Dictionary]=[]) -> void: _data = data - + func _get_custom_commands() -> Array: return _data - + func _set_custom_commands(value: Array) -> void: _data = value class CustomCommandsSourceDynamic extends CustomCommandsSource: signal edited - + var _delegate: Object - + func _init(delegate: Object) -> void: _delegate = delegate - + func _get_custom_commands() -> Array: return _delegate.get("custom_commands") - + func _set_custom_commands(value: Array) -> void: _delegate.set("custom_commands", value) edited.emit() @@ -278,23 +278,23 @@ class CustomCommandsSourceDynamic extends CustomCommandsSource: class CommandsDuo extends Commands: var _local: Commands var _global: Commands - + func _init(local: Commands, global: Commands) -> void: _local = local _global = global - + func all() -> Array[Command]: var result: Array[Command] = [] result.append_array(_global.all()) result.append_array(_local.all()) return result - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: if is_local: return _local.add(name, path, args, is_local, icon, allowed_actions) else: return _global.add(name, path, args, is_local, icon, allowed_actions) - + func remove(name: String, is_local: bool) -> void: if is_local: return _local.remove(name, is_local) @@ -304,27 +304,27 @@ class CommandsDuo extends Commands: class CommandsWrap extends Commands: var _origin: Commands - + func _init(origin: Commands) -> void: _origin = origin - + func all() -> Array[Command]: return _origin.all() - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: return _origin.add(name, path, args, is_local, icon, allowed_actions) - + func remove(name: String, is_local: bool) -> void: _origin.remove(name, is_local) class CommandsWithBasic extends CommandsWrap: var _basic: Array[Command] - + func _init(origin: Commands, basic: Array[Command]) -> void: super._init(origin) _basic = basic - + func all() -> Array[Command]: var result: Array[Command] result.append_array(_basic) @@ -336,12 +336,12 @@ class CommandsGeneric extends Commands: var _custom_commands_source: CustomCommandsSource var _base_process_src: OSProcessSchema.Source var _is_local: bool - + func _init(base_process_src: OSProcessSchema.Source, custom_commands_source: CustomCommandsSource, is_local: bool) -> void: _base_process_src = base_process_src _custom_commands_source = custom_commands_source _is_local = is_local - + func all() -> Array[Command]: var result: Array[Command] var commands := _custom_commands_source.custom_commands @@ -354,7 +354,7 @@ class CommandsGeneric extends Commands: _is_local ))) return result - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: if is_local == _is_local: var commands := _custom_commands_source.custom_commands @@ -382,21 +382,22 @@ class CommandsGeneric extends Commands: _custom_commands_source.custom_commands = commands return _to_command(name, path, args, allowed_actions, icon, is_local) else: - assert(true, "Not implemented") + # assert(true, "Not implemented") <- Again? return null - + func remove(name: String, is_local: bool) -> void: if is_local == _is_local: var commands := _custom_commands_source.custom_commands commands = commands.filter(func(x: Dictionary) -> bool: return x.name != name) _custom_commands_source.custom_commands = commands else: - assert(true, "Not implemented") - + # assert(true, "Not implemented") <- ;-; + pass + func _has_by_name(name: String) -> bool: return len( _custom_commands_source.custom_commands.filter(func(x: Dictionary) -> bool: return x.name == name) ) > 0 - + func _to_command(name: String, path: String, args: PackedStringArray, allowed_actions: PackedStringArray, icon: String, is_local: bool) -> Command: return Command.new(name, path, args, icon, is_local, _base_process_src, allowed_actions) diff --git a/src/components/editors/local/editor_item/show_owners_dialog.gd b/src/components/editors/local/editor_item/show_owners_dialog.gd index c9fb19c7..05f2260b 100644 --- a/src/components/editors/local/editor_item/show_owners_dialog.gd +++ b/src/components/editors/local/editor_item/show_owners_dialog.gd @@ -19,31 +19,31 @@ func raise(editor: LocalEditors.Item) -> void: var item := _tree.create_item() var icon_image: Image = owner.icon.get_image().duplicate() icon_image.resize( - 16 * Config.EDSCALE, - 16 * Config.EDSCALE, + int(16 * Config.EDSCALE), + int(16 * Config.EDSCALE), Image.INTERPOLATE_LANCZOS ) item.set_icon(0, ImageTexture.create_from_image(icon_image)) item.set_text(0, owner.name) item.add_button( - 0, - get_theme_icon("Play", "EditorIcons"), - Buttons.RUN, - not owner.is_valid, + 0, + get_theme_icon("Play", "EditorIcons"), + Buttons.RUN, + not owner.is_valid, tr("Run") ) item.add_button( - 0, - get_theme_icon("Edit", "EditorIcons"), - Buttons.EDIT, - not owner.is_valid, + 0, + get_theme_icon("Edit", "EditorIcons"), + Buttons.EDIT, + not owner.is_valid, tr("Edit") ) item.add_button( - 0, - get_theme_icon("Folder", "EditorIcons"), - Buttons.OPEN_IN_EXPLORER, - not owner.is_valid, + 0, + get_theme_icon("Folder", "EditorIcons"), + Buttons.OPEN_IN_EXPLORER, + not owner.is_valid, tr("Show in File Manager") ) item.set_metadata(0, owner) @@ -57,7 +57,7 @@ func _ready() -> void: if not visible: queue_free() ) - + _tree.button_clicked.connect(func(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void: var project: Projects.Item = item.get_metadata(0) if id == Buttons.EDIT: @@ -69,6 +69,6 @@ func _ready() -> void: ProjectSettings.globalize_path(project.path) ) ) - + _tree.create_item() _tree.hide_root = true diff --git a/src/components/editors/local/editors_list/editors_list.gd b/src/components/editors/local/editors_list/editors_list.gd index 8678d8a7..d7fa0f9d 100644 --- a/src/components/editors/local/editors_list/editors_list.gd +++ b/src/components/editors/local/editors_list/editors_list.gd @@ -29,14 +29,13 @@ func _item_comparator(a: Dictionary, b: Dictionary) -> bool: 1: return a.path < b.path 2: return a.tag_sort_string < b.tag_sort_string _: return a.name < b.name - return a.name < b.name func _fill_sort_options(btn: OptionButton) -> void: btn.add_item(tr("Name")) btn.add_item(tr("Path")) btn.add_item(tr("Tags")) - + var last_checked_sort := Cache.smart_value(self, "last_checked_sort", true) btn.select(last_checked_sort.ret(0) as int) btn.item_selected.connect(func(idx: int) -> void: last_checked_sort.put(idx)) diff --git a/src/components/editors/local_remote_editors_switch.gd b/src/components/editors/local_remote_editors_switch.gd index b8218d74..e9ee320a 100644 --- a/src/components/editors/local_remote_editors_switch.gd +++ b/src/components/editors/local_remote_editors_switch.gd @@ -18,9 +18,9 @@ func _ready() -> void: ctx.go_to_remote() _local.set_pressed_no_signal(true) ) - - add_theme_constant_override("separation", 48 * Config.EDSCALE) - + + add_theme_constant_override("separation", int(48 * Config.EDSCALE)) + _set_theme_to(_local) _set_theme_to(_remote) diff --git a/src/components/editors/remote/remote_editor_install/remote_editor_install.gd b/src/components/editors/remote/remote_editor_install/remote_editor_install.gd index e692d9b5..d985cd0b 100644 --- a/src/components/editors/remote/remote_editor_install/remote_editor_install.gd +++ b/src/components/editors/remote/remote_editor_install/remote_editor_install.gd @@ -7,12 +7,12 @@ signal installed(editor_name: String, editor_exec_path: String) @onready var _editor_name_edit: LineEdit = %EditorNameEdit @onready var _select_exec_file_tree: Tree = %SelectExecFileTree -@onready var _file_dialog := $FileDialog as FileDialog +#@onready var _file_dialog := $FileDialog as FileDialog @onready var _show_all_check_box := %ShowAllCheckBox as CheckBox var _dir_content: Array[edir.DirListResult] -var _show_all: bool: - get: return _show_all_check_box.button_pressed +#var _show_all: bool: + #get: return _show_all_check_box.button_pressed func _ready() -> void: @@ -44,20 +44,20 @@ func init(editor_name: String, editor_exec_path: String) -> void: func _setup_editor_select_tree() -> void: _select_exec_file_tree.clear() var root := _select_exec_file_tree.create_item() - + ## filter: Optional[Callable], should_be_selected: Optional[Callable] - var create_tree_items := func(source: Array[edir.DirListResult], filter: Variant = null, should_be_selected: Variant = null) -> void: + var create_tree_items := func(source: Array[edir.DirListResult], _filter: Variant = null, _should_be_selected: Variant = null) -> void: var selected := false for x in source: - if filter and not (filter as Callable).call(x): + if _filter and not (_filter as Callable).call(x): continue var item := _select_exec_file_tree.create_item(root) item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK) item.set_text(0, x.file) item.set_editable(0, true) item.set_meta("full_path", x.path) - if not selected and should_be_selected != null: - if (should_be_selected as Callable).call(x): + if not selected and _should_be_selected != null: + if (_should_be_selected as Callable).call(x): selected = true item.set_checked(0, true) item.select(0) @@ -83,7 +83,7 @@ func _setup_editor_select_tree() -> void: return x.is_file and ( x.extension.contains("32") or x.extension.contains("64") ) - + create_tree_items.call(_dir_content, filter, should_be_selected) diff --git a/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd b/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd index 619c09f8..e898aab0 100644 --- a/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd +++ b/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd @@ -10,14 +10,14 @@ const uuid = preload("res://addons/uuid.gd") @onready var _check_box_container: HFlowContainer = %CheckBoxContainer var _refresh_button: Button -var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets +#var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets var _src: RemoteEditorsTreeDataSource.I var _i_remote_tree: RemoteEditorsTreeDataSource.RemoteTree var _root_loaded := false var _row_filters: Array[RowFilter] = [NotRelatedFilter.new()] var _current_loadings_number := 0: - set(value): + set(value): _current_loadings_number = value _loadings_number_changed.emit(value) var _remote_editors_checkbox_checked := Cache.smart_section( @@ -27,7 +27,7 @@ var _remote_editors_checkbox_checked := Cache.smart_section( func post_ready(refresh_button: Button) -> void: _refresh_button = refresh_button - + _setup_tree() _setup_checkboxes() @@ -61,7 +61,7 @@ func _refresh() -> void: func _setup_checkboxes() -> void: (%CheckBoxPanelContainer as PanelContainer).add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Tree")) - + var checkbox := func(text: String, filter: RowFilter, button_pressed:=false) -> CheckBox: var box := CheckBox.new() box.text = text @@ -69,7 +69,7 @@ func _setup_checkboxes() -> void: if button_pressed: _row_filters.append(filter) box.toggled.connect(func(pressed: bool) -> void: - if pressed: + if pressed: _row_filters.append(filter) else: var idx := _row_filters.find(filter) @@ -86,7 +86,7 @@ func _setup_checkboxes() -> void: if not button_pressed: _row_filters.append(filter) box.toggled.connect(func(pressed: bool) -> void: - if pressed: + if pressed: var idx := _row_filters.find(filter) if idx >= 0: _row_filters.remove_at(idx) @@ -98,32 +98,32 @@ func _setup_checkboxes() -> void: return box var contains_any := func(words: Array) -> Callable: - return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return words.any(func(x: String) -> bool: return row.get_name().to_lower().contains(x.to_lower())) - + var _not := func(original: Callable) -> Callable: return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> Callable: return not original.call(row) - + _check_box_container.add_child( inverted_checkbox.call( - tr("mono"), + tr("mono"), RowFilter.new(contains_any.call(["mono"]) as Callable), _remote_editors_checkbox_checked.get_value("mono", true) ) as CheckBox ) - + _check_box_container.add_child( inverted_checkbox.call( - tr("unstable"), + tr("unstable"), RowFilter.new(contains_any.call(["rc", "beta", "alpha", "dev", "fixup"]) as Callable), _remote_editors_checkbox_checked.get_value("unstable", false) ) as CheckBox ) - + _check_box_container.add_child( inverted_checkbox.call( - tr("any platform"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("any platform"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_file() and row.is_for_different_platform(_src.get_platform_suffixes())), _remote_editors_checkbox_checked.get_value("any platform", false) ) as CheckBox @@ -141,7 +141,7 @@ func _setup_checkboxes() -> void: if bit: _check_box_container.add_child( checkbox.call( - "%s-bit" % bit, + "%s-bit" % bit, RowFilter.new(contains_any.call([opposite]) as Callable), _remote_editors_checkbox_checked.get_value("%s-bit" % bit, true) ) as CheckBox @@ -149,8 +149,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("4.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("4.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and row.get_name().begins_with("4")), _remote_editors_checkbox_checked.get_value("4.x", true) ) as CheckBox @@ -158,8 +158,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("3.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("3.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and row.get_name().begins_with("3")), _remote_editors_checkbox_checked.get_value("3.x", true) ) as CheckBox @@ -167,8 +167,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("x.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("x.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and not (row.get_name().begins_with("4") or row.get_name().begins_with("3"))), _remote_editors_checkbox_checked.get_value("x.x", false) ) as CheckBox @@ -181,9 +181,9 @@ func _delegate_of(item: TreeItem) -> RemoteEditorsTreeDataSource.Item: func _setup_tree() -> void: _i_remote_tree = RemoteEditorsTreeDataSource.RemoteTree.new(_tree, self) - + _tree.item_collapsed.connect( - func(x: TreeItem) -> void: + func(x: TreeItem) -> void: var expanded := not x.collapsed var delegate := _delegate_of(x) var not_loaded_yet := not delegate.is_loaded() @@ -205,6 +205,7 @@ func _setup_tree() -> void: func _expand(remote_tree_item: RemoteEditorsTreeDataSource.Item) -> void: _current_loadings_number += 1 + @warning_ignore("redundant_await") await remote_tree_item.async_expand(_i_remote_tree) _update_whole_tree_visibility(remote_tree_item) _current_loadings_number -= 1 @@ -224,10 +225,10 @@ func _on_visibility_changed() -> void: class RowFilter: var _delegate: Callable - + func _init(delegate: Callable) -> void: _delegate = delegate - + func test(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return _delegate.call(row) @@ -235,7 +236,7 @@ class RowFilter: class SimpleContainsFilter extends RowFilter: func _init(what: String) -> void: super._init( - func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.get_name().to_lower().contains(what) ) diff --git a/src/components/editors/remote/remote_editors_tree/sources/github.gd b/src/components/editors/remote/remote_editors_tree/sources/github.gd index 64f1b248..90197aef 100644 --- a/src/components/editors/remote/remote_editors_tree/sources/github.gd +++ b/src/components/editors/remote/remote_editors_tree/sources/github.gd @@ -1,40 +1,64 @@ class_name RemoteEditorsTreeDataSourceGithub -class Self extends RemoteEditorsTreeDataSource.I: +class Self: + extends RemoteEditorsTreeDataSource.I var _assets: RemoteEditorsTreeDataSource.RemoteAssets const platforms = { - "X11": { - "suffixes": ["_x11.64.zip", "_linux.64.zip", "_linux.x86_64.zip", "_linux.x86_32.zip", "_linux_x86_64.zip", "_linux_x86_32.zip"], + "X11": + { + "suffixes": + [ + "_x11.64.zip", + "_linux.64.zip", + "_linux.x86_64.zip", + "_linux.x86_32.zip", + "_linux_x86_64.zip", + "_linux_x86_32.zip" + ], }, - "OSX": { - "suffixes": ["_osx.universal.zip", "_macos.universal.zip", "_osx.fat.zip", "_osx32.zip", "_osx64.zip"], + "OSX": + { + "suffixes": + [ + "_osx.universal.zip", + "_macos.universal.zip", + "_osx.fat.zip", + "_osx32.zip", + "_osx64.zip" + ], }, - "Windows": { + "Windows": + { "suffixes": ["_win64.exe.zip", "_win32.exe.zip", "_win64.zip", "_win32.zip"], } } - + func _init(assets: RemoteEditorsTreeDataSource.RemoteAssets) -> void: _assets = assets - + func setup(tree: Tree) -> void: var root := tree.create_item() - root.set_meta( - "delegate", - GithubRootItem.new( - root, - _assets, - GithubVersionSourceParseYml.new( - YmlSourceGithub.new(), - GithubAssetSourceDefault.new() - ), + ( + root + . set_meta( + "delegate", + ( + GithubRootItem + . new( + root, + _assets, + GithubVersionSourceParseYml.new( + YmlSourceGithub.new(), GithubAssetSourceDefault.new() + ), + ) + ) ) ) - + func cleanup(tree: Tree) -> void: tree.clear() - + func get_platform_suffixes() -> Array: var current_platform: Dictionary if OS.has_feature("windows"): @@ -44,7 +68,7 @@ class Self extends RemoteEditorsTreeDataSource.I: elif OS.has_feature("linux"): current_platform = platforms["X11"] return current_platform["suffixes"] - + func to_remote_item(item: TreeItem) -> RemoteEditorsTreeDataSource.Item: return item.get_meta("delegate") @@ -54,10 +78,10 @@ class GithubVersion: var flavor: String var releases: Array[String] = [] var _assets_src: GithubAssetSource - + func get_flavor_release() -> GodotRelease: return GodotRelease.new(name, flavor, _assets_src) - + func get_recent_releases() -> Array[GodotRelease]: var result: Array[GodotRelease] = [] for r in releases: @@ -69,64 +93,70 @@ class GodotRelease: var name: String var _version: String var _assets_src: GithubAssetSource - + func _init(version: String, name: String, assets_src: GithubAssetSource) -> void: self.name = name _assets_src = assets_src _version = version - + func is_stable() -> bool: return name == "stable" - + func async_load_assets() -> Array[GodotAsset]: + @warning_ignore("redundant_await") return await _assets_src.async_load(_version, name) class GodotAsset: var _json: Dictionary - + var name: String: - get: return _json.get("name", "") - + get: + return _json.get("name", "") + var file_name: String: - get: return browser_download_url.get_file() - + get: + return browser_download_url.get_file() + var browser_download_url: String: - get: return _json.get("browser_download_url", "") - + get: + return _json.get("browser_download_url", "") + var is_zip: bool: - get: return name.get_extension() == "zip" - + get: + return name.get_extension() == "zip" + func _init(json: Dictionary) -> void: _json = json -class GithubItemBase extends RemoteEditorsTreeDataSource.Item: +class GithubItemBase: + extends RemoteEditorsTreeDataSource.Item var _item: TreeItem var _assets: RemoteEditorsTreeDataSource.RemoteAssets - + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets) -> void: _item = item _assets = assets - + func is_loaded() -> bool: return _item.has_meta("loaded") - + func async_expand(tree: RemoteTree) -> void: return - + func handle_item_activated() -> void: pass - + func handle_button_clicked(col: int, id: int, mouse: int) -> void: pass - + func update_visibility(filters: Array) -> void: - var filter_target := _to_filter_target() + var filter_target := _to_filter_target() if filter_target == null: return _item.visible = _should_be_visible(filter_target, filters) - + func _should_be_visible(target: GithubFilterTarget, filters: Array) -> bool: if target.is_file() and not target.is_zip(): return false @@ -134,12 +164,12 @@ class GithubItemBase extends RemoteEditorsTreeDataSource.Item: for filter: RemoteEditorsTreeControl.RowFilter in filters: if filter.test(target): return false - + return true - + func _to_filter_target() -> GithubFilterTarget: return null - + func _asset_to_item(asset: GodotAsset, tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: var tree_item := tree.create_item(_item) tree_item.set_meta("delegate", GithubAssetItem.new(tree_item, _assets, asset)) @@ -148,7 +178,7 @@ class GithubItemBase extends RemoteEditorsTreeDataSource.Item: var btn_texture: Texture2D = tree.theme_source.get_theme_icon("AssetLib", "EditorIcons") tree_item.add_button(0, btn_texture) tree_item.collapsed = true - + func get_children() -> Array[RemoteEditorsTreeDataSource.Item]: var result: Array[RemoteEditorsTreeDataSource.Item] = [] for child in _item.get_children(): @@ -157,13 +187,16 @@ class GithubItemBase extends RemoteEditorsTreeDataSource.Item: return result -class GithubAssetItem extends GithubItemBase: +class GithubAssetItem: + extends GithubItemBase var _asset: GodotAsset - - func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, asset: GodotAsset) -> void: + + func _init( + item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, asset: GodotAsset + ) -> void: super._init(item, assets) _asset = asset - + func _to_filter_target() -> GithubFilterTarget: return GithubFilterTarget.new(_asset.name, false, true, _asset.is_zip) @@ -174,13 +207,16 @@ class GithubAssetItem extends GithubItemBase: _assets.download(_asset.browser_download_url, _asset.file_name) -class GithubReleaseItem extends GithubItemBase: +class GithubReleaseItem: + extends GithubItemBase var _release: GodotRelease - - func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, release: GodotRelease) -> void: + + func _init( + item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, release: GodotRelease + ) -> void: super._init(item, assets) _release = release - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) var assets := await _release.async_load_assets() @@ -192,33 +228,33 @@ class GithubReleaseItem extends GithubItemBase: return GithubFilterTarget.new(_release.name, false, false, false) -class GithubVersionItem extends GithubItemBase: +class GithubVersionItem: + extends GithubItemBase var _version: GithubVersion - - func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, version: GithubVersion) -> void: + + func _init( + item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, version: GithubVersion + ) -> void: super._init(item, assets) _version = version - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) - + var releases: Array[GodotRelease] = [] var flavor := _version.get_flavor_release() if not flavor.is_stable(): releases.append(flavor) releases.append_array(_version.get_recent_releases()) - + for release in releases: var tree_item := tree.create_item(_item) tree_item.visible = false tree_item.set_text(0, release.name) tree.set_as_folder(tree_item) - tree_item.set_meta( - "delegate", - GithubReleaseItem.new(tree_item, _assets, release) - ) + tree_item.set_meta("delegate", GithubReleaseItem.new(tree_item, _assets, release)) tree_item.collapsed = true - + if flavor.is_stable(): var assets := await flavor.async_load_assets() for asset in assets: @@ -230,15 +266,21 @@ class GithubVersionItem extends GithubItemBase: return GithubFilterTarget.new(_version.name, true, false, false) -class GithubRootItem extends GithubItemBase: +class GithubRootItem: + extends GithubItemBase var _versions_source: GithubVersionSource - - func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, versions_source: GithubVersionSource) -> void: + + func _init( + item: TreeItem, + assets: RemoteEditorsTreeDataSource.RemoteAssets, + versions_source: GithubVersionSource + ) -> void: super._init(item, assets) _versions_source = versions_source - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) + @warning_ignore("redundant_await") var versions := await _versions_source.async_load() for version in versions: var tree_item := tree.create_item(_item) @@ -249,7 +291,8 @@ class GithubRootItem extends GithubItemBase: tree.free_loading_placeholder(_item) -class GithubFilterTarget extends RemoteEditorsTreeDataSource.FilterTarget: +class GithubFilterTarget: + extends RemoteEditorsTreeDataSource.FilterTarget var _name: String var _is_possible_version_folder: bool var _is_file: bool @@ -272,7 +315,9 @@ class GithubFilterTarget extends RemoteEditorsTreeDataSource.FilterTarget: func is_for_different_platform(platform_suffixes: Array) -> bool: var cached_name := get_name() - return not platform_suffixes.any(func(suffix: String) -> bool: return cached_name.ends_with(suffix)) + return not platform_suffixes.any( + func(suffix: String) -> bool: return cached_name.ends_with(suffix) + ) func get_name() -> String: return _name @@ -288,79 +333,88 @@ class GithubAssetSource: return [] -class GithubAssetSourceDefault extends GithubAssetSource: +class GithubAssetSourceDefault: + extends GithubAssetSource const url = "https://api.github.com/repos/godotengine/godot-builds/releases/tags/%s" - + func async_load(version: String, release: String) -> Array[GodotAsset]: var tag := "%s-%s" % [version, release] var response := await HttpClient.async_http_get( - url % tag, - ["Accept: application/vnd.github.v3+json"] + url % tag, ["Accept: application/vnd.github.v3+json"] ) var json: Dictionary = JSON.parse_string( (response[3] as PackedByteArray).get_string_from_utf8() ) var result: Array[GodotAsset] = [] - for asset_json: Dictionary in json.get('assets', []): + for asset_json: Dictionary in json.get("assets", []): result.append(GodotAsset.new(asset_json)) return result -class GithubAssetSourceFileJson extends GithubAssetSource: +class GithubAssetSourceFileJson: + extends GithubAssetSource var _file_path: String - + func _init(file_path: String) -> void: _file_path = file_path - + func async_load(version: String, release: String) -> Array[GodotAsset]: - var json: Dictionary = JSON.parse_string(FileAccess.open(_file_path, FileAccess.READ).get_as_text()) + var json: Dictionary = JSON.parse_string( + FileAccess.open(_file_path, FileAccess.READ).get_as_text() + ) var result: Array[GodotAsset] = [] - for asset_json: Dictionary in json.get('assets', []): + for asset_json: Dictionary in json.get("assets", []): result.append(GodotAsset.new(asset_json)) return result -class GithubVersionSourceFileJson extends GithubVersionSource: +class GithubVersionSourceFileJson: + extends GithubVersionSource var _file_path: String var _assets_src: GithubAssetSource - + func _init(file_path: String, assets_src: GithubAssetSource) -> void: _file_path = file_path _assets_src = assets_src - + func async_load() -> Array[GithubVersion]: - var json: Array = JSON.parse_string(FileAccess.open(_file_path, FileAccess.READ).get_as_text()) + var json: Array = JSON.parse_string( + FileAccess.open(_file_path, FileAccess.READ).get_as_text() + ) var result: Array[GithubVersion] = [] for el: Dictionary in json: var version := GithubVersion.new() version._assets_src = _assets_src version.name = el.name version.flavor = el.flavor - for release: Dictionary in el.get('releases', []): + for release: Dictionary in el.get("releases", []): version.releases.append(release.name) result.append(version) return result class YmlSource: - func async_load(errors: Array[String]=[]) -> String: + func async_load(errors: Array[String] = []) -> String: return "" -class YmlSourceFile extends YmlSource: +class YmlSourceFile: + extends YmlSource var _file_path: String - + func _init(file_path: String) -> void: _file_path = file_path - - func async_load(errors: Array[String]=[]) -> String: - var text := FileAccess.open(_file_path, FileAccess.READ).get_as_text() + + func async_load(errors: Array[String] = []) -> String: + var text := FileAccess.open(_file_path, FileAccess.READ).get_as_text() return text -class YmlSourceGithub extends YmlSource: +class YmlSourceGithub: + extends YmlSource const url = "https://raw.githubusercontent.com/godotengine/godot-website/master/_data/versions.yml" - func async_load(errors: Array[String]=[]) -> String: + + func async_load(errors: Array[String] = []) -> String: var response := HttpClient.Response.new(await HttpClient.async_http_get(url)) var info := response.to_response_info(url) if info.error_text: @@ -369,19 +423,21 @@ class YmlSourceGithub extends YmlSource: return text -class GithubVersionSourceParseYml extends GithubVersionSource: +class GithubVersionSourceParseYml: + extends GithubVersionSource var _src: YmlSource var _assets_src: GithubAssetSource - - var _version_regex := RegEx.create_from_string('(?m)^-[\\s\\S]*?(?=^-|\\Z)') + + var _version_regex := RegEx.create_from_string("(?m)^-[\\s\\S]*?(?=^-|\\Z)") var _name_regex := RegEx.create_from_string('(?m)\\sname:\\s"(?[^"]+)"$') var _flavor_regex := RegEx.create_from_string('(?m)\\sflavor:\\s"(?[^"]+)"$') - + func _init(src: YmlSource, assets_src: GithubAssetSource) -> void: _src = src _assets_src = assets_src - + func async_load() -> Array[GithubVersion]: + @warning_ignore("redundant_await") var yml := await _src.async_load() var result: Array[GithubVersion] = [] var versions := _version_regex.search_all(yml) diff --git a/src/components/godots_releases/godots_releases.gd b/src/components/godots_releases/godots_releases.gd index b6cbc7cf..6c61efd9 100644 --- a/src/components/godots_releases/godots_releases.gd +++ b/src/components/godots_releases/godots_releases.gd @@ -14,27 +14,23 @@ var _fetching := false func init( - releases: GodotsReleases.I, - godots_downloads: GodotsDownloads.I, - godots_install: GodotsInstall.I + releases: GodotsReleases.I, godots_downloads: GodotsDownloads.I, godots_install: GodotsInstall.I ) -> void: self._releases = releases self._godots_install = godots_install self._godots_downloads = godots_downloads - + if visible: _async_refetch_data() func _ready() -> void: _godots_releases_list.set_search_box_text("tag:newest") - _refresh_button.pressed.connect(func() -> void: - _async_refetch_data() - ) - + _refresh_button.pressed.connect(func() -> void: _async_refetch_data()) + _star_git_hub.icon = get_theme_icon("Favorites", "EditorIcons") - _star_git_hub.pressed.connect(func() -> void: - OS.shell_open("https://github.com/MakovWait/godots") + _star_git_hub.pressed.connect( + func() -> void: OS.shell_open("https://github.com/MakovWait/godots") ) @@ -43,15 +39,16 @@ func _async_refetch_data() -> void: return _fetching = true _refresh_button.disabled = true - + _async_refetch_data_body() - + _data_loaded = true _fetching = false _refresh_button.disabled = false func _async_refetch_data_body() -> void: + @warning_ignore("redundant_await") await _releases.async_load() _godots_releases_list.refresh(_releases.all()) @@ -62,8 +59,7 @@ func _on_godots_releases_list_item_selected(item: GodotsReleasesListItemControl) func _on_godots_releases_list_download_and_install_requested(url: String) -> void: _godots_downloads.download( - url, - func(abs_zip_path: String) -> void: _godots_install.install(abs_zip_path) + url, func(abs_zip_path: String) -> void: _godots_install.install(abs_zip_path) ) diff --git a/src/components/projects/new_project_dialog/new_project_dialog.gd b/src/components/projects/new_project_dialog/new_project_dialog.gd index 7d3ec309..fadb08d1 100644 --- a/src/components/projects/new_project_dialog/new_project_dialog.gd +++ b/src/components/projects/new_project_dialog/new_project_dialog.gd @@ -1,6 +1,7 @@ class_name NewProjectDialog extends "res://src/components/projects/install_project_dialog/install_project_dialog.gd" +@warning_ignore("unused_signal") signal created(path: String) @onready var _handler_option_button: OptionButton = %HandlerOptionButton @@ -9,15 +10,15 @@ signal created(path: String) func _ready() -> void: super._ready() - + _handler_option_button.item_selected.connect(func(idx: int) -> void: var meta: Dictionary = _handler_option_button.get_item_metadata(idx) _custom_form_tabs.current_tab = _custom_form_tabs.get_tab_idx_from_control(meta.form as Control) ) - + _register_handler(NewProjectGodot4.new()) _register_handler(NewProjectGodot3.new()) - + confirmed.connect(func() -> void: var meta: Dictionary = _handler_option_button.get_item_metadata(_handler_option_button.selected) var handler := meta.self as NewProjectHandler @@ -33,7 +34,7 @@ func _register_handler(handler: NewProjectHandler) -> void: var handler_form := handler.custom_form() handler_form.name = handler.label() _custom_form_tabs.add_child(handler_form) - + _handler_option_button.add_item(handler.label()) _handler_option_button.set_item_metadata( _handler_option_button.item_count - 1, @@ -46,17 +47,17 @@ func _register_handler(handler: NewProjectHandler) -> void: class NewProjectContext: var _ctx_delegate: Object - + var dir: String var project_name: String var form: Control - + func _init(ctx_delegate: Object) -> void: _ctx_delegate = ctx_delegate - + func show_error(msg: String) -> void: _ctx_delegate.call("_error", msg) - + func emit_created(path: String) -> void: _ctx_delegate.emit_signal("created", path) @@ -64,10 +65,10 @@ class NewProjectContext: class NewProjectHandler: func custom_form() -> Control: return Control.new() - - func create_project(args: NewProjectContext) -> void: + + func create_project(args: NewProjectContext) -> void: pass - + func label() -> String: return "" @@ -75,7 +76,7 @@ class NewProjectHandler: class NewProjectGodot3 extends NewProjectHandler: func custom_form() -> Control: return NewProjectGodot3Form.new() - + func create_project(ctx: NewProjectContext) -> void: var dir := ctx.dir var project_file_path := dir.path_join("project.godot") @@ -95,14 +96,14 @@ class NewProjectGodot3 extends NewProjectHandler: var img: Texture2D = preload("res://assets/default_project_icon.svg") img.get_image().save_png(dir.path_join("icon.png")) ctx.emit_created(project_file_path) - + func label() -> String: return "Godot 3.x" class NewProjectGodot3Form extends VBoxContainer: var _renderer: RendererSelect - + func _init() -> void: _renderer = RendererSelect.new({ "GLES3": { @@ -125,9 +126,9 @@ class NewProjectGodot3Form extends VBoxContainer: ]), }, }) - + add_child(_renderer) - + Comp.new(Label).on_init([ CompInit.TEXT(tr("The renderer can be changed later, but scenes may need to be adjusted.")), CompInit.CUSTOM(func(label: Label) -> void: @@ -138,7 +139,7 @@ class NewProjectGodot3Form extends VBoxContainer: pass\ ) ]).add_to(self) - + func renderer_method() -> String: return _renderer.current() @@ -156,7 +157,7 @@ class NewProjectGodot4 extends NewProjectHandler: var initial_settings := ConfigFile.new() initial_settings.set_value("application", "config/name", ctx.project_name) initial_settings.set_value("application", "config/icon", "res://icon.svg") - + # rendering initial_settings.set_value("rendering", "renderer/rendering_method", form.renderer_method()) if form.renderer_method() == "gl_compatibility": @@ -179,7 +180,7 @@ class NewProjectGodot4 extends NewProjectHandler: else: ctx.show_error(tr("Couldn't create .gitignore in project path.")) return - + var gitattributes := FileAccess.open(dir.path_join(".gitattributes"), FileAccess.WRITE) if gitattributes != null: gitattributes.store_line("# Normalize EOL for all files that Git considers text files.") @@ -195,7 +196,7 @@ class NewProjectGodot4 extends NewProjectHandler: file_to.close() ctx.emit_created(project_file_path) - + func label() -> String: return "Godot 4.x" @@ -238,9 +239,9 @@ class NewProjectGodot4Form extends VBoxContainer: ]), } }) - + add_child(_renderer) - + Comp.new(Label).on_init([ CompInit.TEXT(tr("The renderer can be changed later, but scenes may need to be adjusted.")), CompInit.CUSTOM(func(label: Label) -> void: @@ -251,34 +252,34 @@ class NewProjectGodot4Form extends VBoxContainer: pass\ ) ]).add_to(self) - + _vcs_meta = VersionControlMetadata.new() add_child(_vcs_meta) - + func renderer_method() -> String: return _renderer.current() - + func vsc_meta() -> String: return _vcs_meta.current() class VersionControlMetadata extends HBoxContainer: var _options: OptionButton - + func _init() -> void: var label := Label.new() label.text = tr("Version Control Metadata:") - + _options = OptionButton.new() _options.add_item("Git") _options.set_item_metadata(_options.item_count - 1, "git") - + _options.add_item("None") _options.set_item_metadata(_options.item_count - 1, "none") - + add_child(label) add_child(_options) - + func current() -> String: return _options.get_item_metadata(_options.selected) as String @@ -286,7 +287,7 @@ class VersionControlMetadata extends HBoxContainer: class RendererSelect extends VBoxContainer: var _button_group := ButtonGroup.new() - + func _init(options: Dictionary) -> void: var renderer_desc_label := CompRefs.Simple.new() @@ -317,13 +318,13 @@ class RendererSelect extends VBoxContainer: Comp.new(Label).on_init([ CompInit.TEXT(tr("Renderer:")) ]), - + Comp.new(HBoxContainer, [ # checkboxes Comp.new(VBoxContainer, checkboxes), - + Comp.new(VSeparator), - + # checkbox desc Comp.new(VBoxContainer, [ Comp.new(Label).on_init([ @@ -337,6 +338,6 @@ class RendererSelect extends VBoxContainer: ]), ]), ]).add_to(self) - + func current() -> String: return _button_group.get_pressed_button().get_meta("rendering_method") diff --git a/src/components/projects/project_item/project_item.gd b/src/components/projects/project_item/project_item.gd index c2c84609..c4b8738d 100644 --- a/src/components/projects/project_item/project_item.gd +++ b/src/components/projects/project_item/project_item.gd @@ -20,9 +20,9 @@ signal tag_clicked(tag: String) @onready var _tag_container: ItemTagContainer = %TagContainer @onready var _project_features: Label = %ProjectFeatures @onready var _info_body: VBoxContainer = %InfoBody -@onready var _info_v_box: VBoxContainer = %InfoVBox +#@onready var _info_v_box: VBoxContainer = %InfoVBox @onready var _actions_h_box: HBoxContainer = %ActionsHBox -@onready var _title_container: HBoxContainer = %TitleContainer +#@onready var _title_container: HBoxContainer = %TitleContainer @onready var _actions_container: HBoxContainer = %ActionsContainer static var settings := ProjectItemActions.Settings.new( @@ -56,10 +56,10 @@ func init(item: Projects.Item) -> void: item.loaded.connect(func() -> void: _fill_data(item) ) - + _editor_button.pressed.connect(_on_rebind_editor.bind(item)) _editor_button.disabled = item.is_missing - + item.internals_changed.connect(func() -> void: _fill_data(item) ) @@ -74,7 +74,7 @@ func init(item: Projects.Item) -> void: double_clicked.connect(func() -> void: if item.is_missing: return - + if item.has_invalid_editor: _on_rebind_editor(item) else: @@ -84,8 +84,8 @@ func init(item: Projects.Item) -> void: func _setup_actions_view(item: Projects.Item) -> void: var action_views := ProjectItemActions.Menu.new( - _actions.without(['view-command']).all(), - settings, + _actions.without(['view-command']).all(), + settings, CustomCommandsPopupItems.Self.new( _actions.by_key('view-command'), _get_commands(item) @@ -145,11 +145,11 @@ func _fill_actions(item: Projects.Item) -> void: "act": _on_edit_with_editor.bind(item), "label": tr("Edit"), }) - + var run := Action.from_dict({ "key": "run", "icon": Action.IconTheme.new(self, "Play", "EditorIcons"), - "act": _on_run_with_editor.bind(item, func(item: Projects.Item) -> void: item.run(), "run", "Run", false), + "act": _on_run_with_editor.bind(item, func(_item: Projects.Item) -> void: _item.run(), "run", "Run", false), "label": tr("Run"), }) @@ -180,14 +180,14 @@ func _fill_actions(item: Projects.Item) -> void: "act": func() -> void: manage_tags_requested.emit(), "label": tr("Manage Tags"), }) - + var view_command := Action.from_dict({ "key": "view-command", "icon": Action.IconTheme.new(self, "Edit", "EditorIcons"), "act": _view_command.bind(item), "label": tr("Edit Commands"), }) - + var remove := Action.from_dict({ "key": "remove", "icon": Action.IconTheme.new(self, "Remove", "EditorIcons"), @@ -219,7 +219,7 @@ func _fill_data(item: Projects.Item) -> void: if item.is_missing: _explore_button.icon = get_theme_icon("FileBroken", "EditorIcons") modulate = Color(1, 1, 1, 0.498) - + _project_warning.visible = item.has_invalid_editor _favorite_button.button_pressed = item.favorite _title_label.text = item.name @@ -229,13 +229,13 @@ func _fill_data(item: Projects.Item) -> void: _tag_container.set_tags(item.tags) _set_features(item.features) _tags = item.tags - + _sort_data.favorite = item.favorite _sort_data.name = item.name _sort_data.path = item.path _sort_data.last_modified = item.last_modified _sort_data.tag_sort_string = "".join(item.tags) - + for action in _actions.sub_list([ 'duplicate', 'bind-editor', @@ -243,7 +243,7 @@ func _fill_data(item: Projects.Item) -> void: 'rename' ]).all(): action.disable(item.is_missing) - + for action in _actions.sub_list([ 'view-command', 'edit', @@ -284,8 +284,8 @@ func _get_commands(item: Projects.Item) -> CommandViewer.Commands: func _set_features(features: Array) -> void: var features_to_print := features.filter(func(x: String) -> bool: return _is_version(x) or x == "C#") if len(features_to_print) > 0: - var str := ", ".join(features_to_print) - _project_features.text = str + var string := ", ".join(features_to_print) + _project_features.text = string # _project_features.custom_minimum_size = Vector2(25 * 15, 10) * Config.EDSCALE if settings.is_show_features(): _project_features.show() @@ -299,37 +299,37 @@ func _is_version(feature: String) -> bool: func _on_rebind_editor(item: Projects.Item) -> void: var bind_dialog := ConfirmationDialogAutoFree.new() - + var vbox := VBoxContainer.new() bind_dialog.add_child(vbox) - + var hbox := HBoxContainer.new() vbox.add_child(hbox) - + var title := Label.new() hbox.add_child(title) - + var options := OptionButton.new() hbox.add_child(options) - + if item.has_version_hint: var hbox2 := HBoxContainer.new() hbox2.modulate = Color(0.5, 0.5, 0.5, 0.5) hbox2.alignment = BoxContainer.ALIGNMENT_CENTER vbox.add_child(hbox2) - + var version_hint_title := Label.new() version_hint_title.text = tr("version hint:") hbox2.add_child(version_hint_title) - + var version_hint_value := Label.new() version_hint_value.text = item.version_hint hbox2.add_child(version_hint_value) - + vbox.add_spacer(false) - + title.text = "%s: " % tr("Editor") - + options.item_selected.connect(func(idx: int) -> void: bind_dialog.get_ok_button().disabled = false ) @@ -339,14 +339,14 @@ func _on_rebind_editor(item: Projects.Item) -> void: var opt: Dictionary = option_items[i] options.add_item(opt.label as String, i) options.set_item_metadata(i, opt.path) - + bind_dialog.confirmed.connect(func() -> void: if options.selected < 0: return var new_editor_path := options.get_item_metadata(options.selected) as String item.editor_path = new_editor_path edited.emit() ) - + add_child(bind_dialog) bind_dialog.popup_centered() @@ -364,36 +364,36 @@ func _on_rename(item: Projects.Item) -> void: func _on_edit_with_editor(item: Projects.Item) -> void: - _on_run_with_editor(item, func(item: Projects.Item) -> void: item.edit(), "edit", "Edit", true) + _on_run_with_editor(item, func(_item: Projects.Item) -> void: _item.edit(), "edit", "Edit", true) func _on_run_with_editor(item: Projects.Item, editor_flag: Callable, action_name: String, ok_button_text: String, auto_close: bool) -> void: if not item.show_edit_warning: _run_with_editor(item, editor_flag, auto_close) return - + var confirmation_dialog := ConfirmationDialogAutoFree.new() confirmation_dialog.ok_button_text = ok_button_text confirmation_dialog.get_label().hide() - + var label := Label.new() label.text = tr("Are you sure to %s the project with the given editor?") % action_name - + var editor_name := Label.new() editor_name.text = item.editor_name editor_name.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - + var checkbox := CheckBox.new() checkbox.text = tr("do not show again for this project") - + var vb := VBoxContainer.new() vb.add_child(label) vb.add_child(editor_name) vb.add_child(checkbox) vb.add_spacer(false) - + confirmation_dialog.add_child(vb) - + confirmation_dialog.confirmed.connect(func() -> void: var before := item.show_edit_warning item.show_edit_warning = not checkbox.button_pressed diff --git a/src/components/projects/projects.gd b/src/components/projects/projects.gd index b1774530..1f7cab34 100644 --- a/src/components/projects/projects.gd +++ b/src/components/projects/projects.gd @@ -14,16 +14,16 @@ signal manage_tags_requested(item_tags: Array, all_tags: Array, on_confirm: Call var _projects: Projects.List -var _load_projects_queue := [] +#var _load_projects_queue := [] var _remove_missing_action: Action.Self func init(projects: Projects.List) -> void: self._projects = projects - + var remove_missing_popup := RemoveMissingDialog.new(_remove_missing) add_child(remove_missing_popup) - + var actions := Action.List.new([ Action.from_dict({ "key": "new-project", @@ -67,7 +67,7 @@ func init(projects: Projects.List) -> void: "act": _refresh }) ]) - + _remove_missing_action = actions.by_key('remove-missing') var project_actions := TabActions.Menu.new( @@ -76,9 +76,9 @@ func init(projects: Projects.List) -> void: 'import-project', 'clone-project', 'scan-projects', - ]).all(), + ]).all(), TabActions.Settings.new( - Cache.section_of(self), + Cache.section_of(self), [ 'new-project', 'import-project', @@ -106,34 +106,34 @@ func init(projects: Projects.List) -> void: project.load() _projects_list.add(project) _projects.save() - + if edit: project.edit() AutoClose.close_if_should() - + if callback: (callback as Callable).call(project, projects) - + _projects_list.sort_items() ) - + _clone_project_dialog.cloned.connect(func(path: String) -> void: assert(path.get_file() == "project.godot") import(path) ) - + _new_project_dialog.created.connect(func(project_path: String) -> void: import(project_path) ) - + _scan_dialog.dir_to_scan_selected.connect(func(dir_to_scan: String) -> void: _scan_projects(dir_to_scan) ) - + _duplicate_project_dialog.duplicated.connect(func(project_path: String, callback: Callable) -> void: import(project_path, callback) ) - + _projects_list.refresh(_projects.all()) _load_projects() @@ -182,7 +182,7 @@ func install_zip(zip_reader: ZIPReader, project_name: String) -> void: if len(project_configs) == 0: _install_project_from_zip_dialog.error(tr("No project.godot found.")) return - + var project_file_path := project_configs[0] _install_project_from_zip_dialog.hide() import(project_file_path.path) @@ -255,5 +255,5 @@ func _on_projects_list_item_manage_tags_requested(item_data: Projects.Item) -> v func _on_projects_list_item_duplicate_requested(project: Projects.Item) -> void: if _duplicate_project_dialog.visible: return - + _duplicate_project_dialog.raise(project.name, project) diff --git a/src/components/projects/projects_list/projects_list.gd b/src/components/projects/projects_list/projects_list.gd index 80829c7f..069a85e2 100644 --- a/src/components/projects/projects_list/projects_list.gd +++ b/src/components/projects/projects_list/projects_list.gd @@ -34,7 +34,6 @@ func _item_comparator(a: Dictionary, b: Dictionary) -> bool: 2: return a.path < b.path 3: return a.tag_sort_string < b.tag_sort_string _: return a.name < b.name - return a.name < b.name func _fill_sort_options(btn: OptionButton) -> void: @@ -42,7 +41,7 @@ func _fill_sort_options(btn: OptionButton) -> void: btn.add_item(tr("Name")) btn.add_item(tr("Path")) btn.add_item(tr("Tags")) - + var last_checked_sort := Cache.smart_value(self, "last_checked_sort", true) btn.select(last_checked_sort.ret(1) as int) btn.item_selected.connect(func(idx: int) -> void: last_checked_sort.put(idx)) diff --git a/src/components/settings/settings_window.gd b/src/components/settings/settings_window.gd index 9a0097e0..c27f00d8 100644 --- a/src/components/settings/settings_window.gd +++ b/src/components/settings/settings_window.gd @@ -34,24 +34,24 @@ func _prepare_settings() -> Array: Config.USE_SYSTEM_TITLE_BAR, SettingCheckbox ))), func() -> bool: return DisplayServer.has_feature(DisplayServer.FEATURE_EXTEND_TO_TITLE)), - + SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/config/use_native_file_dialog", Config.USE_NATIVE_FILE_DIALOG, SettingCheckbox ))), - + SettingChangeObserved(SettingCfg( "application/config/remember_window_rect", Config.REMEMBER_WINDOW_SIZE, SettingCheckbox, tr("Restore last window size and position on startup.") )), - + SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/preset", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/preset" ).bake_default("Default"), @@ -61,18 +61,18 @@ func _prepare_settings() -> Array: SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/base_color", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/base_color" ).bake_default(Color(0.21, 0.24, 0.29)), SettingColorPicker, tr("Base color for the theme. Affects the background and primary UI elements.") )))), - + SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/accent_color", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/accent_color" ).bake_default(Color(0.44, 0.73, 0.98)), @@ -83,7 +83,7 @@ func _prepare_settings() -> Array: SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/contrast", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/contrast" ).bake_default(0.3), @@ -152,9 +152,9 @@ func _init() -> void: (%WarningRect as Button).icon = get_theme_icon("StatusWarning", "EditorIcons") (%WarningRect as Button).self_modulate = get_theme_color("warning_color", "Editor") * Color(1, 1, 1, 0.6) (%RestartInfoLabel as Label).self_modulate = get_theme_color("warning_color", "Editor") * Color(1, 1, 1, 0.6) - + (%OpenConfigFileButton as Button).icon = get_theme_icon("Load", "EditorIcons") - + var sections_root := (%SectionsTree as Tree).get_root() if sections_root: for child in sections_root.get_children(): @@ -169,7 +169,7 @@ func _ready() -> void: Config.save() ) - var title_text := tr("Settings") + var title_text := tr("Settings") var set_title_text := func(pattern: String) -> void: title = pattern % title_text title = title_text @@ -179,19 +179,19 @@ func _ready() -> void: Config.saved.connect(func() -> void: set_title_text.call("%s") ) - + get_ok_button().text = tr("Save & Close") - - + + var left_vb := %LeftVB as VBoxContainer left_vb.custom_minimum_size = Vector2(190, 0) * Config.EDSCALE - - + + var right_vb: = %RightVB as VBoxContainer right_vb.custom_minimum_size = Vector2(300, 0) * Config.EDSCALE right_vb.size_flags_horizontal = Control.SIZE_EXPAND_FILL - - + + (%RestartInfoLabel as Label).text = tr("Godots must be restarted for changes to take effect.") (%RestartButton as Button).pressed.connect(func() -> void: Config.save() @@ -205,12 +205,12 @@ func _ready() -> void: (%RestartContainer as PanelContainer).hide() ) (%RestartContainer as Control).hide() - + (%OpenConfigFileButton as Button).pressed.connect(func() -> void: var config_path := ProjectSettings.globalize_path(Config.APP_CONFIG_PATH.get_base_dir()) OS.shell_show_in_file_manager(config_path) ) - + _setup_settings() @@ -223,17 +223,17 @@ func raise_settings() -> void: func _setup_settings() -> void: var settings := _prepare_settings().filter(func(x: Variant) -> bool: return x != null) - + for setting: Setting in settings: setting.bind_settings_window(self) setting.validate() setting.add_control(SettingControlTarget.new(%InspectorVBox, setting.category.raw)) - + var tree := %SectionsTree as Tree tree.item_selected.connect(func() -> void: - var selected := tree.get_selected() - if selected: - var section: Variant = selected.get_metadata(0) + var _selected := tree.get_selected() + if _selected: + var section: Variant = _selected.get_metadata(0) if section is String: _update_settings_visibility(section as String) ) @@ -245,7 +245,7 @@ func _setup_settings() -> void: if not category.first_lvl in categories: categories[category.first_lvl] = Set.new() var second_lvls := categories[category.first_lvl] as Set - second_lvls.append(category.second_lvl) + second_lvls.append(category.second_lvl) var selected := false for first_lvl: String in categories.keys(): var first_lvl_item := tree.create_item(root) @@ -269,10 +269,10 @@ func _update_settings_visibility(section: String) -> void: func SettingCfg(category: String, cfg_value: ConfigFileValue, prop_factory: Variant, tooltip:="") -> Setting: if prop_factory is Script: - prop_factory = func(a1: Variant, a2: Variant, a3: Variant, a4: Variant) -> Setting: + prop_factory = func(a1: Variant, a2: Variant, a3: Variant, a4: Variant) -> Setting: return (prop_factory as Script).call("new", a1, a2, a3, a4) return ((prop_factory as Callable).call( - category, + category, cfg_value.ret(), tooltip, cfg_value.get_baked_default() @@ -281,7 +281,7 @@ func SettingCfg(category: String, cfg_value: ConfigFileValue, prop_factory: Vari func SettingChangeObserved(origin: Setting) -> Setting: return origin.on_value_changed( - func(new_value: Variant) -> void: + func(new_value: Variant) -> void: _setting_changed.emit(origin, new_value) _settings_changed.emit() ) @@ -304,25 +304,25 @@ func SettingCustomPresetTrigger(origin: Setting) -> Setting: class Category: var _category: String - + var name: String: get: return _category.get_file().capitalize() - + var first_lvl: String: get: return _category.split("/")[0] - + var second_lvl: String: get: return _category.split("/")[1] - + var raw: String: get: return _category - + func _init(category: String) -> void: _category = category - + func validate() -> void: assert( - len(_category.split("/")) == 3, + len(_category.split("/")) == 3, "Invalid category %s! Category format is: s/s/s" % _category ) @@ -330,11 +330,11 @@ class Category: class SettingControlTarget: var _target: Node var _category: String - + func _init(target: Node, category: String) -> void: _target = target _category = category - + func add_child(child: Node) -> void: child.set_meta("category", _category) _target.add_child(child) @@ -342,50 +342,50 @@ class SettingControlTarget: class Setting extends RefCounted: signal changed(new_value: Variant) - + var category: Category var _value: Variant var _tooltip: String var _default_value: Variant var _settings_window: SettingsWindow - + func _init(name: String, value: Variant, tooltip: String, default_value: Variant) -> void: self.category = Category.new(name) self._value = value self._tooltip = tooltip self._default_value = default_value - + func add_control(target: SettingControlTarget) -> void: pass - + func on_value_changed(callback: Callable) -> Setting: changed.connect(callback) return self - + func notify_changed() -> void: changed.emit(_value) - + func set_value(value: Variant) -> void: _value = value - + func set_value_and_notify(value: Variant) -> void: set_value(value) notify_changed() - + func validate() -> void: category.validate() assert(_settings_window != null) - + func reset() -> void: set_value_and_notify(_default_value) - + func value_is_not_default() -> bool: return _value != _default_value - + func bind_settings_window(settings_window: SettingsWindow) -> Setting: _settings_window = settings_window return self - + func with_meta(name: StringName, value: Variant) -> Setting: self.set_meta(name, value) return self @@ -462,7 +462,7 @@ class SettingFilePath extends Setting: func add_control(target: SettingControlTarget) -> void: var file_dialog := CompRefs.Simple.new() var line_edit := CompRefs.Simple.new() - var update_value := func(new_value: String) -> void: + var update_value := func(new_value: String) -> void: set_value_and_notify(new_value) line_edit.value.text = new_value self.on_value_changed(func(new_value: String) -> void: @@ -491,8 +491,8 @@ class SettingFilePath extends Setting: CompInit.TREE_ENTERED( CompInit.SET_THEME_ICON("Load", "EditorIcons") ), - CompInit.PRESSED(func(_a: Control) -> void: - var dialog := file_dialog.value as FileDialog + CompInit.PRESSED(func(_a: Control) -> void: + var dialog := file_dialog.value as FileDialog dialog.current_dir = self._value dialog.popup_centered_ratio(0.5)\ ) @@ -596,12 +596,12 @@ class CompSettingPanelContainer extends Comp: class SettingOptionButton extends Setting: var _options: Dictionary var _fallback_option: String - + func _init(name: String, value: Variant, tooltip: String, default_value: Variant, options: Dictionary, fallback_option: String) -> void: super._init(name, value, tooltip, default_value) self._options = options self._fallback_option = fallback_option - + func add_control(target: SettingControlTarget) -> void: var update_selected_value := func(this: OptionButton) -> void: this.clear() @@ -613,11 +613,11 @@ class SettingOptionButton extends Setting: this.selected = item_idx item_to_select_was_found = true item_idx += 1 - + if not item_to_select_was_found: this.add_item(_fallback_option) this.selected = item_idx - + var control := Comp.new(HBoxContainer, [ CompSettingNameContainer.new(self), CompSettingPanelContainer.new(_tooltip, [ @@ -790,13 +790,13 @@ class SettingSlider extends Setting: this.step = 0.1 this.min_value = -1 this.max_value = 1 - + self.on_value_changed(func(new_value: Variant) -> void: this.value = new_value ) - + this.value = self._value - + this.value_changed.connect(func(new_value: Variant) -> void: self.set_value_and_notify(new_value) ) diff --git a/src/components/title_bar/title_bar.gd b/src/components/title_bar/title_bar.gd index 7f150b6c..ae677768 100644 --- a/src/components/title_bar/title_bar.gd +++ b/src/components/title_bar/title_bar.gd @@ -3,7 +3,7 @@ extends Control @onready var _left_spacer := %LeftSpacer as Control @onready var _right_spacer := %RightSpacer as Control -@onready var _gui_base := get_parent() +#@onready var _gui_base := get_parent() @onready var _main_container := %MainContainer as HBoxContainer @onready var _buttons_container := %ButtonsContainer as HBoxContainer @@ -41,7 +41,7 @@ func _setup_title_label() -> void: var label := %TitleLabel as Label label.add_theme_font_override("font", get_theme_font("bold", "EditorFonts")) label.add_theme_font_size_override("font_size", get_theme_font_size("bold_size", "EditorFonts")) - + #label.set_text_overrun_behavior(TextServer.OVERRUN_TRIM_ELLIPSIS) #label.set_text_overrun_behavior(TextServer.OVERRUN_TRIM_ELLIPSIS) label.set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER) @@ -53,7 +53,7 @@ func _setup_title_label() -> void: func _gui_input(event: InputEvent) -> void: if not _can_move: return - + if event is InputEventMouseMotion and _moving: if (event as InputEventMouseMotion).button_mask & MOUSE_BUTTON_MASK_LEFT: var w := get_window() @@ -87,8 +87,8 @@ func _gui_input(event: InputEvent) -> void: func _resize() -> void: var buttons_offet := Vector2i( - self.global_position.y + (self.size.y / 2), - self.global_position.y + (self.size.y / 2) + int(self.global_position.y + (self.size.y / 2)), + int(self.global_position.y + (self.size.y / 2)) ) DisplayServer.window_set_window_buttons_offset( buttons_offet, @@ -97,13 +97,13 @@ func _resize() -> void: var margin := DisplayServer.window_get_safe_title_margins( DisplayServer.MAIN_WINDOW_ID ) - if _left_spacer: + if _left_spacer: var w := margin.y if self.is_layout_rtl() else margin.x _left_spacer.custom_minimum_size = Vector2(w, 0) - if _right_spacer: + if _right_spacer: var w := margin.x if self.is_layout_rtl() else margin.y _right_spacer.custom_minimum_size = Vector2(w, 0) self.custom_minimum_size = Vector2( - 0, + 0, maxf(margin.z - self.global_position.y, self.custom_minimum_size.y) ) diff --git a/src/extensions/zip.gd b/src/extensions/zip.gd index d351356a..6a1f83d5 100644 --- a/src/extensions/zip.gd +++ b/src/extensions/zip.gd @@ -7,11 +7,11 @@ static func unzip(zip_path: String, target_dir: String) -> void: var exit_code: int if OS.has_feature("windows"): exit_code = OS.execute( - "powershell.exe", + "powershell.exe", [ "-command", - "\"Expand-Archive '%s' '%s'\" -Force" % [ - ProjectSettings.globalize_path(zip_path), + "\"Expand-Archive '%s' '%s'\" -Force" % [ + ProjectSettings.globalize_path(zip_path), ProjectSettings.globalize_path(target_dir) ] ], output, true @@ -20,10 +20,10 @@ static func unzip(zip_path: String, target_dir: String) -> void: Output.push("unzip executed with exit code: %s" % exit_code) elif OS.has_feature("macos"): exit_code = OS.execute( - "unzip", + "unzip", [ - "%s" % ProjectSettings.globalize_path(zip_path), - "-d", + "%s" % ProjectSettings.globalize_path(zip_path), + "-d", "%s" % ProjectSettings.globalize_path(target_dir) ], output, true ) @@ -34,7 +34,7 @@ static func unzip(zip_path: String, target_dir: String) -> void: "unzip", [ "-o", - "%s" % ProjectSettings.globalize_path(zip_path), + "%s" % ProjectSettings.globalize_path(zip_path), "-d", "%s" % ProjectSettings.globalize_path(target_dir) ], output, true @@ -45,8 +45,8 @@ static func unzip(zip_path: String, target_dir: String) -> void: ## A procedure that unzips a zip file to a target directory, keeping the ## target directory as root, rather than the zip's root directory. -static func unzip_to_path(zip: ZIPReader, destiny: String) -> Error: - var files := zip.get_files() +static func unzip_to_path(_zip: ZIPReader, destiny: String) -> Error: + var files := _zip.get_files() var err: int for zip_file_name in files: @@ -56,9 +56,9 @@ static func unzip_to_path(zip: ZIPReader, destiny: String) -> Error: if zip_file_name.ends_with("/"): err = DirAccess.make_dir_recursive_absolute(target_file_name) if err != OK: - return err + return (err as Error) else: - var file_contents := zip.read_file(zip_file_name) + var file_contents: PackedByteArray = _zip.read_file(zip_file_name) var file := FileAccess.open(target_file_name, FileAccess.WRITE) if not file: return FileAccess.get_open_error() diff --git a/src/http_client.gd b/src/http_client.gd index d92ccd0e..073982f7 100644 --- a/src/http_client.gd +++ b/src/http_client.gd @@ -32,10 +32,10 @@ func async_http_get_using(http_request: HTTPRequest, url: String, headers := Pac class Response: var _resp: Array - + var result: int: get: return _resp[0] - + var code: int: get: return _resp[1] @@ -47,20 +47,20 @@ class Response: func _init(resp: Array) -> void: _resp = resp - + func to_json(safe:=true) -> Variant: return utils.response_to_json(_resp, safe) - + func get_string_from_utf8() -> String: return body.get_string_from_utf8() - + func _to_string() -> String: return "[Response] Result: %s; Code: %s; Headers: %s" % [result, code, headers] - + func to_response_info(host: String, download_file:="") -> ResponseInfo: var error_text := "" var status := "" - + match result: HTTPRequest.RESULT_CHUNKED_BODY_SIZE_MISMATCH, HTTPRequest.RESULT_CONNECTION_ERROR, HTTPRequest.RESULT_BODY_SIZE_LIMIT_EXCEEDED: error_text = tr("Connection error, prease try again.") @@ -90,11 +90,11 @@ class Response: if code != 200: error_text = tr("Request failed, return code") + ": " + str(code) status = tr("Failed") + ": " + str(code) - - var result := ResponseInfo.new() - result.error_text = error_text - result.status = status - return result + + var _result := ResponseInfo.new() + _result.error_text = error_text + _result.status = status + return _result class ResponseInfo: diff --git a/src/main/gui/auto_updates.gd b/src/main/gui/auto_updates.gd index 60198359..27657c05 100644 --- a/src/main/gui/auto_updates.gd +++ b/src/main/gui/auto_updates.gd @@ -1,22 +1,16 @@ class_name AutoUpdates extends Node - @export var _notification_button: NotificationsButton var _godots_releases: GodotsRecentReleases.I var _check_lock := false -func init( - godots_releases: GodotsRecentReleases.I, - updates_click_callback: Callable -) -> void: +func init(godots_releases: GodotsRecentReleases.I, updates_click_callback: Callable) -> void: self._godots_releases = godots_releases _check_updates() - _notification_button.pressed.connect(func() -> void: - updates_click_callback.call() - ) + _notification_button.pressed.connect(func() -> void: updates_click_callback.call()) func _notification(what: int) -> void: @@ -25,7 +19,7 @@ func _notification(what: int) -> void: func _check_updates() -> void: - if _check_lock: + if _check_lock: return _check_lock = true await _async_check_updates() @@ -33,6 +27,7 @@ func _check_updates() -> void: func _async_check_updates() -> void: + @warning_ignore("redundant_await") var has_updates := await _godots_releases.async_has_updates() if has_updates: _notification_button.has_notifications = true diff --git a/src/main/gui/gui_main.gd b/src/main/gui/gui_main.gd index a7829c00..8137b372 100644 --- a/src/main/gui/gui_main.gd +++ b/src/main/gui/gui_main.gd @@ -52,14 +52,14 @@ func _ready() -> void: else: zip_reader.close() _remote_editors.install_zip( - file, - file.get_file().replace(".zip", ""), + file, + file.get_file().replace(".zip", ""), utils.guess_editor_name(file.replace(".zip", "")) ) else: _local_editors.import(utils.guess_editor_name(file), file) ) - + _title_tabs.add_child(TitleTabButton.new("ProjectList", tr("Projects"), _tab_container, [_projects])) _title_tabs.add_child(TitleTabButton.new("AssetLib", tr("Asset Library"), _tab_container, [_asset_lib_projects])) _title_tabs.add_child(TitleTabButton.new("GodotMonochrome", tr("Editors"), _tab_container, [_local_editors, _remote_editors])) @@ -73,14 +73,14 @@ func _ready() -> void: _gui_base.set_anchor(SIDE_RIGHT, Control.ANCHOR_END) _gui_base.set_anchor(SIDE_BOTTOM, Control.ANCHOR_END) _gui_base.set_end(Vector2.ZERO) - + _main_v_box.set_anchors_and_offsets_preset( - Control.PRESET_FULL_RECT, - Control.PRESET_MODE_MINSIZE, + Control.PRESET_FULL_RECT, + Control.PRESET_MODE_MINSIZE, get_theme_constant("window_border_margin", "Editor") ) _main_v_box.add_theme_constant_override( - "separation", + "separation", get_theme_constant("top_bar_separation", "Editor") ) @@ -105,12 +105,12 @@ func _ready() -> void: _tab_container.current_tab = _tab_container.get_tab_idx_from_control(_updates) ) _version_button.tooltip_text = tr("Click to see other versions.") - + var news_buttons := %NewsButton as LinkButton news_buttons.self_modulate = Color(1, 1, 1, 0.6) news_buttons.underline = LinkButton.UNDERLINE_MODE_ON_HOVER news_buttons.tooltip_text = tr("Click to see the post.") - + _settings_button.flat = true #_settings_button.text = tr("Settings") _settings_button.text = "" @@ -122,7 +122,7 @@ func _ready() -> void: _settings_button.pressed.connect(func() -> void: ($Settings as SettingsWindow).raise_settings() ) - + _local_editors_service.load() _projects_service.load() @@ -135,7 +135,7 @@ func _ready() -> void: _setup_godots_releases() _setup_asset_lib_projects() - + Context.add(self, %CommandViewer) @@ -151,22 +151,22 @@ func _notification(what: int) -> void: func _enter_tree() -> void: theme_source.set_scale(Config.EDSCALE) theme = theme_source.create_custom_theme(null) - + var window := get_window() window.min_size = Vector2(520, 370) * Config.EDSCALE - + var scale_factor := maxf(1, Config.EDSCALE * 0.75) if scale_factor > 1: var window_size := DisplayServer.window_get_size() var screen_rect := DisplayServer.screen_get_usable_rect(DisplayServer.window_get_current_screen()) - + window_size *= scale_factor - + DisplayServer.window_set_size(window_size) if screen_rect.size != Vector2i(): var window_position := Vector2i( - screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2, - screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2 + int(screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2.0), + int(screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2.0) ) DisplayServer.window_set_position(window_position) @@ -179,13 +179,13 @@ func _enter_tree() -> void: if DisplayServer.get_screen_from_rect(rect) != -1: window.size = rect.size window.position = rect.position - + _local_remote_switch_context = LocalRemoteEditorsSwitchContext.new( _local_editors, _remote_editors, _tab_container ) - + _local_editors_service = LocalEditors.List.new( Config.EDITORS_CONFIG_PATH ) @@ -194,15 +194,15 @@ func _enter_tree() -> void: _local_editors_service, preload("res://assets/default_project_icon.svg") ) - + Context.add(self, _local_remote_switch_context) Context.add(self, _local_editors_service) Context.add(self, _projects_service) - + _on_exit_tree_callbacks.append(func() -> void: _local_editors_service.cleanup() _projects_service.cleanup() - + Context.erase(self, _local_editors_service) Context.erase(self, _projects_service) Context.erase(self, _local_remote_switch_context) @@ -228,21 +228,21 @@ func _setup_asset_lib_projects() -> void: RemoteEditorsTreeDataSourceGithub.YmlSourceGithub.new() ) # var version_src = GodotVersionOptionButton.SrcMock.new(["4.1"]) - + var request := HTTPRequest.new() add_child(request) var asset_lib_factory := AssetLib.FactoryDefault.new(request) - + var category_src := AssetCategoryOptionButton.SrcRemote.new() - + _asset_lib_projects.download_requested.connect(func(item: AssetLib.Item, icon: Texture2D) -> void: var asset_download := _asset_download.instantiate() as AssetDownload (%DownloadsContainer as DownloadsContainer).add_download_item(asset_download) if icon != null: asset_download.icon.texture = icon asset_download.start( - item.download_url, - (Config.DOWNLOADS_PATH.ret() as String) + "/", + item.download_url, + (Config.DOWNLOADS_PATH.ret() as String) + "/", "project.zip", item.title ) @@ -266,7 +266,7 @@ func _setup_asset_lib_projects() -> void: ) ) ) - + _asset_lib_projects.init( asset_lib_factory, category_src, @@ -296,8 +296,8 @@ func _setup_godots_releases() -> void: _auto_updates.init( GodotsRecentReleases.Cached.new( GodotsRecentReleases.Default.new(godots_releases) - ), - func() -> void: + ), + func() -> void: _tab_container.current_tab = _tab_container.get_tab_idx_from_control(_godots_releases) ) _godots_releases.init( @@ -309,7 +309,7 @@ func _setup_godots_releases() -> void: class TitleTabButton extends Button: var _icon_name: String - + func _init(icon: String, text: String, tab_container: TabContainer, tab_controls: Array) -> void: _icon_name = icon self.text = text @@ -322,24 +322,24 @@ class TitleTabButton extends Button: ) tab_container.tab_changed.connect(func(idx: int) -> void: set_pressed_no_signal( - tab_controls.any(func(tab_control: Control) -> bool: + tab_controls.any(func(tab_control: Control) -> bool: return tab_container.get_tab_idx_from_control(tab_control) == idx\ ) ) ) toggle_mode = true focus_mode = Control.FOCUS_NONE - + self.ready.connect(func() -> void: set_pressed_no_signal( - tab_controls.any(func(tab_control: Control) -> bool: + tab_controls.any(func(tab_control: Control) -> bool: return tab_container.get_tab_idx_from_control(tab_control) == tab_container.current_tab\ ) ) add_theme_font_override("font", get_theme_font("main_button_font", "EditorFonts")) add_theme_font_size_override("font_size", get_theme_font_size("main_button_font_size", "EditorFonts")) ) - + func _notification(what: int) -> void: if what == NOTIFICATION_THEME_CHANGED: if _icon_name: diff --git a/src/objects/node_component/comp_scene.gd b/src/objects/node_component/comp_scene.gd index d28444c1..e8d8766d 100644 --- a/src/objects/node_component/comp_scene.gd +++ b/src/objects/node_component/comp_scene.gd @@ -2,6 +2,6 @@ class_name CompScene extends _Component -func _init(scene: PackedScene, children=[]): - super._init(func(): return scene.instantiate()) +func _init(scene: PackedScene, children: Array =[]) -> void: + super._init(func() -> Node: return scene.instantiate()) self.children(children) diff --git a/src/services/godots_recent_releases.gd b/src/services/godots_recent_releases.gd index 4cfd2351..02d2f7c2 100644 --- a/src/services/godots_recent_releases.gd +++ b/src/services/godots_recent_releases.gd @@ -6,38 +6,42 @@ class I: return utils.not_implemeted() -class Default extends I: +class Default: + extends I var _releases: GodotsReleases.I - + func _init(releases: GodotsReleases.I) -> void: _releases = releases func async_has_updates() -> bool: + @warning_ignore("redundant_await") var has_updates := await _releases.async_has_newest_version() return has_updates -class Cached extends I: +class Cached: + extends I const HOUR = 60 * 60 const UPDATES_CACHE_LIFETIME_SEC = 8 * HOUR var _origin: I - + func _init(origin: I) -> void: _origin = origin - + func async_has_updates() -> bool: - await _actualize_cache() + _actualize_cache() return Cache.get_value("has_update", "value", false) - + func _actualize_cache() -> void: - var last_checked_unix:int = Cache.get_value("has_update", "last_checked", 0) + var last_checked_unix: int = Cache.get_value("has_update", "last_checked", 0) if int(Time.get_unix_time_from_system()) - last_checked_unix > UPDATES_CACHE_LIFETIME_SEC: - await _update_cache() + _update_cache() elif Cache.get_value("has_update", "current_version", Config.VERSION) != Config.VERSION: - await _update_cache() - + _update_cache() + func _update_cache() -> bool: + @warning_ignore("redundant_await") var has_updates := await _origin.async_has_updates() Cache.set_value("has_update", "value", has_updates) Cache.set_value("has_update", "current_version", Config.VERSION) @@ -46,6 +50,8 @@ class Cached extends I: return has_updates -class MockHasUpdates extends I: +class MockHasUpdates: + extends I + func async_has_updates() -> bool: return true diff --git a/src/services/godots_releases.gd b/src/services/godots_releases.gd index dc38b1a6..9633bf04 100644 --- a/src/services/godots_releases.gd +++ b/src/services/godots_releases.gd @@ -4,37 +4,39 @@ class_name GodotsReleases class I: func async_load() -> void: pass - + func all() -> Array[Release]: return [] - + func async_has_newest_version() -> bool: return false -class Default extends I: +class Default: + extends I var _src: Src var _data: Array[Release] = [] var _fetched := false - + func _init(src: Src) -> void: _src = src - + func async_load() -> void: + @warning_ignore("redundant_await") var json := await _src.async_all() - - var latest := {'value': null} - var check_is_latest := func(release: Release) -> void: - if latest.value != null or release.is_draft or release.is_prerelease: + + var latest := {"value": null} + var check_is_latest := func(_release: Release) -> void: + if latest.value != null or _release.is_draft or _release.is_prerelease: return - release._mark_as_latest() - latest.value = release + _release._mark_as_latest() + latest.value = _release _data.clear() for el: Dictionary in json: - var release := Release.new(el) - _data.append(release) - check_is_latest.call(release) + var _release := Release.new(el) + _data.append(_release) + check_is_latest.call(_release) var release: Release if Config.ONLY_STABLE_UPDATES.ret() and latest.value: @@ -63,7 +65,7 @@ class Default extends I: func all() -> Array[Release]: return _data - + func _to_release_or_null(json: Variant) -> Release: if json != null: return Release.new(json as Dictionary) @@ -78,18 +80,19 @@ class Src: ## return is Optional[Dictionary] func async_latest() -> Variant: return utils.not_implemeted() - + ## return is Optional[Dictionary] func async_recent() -> Variant: return utils.not_implemeted() -class SrcFileSystem extends Src: +class SrcFileSystem: + extends Src var _filename: String - + func _init(filename: String) -> void: _filename = filename - + func async_all() -> Array: var file := FileAccess.open(_filename, FileAccess.READ) var content := file.get_as_text() @@ -102,7 +105,7 @@ class SrcFileSystem extends Src: if !release.is_prerelease and !release.is_draft: return el return null - + func async_recent() -> Variant: var json := self.async_all() for el: Dictionary in json: @@ -110,9 +113,10 @@ class SrcFileSystem extends Src: return null -class SrcGithub extends Src: +class SrcGithub: + extends Src const headers = ["Accept: application/vnd.github.v3+json"] - + func async_all() -> Array: var json: Variant = await _get_json(Config.RELEASES_API_ENDPOINT) if json: @@ -124,20 +128,18 @@ class SrcGithub extends Src: var json: Variant = await _get_json(Config.RELEASES_LATEST_API_ENDPOINT) if not json is Dictionary: return null - if (json as Dictionary).get('message', '') == 'Not Found': + if (json as Dictionary).get("message", "") == "Not Found": return null return json - + func async_recent() -> Variant: var json: Variant = await _get_json(Config.RELEASES_API_ENDPOINT + "?per_page=1") for el: Variant in json: return el return null - + func _get_json(url: String) -> Variant: - var response := HttpClient.Response.new( - await HttpClient.async_http_get(url, headers) - ) + var response := HttpClient.Response.new(await HttpClient.async_http_get(url, headers)) var json: Variant = response.to_json() return json @@ -146,37 +148,46 @@ class Release: var _json: Dictionary var _is_latest := false var _is_ready_to_update := false - + var name: String: - get: return _json.name - + get: + return _json.name + var tag_name: String: - get: return _json.get('tag_name', '') - + get: + return _json.get("tag_name", "") + var tags: Array[String]: - get: return _get_tags() - + get: + return _get_tags() + var html_url: String: - get: return _json.html_url - + get: + return _json.html_url + var assets: Array[ReleaseAsset]: - get: return _get_assets() - + get: + return _get_assets() + var is_draft: bool: - get: return _json.get("draft", true) - + get: + return _json.get("draft", true) + var is_prerelease: bool: - get: return _json.get("prerelease", true) - + get: + return _json.get("prerelease", true) + var is_latest: bool: - get: return _is_latest - + get: + return _is_latest + var is_ready_to_update: bool: - get: return _is_ready_to_update - + get: + return _is_ready_to_update + func _init(json: Dictionary) -> void: _json = json - + func _get_tags() -> Array[String]: var tags: Array[String] = [] # if len(_json.tag_name) > 1: @@ -190,32 +201,34 @@ class Release: if is_draft: tags.append(tr("draft")) return tags - + func _get_assets() -> Array[ReleaseAsset]: var assets: Array[ReleaseAsset] = [] for asset: Dictionary in _json.get("assets", []): assets.append(ReleaseAsset.new(asset)) return assets - + func _mark_as_latest() -> void: _is_latest = true - + func _mark_as_ready_to_update() -> void: _is_ready_to_update = true class ReleaseAsset: var _json: Dictionary - + var name: String: - get: return _json.get("name", "") - + get: + return _json.get("name", "") + var browser_download_url: String: - get: return _json.get("browser_download_url", "") - + get: + return _json.get("browser_download_url", "") + func _init(json: Dictionary) -> void: _json = json - + func is_godots_bin_for_current_platform() -> bool: var zip_name: String if OS.has_feature("windows"): diff --git a/src/services/local_editors.gd b/src/services/local_editors.gd index 0156de59..ee4a3221 100644 --- a/src/services/local_editors.gd +++ b/src/services/local_editors.gd @@ -2,17 +2,17 @@ class_name LocalEditors class List extends RefCounted: const dict = preload("res://src/extensions/dict.gd") - + signal editor_removed(editor_path: String) signal editor_name_changed(editor_path: String) - + var _cfg_path: String var _cfg := ConfigFile.new() var _editors: Dictionary[String, Item] = {} - + func _init(cfg_path: String) -> void: _cfg_path = cfg_path - + func add(name: String, editor_path: String) -> Item: var editor := Item.new( ConfigFileSection.new(editor_path, IConfigFileLike.of_config(_cfg)), @@ -20,8 +20,8 @@ class List extends RefCounted: if OS.has_feature("linux"): var output := [] var exit_code := OS.execute( - "chmod", - ["+x", "%s" % ProjectSettings.globalize_path(editor_path) ], + "chmod", + ["+x", "%s" % ProjectSettings.globalize_path(editor_path) ], output, true ) @@ -33,29 +33,29 @@ class List extends RefCounted: editor.extra_arguments = [] _editors[editor_path] = editor return editor - + func all() -> Array[Item]: var result: Array[Item] = [] for x: Item in _editors.values(): result.append(x) return result - + func retrieve(editor_path: String) -> Item: return _editors[editor_path] - + func has(editor_path: String) -> bool: return _editors.has(editor_path) - + func editor_is_valid(editor_path: String) -> bool: return has(editor_path) and edir.path_is_valid(editor_path) - + func erase(editor_path: String) -> void: var editor := retrieve(editor_path) editor.free() _editors.erase(editor_path) _cfg.erase_section(editor_path) editor_removed.emit(editor_path) - + func as_option_button_items() -> Array[Dictionary]: var result: Array[Dictionary] for x in all(): @@ -66,7 +66,7 @@ class List extends RefCounted: 'version_hint': x.version_hint }) return result - + # TODO type func get_all_tags() -> Array: var set := Set.new() @@ -74,7 +74,7 @@ class List extends RefCounted: for tag: String in editor.tags: set.append(tag.to_lower()) return set.values() - + func load() -> Error: cleanup() var err := _cfg.load(_cfg_path) @@ -86,15 +86,15 @@ class List extends RefCounted: _connect_name_changed(editor) _editors[section] = editor return Error.OK - + func cleanup() -> void: dict.clear_and_free(_editors) - + func save() -> Error: return _cfg.save(_cfg_path) - + func _connect_name_changed(editor: Item) -> void: - editor.name_changed.connect(func(_new_name: String) -> void: + editor.name_changed.connect(func(_new_name: String) -> void: editor_name_changed.emit(editor.path) ) @@ -102,57 +102,57 @@ class List extends RefCounted: class Item extends Object: signal tags_edited signal name_changed(new_name: String) - + var mac_os_editor_path_postfix: String: get: return _section.get_value("mac_os_editor_path_postfix", "/Contents/MacOS/Godot") - + var path: String: get: return _section.name - + var name: String: get: return _section.get_value("name", "") - set(value): + set(value): _section.set_value("name", value) name_changed.emit(value) - + var extra_arguments: PackedStringArray: get: return _section.get_typed_value( - "extra_arguments", - func(x: Variant) -> bool: return x is PackedStringArray, + "extra_arguments", + func(x: Variant) -> bool: return x is PackedStringArray, [] ) - set(value): + set(value): _section.set_value("extra_arguments", value) - + var favorite: bool: get: return _section.get_value("favorite", false) set(value): _section.set_value("favorite", value) - + # TODO type var tags: Array: get: return Set.of(_section.get_value("tags", []) as Array).values() set(value): _section.set_value("tags", value) - + var is_valid: bool: get: return edir.path_is_valid(path) - + var version_hint: String: get: return _section.get_value( - "version_hint", + "version_hint", self.name.to_lower() .replace("godot", "") .strip_edges() .replace(" ", "-") ) set(value): _section.set_value("version_hint", value) - + # TODO type var custom_commands: Array: get: return _get_custom_commands("custom_commands-v2") set(value): _section.set_value("custom_commands-v2", value) var _section: ConfigFileSection - + func _init(section: ConfigFileSection) -> void: self._section = section @@ -160,11 +160,11 @@ class Item extends Object: if NOTIFICATION_PREDELETE == what: utils.disconnect_all(self) - func fmt_string(str: String) -> String: + func fmt_string(string: String) -> String: var bin_path := _bin_path() - str = str.replace("{{EDITOR_PATH}}", bin_path) - str = str.replace("{{EDITOR_DIR}}", bin_path.get_base_dir()) - return str + string = string.replace("{{EDITOR_PATH}}", bin_path) + string = string.replace("{{EDITOR_DIR}}", bin_path.get_base_dir()) + return string func as_process(args: PackedStringArray) -> OSProcessSchema: var process_path := _bin_path() @@ -186,33 +186,33 @@ class Item extends Object: func run() -> void: var command: Dictionary = _find_custom_command_by_name("Run", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() - + func emit_tags_edited() -> void: tags_edited.emit() - + func is_self_contained() -> bool: if not is_valid: return false var sub_file_exists := func(file: String) -> bool: return FileAccess.file_exists(path.get_base_dir().path_join(file)) return sub_file_exists.call("_sc_") or sub_file_exists.call("._sc_") - + func match_name(search: String) -> bool: var sanitazed_name := _sanitize_name(name) var sanitazed_search := _sanitize_name(search) var findn := sanitazed_name.findn(sanitazed_search) return findn > -1 - + func match_version_hint(hint: String, ignore_mono:=false) -> bool: return VersionHint.are_equal(self.version_hint, hint, ignore_mono) - + func get_version() -> String: var parsed := VersionHint.parse(version_hint) if parsed.is_valid: return parsed.version else: return "" - + func get_cfg_file_path() -> String: var cfg_file_name := get_cfg_file_name() if cfg_file_name.is_empty(): @@ -225,7 +225,7 @@ class Item extends Object: if cfg_folder.is_empty(): return "" return cfg_folder.path_join(cfg_file_name) - + func get_cfg_file_name() -> String: var version := get_version() if version.is_empty(): @@ -236,7 +236,7 @@ class Item extends Object: return "editor_settings-4.tres" else: return "" - + func _bin_path() -> String: var process_path: String if OS.has_feature("windows") or OS.has_feature("linux"): @@ -244,17 +244,17 @@ class Item extends Object: elif OS.has_feature("macos"): process_path = ProjectSettings.globalize_path(path + mac_os_editor_path_postfix) return process_path - + func _sanitize_name(name: String) -> String: return name.replace(" ", "") - + # TODO type func _find_custom_command_by_name(name: String, src:=[]) -> Variant: for command: Dictionary in src: if command.name == name: return command return null - + # TODO type func _get_custom_commands(key: String) -> Array: var commands := _section.get_value(key, []) as Array @@ -265,50 +265,50 @@ class Item extends Object: 'path': '{{EDITOR_PATH}}', 'args': ['-p'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) return commands - + func _to_string() -> String: return "%s (%s)" % [name, VersionHint.parse(version_hint)] class Selector: var _filter: Callable - + ## filter: Optional[Callable[[Item], bool]] func _init(filter: Variant =null) -> void: if filter == null: filter = func(x: Variant) -> bool: return true _filter = filter - + func by_name(name: String) -> Selector: return Selector.new(func(el: Item) -> bool: return _filter.call(el) and el.match_name(name) ) - + func by_version_hint(hint: String, ignore_mono:=false) -> Selector: return Selector.new(func(el: Item) -> bool: return _filter.call(el) and el.match_version_hint(hint, ignore_mono) ) - + func select(editors: List) -> Array[Item]: var result: Array[Item] = [] for el in editors.all(): if _filter.call(el): result.append(el) return result - + func select_first_or_null(editors: List) -> Item: var res := select(editors) if len(res) > 0: return res[0] else: return null - + func select_exact_one(editors: List) -> Item: var res := select(editors) if len(res) == 1: @@ -317,7 +317,7 @@ class Selector: if len(res) > 1: Output.push("There is ambiguity between editors to run.\n%s" % "\n".join(res)) return null - + static func from_cmd(cmd: CliParser.ParsedCommandResult) -> Selector: var name := cmd.args.first_option_value(["name", "n"]) var version_hint := cmd.args.first_option_value(["version-hint", "vh"]) diff --git a/src/services/projects.gd b/src/services/projects.gd index 9fe5bf81..6b935f68 100644 --- a/src/services/projects.gd +++ b/src/services/projects.gd @@ -2,18 +2,18 @@ class_name Projects class List extends RefCounted: const dict = preload("res://src/extensions/dict.gd") - + var _cfg := ConfigFile.new() var _projects: Dictionary[String, Item] = {} var _cfg_path: String var _default_icon: Texture2D var _local_editors: LocalEditors.List - + func _init(cfg_path: String, local_editors: LocalEditors.List, default_icon: Texture2D) -> void: _cfg_path = cfg_path _local_editors = local_editors _default_icon = default_icon - + func add(project_path: String, editor_path: String) -> Item: var project := Item.new( ConfigFileSection.new(project_path, IConfigFileLike.of_config(_cfg)), @@ -25,33 +25,33 @@ class List extends RefCounted: project.editor_path = editor_path _projects[project_path] = project return project - + func all() -> Array[Item]: var result: Array[Item] = [] for x: Item in _projects.values(): result.append(x) return result - + func retrieve(project_path: String) -> Item: return _projects[project_path] - + func has(project_path: String) -> bool: return _projects.has(project_path) - + func erase(project_path: String) -> void: _projects.erase(project_path) _cfg.erase_section(project_path) - + func get_editors_to_bind() -> Array[Dictionary]: return _local_editors.as_option_button_items() - + func get_owners_of(editor: LocalEditors.Item) -> Array[Item]: var result: Array[Item] for project in all(): if project.editor_is(editor): result.append(project) return result - + # TODO type func get_all_tags() -> Array: var set := Set.new() @@ -59,7 +59,7 @@ class List extends RefCounted: for tag: String in project.tags: set.append(tag.to_lower()) return set.values() - + func load() -> Error: cleanup() var err := _cfg.load(_cfg_path) @@ -71,13 +71,13 @@ class List extends RefCounted: _local_editors ) return Error.OK - + func cleanup() -> void: dict.clear_and_free(_projects) - + func save() -> Error: return _cfg.save(_cfg_path) - + func get_last_opened() -> Projects.Item: var last_opened := _ProjectsCache.get_last_opened_project() return retrieve(last_opened) if has(last_opened) else null @@ -86,67 +86,67 @@ class List extends RefCounted: class Item: signal internals_changed signal loaded - + var show_edit_warning: bool: get: return _section.get_value("show_edit_warning", true) set(value): _section.set_value("show_edit_warning", value) - + var path: String: get: return _section.name - + var name: String: get: return _external_project_info.name set(value): _external_project_info.name = value - + var editor_name: String: get: return _get_editor_name() - + var icon: Texture2D: get: return _external_project_info.icon var favorite: bool: get: return _section.get_value("favorite", false) set(value): _section.set_value("favorite", value) - + var editor: LocalEditors.Item: - get: + get: if has_invalid_editor: return null return _local_editors.retrieve(editor_path) - + var editor_path: String: get: return _section.get_value("editor_path", "") - set(value): + set(value): show_edit_warning = true _section.set_value("editor_path", value) - + var has_invalid_editor: bool: get: return not _local_editors.editor_is_valid(editor_path) - + var is_valid: bool: get: return edir.path_is_valid(path) - + # TODO type var editors_to_bind: Array: get: return _get_editors_to_bind() - + var is_missing: bool: get: return _external_project_info.is_missing - + var is_loaded: bool: get: return _external_project_info.is_loaded - + var tags: Array: set(value): _external_project_info.tags = value get: return _external_project_info.tags - + var last_modified: int: get: return _external_project_info.last_modified - + # TODO type var features: Array: get: return _external_project_info.features - + var version_hint: String: get: return _external_project_info.version_hint set(value): _external_project_info.version_hint = value @@ -161,9 +161,9 @@ class Item: var _external_project_info: ExternalProjectInfo var _section: ConfigFileSection var _local_editors: LocalEditors.List - + func _init( - section: ConfigFileSection, + section: ConfigFileSection, project_info: ExternalProjectInfo, local_editors: LocalEditors.List ) -> void: @@ -175,20 +175,20 @@ class Item: ) self._local_editors.editor_name_changed.connect(_check_editor_changes) project_info.loaded.connect(func() -> void: loaded.emit()) - + func before_delete_as_ref_counted() -> void: utils.disconnect_all(self) if _external_project_info: _external_project_info.before_delete_as_ref_counted() - + func load(with_icon:=true) -> void: _external_project_info.load(with_icon) - + func editor_is(editor: LocalEditors.Item) -> bool: if has_invalid_editor: return false return self.editor == editor - + func _get_editor_name() -> String: if has_invalid_editor: return '' @@ -198,10 +198,10 @@ class Item: func _check_editor_changes(editor_path: String) -> void: if editor_path == self.editor_path: emit_internals_changed() - + func emit_internals_changed() -> void: internals_changed.emit() - + func as_process(args: PackedStringArray) -> OSProcessSchema: assert(not has_invalid_editor) var editor := _local_editors.retrieve(editor_path) @@ -211,16 +211,16 @@ class Item: ] result_args.append_array(args) return editor.as_process(result_args) - - func fmt_string(str: String) -> String: + + func fmt_string(string: String) -> String: if not has_invalid_editor: var editor := _local_editors.retrieve(editor_path) - str = editor.fmt_string(str) - str = str.replace( + string = editor.fmt_string(string) + string = string.replace( '{{PROJECT_DIR}}', ProjectSettings.globalize_path(self.path).get_base_dir() ) - return str - + return string + func as_fmt_process(process_path: String, args: PackedStringArray) -> OSProcessSchema: var result_path := process_path var result_args: PackedStringArray @@ -234,23 +234,23 @@ class Item: arg = self.fmt_string(arg) result_args.append(arg) return OSProcessSchema.new(result_path, result_args) - + func edit() -> void: var command: Dictionary = _find_custom_command_by_name("Edit", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() _ProjectsCache.set_last_opened_project(path) - + func run() -> void: var command: Dictionary = _find_custom_command_by_name("Run", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() - + # TODO type func _find_custom_command_by_name(name: String, src:=[]) -> Variant: for command: Dictionary in src: if command.name == name: return command return null - + # TODO type func _get_custom_commands(key: String) -> Array: var commands: Array = _section.get_value(key, []) @@ -261,8 +261,8 @@ class Item: 'path': '{{EDITOR_PATH}}', 'args': ['--path', '{{PROJECT_DIR}}' ,'-e'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) @@ -273,13 +273,13 @@ class Item: 'path': '{{EDITOR_PATH}}', 'args': ['--path', '{{PROJECT_DIR}}' ,'-g'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) return commands - + #TODO type func _get_editors_to_bind() -> Array: var options := _local_editors.as_option_button_items() @@ -299,7 +299,7 @@ class _ProjectsCache: class ExternalProjectInfo extends RefCounted: signal loaded - + var icon: Texture2D: get: return _icon @@ -313,15 +313,15 @@ class ExternalProjectInfo extends RefCounted: var err := cfg.load(_project_path) if not err: cfg.set_value( - "application", - "config/name", + "application", + "config/name", _name ) cfg.save(_project_path) - + var has_version_hint: bool: get: return _version_hint != null - + var version_hint: String: get: return '' if _version_hint == null else _version_hint set(value): @@ -332,21 +332,21 @@ class ExternalProjectInfo extends RefCounted: var err := cfg.load(_project_path) if not err: cfg.set_value( - "godots", - "version_hint", + "godots", + "version_hint", _version_hint ) cfg.save(_project_path) var last_modified: int: get: return _last_modified - + var is_loaded: bool: get: return _is_loaded - + var is_missing: bool: get: return _is_missing - + # TODO type var tags: Array: set(value): @@ -360,17 +360,17 @@ class ExternalProjectInfo extends RefCounted: for tag: String in _tags: set.append(tag.to_lower()) cfg.set_value( - "application", - "config/tags", + "application", + "config/tags", PackedStringArray(set.values()) ) cfg.save(_project_path) get: return Set.of(_tags).values() - + # TODO type var features: Array: get: return _features - + var _is_loaded := false var _project_path: String var _default_icon: Texture2D @@ -384,19 +384,19 @@ class ExternalProjectInfo extends RefCounted: var _has_mono_section := false ## Optional[String], TODO type var _version_hint: Variant = null - + func _init(project_path: String, default_icon: Texture2D = null) -> void: _project_path = project_path _default_icon = default_icon _icon = default_icon - + func before_delete_as_ref_counted() -> void: utils.disconnect_all(self) - + func load(with_icon:=true) -> void: var cfg := ConfigFile.new() var err := cfg.load(_project_path) - + _name = cfg.get_value("application", "config/name", "Missing Project") _tags = cfg.get_value("application", "config/tags", []) _features = cfg.get_value("application", "config/features", []) @@ -406,21 +406,21 @@ class ExternalProjectInfo extends RefCounted: _version_hint = cfg.get_value("godots", "version_hint") if _version_hint == '': _version_hint = null - + _last_modified = FileAccess.get_modified_time(_project_path) if with_icon: _icon = _load_icon(cfg) _is_missing = bool(err) - + _is_loaded = true loaded.emit() - + func _load_icon(cfg: ConfigFile) -> Texture2D: var result := _default_icon var icon_path: String = cfg.get_value("application", "config/icon", "") if not icon_path: return result icon_path = icon_path.replace("res://", self._project_path.get_base_dir() + "/") - + if FileAccess.file_exists(icon_path): var icon_image := Image.new() var err := icon_image.load(icon_path) @@ -430,18 +430,18 @@ class ExternalProjectInfo extends RefCounted: ) result = ImageTexture.create_from_image(icon_image) return result - + # TODO type func sort_editor_options(options: Array) -> void: var has_cs_feature := "C#" in features var is_mono := has_cs_feature or _has_mono_section - + var check_stable := func(label: String) -> bool: return label.contains("stable") - + var check_mono := func(label: String) -> bool: return label.contains("mono") - + var check_version := func(label: String) -> bool: if _version_hint != null: if VersionHint.same_version(_version_hint as String, label): @@ -451,7 +451,7 @@ class ExternalProjectInfo extends RefCounted: elif _config_version == 4: return not label.contains("3.0") and not label.contains("4.") elif _config_version > 4: - var is_version := func(feature: String) -> bool: + var is_version := func(feature: String) -> bool: return feature.contains(".") and feature.substr(0, 3).is_valid_float() var version_tags := Array(features).filter(is_version) if len(version_tags) > 0: @@ -460,7 +460,7 @@ class ExternalProjectInfo extends RefCounted: return label.contains("4.") else: return false - + var check_version_hint_similarity := func(version_hint: String) -> int: var score := VersionHint.similarity(_version_hint as String, version_hint) return score @@ -468,7 +468,7 @@ class ExternalProjectInfo extends RefCounted: options.sort_custom(func(item_a: Dictionary, item_b: Dictionary) -> bool: var a := (item_a.version_hint as String).to_lower() var b := (item_b.version_hint as String).to_lower() - + if _version_hint != null: var sim_a: int = check_version_hint_similarity.call(a) var sim_b: int = check_version_hint_similarity.call(b) @@ -490,6 +490,6 @@ class ExternalProjectInfo extends RefCounted: return true if check_stable.call(b) && !check_stable.call(a): return false - + return VersionHint.version_or_nothing(a) > VersionHint.version_or_nothing(b) ) diff --git a/src/services/remote_image_src.gd b/src/services/remote_image_src.gd index cfd82a37..c087f5d1 100644 --- a/src/services/remote_image_src.gd +++ b/src/services/remote_image_src.gd @@ -6,34 +6,37 @@ class I: pass -class AlwaysBroken extends I: +class AlwaysBroken: + extends I var _theme_src: Control - + func _init(theme_src: Control) -> void: _theme_src = theme_src - + func async_load_img(url: String, callback: Callable) -> void: var texture := _theme_src.get_theme_icon("FileBrokenBigThumb", "EditorIcons") callback.call(texture) -class LoadFileBuffer extends I: +class LoadFileBuffer: + extends I var _file_src: FileByUrlSrc var _fallback_texture: Texture2D - + func _init(file_src: FileByUrlSrc, fallback_texture: Texture2D) -> void: _fallback_texture = fallback_texture _file_src = file_src - + func async_load_img(url: String, callback: Callable) -> void: + @warning_ignore("redundant_await") var file_path := await _file_src.async_load(url) - + if file_path.is_empty(): return - + if not callback.is_valid(): return - + # some weird additional check is required due to: # 'Trying to call a lambda with an invalid instance.' # https://github.com/godotengine/godot/blob/c7fb0645af400a1859154bcee9394e63bdabd198/modules/gdscript/gdscript_lambda_callable.cpp#L195 @@ -44,7 +47,7 @@ class LoadFileBuffer extends I: if file == null: callback.call(_fallback_texture) return - + var file_buffer := file.get_buffer(file.get_length()) var img := Image.new() var load_err := _load_img_from_buffer(img, file_buffer) @@ -53,13 +56,13 @@ class LoadFileBuffer extends I: else: var tex := ImageTexture.create_from_image(img) callback.call(tex) - + func _load_img_from_buffer(img: Image, buffer: PackedByteArray) -> int: var png_signature := PackedByteArray([137, 80, 78, 71, 13, 10, 26, 10]) var jpg_signature := PackedByteArray([255, 216, 255]) var webp_signature := PackedByteArray([82, 73, 70, 70]) var bmp_signature := PackedByteArray([66, 77]) - + var load_err := ERR_PARAMETER_RANGE_ERROR if png_signature == buffer.slice(0, 8): load_err = img.load_png_from_buffer(buffer) @@ -78,20 +81,24 @@ class FileByUrlSrc: return "" -class FileByUrlSrcAsIs extends FileByUrlSrc: +class FileByUrlSrcAsIs: + extends FileByUrlSrc + func async_load(url: String) -> String: var file_path := (Config.CACHE_DIR_PATH.ret() as String).path_join(url.md5_text()) - var response := HttpClient.Response.new( - await HttpClient.async_http_get(url, [], file_path) - ) + var response := HttpClient.Response.new(await HttpClient.async_http_get(url, [], file_path)) if response.code != 200: return "" return file_path -class FileByUrlCachedEtag extends FileByUrlSrc: +class FileByUrlCachedEtag: + extends FileByUrlSrc + func async_load(url: String) -> String: - var file_path_base := (Config.CACHE_DIR_PATH.ret() as String).path_join("assetimage_" + url.md5_text()) + var file_path_base := (Config.CACHE_DIR_PATH.ret() as String).path_join( + "assetimage_" + url.md5_text() + ) var etag_path := file_path_base + ".etag" var data_path := file_path_base + ".data" var headers := [] @@ -102,12 +109,17 @@ class FileByUrlCachedEtag extends FileByUrlSrc: var response := HttpClient.Response.new( await HttpClient.async_http_get(url, headers, data_path) ) - if response.result == HTTPRequest.RESULT_SUCCESS and response.result < HTTPClient.RESPONSE_BAD_REQUEST: + if ( + response.result == HTTPRequest.RESULT_SUCCESS + and response.result < HTTPClient.RESPONSE_BAD_REQUEST + ): if response.code != HTTPClient.RESPONSE_NOT_MODIFIED: for header in response.headers: header = header as String if header.findn("ETag:") == 0: - var new_etag := header.substr(header.find(":") + 1, header.length()).strip_edges() + var new_etag := ( + header.substr(header.find(":") + 1, header.length()).strip_edges() + ) var file := FileAccess.open(etag_path, FileAccess.WRITE) if file: file.store_line(new_etag) diff --git a/src/utils.gd b/src/utils.gd index 7f8fadf5..9d705a00 100644 --- a/src/utils.gd +++ b/src/utils.gd @@ -4,20 +4,22 @@ class_name utils static func guess_editor_name(file_name: String) -> String: var possible_editor_name := file_name.get_file() var tokens_to_replace: Array[String] - tokens_to_replace.append_array([ - "x11.64", - "linux.64", - "linux.x86_64", - "linux.x86_32", - "osx.universal", - "macos.universal", - "osx.fat", - "osx32", - "osx64", - "win64", - "win32", - ".%s" % file_name.get_extension() - ]) + tokens_to_replace.append_array( + [ + "x11.64", + "linux.64", + "linux.x86_64", + "linux.x86_32", + "osx.universal", + "macos.universal", + "osx.fat", + "osx32", + "osx64", + "win64", + "win32", + ".%s" % file_name.get_extension() + ] + ) tokens_to_replace.append_array(["_", "-"]) for token in tokens_to_replace: possible_editor_name = possible_editor_name.replace(token, " ") @@ -27,17 +29,15 @@ static func guess_editor_name(file_name: String) -> String: static func find_project_godot_files(dir_path: String) -> Array[edir.DirListResult]: var project_configs := edir.list_recursive( - ProjectSettings.globalize_path(dir_path), + ProjectSettings.globalize_path(dir_path), false, - (func(x: edir.DirListResult) -> bool: - return x.is_file and x.file == "project.godot"), - (func(x: String) -> bool: - return not x.get_file().begins_with(".")) + func(x: edir.DirListResult) -> bool: return x.is_file and x.file == "project.godot", + func(x: String) -> bool: return not x.get_file().begins_with(".") ) return project_configs -static func response_to_json(response: Variant, safe:=true) -> Variant: +static func response_to_json(response: Variant, safe := true) -> Variant: var body := response[3] as PackedByteArray var string := body.get_string_from_utf8() if safe: @@ -57,11 +57,13 @@ static func parse_json_safe(string: String) -> Variant: static func fit_height(max_height: float, cur_size: Vector2i, callback: Callable) -> void: var scale_ratio := max_height / (cur_size.y * Config.EDSCALE) - if scale_ratio < 1: - callback.call(Vector2i( - cur_size.x * Config.EDSCALE * scale_ratio, - cur_size.y * Config.EDSCALE * scale_ratio - )) + if scale_ratio < 1.0: + callback.call( + Vector2i( + cur_size.x * int(Config.EDSCALE) * int(scale_ratio), + cur_size.y * int(Config.EDSCALE) * int(scale_ratio) + ) + ) static func disconnect_all(obj: Object) -> void: diff --git a/tests/cases/cli/parser/parser_not_ok.gd b/tests/cases/cli/parser/parser_not_ok.gd index 56ff9c6e..8764007e 100644 --- a/tests/cases/cli/parser/parser_not_ok.gd +++ b/tests/cases/cli/parser/parser_not_ok.gd @@ -1,34 +1,34 @@ class_name CliParserNotOkTests extends GdUnitTestSuite -func test_invalid_namespace(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["invalidNamespace"]) +func test_invalid_namespace() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["invalidNamespace"]) assert(result.namesp.is_empty()) assert(result.verb.is_empty()) assert(result.args.names[0] == "invalidNamespace") -func test_invalid_command(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["namespace1", "invalidVerb"]) +func test_invalid_command() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["namespace1", "invalidVerb"]) assert(result.namesp == "namespace1") assert(result.verb.is_empty()) assert(result.args.names[0] == "invalidVerb") -func test_invalid_option(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["namespace1", "verb1", "--invalidOption"]) +func test_invalid_option() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["namespace1", "verb1", "--invalidOption"]) assert(result.has_error()) assert(result.errors[0] == "Unsupported option: --invalidOption") -func test_repeated_options(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "--flag1", "value2"]) +func test_repeated_options() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "--flag1", "value2"]) assert(result.has_error()) assert(result.errors[0] == "Only one option with name (`flag1`, `f1`) can be used.") -func test_repeated_short_and_long_options(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "-f1", "value2"]) +func test_repeated_short_and_long_options() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "-f1", "value2"]) assert(result.has_error()) assert(result.errors[0] == "Only one option with name (`flag1`, `f1`) can be used.") diff --git a/tests/cases/cli/parser/parser_ok.gd b/tests/cases/cli/parser/parser_ok.gd index 105b5b7f..a2fe522d 100644 --- a/tests/cases/cli/parser/parser_ok.gd +++ b/tests/cases/cli/parser/parser_ok.gd @@ -1,9 +1,9 @@ class_name CliParserOkTests extends GdUnitTestSuite -func test_parse_command(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["namespace1", "verb1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_command() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["namespace1", "verb1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "namespace1") assert(result.verb == "verb1") @@ -13,9 +13,9 @@ func test_parse_command(): assert(args.has_options(["bool-flag"])) assert(args.has_options(["a"])) -func test_parse_without_verb(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["namespace1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_without_verb() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["namespace1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "namespace1") assert(result.verb == "") @@ -25,9 +25,9 @@ func test_parse_without_verb(): assert(args.has_options(["bool-flag"])) assert(args.has_options(["a"])) -func test_parse_without_namespace_and_verb(): - var parser = CliParser.CommandParser.new(TestGrammar.grammar) - var result = parser.parse_command(["just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_without_namespace_and_verb() -> void: + var parser := CliParser.CommandParser.new(TestGrammar.grammar) + var result := parser.parse_command(["just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "") assert(result.verb == "") diff --git a/tests/cases/cli/parser/test_grammar.gd b/tests/cases/cli/parser/test_grammar.gd index c8ec30df..3e11eeb6 100644 --- a/tests/cases/cli/parser/test_grammar.gd +++ b/tests/cases/cli/parser/test_grammar.gd @@ -1,6 +1,6 @@ class_name TestGrammar -static var grammar = CliGrammar.new([ +static var grammar := CliGrammar.new([ CliCommand.new( "namespace1", "verb1", diff --git a/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd b/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd index c6ca0102..54d3466a 100644 --- a/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd +++ b/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd @@ -2,19 +2,24 @@ class_name GdUnitExampleTest extends GdUnitTestSuite -func test_list_dir(): - var result = edir.list_recursive( +func test_list_dir() -> void: + var result := edir.list_recursive( "res://tests/cases/dir_extensions/list_dir_recursive/assets/1/" ) assert_int(len(result)).is_equal(8) - - var files = result.filter(func(x): return x.is_file).map(func(x): return x.file) - assert_array(files).contains_exactly(["file.txt", "file2.txt", "file3.txt", "file3.txt", "file4.txt"]) - - var dirs = result.filter(func(x): return x.is_dir).map(func(x): return x.file) + + @warning_ignore("untyped_declaration") # I cannot figure out the type of x + var files := result.filter(func(x): return x.is_file).map(func(x): return x.file) + assert_array(files).contains_exactly( + ["file.txt", "file2.txt", "file3.txt", "file3.txt", "file4.txt"] + ) + + @warning_ignore("untyped_declaration") # I cannot figure out the type of x + var dirs := result.filter(func(x): return x.is_dir).map(func(x): return x.file) assert_array(dirs).contains_exactly(["sub-dir", "sub-dir-2", "sub-dir-3"]) - - var raw_dirs = result.filter(func(x): return x.is_dir) + + @warning_ignore("untyped_declaration") # I cannot figure out the type of x + var raw_dirs := result.filter(func(x): return x.is_dir) assert_str(raw_dirs[0].path).is_equal( "res://tests/cases/dir_extensions/list_dir_recursive/assets/1/sub-dir" ) diff --git a/tests/cases/services/local_editor_tests.gd b/tests/cases/services/local_editor_tests.gd index d3f0a35c..4f751ca5 100644 --- a/tests/cases/services/local_editor_tests.gd +++ b/tests/cases/services/local_editor_tests.gd @@ -10,8 +10,8 @@ func test_filter_by_name_pattern(name: String, expected: int, test_parameters:= [" 4.1 s", 1], ["4.1 StAble", 1], ["invalid", 0], -]): - var editors = LocalEditors.List.new(config_path) +]) -> void: + var editors := LocalEditors.List.new(config_path) editors.load() - var result = LocalEditors.Selector.new().by_name(name).select(editors) + var result := LocalEditors.Selector.new().by_name(name).select(editors) assert_int(result.size()).is_equal(expected) diff --git a/theme/fill_icons_registry.gd b/theme/fill_icons_registry.gd index 72cc5010..7fa5553d 100644 --- a/theme/fill_icons_registry.gd +++ b/theme/fill_icons_registry.gd @@ -7,10 +7,10 @@ func _run() -> void: _create_cfg('res://theme/icons-light', 'res://theme/icons-light.cfg') -func _create_cfg(icons_dir, result_file_path): - var result = ConfigFile.new() - var dir = EditorInterface.get_resource_filesystem().get_filesystem_path(icons_dir) +func _create_cfg(icons_dir: String, result_file_path: String) -> void: + var result := ConfigFile.new() + var dir := EditorInterface.get_resource_filesystem().get_filesystem_path(icons_dir) for i in range(dir.get_file_count()): - var path = dir.get_file_path(i) + var path := dir.get_file_path(i) result.set_value(path, "name", path.get_basename().get_file()) result.save(result_file_path) From 05698c0e5105cb87fadb0af1df59f347f8580d36 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 13 Mar 2025 08:25:52 -0300 Subject: [PATCH 03/23] chore: don't create desktop entry when launching from editor --- src/main/main.gd | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/main.gd b/src/main/main.gd index 2b087a1c..19bede85 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -7,7 +7,6 @@ const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" @export_file() var gui_scene_path: String - func _ready() -> void: var args := OS.get_cmdline_args() var user_args := OS.get_cmdline_user_args() @@ -16,7 +15,7 @@ func _ready() -> void: var is_flatpak := FileAccess.file_exists("/.flatpak-info") # Check and create GVM desktop entry if needed - if OS.get_name() == "Linux" and not is_flatpak: + if OS.get_name() == "Linux" and not OS.has_feature("editor") and not is_flatpak: _ensure_desktop_entry() if _is_cli_mode(args): @@ -29,6 +28,7 @@ func _ready() -> void: add_child.call_deferred((load(gui_scene_path) as PackedScene).instantiate()) pass + func _is_cli_mode(args: PackedStringArray) -> bool: if args.size() > 1 and OS.has_feature("editor"): return true @@ -36,6 +36,7 @@ func _is_cli_mode(args: PackedStringArray) -> bool: return true return false + func _ensure_desktop_entry() -> void: var home := OS.get_environment("HOME") var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) @@ -77,7 +78,8 @@ func _ensure_desktop_entry() -> void: func _create_desktop_entry(exe_path: String, icon_path: String) -> String: - return """[Desktop Entry] + return ( + """[Desktop Entry] Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! @@ -88,9 +90,10 @@ PrefersNonDefaultGPU=true Type=Application Categories=Development;IDE; StartupWMClass=Godot -""".format( - {"exe": exe_path, "icon": icon_path} +""" + . format({"exe": exe_path, "icon": icon_path}) ) + func _exit() -> void: get_tree().quit() From 41f28a6afffbbc808e20282422c87f25aa570401 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 13 Mar 2025 09:39:19 -0300 Subject: [PATCH 04/23] Fix: handle debug builds and fix some vriable naming and comments --- .gitignore | 5 +- export_presets.cfg | 189 ++++++++++++++++++++++++++++++++++++++++++--- src/main/main.gd | 49 +++++++----- 3 files changed, 213 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index f95fe259..de76f3f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Godot 4+ specific ignores .godot/ +# Export ignore +build_dir/ + # Godot-specific ignores .import/ export.cfg @@ -29,4 +32,4 @@ addons/gdUnit # Mac files .DS_Store -/override.cfg \ No newline at end of file +/override.cfg diff --git a/export_presets.cfg b/export_presets.cfg index 851bddb1..fed955b6 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -3,16 +3,20 @@ name="macOS" platform="macOS" runnable=false +advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.zip" +patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" +seed=0 encrypt_pck=false encrypt_directory=false +script_export_mode=2 [preset.0.options] @@ -30,8 +34,11 @@ application/short_version="1.0" application/version="1.0" application/copyright="" application/copyright_localized={} -application/min_macos_version="10.12" +application/min_macos_version_x86_64="10.12" +application/min_macos_version_arm64="11.00" +application/export_angle=0 display/high_res=true +application/additional_plist_content="" xcode/platform_build="14C18" xcode/sdk_version="13.1" xcode/sdk_build="22C55" @@ -64,7 +71,9 @@ codesign/entitlements/app_sandbox/files_downloads=0 codesign/entitlements/app_sandbox/files_pictures=0 codesign/entitlements/app_sandbox/files_music=0 codesign/entitlements/app_sandbox/files_movies=0 +codesign/entitlements/app_sandbox/files_user_selected=0 codesign/entitlements/app_sandbox/helper_executables=[] +codesign/entitlements/additional="" codesign/custom_options=PackedStringArray() notarization/notarization=0 privacy/microphone_usage_description="" @@ -89,6 +98,148 @@ privacy/network_volumes_usage_description="" privacy/network_volumes_usage_description_localized={} privacy/removable_volumes_usage_description="" privacy/removable_volumes_usage_description_localized={} +privacy/tracking_enabled=false +privacy/tracking_domains=PackedStringArray() +privacy/collected_data/name/collected=false +privacy/collected_data/name/linked_to_user=false +privacy/collected_data/name/used_for_tracking=false +privacy/collected_data/name/collection_purposes=0 +privacy/collected_data/email_address/collected=false +privacy/collected_data/email_address/linked_to_user=false +privacy/collected_data/email_address/used_for_tracking=false +privacy/collected_data/email_address/collection_purposes=0 +privacy/collected_data/phone_number/collected=false +privacy/collected_data/phone_number/linked_to_user=false +privacy/collected_data/phone_number/used_for_tracking=false +privacy/collected_data/phone_number/collection_purposes=0 +privacy/collected_data/physical_address/collected=false +privacy/collected_data/physical_address/linked_to_user=false +privacy/collected_data/physical_address/used_for_tracking=false +privacy/collected_data/physical_address/collection_purposes=0 +privacy/collected_data/other_contact_info/collected=false +privacy/collected_data/other_contact_info/linked_to_user=false +privacy/collected_data/other_contact_info/used_for_tracking=false +privacy/collected_data/other_contact_info/collection_purposes=0 +privacy/collected_data/health/collected=false +privacy/collected_data/health/linked_to_user=false +privacy/collected_data/health/used_for_tracking=false +privacy/collected_data/health/collection_purposes=0 +privacy/collected_data/fitness/collected=false +privacy/collected_data/fitness/linked_to_user=false +privacy/collected_data/fitness/used_for_tracking=false +privacy/collected_data/fitness/collection_purposes=0 +privacy/collected_data/payment_info/collected=false +privacy/collected_data/payment_info/linked_to_user=false +privacy/collected_data/payment_info/used_for_tracking=false +privacy/collected_data/payment_info/collection_purposes=0 +privacy/collected_data/credit_info/collected=false +privacy/collected_data/credit_info/linked_to_user=false +privacy/collected_data/credit_info/used_for_tracking=false +privacy/collected_data/credit_info/collection_purposes=0 +privacy/collected_data/other_financial_info/collected=false +privacy/collected_data/other_financial_info/linked_to_user=false +privacy/collected_data/other_financial_info/used_for_tracking=false +privacy/collected_data/other_financial_info/collection_purposes=0 +privacy/collected_data/precise_location/collected=false +privacy/collected_data/precise_location/linked_to_user=false +privacy/collected_data/precise_location/used_for_tracking=false +privacy/collected_data/precise_location/collection_purposes=0 +privacy/collected_data/coarse_location/collected=false +privacy/collected_data/coarse_location/linked_to_user=false +privacy/collected_data/coarse_location/used_for_tracking=false +privacy/collected_data/coarse_location/collection_purposes=0 +privacy/collected_data/sensitive_info/collected=false +privacy/collected_data/sensitive_info/linked_to_user=false +privacy/collected_data/sensitive_info/used_for_tracking=false +privacy/collected_data/sensitive_info/collection_purposes=0 +privacy/collected_data/contacts/collected=false +privacy/collected_data/contacts/linked_to_user=false +privacy/collected_data/contacts/used_for_tracking=false +privacy/collected_data/contacts/collection_purposes=0 +privacy/collected_data/emails_or_text_messages/collected=false +privacy/collected_data/emails_or_text_messages/linked_to_user=false +privacy/collected_data/emails_or_text_messages/used_for_tracking=false +privacy/collected_data/emails_or_text_messages/collection_purposes=0 +privacy/collected_data/photos_or_videos/collected=false +privacy/collected_data/photos_or_videos/linked_to_user=false +privacy/collected_data/photos_or_videos/used_for_tracking=false +privacy/collected_data/photos_or_videos/collection_purposes=0 +privacy/collected_data/audio_data/collected=false +privacy/collected_data/audio_data/linked_to_user=false +privacy/collected_data/audio_data/used_for_tracking=false +privacy/collected_data/audio_data/collection_purposes=0 +privacy/collected_data/gameplay_content/collected=false +privacy/collected_data/gameplay_content/linked_to_user=false +privacy/collected_data/gameplay_content/used_for_tracking=false +privacy/collected_data/gameplay_content/collection_purposes=0 +privacy/collected_data/customer_support/collected=false +privacy/collected_data/customer_support/linked_to_user=false +privacy/collected_data/customer_support/used_for_tracking=false +privacy/collected_data/customer_support/collection_purposes=0 +privacy/collected_data/other_user_content/collected=false +privacy/collected_data/other_user_content/linked_to_user=false +privacy/collected_data/other_user_content/used_for_tracking=false +privacy/collected_data/other_user_content/collection_purposes=0 +privacy/collected_data/browsing_history/collected=false +privacy/collected_data/browsing_history/linked_to_user=false +privacy/collected_data/browsing_history/used_for_tracking=false +privacy/collected_data/browsing_history/collection_purposes=0 +privacy/collected_data/search_hhistory/collected=false +privacy/collected_data/search_hhistory/linked_to_user=false +privacy/collected_data/search_hhistory/used_for_tracking=false +privacy/collected_data/search_hhistory/collection_purposes=0 +privacy/collected_data/user_id/collected=false +privacy/collected_data/user_id/linked_to_user=false +privacy/collected_data/user_id/used_for_tracking=false +privacy/collected_data/user_id/collection_purposes=0 +privacy/collected_data/device_id/collected=false +privacy/collected_data/device_id/linked_to_user=false +privacy/collected_data/device_id/used_for_tracking=false +privacy/collected_data/device_id/collection_purposes=0 +privacy/collected_data/purchase_history/collected=false +privacy/collected_data/purchase_history/linked_to_user=false +privacy/collected_data/purchase_history/used_for_tracking=false +privacy/collected_data/purchase_history/collection_purposes=0 +privacy/collected_data/product_interaction/collected=false +privacy/collected_data/product_interaction/linked_to_user=false +privacy/collected_data/product_interaction/used_for_tracking=false +privacy/collected_data/product_interaction/collection_purposes=0 +privacy/collected_data/advertising_data/collected=false +privacy/collected_data/advertising_data/linked_to_user=false +privacy/collected_data/advertising_data/used_for_tracking=false +privacy/collected_data/advertising_data/collection_purposes=0 +privacy/collected_data/other_usage_data/collected=false +privacy/collected_data/other_usage_data/linked_to_user=false +privacy/collected_data/other_usage_data/used_for_tracking=false +privacy/collected_data/other_usage_data/collection_purposes=0 +privacy/collected_data/crash_data/collected=false +privacy/collected_data/crash_data/linked_to_user=false +privacy/collected_data/crash_data/used_for_tracking=false +privacy/collected_data/crash_data/collection_purposes=0 +privacy/collected_data/performance_data/collected=false +privacy/collected_data/performance_data/linked_to_user=false +privacy/collected_data/performance_data/used_for_tracking=false +privacy/collected_data/performance_data/collection_purposes=0 +privacy/collected_data/other_diagnostic_data/collected=false +privacy/collected_data/other_diagnostic_data/linked_to_user=false +privacy/collected_data/other_diagnostic_data/used_for_tracking=false +privacy/collected_data/other_diagnostic_data/collection_purposes=0 +privacy/collected_data/environment_scanning/collected=false +privacy/collected_data/environment_scanning/linked_to_user=false +privacy/collected_data/environment_scanning/used_for_tracking=false +privacy/collected_data/environment_scanning/collection_purposes=0 +privacy/collected_data/hands/collected=false +privacy/collected_data/hands/linked_to_user=false +privacy/collected_data/hands/used_for_tracking=false +privacy/collected_data/hands/collection_purposes=0 +privacy/collected_data/head/collected=false +privacy/collected_data/head/linked_to_user=false +privacy/collected_data/head/used_for_tracking=false +privacy/collected_data/head/collection_purposes=0 +privacy/collected_data/other_data_types/collected=false +privacy/collected_data/other_data_types/linked_to_user=false +privacy/collected_data/other_data_types/used_for_tracking=false +privacy/collected_data/other_data_types/collection_purposes=0 ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -100,22 +251,27 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" +application/min_macos_version="10.12" [preset.1] name="Linux/X11" -platform="Linux/X11" +platform="Linux" runnable=true +advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" -export_path="../builds/godots/Godots.x86_64" +export_path="build_dir/Godots.x86_64" +patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" +seed=0 encrypt_pck=false encrypt_directory=false +script_export_mode=2 [preset.1.options] @@ -123,10 +279,8 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false +texture_format/s3tc_bptc=true +texture_format/etc2_astc=false binary_format/architecture="x86_64" ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" @@ -140,22 +294,30 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false [preset.2] name="Windows Desktop" platform="Windows Desktop" runnable=true +advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.exe" +patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" +seed=0 encrypt_pck=false encrypt_directory=false +script_export_mode=2 [preset.2.options] @@ -163,10 +325,8 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false +texture_format/s3tc_bptc=true +texture_format/etc2_astc=false binary_format/architecture="x86_64" codesign/enable=false codesign/timestamp=true @@ -185,6 +345,9 @@ application/product_name="" application/file_description="" application/copyright="" application/trademarks="" +application/export_angle=0 +application/export_d3d12=0 +application/d3d12_agility_sdk_multiarch=true ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -202,3 +365,7 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue Remove-Item -Recurse -Force '{temp_dir}'" +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false diff --git a/src/main/main.gd b/src/main/main.gd index 19bede85..dee579f9 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -1,8 +1,8 @@ extends Node const DESKTOP_ENTRY_FOLDER = ".local/share/applications" -const GVM_APP_FOLDER = ".local/godots.app" -const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" +const APP_FOLDER = ".local/godots.app" +const DESKTOP_ENTRY_NAME = "godots.desktop" @export_file() var gui_scene_path: String @@ -14,7 +14,7 @@ func _ready() -> void: # Check if running as Flatpak by checking for the .flatpak-info file var is_flatpak := FileAccess.file_exists("/.flatpak-info") - # Check and create GVM desktop entry if needed + # Check and create Godots desktop entry if needed if OS.get_name() == "Linux" and not OS.has_feature("editor") and not is_flatpak: _ensure_desktop_entry() @@ -39,32 +39,44 @@ func _is_cli_mode(args: PackedStringArray) -> bool: func _ensure_desktop_entry() -> void: var home := OS.get_environment("HOME") - var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) - var gvm_app_path := home.path_join(GVM_APP_FOLDER) + var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(DESKTOP_ENTRY_NAME) + var app_path := home.path_join(APP_FOLDER) - # Create gvm.app folder and copy executable + # Create godots.app folder and copy executable var dir := DirAccess.open("user://") - if FileAccess.file_exists(gvm_app_path): + if dir.dir_exists(app_path): return else: - dir.make_dir_recursive(gvm_app_path) + dir.make_dir_recursive(app_path) - # Copy the current executable to gvm.app folder var current_exe := OS.get_executable_path() - var new_exe_path := gvm_app_path.path_join("godots.x86_64") + var new_exe_path := app_path.path_join("Godots.x86_64") + var run_path := new_exe_path + + var is_debug := OS.is_debug_build() + var script_path := current_exe.get_base_dir().path_join("Godots.sh") + + if is_debug and FileAccess.file_exists(script_path): + var new_script_path := app_path.path_join("Godots.sh") + if DirAccess.copy_absolute(script_path, new_script_path) == OK: + OS.execute("chmod", ["+x", new_script_path]) + run_path = new_script_path + else: + is_debug = false + if DirAccess.copy_absolute(current_exe, new_exe_path) == OK: # Make it executable OS.execute("chmod", ["+x", new_exe_path]) # Create desktop entry # Copy and save the icon - var icon_path := gvm_app_path.path_join("icon.png") + var icon_path := app_path.path_join("icon.png") var icon := load("res://icon.svg") as Texture2D var image := icon.get_image() image.save_png(icon_path) # Create desktop entry - var desktop_entry := _create_desktop_entry(new_exe_path, icon_path) + var desktop_entry := _create_desktop_entry(run_path, icon_path, is_debug) var file := FileAccess.open(desktop_entry_path, FileAccess.WRITE) if file: file.store_string(desktop_entry) @@ -77,21 +89,22 @@ func _ensure_desktop_entry() -> void: printerr("Failed to copy executable") -func _create_desktop_entry(exe_path: String, icon_path: String) -> String: +func _create_desktop_entry(exec: String, icon: String, terminal: bool) -> String: return ( - """[Desktop Entry] - Name=Godots + """\ +[Desktop Entry] +Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec="{exe}" %f +Exec="{exec}" %f Icon={icon} -Terminal=false +Terminal={terminal} PrefersNonDefaultGPU=true Type=Application Categories=Development;IDE; StartupWMClass=Godot """ - . format({"exe": exe_path, "icon": icon_path}) + . format({"exec": exec, "icon": icon, "terminal": terminal}) ) From f602296c2f1a8259b91f80af177c8d1072328a3f Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 13 Mar 2025 12:49:57 -0300 Subject: [PATCH 05/23] Revert "chore: fix several erros and warnings" This reverts commit be959ccb5dd62e9d3d84d348130700caffc2eed1. --- plug.gd | 5 +- project.godot | 2 +- .../asset_lib_item_details.gd | 19 +- .../asset_lib_projects/asset_lib_projects.gd | 51 ++-- .../asset_list_item/asset_list_item.gd | 8 +- .../asset_lib_projects/assets_container.gd | 2 +- .../category_option_button.gd | 20 +- .../pagination_container.gd | 18 +- .../version_option_button.gd | 22 +- .../command_viewer/command_viewer.gd | 101 ++++--- .../local/editor_item/show_owners_dialog.gd | 32 +-- .../local/editors_list/editors_list.gd | 3 +- .../editors/local_remote_editors_switch.gd | 6 +- .../remote_editor_install.gd | 18 +- .../remote_editors_tree.gd | 55 ++-- .../remote_editors_tree/sources/github.gd | 256 +++++++----------- .../godots_releases/godots_releases.gd | 24 +- .../new_project_dialog/new_project_dialog.gd | 71 +++-- .../projects/project_item/project_item.gd | 74 ++--- src/components/projects/projects.gd | 32 +-- .../projects/projects_list/projects_list.gd | 3 +- src/components/settings/settings_window.gd | 120 ++++---- src/components/title_bar/title_bar.gd | 16 +- src/extensions/zip.gd | 22 +- src/http_client.gd | 24 +- src/main/gui/auto_updates.gd | 13 +- src/main/gui/gui_main.gd | 70 ++--- src/objects/node_component/comp_scene.gd | 4 +- src/services/godots_recent_releases.gd | 30 +- src/services/godots_releases.gd | 127 ++++----- src/services/local_editors.gd | 116 ++++---- src/services/projects.gd | 170 ++++++------ src/services/remote_image_src.gd | 52 ++-- src/utils.gd | 52 ++-- tests/cases/cli/parser/parser_not_ok.gd | 30 +- tests/cases/cli/parser/parser_ok.gd | 18 +- tests/cases/cli/parser/test_grammar.gd | 2 +- .../list_dir_recursive/list_dir_test.gd | 23 +- tests/cases/services/local_editor_tests.gd | 6 +- theme/fill_icons_registry.gd | 8 +- 40 files changed, 812 insertions(+), 913 deletions(-) diff --git a/plug.gd b/plug.gd index 8d8e42bc..6c722928 100644 --- a/plug.gd +++ b/plug.gd @@ -1,11 +1,10 @@ -@tool extends "res://addons/gd-plug/plug.gd" -func _plugging() -> void: +func _plugging(): plug("MikeSchulze/gdUnit4", {"commit": "8226bc34faaa9fde7829b065fa51b63a8fe140c4"}) plug("MakovWait/godot-use-context") - + if "--include-editor" in OS.get_cmdline_args(): plug("MakovWait/godot-expand-region", {"exclude": ["addons/gdUnit4"]}) plug("MakovWait/godot-find-everywhere") diff --git a/project.godot b/project.godot index b3a381b6..c02892c1 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg", "res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/use-context/plugin.cfg") [filesystem] diff --git a/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd b/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd index a1c85073..7da925c0 100644 --- a/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd +++ b/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd @@ -26,8 +26,7 @@ func _ready() -> void: _preview.custom_minimum_size = Vector2(640, 345) * Config.EDSCALE _preview_bg.custom_minimum_size = Vector2(640, 101) * Config.EDSCALE - - @warning_ignore("redundant_await") + var item := await _asset_lib.async_fetch_one(_item_id) _configure(item) @@ -41,8 +40,7 @@ func _configure(item: AssetLib.Item) -> void: title = item.title var first_preview_selected := false for preview in item.previews: - @warning_ignore("redundant_await") - var btn := await add_preview(preview) + var btn := add_preview(preview) if not first_preview_selected and not preview.is_video: first_preview_selected = true _handle_btn_pressed.bind(preview, btn).call_deferred() @@ -54,11 +52,10 @@ func add_preview(item: AssetLib.ItemPreview) -> Button: btn.toggle_mode = true btn.pressed.connect(_handle_btn_pressed.bind(item, btn)) _previews_container.add_child(btn) - @warning_ignore("redundant_await") - await _images_src.async_load_img(item.thumbnail, func(tex: Texture2D) -> void: + _images_src.async_load_img(item.thumbnail, func(tex: Texture2D) -> void: if not item.is_video: if tex is ImageTexture: - utils.fit_height(85 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(85 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: (tex as ImageTexture).set_size_override(new_size) ) btn.icon = tex @@ -67,13 +64,13 @@ func add_preview(item: AssetLib.ItemPreview) -> Button: var tex_image: Image = tex.get_image() if tex_image == null: tex_image = get_theme_icon("FileBrokenBigThumb", "EditorIcons").get_image() - utils.fit_height(85 * Config.EDSCALE, tex_image.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(85 * Config.EDSCALE, tex_image.get_size(), func(new_size: Vector2i) -> void: tex_image.resize(new_size.x, new_size.y, Image.INTERPOLATE_LANCZOS) ) var thumbnail := tex_image.duplicate() as Image var overlay_pos := Vector2i( - int((thumbnail.get_width() - overlay.get_width()) / 2.0), - int((thumbnail.get_height() - overlay.get_height()) / 2.0) + (thumbnail.get_width() - overlay.get_width()) / 2, + (thumbnail.get_height() - overlay.get_height()) / 2 ) thumbnail.convert(Image.FORMAT_RGBA8) thumbnail.blend_rect(overlay, overlay.get_used_rect(), overlay_pos) @@ -92,7 +89,7 @@ func _handle_btn_pressed(item: AssetLib.ItemPreview, btn: Button) -> void: else: _images_src.async_load_img(item.link, func(tex: Texture2D) -> void: if tex is ImageTexture: - utils.fit_height(397 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(397 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: (tex as ImageTexture).set_size_override(new_size) ) _preview.texture = tex diff --git a/src/components/asset_lib_projects/asset_lib_projects.gd b/src/components/asset_lib_projects/asset_lib_projects.gd index e38e9e9c..d9d2c0c0 100644 --- a/src/components/asset_lib_projects/asset_lib_projects.gd +++ b/src/components/asset_lib_projects/asset_lib_projects.gd @@ -10,7 +10,7 @@ signal download_requested(item: AssetLib.Item, icon: Texture2D) @onready var _assets_container := %AssetsContainer as AssetsContainer @onready var _filter_edit := %FilterEdit as LineEdit @onready var _version_option_button := %VersionOptionButton as GodotVersionOptionButton -#@onready var _sort_option_button := %SortOptionButton as OptionButton +@onready var _sort_option_button := %SortOptionButton as OptionButton @onready var _category_option_button := %CategoryOptionButton as AssetCategoryOptionButton @onready var _site_option_button := %SiteOptionButton as AssetLibProjectsSiteOptionButton @onready var _support_menu_button := %SupportMenuButton as AssetLibProjectsSupportMenuButton @@ -23,8 +23,8 @@ var _params_sources_composed: ParamSources var _asset_lib_factory: AssetLib.Factory var _current_page := 0 -#var _top_pages: HBoxContainer -#var _bottom_pages: HBoxContainer +var _top_pages: HBoxContainer +var _bottom_pages: HBoxContainer var _versions_loaded := false var _config_loaded := false var _initial_fetch := false @@ -33,7 +33,7 @@ var _next_fetch_queued := false func init( - asset_lib_factory: AssetLib.Factory, + asset_lib_factory: AssetLib.Factory, category_src: AssetCategoryOptionButton.Src, version_src: GodotVersionOptionButton.Src, images_src: RemoteImageSrc.I @@ -41,20 +41,20 @@ func init( _category_option_button.init(category_src) _version_option_button.init(version_src) _asset_lib_factory = asset_lib_factory - + _assets_container.init(images_src) _assets_container.title_pressed.connect(func(item: AssetLib.Item) -> void: var asset_lib := _get_asset_lib() var item_details: AssetLibItemDetailsDialog = _item_details_scene.instantiate() - item_details.download_requested.connect(func(asset: AssetLib.Item, icon: Texture2D) -> void: + item_details.download_requested.connect(func(item: AssetLib.Item, icon: Texture2D) -> void: download_requested.emit(item, icon) ) item_details.init(item.id as String, asset_lib, images_src) add_child(item_details) item_details.popup_centered() ) - _assets_container.category_pressed.connect(func(asset: AssetLib.Item) -> void: - _category_option_button.force_select_by_label(asset.category) + _assets_container.category_pressed.connect(func(item: AssetLib.Item) -> void: + _category_option_button.force_select_by_label(item.category) ) if is_visible_in_tree(): @@ -72,23 +72,23 @@ func _init() -> void: func _ready() -> void: _params_sources_composed = ParamSources.new(_params_sources) - - (%LibVb as Control).add_theme_constant_override("separation", int(20 * Config.EDSCALE)) + + (%LibVb as Control).add_theme_constant_override("separation", 20 * Config.EDSCALE) _filter_edit.placeholder_text = tr("Search Templates, Projects, and Demos") - - _assets_container.add_theme_constant_override("h_separation", int(10 * Config.EDSCALE)) - _assets_container.add_theme_constant_override("v_separation", int(10 * Config.EDSCALE)) - + + _assets_container.add_theme_constant_override("h_separation", 10 * Config.EDSCALE) + _assets_container.add_theme_constant_override("v_separation", 10 * Config.EDSCALE) + _params_sources_composed.connect_changed(func() -> void: _current_page = 0 _async_fetch() ) - + _site_option_button.site_selected.connect(func() -> void: _config_loaded = false _async_fetch() ) - + (%TopPagesContainer as PaginationContainer).page_changed.connect(_change_page) (%BotPagesContainer as PaginationContainer).page_changed.connect(_change_page) @@ -102,19 +102,17 @@ func _async_fetch() -> void: _next_fetch_queued = false if not _versions_loaded: - @warning_ignore("redundant_await") var version_error := await __async_load_versions_list() if version_error: return - + if not _config_loaded: var config_error := await __async_load_configuration() if config_error: return - - @warning_ignore("redundant_await") + await __async_fetch_assets() - + _fetching = false if _next_fetch_queued: _async_fetch() @@ -128,7 +126,6 @@ func __async_load_versions_list() -> Error: _assets_container.clear() _clear_pages() - @warning_ignore("redundant_await") var versions_load_errors := await _version_option_button.async_load_versions() var return_error: Error if len(versions_load_errors) > 0: @@ -156,7 +153,6 @@ func __async_load_configuration() -> Error: _scroll_container.dim() _error_container.hide() - @warning_ignore("redundant_await") var config_load_errors := await _category_option_button.async_load_items( _site_option_button.get_selected_site() ) @@ -185,7 +181,6 @@ func __async_fetch_assets() -> void: var asset_lib := _get_asset_lib() var params := _get_asset_lib_params() var errors: Array[String] = [] - @warning_ignore("redundant_await") var items := await asset_lib.async_fetch(params, errors) if len(errors) > 0: @@ -258,15 +253,15 @@ func _set_status(text: String) -> void: class ParamSources: var _elements: Array - + func _init(elements: Array) -> void: _elements = elements - + func enable() -> void: for x: Object in _elements: if x.has_method("_on_fetch_enable"): x.call("_on_fetch_enable") - + func disable() -> void: for x: Object in _elements: if x.has_method("_on_fetch_disable"): @@ -276,7 +271,7 @@ class ParamSources: for x: Object in _elements: if x.has_signal("changed"): x.connect("changed", callback) - + func fill_params(params: AssetLib.Params) -> void: for x: Object in _elements: if x.has_method("fill_params"): diff --git a/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd b/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd index c1369b7d..3fffe404 100644 --- a/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd +++ b/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd @@ -19,7 +19,7 @@ var _original_title_text: String func _init() -> void: custom_minimum_size = Vector2i(DEFAULT_MIN_SIZE_X, 100) * Config.EDSCALE - add_theme_constant_override("separation", int(15 * Config.EDSCALE)) + add_theme_constant_override("separation", 15 * Config.EDSCALE) func _ready() -> void: @@ -34,9 +34,9 @@ func init(item: AssetLib.Item, images: RemoteImageSrc.I) -> void: _category.text = item.category _author.text = item.author _cost.text = item.cost - + _original_title_text = item.title - + _title.pressed.connect(func() -> void: title_pressed.emit(item) ) @@ -69,5 +69,5 @@ func clamp_width(max_width: int) -> void: if text_pixel_width > max_width: # Truncate title text to within the current column width. var max_length := max_width / (text_pixel_width / full_text.length()) - var truncated_text := full_text.left(int(max_length - 3)) + "..." + var truncated_text := full_text.left(max_length - 3) + "..." _title.text = truncated_text diff --git a/src/components/asset_lib_projects/assets_container.gd b/src/components/asset_lib_projects/assets_container.gd index 11612f09..81e452e9 100644 --- a/src/components/asset_lib_projects/assets_container.gd +++ b/src/components/asset_lib_projects/assets_container.gd @@ -45,7 +45,7 @@ func _update_columns() -> void: new_columns = max(1, new_columns) # prints(size.x, new_columns, (size.x / new_columns) - (100 * Config.EDSCALE)) if new_columns != columns: - columns = int(new_columns) + columns = new_columns # for c in get_children(): # if c.has_method('clamp_width'): # c.clamp_width((size.x / new_columns) - (100 * Config.EDSCALE)) diff --git a/src/components/asset_lib_projects/category_option_button.gd b/src/components/asset_lib_projects/category_option_button.gd index 53c74451..e04ee764 100644 --- a/src/components/asset_lib_projects/category_option_button.gd +++ b/src/components/asset_lib_projects/category_option_button.gd @@ -1,8 +1,10 @@ class_name AssetCategoryOptionButton extends OptionButton + signal changed + var _src: Src @@ -17,10 +19,8 @@ func _init() -> void: func async_load_items(url: String) -> Array[String]: clear() - @warning_ignore("redundant_await") - await add_item(tr("All"), 0) + add_item(tr("All"), 0) var errors: Array[String] = [] - @warning_ignore("redundant_await") var json := await _src.async_load(url, errors) for category: Dictionary in json.get("categories", []): add_item(tr(category.name as String), category.id as int) @@ -51,17 +51,15 @@ func force_select_by_label(opt_label: String) -> void: class Src: - func async_load(url: String, errors: Array[String] = []) -> Dictionary: + func async_load(url: String, errors: Array[String]=[]) -> Dictionary: return {} -class SrcRemote: - extends Src - - func async_load(url: String, errors: Array[String] = []) -> Dictionary: - var response := HttpClient.Response.new( - await HttpClient.async_http_get(url.path_join("configure?type=project")) - ) +class SrcRemote extends Src: + func async_load(url: String, errors: Array[String]=[]) -> Dictionary: + var response := HttpClient.Response.new(await HttpClient.async_http_get( + url.path_join("configure?type=project") + )) var info := response.to_response_info(url) if info.error_text: errors.append(info.error_text) diff --git a/src/components/asset_lib_projects/pagination_container.gd b/src/components/asset_lib_projects/pagination_container.gd index e8afab5d..1d7d3c52 100644 --- a/src/components/asset_lib_projects/pagination_container.gd +++ b/src/components/asset_lib_projects/pagination_container.gd @@ -22,25 +22,25 @@ func clear() -> void: func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> HBoxContainer: var hbc := HBoxContainer.new() hbc.alignment = HBoxContainer.ALIGNMENT_CENTER - + if page_count < 2: return hbc - + var from := page - (5 / Config.EDSCALE) if from < 0: from = 0 var to := from + (10 / Config.EDSCALE) if to > page_count: to = page_count - + hbc.add_spacer(false) - hbc.add_theme_constant_override("separation", int(5 * Config.EDSCALE)) - + hbc.add_theme_constant_override("separation", 5 * Config.EDSCALE) + var trigger_search := func(btn: Button, p: int) -> void: btn.pressed.connect(func() -> void: page_changed.emit(p) ) - + var first := Button.new() first.text = tr("First", "Pagination") if page != 0: @@ -49,7 +49,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> first.set_disabled(true) first.set_focus_mode(Control.FOCUS_NONE) hbc.add_child(first) - + var prev := Button.new() prev.text = tr("Previous", "Pagination") if page > 0: @@ -59,7 +59,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> prev.set_focus_mode(Control.FOCUS_NONE) hbc.add_child(prev) hbc.add_child(VSeparator.new()) - + for i in range(from, to): if i == page: var current := Button.new() @@ -76,7 +76,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> trigger_search.call(current, i) hbc.add_child(current) - + var next := Button.new() next.set_text(tr("Next", "Pagination")) if page < page_count - 1: diff --git a/src/components/asset_lib_projects/version_option_button.gd b/src/components/asset_lib_projects/version_option_button.gd index 5f6f0de6..90a15390 100644 --- a/src/components/asset_lib_projects/version_option_button.gd +++ b/src/components/asset_lib_projects/version_option_button.gd @@ -17,7 +17,6 @@ func init(src: Src) -> void: func async_load_versions() -> Array[String]: clear() var errors: Array[String] = [] - @warning_ignore("redundant_await") var versions := await _src.async_fetch(errors) for i in range(len(versions)): add_item(versions[i]) @@ -30,31 +29,28 @@ func fill_params(params: AssetLib.Params) -> void: class Src: - func async_fetch(errors: Array[String] = []) -> PackedStringArray: + func async_fetch(errors: Array[String]=[]) -> PackedStringArray: return [] -class SrcMock: - extends Src +class SrcMock extends Src: var _data: PackedStringArray - + func _init(data: PackedStringArray) -> void: _data = data - - func async_fetch(errors: Array[String] = []) -> PackedStringArray: + + func async_fetch(errors: Array[String]=[]) -> PackedStringArray: return _data -class SrcGithubYml: - extends Src +class SrcGithubYml extends Src: var _yml_src: RemoteEditorsTreeDataSourceGithub.YmlSource var _name_regex := RegEx.create_from_string('(?m)\\sname:\\s"(?[^"]+)"$') - + func _init(yml_src: RemoteEditorsTreeDataSourceGithub.YmlSource) -> void: _yml_src = yml_src - - func async_fetch(errors: Array[String] = []) -> PackedStringArray: - @warning_ignore("redundant_await") + + func async_fetch(errors: Array[String]=[]) -> PackedStringArray: var yml := await _yml_src.async_load(errors) var versions := _name_regex.search_all(yml) var result: PackedStringArray = [] diff --git a/src/components/command_viewer/command_viewer.gd b/src/components/command_viewer/command_viewer.gd index 7ad7b533..d25477d1 100644 --- a/src/components/command_viewer/command_viewer.gd +++ b/src/components/command_viewer/command_viewer.gd @@ -22,16 +22,16 @@ func _ready() -> void: if not visible: _commands = null ) - + var help := add_button(tr("Help")) help.pressed.connect(func() -> void: OS.shell_open("https://github.com/MakovWait/godots/blob/main/.github/assets/FEATURES.md#edit-commands") ) help.icon = get_theme_icon("ExternalLink", "EditorIcons") - + _create_new_command_btn = add_button(tr("New Command")) _create_new_command_btn.pressed.connect(func() -> void: - _popup_new_command_dialog("", "", [], "Terminal", false, + _popup_new_command_dialog("", "", [], "Terminal", false, func(cmd_name: String, cmd_path: String, cmd_args: PackedStringArray, cmd_icon: String, is_local: bool) -> void: if _commands: var command := _commands.add( @@ -60,7 +60,7 @@ func _update_view(commands: Commands, command_creation_allowed:=false) -> void: if c.has_method("hide"): c.call("hide") c.queue_free() - + for command in commands.all(): _add_view(command, commands) @@ -98,7 +98,7 @@ func _add_view(command: Command, commands: Commands) -> void: var output_text := "" if len(output) > 0: output_text = output[0] - + var rich_text_label := %OutputLabel as RichTextLabel rich_text_label.custom_minimum_size = Vector2i(0, 100) * Config.EDSCALE rich_text_label.clear() @@ -125,8 +125,8 @@ func _add_view(command: Command, commands: Commands) -> void: func _set_text_to_command_view(command: Command, command_view: CommandTextView) -> void: var local_badge := tr("Local") if command.is_local() else tr("Global") command_view.set_text( - "%s (%s):" % [command.name(), local_badge], - "", + "%s (%s):" % [command.name(), local_badge], + "", str(command), command.icon() ) @@ -155,14 +155,14 @@ class Command: var _icon: String var _process_src: OSProcessSchema.Source var _allowed_actions: PackedStringArray - + func _init( name: String, path: String, args: PackedStringArray, icon: String, - is_local: bool, - process_src: OSProcessSchema.Source, + is_local: bool, + process_src: OSProcessSchema.Source, allowed_actions: PackedStringArray ) -> void: _icon = icon @@ -172,36 +172,36 @@ class Command: _is_local = is_local _process_src = process_src _allowed_actions = allowed_actions - + func icon() -> String: return _icon - + func is_local() -> bool: return _is_local - + func is_action_allowed(action: String) -> bool: return action in _allowed_actions - + func args() -> PackedStringArray: return _args - + func path() -> String: return _path - + func name() -> String: return _name - + func execute(output:=[]) -> int: return _process_src.get_os_process_schema(_path, _args).execute( output, true, true ) - + func create_process() -> void: _process_src.get_os_process_schema(_path, _args).create_process(true) - + func remove_from(commands: Commands) -> void: commands.remove(_name, _is_local) - + func _to_string() -> String: return str(_process_src.get_os_process_schema(_path, _args)) @@ -209,11 +209,11 @@ class Command: class Commands: func all() -> Array[Command]: return [] - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: - # assert(true, "Not implemented") <- Why??? assert true is redundant + assert(true, "Not implemented") return null - + func remove(name: String, is_local: bool) -> void: pass @@ -222,10 +222,10 @@ class CustomCommandsSource: var custom_commands: Array: get: return _get_custom_commands() set(value): _set_custom_commands(value) - + func _get_custom_commands() -> Array: return [] - + func _set_custom_commands(value: Array) -> void: pass @@ -248,28 +248,28 @@ class CommandsInMemory extends CommandsWrap: class CustomCommandsSourceArray extends CustomCommandsSource: var _data: Array[Dictionary] = [] - + func _init(data: Array[Dictionary]=[]) -> void: _data = data - + func _get_custom_commands() -> Array: return _data - + func _set_custom_commands(value: Array) -> void: _data = value class CustomCommandsSourceDynamic extends CustomCommandsSource: signal edited - + var _delegate: Object - + func _init(delegate: Object) -> void: _delegate = delegate - + func _get_custom_commands() -> Array: return _delegate.get("custom_commands") - + func _set_custom_commands(value: Array) -> void: _delegate.set("custom_commands", value) edited.emit() @@ -278,23 +278,23 @@ class CustomCommandsSourceDynamic extends CustomCommandsSource: class CommandsDuo extends Commands: var _local: Commands var _global: Commands - + func _init(local: Commands, global: Commands) -> void: _local = local _global = global - + func all() -> Array[Command]: var result: Array[Command] = [] result.append_array(_global.all()) result.append_array(_local.all()) return result - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: if is_local: return _local.add(name, path, args, is_local, icon, allowed_actions) else: return _global.add(name, path, args, is_local, icon, allowed_actions) - + func remove(name: String, is_local: bool) -> void: if is_local: return _local.remove(name, is_local) @@ -304,27 +304,27 @@ class CommandsDuo extends Commands: class CommandsWrap extends Commands: var _origin: Commands - + func _init(origin: Commands) -> void: _origin = origin - + func all() -> Array[Command]: return _origin.all() - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: return _origin.add(name, path, args, is_local, icon, allowed_actions) - + func remove(name: String, is_local: bool) -> void: _origin.remove(name, is_local) class CommandsWithBasic extends CommandsWrap: var _basic: Array[Command] - + func _init(origin: Commands, basic: Array[Command]) -> void: super._init(origin) _basic = basic - + func all() -> Array[Command]: var result: Array[Command] result.append_array(_basic) @@ -336,12 +336,12 @@ class CommandsGeneric extends Commands: var _custom_commands_source: CustomCommandsSource var _base_process_src: OSProcessSchema.Source var _is_local: bool - + func _init(base_process_src: OSProcessSchema.Source, custom_commands_source: CustomCommandsSource, is_local: bool) -> void: _base_process_src = base_process_src _custom_commands_source = custom_commands_source _is_local = is_local - + func all() -> Array[Command]: var result: Array[Command] var commands := _custom_commands_source.custom_commands @@ -354,7 +354,7 @@ class CommandsGeneric extends Commands: _is_local ))) return result - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: if is_local == _is_local: var commands := _custom_commands_source.custom_commands @@ -382,22 +382,21 @@ class CommandsGeneric extends Commands: _custom_commands_source.custom_commands = commands return _to_command(name, path, args, allowed_actions, icon, is_local) else: - # assert(true, "Not implemented") <- Again? + assert(true, "Not implemented") return null - + func remove(name: String, is_local: bool) -> void: if is_local == _is_local: var commands := _custom_commands_source.custom_commands commands = commands.filter(func(x: Dictionary) -> bool: return x.name != name) _custom_commands_source.custom_commands = commands else: - # assert(true, "Not implemented") <- ;-; - pass - + assert(true, "Not implemented") + func _has_by_name(name: String) -> bool: return len( _custom_commands_source.custom_commands.filter(func(x: Dictionary) -> bool: return x.name == name) ) > 0 - + func _to_command(name: String, path: String, args: PackedStringArray, allowed_actions: PackedStringArray, icon: String, is_local: bool) -> Command: return Command.new(name, path, args, icon, is_local, _base_process_src, allowed_actions) diff --git a/src/components/editors/local/editor_item/show_owners_dialog.gd b/src/components/editors/local/editor_item/show_owners_dialog.gd index 05f2260b..c9fb19c7 100644 --- a/src/components/editors/local/editor_item/show_owners_dialog.gd +++ b/src/components/editors/local/editor_item/show_owners_dialog.gd @@ -19,31 +19,31 @@ func raise(editor: LocalEditors.Item) -> void: var item := _tree.create_item() var icon_image: Image = owner.icon.get_image().duplicate() icon_image.resize( - int(16 * Config.EDSCALE), - int(16 * Config.EDSCALE), + 16 * Config.EDSCALE, + 16 * Config.EDSCALE, Image.INTERPOLATE_LANCZOS ) item.set_icon(0, ImageTexture.create_from_image(icon_image)) item.set_text(0, owner.name) item.add_button( - 0, - get_theme_icon("Play", "EditorIcons"), - Buttons.RUN, - not owner.is_valid, + 0, + get_theme_icon("Play", "EditorIcons"), + Buttons.RUN, + not owner.is_valid, tr("Run") ) item.add_button( - 0, - get_theme_icon("Edit", "EditorIcons"), - Buttons.EDIT, - not owner.is_valid, + 0, + get_theme_icon("Edit", "EditorIcons"), + Buttons.EDIT, + not owner.is_valid, tr("Edit") ) item.add_button( - 0, - get_theme_icon("Folder", "EditorIcons"), - Buttons.OPEN_IN_EXPLORER, - not owner.is_valid, + 0, + get_theme_icon("Folder", "EditorIcons"), + Buttons.OPEN_IN_EXPLORER, + not owner.is_valid, tr("Show in File Manager") ) item.set_metadata(0, owner) @@ -57,7 +57,7 @@ func _ready() -> void: if not visible: queue_free() ) - + _tree.button_clicked.connect(func(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void: var project: Projects.Item = item.get_metadata(0) if id == Buttons.EDIT: @@ -69,6 +69,6 @@ func _ready() -> void: ProjectSettings.globalize_path(project.path) ) ) - + _tree.create_item() _tree.hide_root = true diff --git a/src/components/editors/local/editors_list/editors_list.gd b/src/components/editors/local/editors_list/editors_list.gd index d7fa0f9d..8678d8a7 100644 --- a/src/components/editors/local/editors_list/editors_list.gd +++ b/src/components/editors/local/editors_list/editors_list.gd @@ -29,13 +29,14 @@ func _item_comparator(a: Dictionary, b: Dictionary) -> bool: 1: return a.path < b.path 2: return a.tag_sort_string < b.tag_sort_string _: return a.name < b.name + return a.name < b.name func _fill_sort_options(btn: OptionButton) -> void: btn.add_item(tr("Name")) btn.add_item(tr("Path")) btn.add_item(tr("Tags")) - + var last_checked_sort := Cache.smart_value(self, "last_checked_sort", true) btn.select(last_checked_sort.ret(0) as int) btn.item_selected.connect(func(idx: int) -> void: last_checked_sort.put(idx)) diff --git a/src/components/editors/local_remote_editors_switch.gd b/src/components/editors/local_remote_editors_switch.gd index e9ee320a..b8218d74 100644 --- a/src/components/editors/local_remote_editors_switch.gd +++ b/src/components/editors/local_remote_editors_switch.gd @@ -18,9 +18,9 @@ func _ready() -> void: ctx.go_to_remote() _local.set_pressed_no_signal(true) ) - - add_theme_constant_override("separation", int(48 * Config.EDSCALE)) - + + add_theme_constant_override("separation", 48 * Config.EDSCALE) + _set_theme_to(_local) _set_theme_to(_remote) diff --git a/src/components/editors/remote/remote_editor_install/remote_editor_install.gd b/src/components/editors/remote/remote_editor_install/remote_editor_install.gd index d985cd0b..e692d9b5 100644 --- a/src/components/editors/remote/remote_editor_install/remote_editor_install.gd +++ b/src/components/editors/remote/remote_editor_install/remote_editor_install.gd @@ -7,12 +7,12 @@ signal installed(editor_name: String, editor_exec_path: String) @onready var _editor_name_edit: LineEdit = %EditorNameEdit @onready var _select_exec_file_tree: Tree = %SelectExecFileTree -#@onready var _file_dialog := $FileDialog as FileDialog +@onready var _file_dialog := $FileDialog as FileDialog @onready var _show_all_check_box := %ShowAllCheckBox as CheckBox var _dir_content: Array[edir.DirListResult] -#var _show_all: bool: - #get: return _show_all_check_box.button_pressed +var _show_all: bool: + get: return _show_all_check_box.button_pressed func _ready() -> void: @@ -44,20 +44,20 @@ func init(editor_name: String, editor_exec_path: String) -> void: func _setup_editor_select_tree() -> void: _select_exec_file_tree.clear() var root := _select_exec_file_tree.create_item() - + ## filter: Optional[Callable], should_be_selected: Optional[Callable] - var create_tree_items := func(source: Array[edir.DirListResult], _filter: Variant = null, _should_be_selected: Variant = null) -> void: + var create_tree_items := func(source: Array[edir.DirListResult], filter: Variant = null, should_be_selected: Variant = null) -> void: var selected := false for x in source: - if _filter and not (_filter as Callable).call(x): + if filter and not (filter as Callable).call(x): continue var item := _select_exec_file_tree.create_item(root) item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK) item.set_text(0, x.file) item.set_editable(0, true) item.set_meta("full_path", x.path) - if not selected and _should_be_selected != null: - if (_should_be_selected as Callable).call(x): + if not selected and should_be_selected != null: + if (should_be_selected as Callable).call(x): selected = true item.set_checked(0, true) item.select(0) @@ -83,7 +83,7 @@ func _setup_editor_select_tree() -> void: return x.is_file and ( x.extension.contains("32") or x.extension.contains("64") ) - + create_tree_items.call(_dir_content, filter, should_be_selected) diff --git a/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd b/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd index e898aab0..619c09f8 100644 --- a/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd +++ b/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd @@ -10,14 +10,14 @@ const uuid = preload("res://addons/uuid.gd") @onready var _check_box_container: HFlowContainer = %CheckBoxContainer var _refresh_button: Button -#var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets +var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets var _src: RemoteEditorsTreeDataSource.I var _i_remote_tree: RemoteEditorsTreeDataSource.RemoteTree var _root_loaded := false var _row_filters: Array[RowFilter] = [NotRelatedFilter.new()] var _current_loadings_number := 0: - set(value): + set(value): _current_loadings_number = value _loadings_number_changed.emit(value) var _remote_editors_checkbox_checked := Cache.smart_section( @@ -27,7 +27,7 @@ var _remote_editors_checkbox_checked := Cache.smart_section( func post_ready(refresh_button: Button) -> void: _refresh_button = refresh_button - + _setup_tree() _setup_checkboxes() @@ -61,7 +61,7 @@ func _refresh() -> void: func _setup_checkboxes() -> void: (%CheckBoxPanelContainer as PanelContainer).add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Tree")) - + var checkbox := func(text: String, filter: RowFilter, button_pressed:=false) -> CheckBox: var box := CheckBox.new() box.text = text @@ -69,7 +69,7 @@ func _setup_checkboxes() -> void: if button_pressed: _row_filters.append(filter) box.toggled.connect(func(pressed: bool) -> void: - if pressed: + if pressed: _row_filters.append(filter) else: var idx := _row_filters.find(filter) @@ -86,7 +86,7 @@ func _setup_checkboxes() -> void: if not button_pressed: _row_filters.append(filter) box.toggled.connect(func(pressed: bool) -> void: - if pressed: + if pressed: var idx := _row_filters.find(filter) if idx >= 0: _row_filters.remove_at(idx) @@ -98,32 +98,32 @@ func _setup_checkboxes() -> void: return box var contains_any := func(words: Array) -> Callable: - return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return words.any(func(x: String) -> bool: return row.get_name().to_lower().contains(x.to_lower())) - + var _not := func(original: Callable) -> Callable: return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> Callable: return not original.call(row) - + _check_box_container.add_child( inverted_checkbox.call( - tr("mono"), + tr("mono"), RowFilter.new(contains_any.call(["mono"]) as Callable), _remote_editors_checkbox_checked.get_value("mono", true) ) as CheckBox ) - + _check_box_container.add_child( inverted_checkbox.call( - tr("unstable"), + tr("unstable"), RowFilter.new(contains_any.call(["rc", "beta", "alpha", "dev", "fixup"]) as Callable), _remote_editors_checkbox_checked.get_value("unstable", false) ) as CheckBox ) - + _check_box_container.add_child( inverted_checkbox.call( - tr("any platform"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("any platform"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_file() and row.is_for_different_platform(_src.get_platform_suffixes())), _remote_editors_checkbox_checked.get_value("any platform", false) ) as CheckBox @@ -141,7 +141,7 @@ func _setup_checkboxes() -> void: if bit: _check_box_container.add_child( checkbox.call( - "%s-bit" % bit, + "%s-bit" % bit, RowFilter.new(contains_any.call([opposite]) as Callable), _remote_editors_checkbox_checked.get_value("%s-bit" % bit, true) ) as CheckBox @@ -149,8 +149,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("4.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("4.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and row.get_name().begins_with("4")), _remote_editors_checkbox_checked.get_value("4.x", true) ) as CheckBox @@ -158,8 +158,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("3.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("3.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and row.get_name().begins_with("3")), _remote_editors_checkbox_checked.get_value("3.x", true) ) as CheckBox @@ -167,8 +167,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("x.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("x.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and not (row.get_name().begins_with("4") or row.get_name().begins_with("3"))), _remote_editors_checkbox_checked.get_value("x.x", false) ) as CheckBox @@ -181,9 +181,9 @@ func _delegate_of(item: TreeItem) -> RemoteEditorsTreeDataSource.Item: func _setup_tree() -> void: _i_remote_tree = RemoteEditorsTreeDataSource.RemoteTree.new(_tree, self) - + _tree.item_collapsed.connect( - func(x: TreeItem) -> void: + func(x: TreeItem) -> void: var expanded := not x.collapsed var delegate := _delegate_of(x) var not_loaded_yet := not delegate.is_loaded() @@ -205,7 +205,6 @@ func _setup_tree() -> void: func _expand(remote_tree_item: RemoteEditorsTreeDataSource.Item) -> void: _current_loadings_number += 1 - @warning_ignore("redundant_await") await remote_tree_item.async_expand(_i_remote_tree) _update_whole_tree_visibility(remote_tree_item) _current_loadings_number -= 1 @@ -225,10 +224,10 @@ func _on_visibility_changed() -> void: class RowFilter: var _delegate: Callable - + func _init(delegate: Callable) -> void: _delegate = delegate - + func test(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return _delegate.call(row) @@ -236,7 +235,7 @@ class RowFilter: class SimpleContainsFilter extends RowFilter: func _init(what: String) -> void: super._init( - func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.get_name().to_lower().contains(what) ) diff --git a/src/components/editors/remote/remote_editors_tree/sources/github.gd b/src/components/editors/remote/remote_editors_tree/sources/github.gd index 90197aef..64f1b248 100644 --- a/src/components/editors/remote/remote_editors_tree/sources/github.gd +++ b/src/components/editors/remote/remote_editors_tree/sources/github.gd @@ -1,64 +1,40 @@ class_name RemoteEditorsTreeDataSourceGithub -class Self: - extends RemoteEditorsTreeDataSource.I +class Self extends RemoteEditorsTreeDataSource.I: var _assets: RemoteEditorsTreeDataSource.RemoteAssets const platforms = { - "X11": - { - "suffixes": - [ - "_x11.64.zip", - "_linux.64.zip", - "_linux.x86_64.zip", - "_linux.x86_32.zip", - "_linux_x86_64.zip", - "_linux_x86_32.zip" - ], + "X11": { + "suffixes": ["_x11.64.zip", "_linux.64.zip", "_linux.x86_64.zip", "_linux.x86_32.zip", "_linux_x86_64.zip", "_linux_x86_32.zip"], }, - "OSX": - { - "suffixes": - [ - "_osx.universal.zip", - "_macos.universal.zip", - "_osx.fat.zip", - "_osx32.zip", - "_osx64.zip" - ], + "OSX": { + "suffixes": ["_osx.universal.zip", "_macos.universal.zip", "_osx.fat.zip", "_osx32.zip", "_osx64.zip"], }, - "Windows": - { + "Windows": { "suffixes": ["_win64.exe.zip", "_win32.exe.zip", "_win64.zip", "_win32.zip"], } } - + func _init(assets: RemoteEditorsTreeDataSource.RemoteAssets) -> void: _assets = assets - + func setup(tree: Tree) -> void: var root := tree.create_item() - ( - root - . set_meta( - "delegate", - ( - GithubRootItem - . new( - root, - _assets, - GithubVersionSourceParseYml.new( - YmlSourceGithub.new(), GithubAssetSourceDefault.new() - ), - ) - ) + root.set_meta( + "delegate", + GithubRootItem.new( + root, + _assets, + GithubVersionSourceParseYml.new( + YmlSourceGithub.new(), + GithubAssetSourceDefault.new() + ), ) ) - + func cleanup(tree: Tree) -> void: tree.clear() - + func get_platform_suffixes() -> Array: var current_platform: Dictionary if OS.has_feature("windows"): @@ -68,7 +44,7 @@ class Self: elif OS.has_feature("linux"): current_platform = platforms["X11"] return current_platform["suffixes"] - + func to_remote_item(item: TreeItem) -> RemoteEditorsTreeDataSource.Item: return item.get_meta("delegate") @@ -78,10 +54,10 @@ class GithubVersion: var flavor: String var releases: Array[String] = [] var _assets_src: GithubAssetSource - + func get_flavor_release() -> GodotRelease: return GodotRelease.new(name, flavor, _assets_src) - + func get_recent_releases() -> Array[GodotRelease]: var result: Array[GodotRelease] = [] for r in releases: @@ -93,70 +69,64 @@ class GodotRelease: var name: String var _version: String var _assets_src: GithubAssetSource - + func _init(version: String, name: String, assets_src: GithubAssetSource) -> void: self.name = name _assets_src = assets_src _version = version - + func is_stable() -> bool: return name == "stable" - + func async_load_assets() -> Array[GodotAsset]: - @warning_ignore("redundant_await") return await _assets_src.async_load(_version, name) class GodotAsset: var _json: Dictionary - + var name: String: - get: - return _json.get("name", "") - + get: return _json.get("name", "") + var file_name: String: - get: - return browser_download_url.get_file() - + get: return browser_download_url.get_file() + var browser_download_url: String: - get: - return _json.get("browser_download_url", "") - + get: return _json.get("browser_download_url", "") + var is_zip: bool: - get: - return name.get_extension() == "zip" - + get: return name.get_extension() == "zip" + func _init(json: Dictionary) -> void: _json = json -class GithubItemBase: - extends RemoteEditorsTreeDataSource.Item +class GithubItemBase extends RemoteEditorsTreeDataSource.Item: var _item: TreeItem var _assets: RemoteEditorsTreeDataSource.RemoteAssets - + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets) -> void: _item = item _assets = assets - + func is_loaded() -> bool: return _item.has_meta("loaded") - + func async_expand(tree: RemoteTree) -> void: return - + func handle_item_activated() -> void: pass - + func handle_button_clicked(col: int, id: int, mouse: int) -> void: pass - + func update_visibility(filters: Array) -> void: - var filter_target := _to_filter_target() + var filter_target := _to_filter_target() if filter_target == null: return _item.visible = _should_be_visible(filter_target, filters) - + func _should_be_visible(target: GithubFilterTarget, filters: Array) -> bool: if target.is_file() and not target.is_zip(): return false @@ -164,12 +134,12 @@ class GithubItemBase: for filter: RemoteEditorsTreeControl.RowFilter in filters: if filter.test(target): return false - + return true - + func _to_filter_target() -> GithubFilterTarget: return null - + func _asset_to_item(asset: GodotAsset, tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: var tree_item := tree.create_item(_item) tree_item.set_meta("delegate", GithubAssetItem.new(tree_item, _assets, asset)) @@ -178,7 +148,7 @@ class GithubItemBase: var btn_texture: Texture2D = tree.theme_source.get_theme_icon("AssetLib", "EditorIcons") tree_item.add_button(0, btn_texture) tree_item.collapsed = true - + func get_children() -> Array[RemoteEditorsTreeDataSource.Item]: var result: Array[RemoteEditorsTreeDataSource.Item] = [] for child in _item.get_children(): @@ -187,16 +157,13 @@ class GithubItemBase: return result -class GithubAssetItem: - extends GithubItemBase +class GithubAssetItem extends GithubItemBase: var _asset: GodotAsset - - func _init( - item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, asset: GodotAsset - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, asset: GodotAsset) -> void: super._init(item, assets) _asset = asset - + func _to_filter_target() -> GithubFilterTarget: return GithubFilterTarget.new(_asset.name, false, true, _asset.is_zip) @@ -207,16 +174,13 @@ class GithubAssetItem: _assets.download(_asset.browser_download_url, _asset.file_name) -class GithubReleaseItem: - extends GithubItemBase +class GithubReleaseItem extends GithubItemBase: var _release: GodotRelease - - func _init( - item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, release: GodotRelease - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, release: GodotRelease) -> void: super._init(item, assets) _release = release - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) var assets := await _release.async_load_assets() @@ -228,33 +192,33 @@ class GithubReleaseItem: return GithubFilterTarget.new(_release.name, false, false, false) -class GithubVersionItem: - extends GithubItemBase +class GithubVersionItem extends GithubItemBase: var _version: GithubVersion - - func _init( - item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, version: GithubVersion - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, version: GithubVersion) -> void: super._init(item, assets) _version = version - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) - + var releases: Array[GodotRelease] = [] var flavor := _version.get_flavor_release() if not flavor.is_stable(): releases.append(flavor) releases.append_array(_version.get_recent_releases()) - + for release in releases: var tree_item := tree.create_item(_item) tree_item.visible = false tree_item.set_text(0, release.name) tree.set_as_folder(tree_item) - tree_item.set_meta("delegate", GithubReleaseItem.new(tree_item, _assets, release)) + tree_item.set_meta( + "delegate", + GithubReleaseItem.new(tree_item, _assets, release) + ) tree_item.collapsed = true - + if flavor.is_stable(): var assets := await flavor.async_load_assets() for asset in assets: @@ -266,21 +230,15 @@ class GithubVersionItem: return GithubFilterTarget.new(_version.name, true, false, false) -class GithubRootItem: - extends GithubItemBase +class GithubRootItem extends GithubItemBase: var _versions_source: GithubVersionSource - - func _init( - item: TreeItem, - assets: RemoteEditorsTreeDataSource.RemoteAssets, - versions_source: GithubVersionSource - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, versions_source: GithubVersionSource) -> void: super._init(item, assets) _versions_source = versions_source - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) - @warning_ignore("redundant_await") var versions := await _versions_source.async_load() for version in versions: var tree_item := tree.create_item(_item) @@ -291,8 +249,7 @@ class GithubRootItem: tree.free_loading_placeholder(_item) -class GithubFilterTarget: - extends RemoteEditorsTreeDataSource.FilterTarget +class GithubFilterTarget extends RemoteEditorsTreeDataSource.FilterTarget: var _name: String var _is_possible_version_folder: bool var _is_file: bool @@ -315,9 +272,7 @@ class GithubFilterTarget: func is_for_different_platform(platform_suffixes: Array) -> bool: var cached_name := get_name() - return not platform_suffixes.any( - func(suffix: String) -> bool: return cached_name.ends_with(suffix) - ) + return not platform_suffixes.any(func(suffix: String) -> bool: return cached_name.ends_with(suffix)) func get_name() -> String: return _name @@ -333,88 +288,79 @@ class GithubAssetSource: return [] -class GithubAssetSourceDefault: - extends GithubAssetSource +class GithubAssetSourceDefault extends GithubAssetSource: const url = "https://api.github.com/repos/godotengine/godot-builds/releases/tags/%s" - + func async_load(version: String, release: String) -> Array[GodotAsset]: var tag := "%s-%s" % [version, release] var response := await HttpClient.async_http_get( - url % tag, ["Accept: application/vnd.github.v3+json"] + url % tag, + ["Accept: application/vnd.github.v3+json"] ) var json: Dictionary = JSON.parse_string( (response[3] as PackedByteArray).get_string_from_utf8() ) var result: Array[GodotAsset] = [] - for asset_json: Dictionary in json.get("assets", []): + for asset_json: Dictionary in json.get('assets', []): result.append(GodotAsset.new(asset_json)) return result -class GithubAssetSourceFileJson: - extends GithubAssetSource +class GithubAssetSourceFileJson extends GithubAssetSource: var _file_path: String - + func _init(file_path: String) -> void: _file_path = file_path - + func async_load(version: String, release: String) -> Array[GodotAsset]: - var json: Dictionary = JSON.parse_string( - FileAccess.open(_file_path, FileAccess.READ).get_as_text() - ) + var json: Dictionary = JSON.parse_string(FileAccess.open(_file_path, FileAccess.READ).get_as_text()) var result: Array[GodotAsset] = [] - for asset_json: Dictionary in json.get("assets", []): + for asset_json: Dictionary in json.get('assets', []): result.append(GodotAsset.new(asset_json)) return result -class GithubVersionSourceFileJson: - extends GithubVersionSource +class GithubVersionSourceFileJson extends GithubVersionSource: var _file_path: String var _assets_src: GithubAssetSource - + func _init(file_path: String, assets_src: GithubAssetSource) -> void: _file_path = file_path _assets_src = assets_src - + func async_load() -> Array[GithubVersion]: - var json: Array = JSON.parse_string( - FileAccess.open(_file_path, FileAccess.READ).get_as_text() - ) + var json: Array = JSON.parse_string(FileAccess.open(_file_path, FileAccess.READ).get_as_text()) var result: Array[GithubVersion] = [] for el: Dictionary in json: var version := GithubVersion.new() version._assets_src = _assets_src version.name = el.name version.flavor = el.flavor - for release: Dictionary in el.get("releases", []): + for release: Dictionary in el.get('releases', []): version.releases.append(release.name) result.append(version) return result class YmlSource: - func async_load(errors: Array[String] = []) -> String: + func async_load(errors: Array[String]=[]) -> String: return "" -class YmlSourceFile: - extends YmlSource +class YmlSourceFile extends YmlSource: var _file_path: String - + func _init(file_path: String) -> void: _file_path = file_path - - func async_load(errors: Array[String] = []) -> String: - var text := FileAccess.open(_file_path, FileAccess.READ).get_as_text() + + func async_load(errors: Array[String]=[]) -> String: + var text := FileAccess.open(_file_path, FileAccess.READ).get_as_text() return text -class YmlSourceGithub: - extends YmlSource +class YmlSourceGithub extends YmlSource: const url = "https://raw.githubusercontent.com/godotengine/godot-website/master/_data/versions.yml" - - func async_load(errors: Array[String] = []) -> String: + func async_load(errors: Array[String]=[]) -> String: var response := HttpClient.Response.new(await HttpClient.async_http_get(url)) var info := response.to_response_info(url) if info.error_text: @@ -423,21 +369,19 @@ class YmlSourceGithub: return text -class GithubVersionSourceParseYml: - extends GithubVersionSource +class GithubVersionSourceParseYml extends GithubVersionSource: var _src: YmlSource var _assets_src: GithubAssetSource - - var _version_regex := RegEx.create_from_string("(?m)^-[\\s\\S]*?(?=^-|\\Z)") + + var _version_regex := RegEx.create_from_string('(?m)^-[\\s\\S]*?(?=^-|\\Z)') var _name_regex := RegEx.create_from_string('(?m)\\sname:\\s"(?[^"]+)"$') var _flavor_regex := RegEx.create_from_string('(?m)\\sflavor:\\s"(?[^"]+)"$') - + func _init(src: YmlSource, assets_src: GithubAssetSource) -> void: _src = src _assets_src = assets_src - + func async_load() -> Array[GithubVersion]: - @warning_ignore("redundant_await") var yml := await _src.async_load() var result: Array[GithubVersion] = [] var versions := _version_regex.search_all(yml) diff --git a/src/components/godots_releases/godots_releases.gd b/src/components/godots_releases/godots_releases.gd index 6c61efd9..b6cbc7cf 100644 --- a/src/components/godots_releases/godots_releases.gd +++ b/src/components/godots_releases/godots_releases.gd @@ -14,23 +14,27 @@ var _fetching := false func init( - releases: GodotsReleases.I, godots_downloads: GodotsDownloads.I, godots_install: GodotsInstall.I + releases: GodotsReleases.I, + godots_downloads: GodotsDownloads.I, + godots_install: GodotsInstall.I ) -> void: self._releases = releases self._godots_install = godots_install self._godots_downloads = godots_downloads - + if visible: _async_refetch_data() func _ready() -> void: _godots_releases_list.set_search_box_text("tag:newest") - _refresh_button.pressed.connect(func() -> void: _async_refetch_data()) - + _refresh_button.pressed.connect(func() -> void: + _async_refetch_data() + ) + _star_git_hub.icon = get_theme_icon("Favorites", "EditorIcons") - _star_git_hub.pressed.connect( - func() -> void: OS.shell_open("https://github.com/MakovWait/godots") + _star_git_hub.pressed.connect(func() -> void: + OS.shell_open("https://github.com/MakovWait/godots") ) @@ -39,16 +43,15 @@ func _async_refetch_data() -> void: return _fetching = true _refresh_button.disabled = true - + _async_refetch_data_body() - + _data_loaded = true _fetching = false _refresh_button.disabled = false func _async_refetch_data_body() -> void: - @warning_ignore("redundant_await") await _releases.async_load() _godots_releases_list.refresh(_releases.all()) @@ -59,7 +62,8 @@ func _on_godots_releases_list_item_selected(item: GodotsReleasesListItemControl) func _on_godots_releases_list_download_and_install_requested(url: String) -> void: _godots_downloads.download( - url, func(abs_zip_path: String) -> void: _godots_install.install(abs_zip_path) + url, + func(abs_zip_path: String) -> void: _godots_install.install(abs_zip_path) ) diff --git a/src/components/projects/new_project_dialog/new_project_dialog.gd b/src/components/projects/new_project_dialog/new_project_dialog.gd index fadb08d1..7d3ec309 100644 --- a/src/components/projects/new_project_dialog/new_project_dialog.gd +++ b/src/components/projects/new_project_dialog/new_project_dialog.gd @@ -1,7 +1,6 @@ class_name NewProjectDialog extends "res://src/components/projects/install_project_dialog/install_project_dialog.gd" -@warning_ignore("unused_signal") signal created(path: String) @onready var _handler_option_button: OptionButton = %HandlerOptionButton @@ -10,15 +9,15 @@ signal created(path: String) func _ready() -> void: super._ready() - + _handler_option_button.item_selected.connect(func(idx: int) -> void: var meta: Dictionary = _handler_option_button.get_item_metadata(idx) _custom_form_tabs.current_tab = _custom_form_tabs.get_tab_idx_from_control(meta.form as Control) ) - + _register_handler(NewProjectGodot4.new()) _register_handler(NewProjectGodot3.new()) - + confirmed.connect(func() -> void: var meta: Dictionary = _handler_option_button.get_item_metadata(_handler_option_button.selected) var handler := meta.self as NewProjectHandler @@ -34,7 +33,7 @@ func _register_handler(handler: NewProjectHandler) -> void: var handler_form := handler.custom_form() handler_form.name = handler.label() _custom_form_tabs.add_child(handler_form) - + _handler_option_button.add_item(handler.label()) _handler_option_button.set_item_metadata( _handler_option_button.item_count - 1, @@ -47,17 +46,17 @@ func _register_handler(handler: NewProjectHandler) -> void: class NewProjectContext: var _ctx_delegate: Object - + var dir: String var project_name: String var form: Control - + func _init(ctx_delegate: Object) -> void: _ctx_delegate = ctx_delegate - + func show_error(msg: String) -> void: _ctx_delegate.call("_error", msg) - + func emit_created(path: String) -> void: _ctx_delegate.emit_signal("created", path) @@ -65,10 +64,10 @@ class NewProjectContext: class NewProjectHandler: func custom_form() -> Control: return Control.new() - - func create_project(args: NewProjectContext) -> void: + + func create_project(args: NewProjectContext) -> void: pass - + func label() -> String: return "" @@ -76,7 +75,7 @@ class NewProjectHandler: class NewProjectGodot3 extends NewProjectHandler: func custom_form() -> Control: return NewProjectGodot3Form.new() - + func create_project(ctx: NewProjectContext) -> void: var dir := ctx.dir var project_file_path := dir.path_join("project.godot") @@ -96,14 +95,14 @@ class NewProjectGodot3 extends NewProjectHandler: var img: Texture2D = preload("res://assets/default_project_icon.svg") img.get_image().save_png(dir.path_join("icon.png")) ctx.emit_created(project_file_path) - + func label() -> String: return "Godot 3.x" class NewProjectGodot3Form extends VBoxContainer: var _renderer: RendererSelect - + func _init() -> void: _renderer = RendererSelect.new({ "GLES3": { @@ -126,9 +125,9 @@ class NewProjectGodot3Form extends VBoxContainer: ]), }, }) - + add_child(_renderer) - + Comp.new(Label).on_init([ CompInit.TEXT(tr("The renderer can be changed later, but scenes may need to be adjusted.")), CompInit.CUSTOM(func(label: Label) -> void: @@ -139,7 +138,7 @@ class NewProjectGodot3Form extends VBoxContainer: pass\ ) ]).add_to(self) - + func renderer_method() -> String: return _renderer.current() @@ -157,7 +156,7 @@ class NewProjectGodot4 extends NewProjectHandler: var initial_settings := ConfigFile.new() initial_settings.set_value("application", "config/name", ctx.project_name) initial_settings.set_value("application", "config/icon", "res://icon.svg") - + # rendering initial_settings.set_value("rendering", "renderer/rendering_method", form.renderer_method()) if form.renderer_method() == "gl_compatibility": @@ -180,7 +179,7 @@ class NewProjectGodot4 extends NewProjectHandler: else: ctx.show_error(tr("Couldn't create .gitignore in project path.")) return - + var gitattributes := FileAccess.open(dir.path_join(".gitattributes"), FileAccess.WRITE) if gitattributes != null: gitattributes.store_line("# Normalize EOL for all files that Git considers text files.") @@ -196,7 +195,7 @@ class NewProjectGodot4 extends NewProjectHandler: file_to.close() ctx.emit_created(project_file_path) - + func label() -> String: return "Godot 4.x" @@ -239,9 +238,9 @@ class NewProjectGodot4Form extends VBoxContainer: ]), } }) - + add_child(_renderer) - + Comp.new(Label).on_init([ CompInit.TEXT(tr("The renderer can be changed later, but scenes may need to be adjusted.")), CompInit.CUSTOM(func(label: Label) -> void: @@ -252,34 +251,34 @@ class NewProjectGodot4Form extends VBoxContainer: pass\ ) ]).add_to(self) - + _vcs_meta = VersionControlMetadata.new() add_child(_vcs_meta) - + func renderer_method() -> String: return _renderer.current() - + func vsc_meta() -> String: return _vcs_meta.current() class VersionControlMetadata extends HBoxContainer: var _options: OptionButton - + func _init() -> void: var label := Label.new() label.text = tr("Version Control Metadata:") - + _options = OptionButton.new() _options.add_item("Git") _options.set_item_metadata(_options.item_count - 1, "git") - + _options.add_item("None") _options.set_item_metadata(_options.item_count - 1, "none") - + add_child(label) add_child(_options) - + func current() -> String: return _options.get_item_metadata(_options.selected) as String @@ -287,7 +286,7 @@ class VersionControlMetadata extends HBoxContainer: class RendererSelect extends VBoxContainer: var _button_group := ButtonGroup.new() - + func _init(options: Dictionary) -> void: var renderer_desc_label := CompRefs.Simple.new() @@ -318,13 +317,13 @@ class RendererSelect extends VBoxContainer: Comp.new(Label).on_init([ CompInit.TEXT(tr("Renderer:")) ]), - + Comp.new(HBoxContainer, [ # checkboxes Comp.new(VBoxContainer, checkboxes), - + Comp.new(VSeparator), - + # checkbox desc Comp.new(VBoxContainer, [ Comp.new(Label).on_init([ @@ -338,6 +337,6 @@ class RendererSelect extends VBoxContainer: ]), ]), ]).add_to(self) - + func current() -> String: return _button_group.get_pressed_button().get_meta("rendering_method") diff --git a/src/components/projects/project_item/project_item.gd b/src/components/projects/project_item/project_item.gd index c4b8738d..c2c84609 100644 --- a/src/components/projects/project_item/project_item.gd +++ b/src/components/projects/project_item/project_item.gd @@ -20,9 +20,9 @@ signal tag_clicked(tag: String) @onready var _tag_container: ItemTagContainer = %TagContainer @onready var _project_features: Label = %ProjectFeatures @onready var _info_body: VBoxContainer = %InfoBody -#@onready var _info_v_box: VBoxContainer = %InfoVBox +@onready var _info_v_box: VBoxContainer = %InfoVBox @onready var _actions_h_box: HBoxContainer = %ActionsHBox -#@onready var _title_container: HBoxContainer = %TitleContainer +@onready var _title_container: HBoxContainer = %TitleContainer @onready var _actions_container: HBoxContainer = %ActionsContainer static var settings := ProjectItemActions.Settings.new( @@ -56,10 +56,10 @@ func init(item: Projects.Item) -> void: item.loaded.connect(func() -> void: _fill_data(item) ) - + _editor_button.pressed.connect(_on_rebind_editor.bind(item)) _editor_button.disabled = item.is_missing - + item.internals_changed.connect(func() -> void: _fill_data(item) ) @@ -74,7 +74,7 @@ func init(item: Projects.Item) -> void: double_clicked.connect(func() -> void: if item.is_missing: return - + if item.has_invalid_editor: _on_rebind_editor(item) else: @@ -84,8 +84,8 @@ func init(item: Projects.Item) -> void: func _setup_actions_view(item: Projects.Item) -> void: var action_views := ProjectItemActions.Menu.new( - _actions.without(['view-command']).all(), - settings, + _actions.without(['view-command']).all(), + settings, CustomCommandsPopupItems.Self.new( _actions.by_key('view-command'), _get_commands(item) @@ -145,11 +145,11 @@ func _fill_actions(item: Projects.Item) -> void: "act": _on_edit_with_editor.bind(item), "label": tr("Edit"), }) - + var run := Action.from_dict({ "key": "run", "icon": Action.IconTheme.new(self, "Play", "EditorIcons"), - "act": _on_run_with_editor.bind(item, func(_item: Projects.Item) -> void: _item.run(), "run", "Run", false), + "act": _on_run_with_editor.bind(item, func(item: Projects.Item) -> void: item.run(), "run", "Run", false), "label": tr("Run"), }) @@ -180,14 +180,14 @@ func _fill_actions(item: Projects.Item) -> void: "act": func() -> void: manage_tags_requested.emit(), "label": tr("Manage Tags"), }) - + var view_command := Action.from_dict({ "key": "view-command", "icon": Action.IconTheme.new(self, "Edit", "EditorIcons"), "act": _view_command.bind(item), "label": tr("Edit Commands"), }) - + var remove := Action.from_dict({ "key": "remove", "icon": Action.IconTheme.new(self, "Remove", "EditorIcons"), @@ -219,7 +219,7 @@ func _fill_data(item: Projects.Item) -> void: if item.is_missing: _explore_button.icon = get_theme_icon("FileBroken", "EditorIcons") modulate = Color(1, 1, 1, 0.498) - + _project_warning.visible = item.has_invalid_editor _favorite_button.button_pressed = item.favorite _title_label.text = item.name @@ -229,13 +229,13 @@ func _fill_data(item: Projects.Item) -> void: _tag_container.set_tags(item.tags) _set_features(item.features) _tags = item.tags - + _sort_data.favorite = item.favorite _sort_data.name = item.name _sort_data.path = item.path _sort_data.last_modified = item.last_modified _sort_data.tag_sort_string = "".join(item.tags) - + for action in _actions.sub_list([ 'duplicate', 'bind-editor', @@ -243,7 +243,7 @@ func _fill_data(item: Projects.Item) -> void: 'rename' ]).all(): action.disable(item.is_missing) - + for action in _actions.sub_list([ 'view-command', 'edit', @@ -284,8 +284,8 @@ func _get_commands(item: Projects.Item) -> CommandViewer.Commands: func _set_features(features: Array) -> void: var features_to_print := features.filter(func(x: String) -> bool: return _is_version(x) or x == "C#") if len(features_to_print) > 0: - var string := ", ".join(features_to_print) - _project_features.text = string + var str := ", ".join(features_to_print) + _project_features.text = str # _project_features.custom_minimum_size = Vector2(25 * 15, 10) * Config.EDSCALE if settings.is_show_features(): _project_features.show() @@ -299,37 +299,37 @@ func _is_version(feature: String) -> bool: func _on_rebind_editor(item: Projects.Item) -> void: var bind_dialog := ConfirmationDialogAutoFree.new() - + var vbox := VBoxContainer.new() bind_dialog.add_child(vbox) - + var hbox := HBoxContainer.new() vbox.add_child(hbox) - + var title := Label.new() hbox.add_child(title) - + var options := OptionButton.new() hbox.add_child(options) - + if item.has_version_hint: var hbox2 := HBoxContainer.new() hbox2.modulate = Color(0.5, 0.5, 0.5, 0.5) hbox2.alignment = BoxContainer.ALIGNMENT_CENTER vbox.add_child(hbox2) - + var version_hint_title := Label.new() version_hint_title.text = tr("version hint:") hbox2.add_child(version_hint_title) - + var version_hint_value := Label.new() version_hint_value.text = item.version_hint hbox2.add_child(version_hint_value) - + vbox.add_spacer(false) - + title.text = "%s: " % tr("Editor") - + options.item_selected.connect(func(idx: int) -> void: bind_dialog.get_ok_button().disabled = false ) @@ -339,14 +339,14 @@ func _on_rebind_editor(item: Projects.Item) -> void: var opt: Dictionary = option_items[i] options.add_item(opt.label as String, i) options.set_item_metadata(i, opt.path) - + bind_dialog.confirmed.connect(func() -> void: if options.selected < 0: return var new_editor_path := options.get_item_metadata(options.selected) as String item.editor_path = new_editor_path edited.emit() ) - + add_child(bind_dialog) bind_dialog.popup_centered() @@ -364,36 +364,36 @@ func _on_rename(item: Projects.Item) -> void: func _on_edit_with_editor(item: Projects.Item) -> void: - _on_run_with_editor(item, func(_item: Projects.Item) -> void: _item.edit(), "edit", "Edit", true) + _on_run_with_editor(item, func(item: Projects.Item) -> void: item.edit(), "edit", "Edit", true) func _on_run_with_editor(item: Projects.Item, editor_flag: Callable, action_name: String, ok_button_text: String, auto_close: bool) -> void: if not item.show_edit_warning: _run_with_editor(item, editor_flag, auto_close) return - + var confirmation_dialog := ConfirmationDialogAutoFree.new() confirmation_dialog.ok_button_text = ok_button_text confirmation_dialog.get_label().hide() - + var label := Label.new() label.text = tr("Are you sure to %s the project with the given editor?") % action_name - + var editor_name := Label.new() editor_name.text = item.editor_name editor_name.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - + var checkbox := CheckBox.new() checkbox.text = tr("do not show again for this project") - + var vb := VBoxContainer.new() vb.add_child(label) vb.add_child(editor_name) vb.add_child(checkbox) vb.add_spacer(false) - + confirmation_dialog.add_child(vb) - + confirmation_dialog.confirmed.connect(func() -> void: var before := item.show_edit_warning item.show_edit_warning = not checkbox.button_pressed diff --git a/src/components/projects/projects.gd b/src/components/projects/projects.gd index 1f7cab34..b1774530 100644 --- a/src/components/projects/projects.gd +++ b/src/components/projects/projects.gd @@ -14,16 +14,16 @@ signal manage_tags_requested(item_tags: Array, all_tags: Array, on_confirm: Call var _projects: Projects.List -#var _load_projects_queue := [] +var _load_projects_queue := [] var _remove_missing_action: Action.Self func init(projects: Projects.List) -> void: self._projects = projects - + var remove_missing_popup := RemoveMissingDialog.new(_remove_missing) add_child(remove_missing_popup) - + var actions := Action.List.new([ Action.from_dict({ "key": "new-project", @@ -67,7 +67,7 @@ func init(projects: Projects.List) -> void: "act": _refresh }) ]) - + _remove_missing_action = actions.by_key('remove-missing') var project_actions := TabActions.Menu.new( @@ -76,9 +76,9 @@ func init(projects: Projects.List) -> void: 'import-project', 'clone-project', 'scan-projects', - ]).all(), + ]).all(), TabActions.Settings.new( - Cache.section_of(self), + Cache.section_of(self), [ 'new-project', 'import-project', @@ -106,34 +106,34 @@ func init(projects: Projects.List) -> void: project.load() _projects_list.add(project) _projects.save() - + if edit: project.edit() AutoClose.close_if_should() - + if callback: (callback as Callable).call(project, projects) - + _projects_list.sort_items() ) - + _clone_project_dialog.cloned.connect(func(path: String) -> void: assert(path.get_file() == "project.godot") import(path) ) - + _new_project_dialog.created.connect(func(project_path: String) -> void: import(project_path) ) - + _scan_dialog.dir_to_scan_selected.connect(func(dir_to_scan: String) -> void: _scan_projects(dir_to_scan) ) - + _duplicate_project_dialog.duplicated.connect(func(project_path: String, callback: Callable) -> void: import(project_path, callback) ) - + _projects_list.refresh(_projects.all()) _load_projects() @@ -182,7 +182,7 @@ func install_zip(zip_reader: ZIPReader, project_name: String) -> void: if len(project_configs) == 0: _install_project_from_zip_dialog.error(tr("No project.godot found.")) return - + var project_file_path := project_configs[0] _install_project_from_zip_dialog.hide() import(project_file_path.path) @@ -255,5 +255,5 @@ func _on_projects_list_item_manage_tags_requested(item_data: Projects.Item) -> v func _on_projects_list_item_duplicate_requested(project: Projects.Item) -> void: if _duplicate_project_dialog.visible: return - + _duplicate_project_dialog.raise(project.name, project) diff --git a/src/components/projects/projects_list/projects_list.gd b/src/components/projects/projects_list/projects_list.gd index 069a85e2..80829c7f 100644 --- a/src/components/projects/projects_list/projects_list.gd +++ b/src/components/projects/projects_list/projects_list.gd @@ -34,6 +34,7 @@ func _item_comparator(a: Dictionary, b: Dictionary) -> bool: 2: return a.path < b.path 3: return a.tag_sort_string < b.tag_sort_string _: return a.name < b.name + return a.name < b.name func _fill_sort_options(btn: OptionButton) -> void: @@ -41,7 +42,7 @@ func _fill_sort_options(btn: OptionButton) -> void: btn.add_item(tr("Name")) btn.add_item(tr("Path")) btn.add_item(tr("Tags")) - + var last_checked_sort := Cache.smart_value(self, "last_checked_sort", true) btn.select(last_checked_sort.ret(1) as int) btn.item_selected.connect(func(idx: int) -> void: last_checked_sort.put(idx)) diff --git a/src/components/settings/settings_window.gd b/src/components/settings/settings_window.gd index c27f00d8..9a0097e0 100644 --- a/src/components/settings/settings_window.gd +++ b/src/components/settings/settings_window.gd @@ -34,24 +34,24 @@ func _prepare_settings() -> Array: Config.USE_SYSTEM_TITLE_BAR, SettingCheckbox ))), func() -> bool: return DisplayServer.has_feature(DisplayServer.FEATURE_EXTEND_TO_TITLE)), - + SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/config/use_native_file_dialog", Config.USE_NATIVE_FILE_DIALOG, SettingCheckbox ))), - + SettingChangeObserved(SettingCfg( "application/config/remember_window_rect", Config.REMEMBER_WINDOW_SIZE, SettingCheckbox, tr("Restore last window size and position on startup.") )), - + SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/preset", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/preset" ).bake_default("Default"), @@ -61,18 +61,18 @@ func _prepare_settings() -> Array: SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/base_color", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/base_color" ).bake_default(Color(0.21, 0.24, 0.29)), SettingColorPicker, tr("Base color for the theme. Affects the background and primary UI elements.") )))), - + SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/accent_color", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/accent_color" ).bake_default(Color(0.44, 0.73, 0.98)), @@ -83,7 +83,7 @@ func _prepare_settings() -> Array: SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/contrast", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/contrast" ).bake_default(0.3), @@ -152,9 +152,9 @@ func _init() -> void: (%WarningRect as Button).icon = get_theme_icon("StatusWarning", "EditorIcons") (%WarningRect as Button).self_modulate = get_theme_color("warning_color", "Editor") * Color(1, 1, 1, 0.6) (%RestartInfoLabel as Label).self_modulate = get_theme_color("warning_color", "Editor") * Color(1, 1, 1, 0.6) - + (%OpenConfigFileButton as Button).icon = get_theme_icon("Load", "EditorIcons") - + var sections_root := (%SectionsTree as Tree).get_root() if sections_root: for child in sections_root.get_children(): @@ -169,7 +169,7 @@ func _ready() -> void: Config.save() ) - var title_text := tr("Settings") + var title_text := tr("Settings") var set_title_text := func(pattern: String) -> void: title = pattern % title_text title = title_text @@ -179,19 +179,19 @@ func _ready() -> void: Config.saved.connect(func() -> void: set_title_text.call("%s") ) - + get_ok_button().text = tr("Save & Close") - - + + var left_vb := %LeftVB as VBoxContainer left_vb.custom_minimum_size = Vector2(190, 0) * Config.EDSCALE - - + + var right_vb: = %RightVB as VBoxContainer right_vb.custom_minimum_size = Vector2(300, 0) * Config.EDSCALE right_vb.size_flags_horizontal = Control.SIZE_EXPAND_FILL - - + + (%RestartInfoLabel as Label).text = tr("Godots must be restarted for changes to take effect.") (%RestartButton as Button).pressed.connect(func() -> void: Config.save() @@ -205,12 +205,12 @@ func _ready() -> void: (%RestartContainer as PanelContainer).hide() ) (%RestartContainer as Control).hide() - + (%OpenConfigFileButton as Button).pressed.connect(func() -> void: var config_path := ProjectSettings.globalize_path(Config.APP_CONFIG_PATH.get_base_dir()) OS.shell_show_in_file_manager(config_path) ) - + _setup_settings() @@ -223,17 +223,17 @@ func raise_settings() -> void: func _setup_settings() -> void: var settings := _prepare_settings().filter(func(x: Variant) -> bool: return x != null) - + for setting: Setting in settings: setting.bind_settings_window(self) setting.validate() setting.add_control(SettingControlTarget.new(%InspectorVBox, setting.category.raw)) - + var tree := %SectionsTree as Tree tree.item_selected.connect(func() -> void: - var _selected := tree.get_selected() - if _selected: - var section: Variant = _selected.get_metadata(0) + var selected := tree.get_selected() + if selected: + var section: Variant = selected.get_metadata(0) if section is String: _update_settings_visibility(section as String) ) @@ -245,7 +245,7 @@ func _setup_settings() -> void: if not category.first_lvl in categories: categories[category.first_lvl] = Set.new() var second_lvls := categories[category.first_lvl] as Set - second_lvls.append(category.second_lvl) + second_lvls.append(category.second_lvl) var selected := false for first_lvl: String in categories.keys(): var first_lvl_item := tree.create_item(root) @@ -269,10 +269,10 @@ func _update_settings_visibility(section: String) -> void: func SettingCfg(category: String, cfg_value: ConfigFileValue, prop_factory: Variant, tooltip:="") -> Setting: if prop_factory is Script: - prop_factory = func(a1: Variant, a2: Variant, a3: Variant, a4: Variant) -> Setting: + prop_factory = func(a1: Variant, a2: Variant, a3: Variant, a4: Variant) -> Setting: return (prop_factory as Script).call("new", a1, a2, a3, a4) return ((prop_factory as Callable).call( - category, + category, cfg_value.ret(), tooltip, cfg_value.get_baked_default() @@ -281,7 +281,7 @@ func SettingCfg(category: String, cfg_value: ConfigFileValue, prop_factory: Vari func SettingChangeObserved(origin: Setting) -> Setting: return origin.on_value_changed( - func(new_value: Variant) -> void: + func(new_value: Variant) -> void: _setting_changed.emit(origin, new_value) _settings_changed.emit() ) @@ -304,25 +304,25 @@ func SettingCustomPresetTrigger(origin: Setting) -> Setting: class Category: var _category: String - + var name: String: get: return _category.get_file().capitalize() - + var first_lvl: String: get: return _category.split("/")[0] - + var second_lvl: String: get: return _category.split("/")[1] - + var raw: String: get: return _category - + func _init(category: String) -> void: _category = category - + func validate() -> void: assert( - len(_category.split("/")) == 3, + len(_category.split("/")) == 3, "Invalid category %s! Category format is: s/s/s" % _category ) @@ -330,11 +330,11 @@ class Category: class SettingControlTarget: var _target: Node var _category: String - + func _init(target: Node, category: String) -> void: _target = target _category = category - + func add_child(child: Node) -> void: child.set_meta("category", _category) _target.add_child(child) @@ -342,50 +342,50 @@ class SettingControlTarget: class Setting extends RefCounted: signal changed(new_value: Variant) - + var category: Category var _value: Variant var _tooltip: String var _default_value: Variant var _settings_window: SettingsWindow - + func _init(name: String, value: Variant, tooltip: String, default_value: Variant) -> void: self.category = Category.new(name) self._value = value self._tooltip = tooltip self._default_value = default_value - + func add_control(target: SettingControlTarget) -> void: pass - + func on_value_changed(callback: Callable) -> Setting: changed.connect(callback) return self - + func notify_changed() -> void: changed.emit(_value) - + func set_value(value: Variant) -> void: _value = value - + func set_value_and_notify(value: Variant) -> void: set_value(value) notify_changed() - + func validate() -> void: category.validate() assert(_settings_window != null) - + func reset() -> void: set_value_and_notify(_default_value) - + func value_is_not_default() -> bool: return _value != _default_value - + func bind_settings_window(settings_window: SettingsWindow) -> Setting: _settings_window = settings_window return self - + func with_meta(name: StringName, value: Variant) -> Setting: self.set_meta(name, value) return self @@ -462,7 +462,7 @@ class SettingFilePath extends Setting: func add_control(target: SettingControlTarget) -> void: var file_dialog := CompRefs.Simple.new() var line_edit := CompRefs.Simple.new() - var update_value := func(new_value: String) -> void: + var update_value := func(new_value: String) -> void: set_value_and_notify(new_value) line_edit.value.text = new_value self.on_value_changed(func(new_value: String) -> void: @@ -491,8 +491,8 @@ class SettingFilePath extends Setting: CompInit.TREE_ENTERED( CompInit.SET_THEME_ICON("Load", "EditorIcons") ), - CompInit.PRESSED(func(_a: Control) -> void: - var dialog := file_dialog.value as FileDialog + CompInit.PRESSED(func(_a: Control) -> void: + var dialog := file_dialog.value as FileDialog dialog.current_dir = self._value dialog.popup_centered_ratio(0.5)\ ) @@ -596,12 +596,12 @@ class CompSettingPanelContainer extends Comp: class SettingOptionButton extends Setting: var _options: Dictionary var _fallback_option: String - + func _init(name: String, value: Variant, tooltip: String, default_value: Variant, options: Dictionary, fallback_option: String) -> void: super._init(name, value, tooltip, default_value) self._options = options self._fallback_option = fallback_option - + func add_control(target: SettingControlTarget) -> void: var update_selected_value := func(this: OptionButton) -> void: this.clear() @@ -613,11 +613,11 @@ class SettingOptionButton extends Setting: this.selected = item_idx item_to_select_was_found = true item_idx += 1 - + if not item_to_select_was_found: this.add_item(_fallback_option) this.selected = item_idx - + var control := Comp.new(HBoxContainer, [ CompSettingNameContainer.new(self), CompSettingPanelContainer.new(_tooltip, [ @@ -790,13 +790,13 @@ class SettingSlider extends Setting: this.step = 0.1 this.min_value = -1 this.max_value = 1 - + self.on_value_changed(func(new_value: Variant) -> void: this.value = new_value ) - + this.value = self._value - + this.value_changed.connect(func(new_value: Variant) -> void: self.set_value_and_notify(new_value) ) diff --git a/src/components/title_bar/title_bar.gd b/src/components/title_bar/title_bar.gd index ae677768..7f150b6c 100644 --- a/src/components/title_bar/title_bar.gd +++ b/src/components/title_bar/title_bar.gd @@ -3,7 +3,7 @@ extends Control @onready var _left_spacer := %LeftSpacer as Control @onready var _right_spacer := %RightSpacer as Control -#@onready var _gui_base := get_parent() +@onready var _gui_base := get_parent() @onready var _main_container := %MainContainer as HBoxContainer @onready var _buttons_container := %ButtonsContainer as HBoxContainer @@ -41,7 +41,7 @@ func _setup_title_label() -> void: var label := %TitleLabel as Label label.add_theme_font_override("font", get_theme_font("bold", "EditorFonts")) label.add_theme_font_size_override("font_size", get_theme_font_size("bold_size", "EditorFonts")) - + #label.set_text_overrun_behavior(TextServer.OVERRUN_TRIM_ELLIPSIS) #label.set_text_overrun_behavior(TextServer.OVERRUN_TRIM_ELLIPSIS) label.set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER) @@ -53,7 +53,7 @@ func _setup_title_label() -> void: func _gui_input(event: InputEvent) -> void: if not _can_move: return - + if event is InputEventMouseMotion and _moving: if (event as InputEventMouseMotion).button_mask & MOUSE_BUTTON_MASK_LEFT: var w := get_window() @@ -87,8 +87,8 @@ func _gui_input(event: InputEvent) -> void: func _resize() -> void: var buttons_offet := Vector2i( - int(self.global_position.y + (self.size.y / 2)), - int(self.global_position.y + (self.size.y / 2)) + self.global_position.y + (self.size.y / 2), + self.global_position.y + (self.size.y / 2) ) DisplayServer.window_set_window_buttons_offset( buttons_offet, @@ -97,13 +97,13 @@ func _resize() -> void: var margin := DisplayServer.window_get_safe_title_margins( DisplayServer.MAIN_WINDOW_ID ) - if _left_spacer: + if _left_spacer: var w := margin.y if self.is_layout_rtl() else margin.x _left_spacer.custom_minimum_size = Vector2(w, 0) - if _right_spacer: + if _right_spacer: var w := margin.x if self.is_layout_rtl() else margin.y _right_spacer.custom_minimum_size = Vector2(w, 0) self.custom_minimum_size = Vector2( - 0, + 0, maxf(margin.z - self.global_position.y, self.custom_minimum_size.y) ) diff --git a/src/extensions/zip.gd b/src/extensions/zip.gd index 6a1f83d5..d351356a 100644 --- a/src/extensions/zip.gd +++ b/src/extensions/zip.gd @@ -7,11 +7,11 @@ static func unzip(zip_path: String, target_dir: String) -> void: var exit_code: int if OS.has_feature("windows"): exit_code = OS.execute( - "powershell.exe", + "powershell.exe", [ "-command", - "\"Expand-Archive '%s' '%s'\" -Force" % [ - ProjectSettings.globalize_path(zip_path), + "\"Expand-Archive '%s' '%s'\" -Force" % [ + ProjectSettings.globalize_path(zip_path), ProjectSettings.globalize_path(target_dir) ] ], output, true @@ -20,10 +20,10 @@ static func unzip(zip_path: String, target_dir: String) -> void: Output.push("unzip executed with exit code: %s" % exit_code) elif OS.has_feature("macos"): exit_code = OS.execute( - "unzip", + "unzip", [ - "%s" % ProjectSettings.globalize_path(zip_path), - "-d", + "%s" % ProjectSettings.globalize_path(zip_path), + "-d", "%s" % ProjectSettings.globalize_path(target_dir) ], output, true ) @@ -34,7 +34,7 @@ static func unzip(zip_path: String, target_dir: String) -> void: "unzip", [ "-o", - "%s" % ProjectSettings.globalize_path(zip_path), + "%s" % ProjectSettings.globalize_path(zip_path), "-d", "%s" % ProjectSettings.globalize_path(target_dir) ], output, true @@ -45,8 +45,8 @@ static func unzip(zip_path: String, target_dir: String) -> void: ## A procedure that unzips a zip file to a target directory, keeping the ## target directory as root, rather than the zip's root directory. -static func unzip_to_path(_zip: ZIPReader, destiny: String) -> Error: - var files := _zip.get_files() +static func unzip_to_path(zip: ZIPReader, destiny: String) -> Error: + var files := zip.get_files() var err: int for zip_file_name in files: @@ -56,9 +56,9 @@ static func unzip_to_path(_zip: ZIPReader, destiny: String) -> Error: if zip_file_name.ends_with("/"): err = DirAccess.make_dir_recursive_absolute(target_file_name) if err != OK: - return (err as Error) + return err else: - var file_contents: PackedByteArray = _zip.read_file(zip_file_name) + var file_contents := zip.read_file(zip_file_name) var file := FileAccess.open(target_file_name, FileAccess.WRITE) if not file: return FileAccess.get_open_error() diff --git a/src/http_client.gd b/src/http_client.gd index 073982f7..d92ccd0e 100644 --- a/src/http_client.gd +++ b/src/http_client.gd @@ -32,10 +32,10 @@ func async_http_get_using(http_request: HTTPRequest, url: String, headers := Pac class Response: var _resp: Array - + var result: int: get: return _resp[0] - + var code: int: get: return _resp[1] @@ -47,20 +47,20 @@ class Response: func _init(resp: Array) -> void: _resp = resp - + func to_json(safe:=true) -> Variant: return utils.response_to_json(_resp, safe) - + func get_string_from_utf8() -> String: return body.get_string_from_utf8() - + func _to_string() -> String: return "[Response] Result: %s; Code: %s; Headers: %s" % [result, code, headers] - + func to_response_info(host: String, download_file:="") -> ResponseInfo: var error_text := "" var status := "" - + match result: HTTPRequest.RESULT_CHUNKED_BODY_SIZE_MISMATCH, HTTPRequest.RESULT_CONNECTION_ERROR, HTTPRequest.RESULT_BODY_SIZE_LIMIT_EXCEEDED: error_text = tr("Connection error, prease try again.") @@ -90,11 +90,11 @@ class Response: if code != 200: error_text = tr("Request failed, return code") + ": " + str(code) status = tr("Failed") + ": " + str(code) - - var _result := ResponseInfo.new() - _result.error_text = error_text - _result.status = status - return _result + + var result := ResponseInfo.new() + result.error_text = error_text + result.status = status + return result class ResponseInfo: diff --git a/src/main/gui/auto_updates.gd b/src/main/gui/auto_updates.gd index 27657c05..60198359 100644 --- a/src/main/gui/auto_updates.gd +++ b/src/main/gui/auto_updates.gd @@ -1,16 +1,22 @@ class_name AutoUpdates extends Node + @export var _notification_button: NotificationsButton var _godots_releases: GodotsRecentReleases.I var _check_lock := false -func init(godots_releases: GodotsRecentReleases.I, updates_click_callback: Callable) -> void: +func init( + godots_releases: GodotsRecentReleases.I, + updates_click_callback: Callable +) -> void: self._godots_releases = godots_releases _check_updates() - _notification_button.pressed.connect(func() -> void: updates_click_callback.call()) + _notification_button.pressed.connect(func() -> void: + updates_click_callback.call() + ) func _notification(what: int) -> void: @@ -19,7 +25,7 @@ func _notification(what: int) -> void: func _check_updates() -> void: - if _check_lock: + if _check_lock: return _check_lock = true await _async_check_updates() @@ -27,7 +33,6 @@ func _check_updates() -> void: func _async_check_updates() -> void: - @warning_ignore("redundant_await") var has_updates := await _godots_releases.async_has_updates() if has_updates: _notification_button.has_notifications = true diff --git a/src/main/gui/gui_main.gd b/src/main/gui/gui_main.gd index 8137b372..a7829c00 100644 --- a/src/main/gui/gui_main.gd +++ b/src/main/gui/gui_main.gd @@ -52,14 +52,14 @@ func _ready() -> void: else: zip_reader.close() _remote_editors.install_zip( - file, - file.get_file().replace(".zip", ""), + file, + file.get_file().replace(".zip", ""), utils.guess_editor_name(file.replace(".zip", "")) ) else: _local_editors.import(utils.guess_editor_name(file), file) ) - + _title_tabs.add_child(TitleTabButton.new("ProjectList", tr("Projects"), _tab_container, [_projects])) _title_tabs.add_child(TitleTabButton.new("AssetLib", tr("Asset Library"), _tab_container, [_asset_lib_projects])) _title_tabs.add_child(TitleTabButton.new("GodotMonochrome", tr("Editors"), _tab_container, [_local_editors, _remote_editors])) @@ -73,14 +73,14 @@ func _ready() -> void: _gui_base.set_anchor(SIDE_RIGHT, Control.ANCHOR_END) _gui_base.set_anchor(SIDE_BOTTOM, Control.ANCHOR_END) _gui_base.set_end(Vector2.ZERO) - + _main_v_box.set_anchors_and_offsets_preset( - Control.PRESET_FULL_RECT, - Control.PRESET_MODE_MINSIZE, + Control.PRESET_FULL_RECT, + Control.PRESET_MODE_MINSIZE, get_theme_constant("window_border_margin", "Editor") ) _main_v_box.add_theme_constant_override( - "separation", + "separation", get_theme_constant("top_bar_separation", "Editor") ) @@ -105,12 +105,12 @@ func _ready() -> void: _tab_container.current_tab = _tab_container.get_tab_idx_from_control(_updates) ) _version_button.tooltip_text = tr("Click to see other versions.") - + var news_buttons := %NewsButton as LinkButton news_buttons.self_modulate = Color(1, 1, 1, 0.6) news_buttons.underline = LinkButton.UNDERLINE_MODE_ON_HOVER news_buttons.tooltip_text = tr("Click to see the post.") - + _settings_button.flat = true #_settings_button.text = tr("Settings") _settings_button.text = "" @@ -122,7 +122,7 @@ func _ready() -> void: _settings_button.pressed.connect(func() -> void: ($Settings as SettingsWindow).raise_settings() ) - + _local_editors_service.load() _projects_service.load() @@ -135,7 +135,7 @@ func _ready() -> void: _setup_godots_releases() _setup_asset_lib_projects() - + Context.add(self, %CommandViewer) @@ -151,22 +151,22 @@ func _notification(what: int) -> void: func _enter_tree() -> void: theme_source.set_scale(Config.EDSCALE) theme = theme_source.create_custom_theme(null) - + var window := get_window() window.min_size = Vector2(520, 370) * Config.EDSCALE - + var scale_factor := maxf(1, Config.EDSCALE * 0.75) if scale_factor > 1: var window_size := DisplayServer.window_get_size() var screen_rect := DisplayServer.screen_get_usable_rect(DisplayServer.window_get_current_screen()) - + window_size *= scale_factor - + DisplayServer.window_set_size(window_size) if screen_rect.size != Vector2i(): var window_position := Vector2i( - int(screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2.0), - int(screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2.0) + screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2, + screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2 ) DisplayServer.window_set_position(window_position) @@ -179,13 +179,13 @@ func _enter_tree() -> void: if DisplayServer.get_screen_from_rect(rect) != -1: window.size = rect.size window.position = rect.position - + _local_remote_switch_context = LocalRemoteEditorsSwitchContext.new( _local_editors, _remote_editors, _tab_container ) - + _local_editors_service = LocalEditors.List.new( Config.EDITORS_CONFIG_PATH ) @@ -194,15 +194,15 @@ func _enter_tree() -> void: _local_editors_service, preload("res://assets/default_project_icon.svg") ) - + Context.add(self, _local_remote_switch_context) Context.add(self, _local_editors_service) Context.add(self, _projects_service) - + _on_exit_tree_callbacks.append(func() -> void: _local_editors_service.cleanup() _projects_service.cleanup() - + Context.erase(self, _local_editors_service) Context.erase(self, _projects_service) Context.erase(self, _local_remote_switch_context) @@ -228,21 +228,21 @@ func _setup_asset_lib_projects() -> void: RemoteEditorsTreeDataSourceGithub.YmlSourceGithub.new() ) # var version_src = GodotVersionOptionButton.SrcMock.new(["4.1"]) - + var request := HTTPRequest.new() add_child(request) var asset_lib_factory := AssetLib.FactoryDefault.new(request) - + var category_src := AssetCategoryOptionButton.SrcRemote.new() - + _asset_lib_projects.download_requested.connect(func(item: AssetLib.Item, icon: Texture2D) -> void: var asset_download := _asset_download.instantiate() as AssetDownload (%DownloadsContainer as DownloadsContainer).add_download_item(asset_download) if icon != null: asset_download.icon.texture = icon asset_download.start( - item.download_url, - (Config.DOWNLOADS_PATH.ret() as String) + "/", + item.download_url, + (Config.DOWNLOADS_PATH.ret() as String) + "/", "project.zip", item.title ) @@ -266,7 +266,7 @@ func _setup_asset_lib_projects() -> void: ) ) ) - + _asset_lib_projects.init( asset_lib_factory, category_src, @@ -296,8 +296,8 @@ func _setup_godots_releases() -> void: _auto_updates.init( GodotsRecentReleases.Cached.new( GodotsRecentReleases.Default.new(godots_releases) - ), - func() -> void: + ), + func() -> void: _tab_container.current_tab = _tab_container.get_tab_idx_from_control(_godots_releases) ) _godots_releases.init( @@ -309,7 +309,7 @@ func _setup_godots_releases() -> void: class TitleTabButton extends Button: var _icon_name: String - + func _init(icon: String, text: String, tab_container: TabContainer, tab_controls: Array) -> void: _icon_name = icon self.text = text @@ -322,24 +322,24 @@ class TitleTabButton extends Button: ) tab_container.tab_changed.connect(func(idx: int) -> void: set_pressed_no_signal( - tab_controls.any(func(tab_control: Control) -> bool: + tab_controls.any(func(tab_control: Control) -> bool: return tab_container.get_tab_idx_from_control(tab_control) == idx\ ) ) ) toggle_mode = true focus_mode = Control.FOCUS_NONE - + self.ready.connect(func() -> void: set_pressed_no_signal( - tab_controls.any(func(tab_control: Control) -> bool: + tab_controls.any(func(tab_control: Control) -> bool: return tab_container.get_tab_idx_from_control(tab_control) == tab_container.current_tab\ ) ) add_theme_font_override("font", get_theme_font("main_button_font", "EditorFonts")) add_theme_font_size_override("font_size", get_theme_font_size("main_button_font_size", "EditorFonts")) ) - + func _notification(what: int) -> void: if what == NOTIFICATION_THEME_CHANGED: if _icon_name: diff --git a/src/objects/node_component/comp_scene.gd b/src/objects/node_component/comp_scene.gd index e8d8766d..d28444c1 100644 --- a/src/objects/node_component/comp_scene.gd +++ b/src/objects/node_component/comp_scene.gd @@ -2,6 +2,6 @@ class_name CompScene extends _Component -func _init(scene: PackedScene, children: Array =[]) -> void: - super._init(func() -> Node: return scene.instantiate()) +func _init(scene: PackedScene, children=[]): + super._init(func(): return scene.instantiate()) self.children(children) diff --git a/src/services/godots_recent_releases.gd b/src/services/godots_recent_releases.gd index 02d2f7c2..4cfd2351 100644 --- a/src/services/godots_recent_releases.gd +++ b/src/services/godots_recent_releases.gd @@ -6,42 +6,38 @@ class I: return utils.not_implemeted() -class Default: - extends I +class Default extends I: var _releases: GodotsReleases.I - + func _init(releases: GodotsReleases.I) -> void: _releases = releases func async_has_updates() -> bool: - @warning_ignore("redundant_await") var has_updates := await _releases.async_has_newest_version() return has_updates -class Cached: - extends I +class Cached extends I: const HOUR = 60 * 60 const UPDATES_CACHE_LIFETIME_SEC = 8 * HOUR var _origin: I - + func _init(origin: I) -> void: _origin = origin - + func async_has_updates() -> bool: - _actualize_cache() + await _actualize_cache() return Cache.get_value("has_update", "value", false) - + func _actualize_cache() -> void: - var last_checked_unix: int = Cache.get_value("has_update", "last_checked", 0) + var last_checked_unix:int = Cache.get_value("has_update", "last_checked", 0) if int(Time.get_unix_time_from_system()) - last_checked_unix > UPDATES_CACHE_LIFETIME_SEC: - _update_cache() + await _update_cache() elif Cache.get_value("has_update", "current_version", Config.VERSION) != Config.VERSION: - _update_cache() - + await _update_cache() + func _update_cache() -> bool: - @warning_ignore("redundant_await") var has_updates := await _origin.async_has_updates() Cache.set_value("has_update", "value", has_updates) Cache.set_value("has_update", "current_version", Config.VERSION) @@ -50,8 +46,6 @@ class Cached: return has_updates -class MockHasUpdates: - extends I - +class MockHasUpdates extends I: func async_has_updates() -> bool: return true diff --git a/src/services/godots_releases.gd b/src/services/godots_releases.gd index 9633bf04..dc38b1a6 100644 --- a/src/services/godots_releases.gd +++ b/src/services/godots_releases.gd @@ -4,39 +4,37 @@ class_name GodotsReleases class I: func async_load() -> void: pass - + func all() -> Array[Release]: return [] - + func async_has_newest_version() -> bool: return false -class Default: - extends I +class Default extends I: var _src: Src var _data: Array[Release] = [] var _fetched := false - + func _init(src: Src) -> void: _src = src - + func async_load() -> void: - @warning_ignore("redundant_await") var json := await _src.async_all() - - var latest := {"value": null} - var check_is_latest := func(_release: Release) -> void: - if latest.value != null or _release.is_draft or _release.is_prerelease: + + var latest := {'value': null} + var check_is_latest := func(release: Release) -> void: + if latest.value != null or release.is_draft or release.is_prerelease: return - _release._mark_as_latest() - latest.value = _release + release._mark_as_latest() + latest.value = release _data.clear() for el: Dictionary in json: - var _release := Release.new(el) - _data.append(_release) - check_is_latest.call(_release) + var release := Release.new(el) + _data.append(release) + check_is_latest.call(release) var release: Release if Config.ONLY_STABLE_UPDATES.ret() and latest.value: @@ -65,7 +63,7 @@ class Default: func all() -> Array[Release]: return _data - + func _to_release_or_null(json: Variant) -> Release: if json != null: return Release.new(json as Dictionary) @@ -80,19 +78,18 @@ class Src: ## return is Optional[Dictionary] func async_latest() -> Variant: return utils.not_implemeted() - + ## return is Optional[Dictionary] func async_recent() -> Variant: return utils.not_implemeted() -class SrcFileSystem: - extends Src +class SrcFileSystem extends Src: var _filename: String - + func _init(filename: String) -> void: _filename = filename - + func async_all() -> Array: var file := FileAccess.open(_filename, FileAccess.READ) var content := file.get_as_text() @@ -105,7 +102,7 @@ class SrcFileSystem: if !release.is_prerelease and !release.is_draft: return el return null - + func async_recent() -> Variant: var json := self.async_all() for el: Dictionary in json: @@ -113,10 +110,9 @@ class SrcFileSystem: return null -class SrcGithub: - extends Src +class SrcGithub extends Src: const headers = ["Accept: application/vnd.github.v3+json"] - + func async_all() -> Array: var json: Variant = await _get_json(Config.RELEASES_API_ENDPOINT) if json: @@ -128,18 +124,20 @@ class SrcGithub: var json: Variant = await _get_json(Config.RELEASES_LATEST_API_ENDPOINT) if not json is Dictionary: return null - if (json as Dictionary).get("message", "") == "Not Found": + if (json as Dictionary).get('message', '') == 'Not Found': return null return json - + func async_recent() -> Variant: var json: Variant = await _get_json(Config.RELEASES_API_ENDPOINT + "?per_page=1") for el: Variant in json: return el return null - + func _get_json(url: String) -> Variant: - var response := HttpClient.Response.new(await HttpClient.async_http_get(url, headers)) + var response := HttpClient.Response.new( + await HttpClient.async_http_get(url, headers) + ) var json: Variant = response.to_json() return json @@ -148,46 +146,37 @@ class Release: var _json: Dictionary var _is_latest := false var _is_ready_to_update := false - + var name: String: - get: - return _json.name - + get: return _json.name + var tag_name: String: - get: - return _json.get("tag_name", "") - + get: return _json.get('tag_name', '') + var tags: Array[String]: - get: - return _get_tags() - + get: return _get_tags() + var html_url: String: - get: - return _json.html_url - + get: return _json.html_url + var assets: Array[ReleaseAsset]: - get: - return _get_assets() - + get: return _get_assets() + var is_draft: bool: - get: - return _json.get("draft", true) - + get: return _json.get("draft", true) + var is_prerelease: bool: - get: - return _json.get("prerelease", true) - + get: return _json.get("prerelease", true) + var is_latest: bool: - get: - return _is_latest - + get: return _is_latest + var is_ready_to_update: bool: - get: - return _is_ready_to_update - + get: return _is_ready_to_update + func _init(json: Dictionary) -> void: _json = json - + func _get_tags() -> Array[String]: var tags: Array[String] = [] # if len(_json.tag_name) > 1: @@ -201,34 +190,32 @@ class Release: if is_draft: tags.append(tr("draft")) return tags - + func _get_assets() -> Array[ReleaseAsset]: var assets: Array[ReleaseAsset] = [] for asset: Dictionary in _json.get("assets", []): assets.append(ReleaseAsset.new(asset)) return assets - + func _mark_as_latest() -> void: _is_latest = true - + func _mark_as_ready_to_update() -> void: _is_ready_to_update = true class ReleaseAsset: var _json: Dictionary - + var name: String: - get: - return _json.get("name", "") - + get: return _json.get("name", "") + var browser_download_url: String: - get: - return _json.get("browser_download_url", "") - + get: return _json.get("browser_download_url", "") + func _init(json: Dictionary) -> void: _json = json - + func is_godots_bin_for_current_platform() -> bool: var zip_name: String if OS.has_feature("windows"): diff --git a/src/services/local_editors.gd b/src/services/local_editors.gd index ee4a3221..0156de59 100644 --- a/src/services/local_editors.gd +++ b/src/services/local_editors.gd @@ -2,17 +2,17 @@ class_name LocalEditors class List extends RefCounted: const dict = preload("res://src/extensions/dict.gd") - + signal editor_removed(editor_path: String) signal editor_name_changed(editor_path: String) - + var _cfg_path: String var _cfg := ConfigFile.new() var _editors: Dictionary[String, Item] = {} - + func _init(cfg_path: String) -> void: _cfg_path = cfg_path - + func add(name: String, editor_path: String) -> Item: var editor := Item.new( ConfigFileSection.new(editor_path, IConfigFileLike.of_config(_cfg)), @@ -20,8 +20,8 @@ class List extends RefCounted: if OS.has_feature("linux"): var output := [] var exit_code := OS.execute( - "chmod", - ["+x", "%s" % ProjectSettings.globalize_path(editor_path) ], + "chmod", + ["+x", "%s" % ProjectSettings.globalize_path(editor_path) ], output, true ) @@ -33,29 +33,29 @@ class List extends RefCounted: editor.extra_arguments = [] _editors[editor_path] = editor return editor - + func all() -> Array[Item]: var result: Array[Item] = [] for x: Item in _editors.values(): result.append(x) return result - + func retrieve(editor_path: String) -> Item: return _editors[editor_path] - + func has(editor_path: String) -> bool: return _editors.has(editor_path) - + func editor_is_valid(editor_path: String) -> bool: return has(editor_path) and edir.path_is_valid(editor_path) - + func erase(editor_path: String) -> void: var editor := retrieve(editor_path) editor.free() _editors.erase(editor_path) _cfg.erase_section(editor_path) editor_removed.emit(editor_path) - + func as_option_button_items() -> Array[Dictionary]: var result: Array[Dictionary] for x in all(): @@ -66,7 +66,7 @@ class List extends RefCounted: 'version_hint': x.version_hint }) return result - + # TODO type func get_all_tags() -> Array: var set := Set.new() @@ -74,7 +74,7 @@ class List extends RefCounted: for tag: String in editor.tags: set.append(tag.to_lower()) return set.values() - + func load() -> Error: cleanup() var err := _cfg.load(_cfg_path) @@ -86,15 +86,15 @@ class List extends RefCounted: _connect_name_changed(editor) _editors[section] = editor return Error.OK - + func cleanup() -> void: dict.clear_and_free(_editors) - + func save() -> Error: return _cfg.save(_cfg_path) - + func _connect_name_changed(editor: Item) -> void: - editor.name_changed.connect(func(_new_name: String) -> void: + editor.name_changed.connect(func(_new_name: String) -> void: editor_name_changed.emit(editor.path) ) @@ -102,57 +102,57 @@ class List extends RefCounted: class Item extends Object: signal tags_edited signal name_changed(new_name: String) - + var mac_os_editor_path_postfix: String: get: return _section.get_value("mac_os_editor_path_postfix", "/Contents/MacOS/Godot") - + var path: String: get: return _section.name - + var name: String: get: return _section.get_value("name", "") - set(value): + set(value): _section.set_value("name", value) name_changed.emit(value) - + var extra_arguments: PackedStringArray: get: return _section.get_typed_value( - "extra_arguments", - func(x: Variant) -> bool: return x is PackedStringArray, + "extra_arguments", + func(x: Variant) -> bool: return x is PackedStringArray, [] ) - set(value): + set(value): _section.set_value("extra_arguments", value) - + var favorite: bool: get: return _section.get_value("favorite", false) set(value): _section.set_value("favorite", value) - + # TODO type var tags: Array: get: return Set.of(_section.get_value("tags", []) as Array).values() set(value): _section.set_value("tags", value) - + var is_valid: bool: get: return edir.path_is_valid(path) - + var version_hint: String: get: return _section.get_value( - "version_hint", + "version_hint", self.name.to_lower() .replace("godot", "") .strip_edges() .replace(" ", "-") ) set(value): _section.set_value("version_hint", value) - + # TODO type var custom_commands: Array: get: return _get_custom_commands("custom_commands-v2") set(value): _section.set_value("custom_commands-v2", value) var _section: ConfigFileSection - + func _init(section: ConfigFileSection) -> void: self._section = section @@ -160,11 +160,11 @@ class Item extends Object: if NOTIFICATION_PREDELETE == what: utils.disconnect_all(self) - func fmt_string(string: String) -> String: + func fmt_string(str: String) -> String: var bin_path := _bin_path() - string = string.replace("{{EDITOR_PATH}}", bin_path) - string = string.replace("{{EDITOR_DIR}}", bin_path.get_base_dir()) - return string + str = str.replace("{{EDITOR_PATH}}", bin_path) + str = str.replace("{{EDITOR_DIR}}", bin_path.get_base_dir()) + return str func as_process(args: PackedStringArray) -> OSProcessSchema: var process_path := _bin_path() @@ -186,33 +186,33 @@ class Item extends Object: func run() -> void: var command: Dictionary = _find_custom_command_by_name("Run", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() - + func emit_tags_edited() -> void: tags_edited.emit() - + func is_self_contained() -> bool: if not is_valid: return false var sub_file_exists := func(file: String) -> bool: return FileAccess.file_exists(path.get_base_dir().path_join(file)) return sub_file_exists.call("_sc_") or sub_file_exists.call("._sc_") - + func match_name(search: String) -> bool: var sanitazed_name := _sanitize_name(name) var sanitazed_search := _sanitize_name(search) var findn := sanitazed_name.findn(sanitazed_search) return findn > -1 - + func match_version_hint(hint: String, ignore_mono:=false) -> bool: return VersionHint.are_equal(self.version_hint, hint, ignore_mono) - + func get_version() -> String: var parsed := VersionHint.parse(version_hint) if parsed.is_valid: return parsed.version else: return "" - + func get_cfg_file_path() -> String: var cfg_file_name := get_cfg_file_name() if cfg_file_name.is_empty(): @@ -225,7 +225,7 @@ class Item extends Object: if cfg_folder.is_empty(): return "" return cfg_folder.path_join(cfg_file_name) - + func get_cfg_file_name() -> String: var version := get_version() if version.is_empty(): @@ -236,7 +236,7 @@ class Item extends Object: return "editor_settings-4.tres" else: return "" - + func _bin_path() -> String: var process_path: String if OS.has_feature("windows") or OS.has_feature("linux"): @@ -244,17 +244,17 @@ class Item extends Object: elif OS.has_feature("macos"): process_path = ProjectSettings.globalize_path(path + mac_os_editor_path_postfix) return process_path - + func _sanitize_name(name: String) -> String: return name.replace(" ", "") - + # TODO type func _find_custom_command_by_name(name: String, src:=[]) -> Variant: for command: Dictionary in src: if command.name == name: return command return null - + # TODO type func _get_custom_commands(key: String) -> Array: var commands := _section.get_value(key, []) as Array @@ -265,50 +265,50 @@ class Item extends Object: 'path': '{{EDITOR_PATH}}', 'args': ['-p'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) return commands - + func _to_string() -> String: return "%s (%s)" % [name, VersionHint.parse(version_hint)] class Selector: var _filter: Callable - + ## filter: Optional[Callable[[Item], bool]] func _init(filter: Variant =null) -> void: if filter == null: filter = func(x: Variant) -> bool: return true _filter = filter - + func by_name(name: String) -> Selector: return Selector.new(func(el: Item) -> bool: return _filter.call(el) and el.match_name(name) ) - + func by_version_hint(hint: String, ignore_mono:=false) -> Selector: return Selector.new(func(el: Item) -> bool: return _filter.call(el) and el.match_version_hint(hint, ignore_mono) ) - + func select(editors: List) -> Array[Item]: var result: Array[Item] = [] for el in editors.all(): if _filter.call(el): result.append(el) return result - + func select_first_or_null(editors: List) -> Item: var res := select(editors) if len(res) > 0: return res[0] else: return null - + func select_exact_one(editors: List) -> Item: var res := select(editors) if len(res) == 1: @@ -317,7 +317,7 @@ class Selector: if len(res) > 1: Output.push("There is ambiguity between editors to run.\n%s" % "\n".join(res)) return null - + static func from_cmd(cmd: CliParser.ParsedCommandResult) -> Selector: var name := cmd.args.first_option_value(["name", "n"]) var version_hint := cmd.args.first_option_value(["version-hint", "vh"]) diff --git a/src/services/projects.gd b/src/services/projects.gd index 6b935f68..9fe5bf81 100644 --- a/src/services/projects.gd +++ b/src/services/projects.gd @@ -2,18 +2,18 @@ class_name Projects class List extends RefCounted: const dict = preload("res://src/extensions/dict.gd") - + var _cfg := ConfigFile.new() var _projects: Dictionary[String, Item] = {} var _cfg_path: String var _default_icon: Texture2D var _local_editors: LocalEditors.List - + func _init(cfg_path: String, local_editors: LocalEditors.List, default_icon: Texture2D) -> void: _cfg_path = cfg_path _local_editors = local_editors _default_icon = default_icon - + func add(project_path: String, editor_path: String) -> Item: var project := Item.new( ConfigFileSection.new(project_path, IConfigFileLike.of_config(_cfg)), @@ -25,33 +25,33 @@ class List extends RefCounted: project.editor_path = editor_path _projects[project_path] = project return project - + func all() -> Array[Item]: var result: Array[Item] = [] for x: Item in _projects.values(): result.append(x) return result - + func retrieve(project_path: String) -> Item: return _projects[project_path] - + func has(project_path: String) -> bool: return _projects.has(project_path) - + func erase(project_path: String) -> void: _projects.erase(project_path) _cfg.erase_section(project_path) - + func get_editors_to_bind() -> Array[Dictionary]: return _local_editors.as_option_button_items() - + func get_owners_of(editor: LocalEditors.Item) -> Array[Item]: var result: Array[Item] for project in all(): if project.editor_is(editor): result.append(project) return result - + # TODO type func get_all_tags() -> Array: var set := Set.new() @@ -59,7 +59,7 @@ class List extends RefCounted: for tag: String in project.tags: set.append(tag.to_lower()) return set.values() - + func load() -> Error: cleanup() var err := _cfg.load(_cfg_path) @@ -71,13 +71,13 @@ class List extends RefCounted: _local_editors ) return Error.OK - + func cleanup() -> void: dict.clear_and_free(_projects) - + func save() -> Error: return _cfg.save(_cfg_path) - + func get_last_opened() -> Projects.Item: var last_opened := _ProjectsCache.get_last_opened_project() return retrieve(last_opened) if has(last_opened) else null @@ -86,67 +86,67 @@ class List extends RefCounted: class Item: signal internals_changed signal loaded - + var show_edit_warning: bool: get: return _section.get_value("show_edit_warning", true) set(value): _section.set_value("show_edit_warning", value) - + var path: String: get: return _section.name - + var name: String: get: return _external_project_info.name set(value): _external_project_info.name = value - + var editor_name: String: get: return _get_editor_name() - + var icon: Texture2D: get: return _external_project_info.icon var favorite: bool: get: return _section.get_value("favorite", false) set(value): _section.set_value("favorite", value) - + var editor: LocalEditors.Item: - get: + get: if has_invalid_editor: return null return _local_editors.retrieve(editor_path) - + var editor_path: String: get: return _section.get_value("editor_path", "") - set(value): + set(value): show_edit_warning = true _section.set_value("editor_path", value) - + var has_invalid_editor: bool: get: return not _local_editors.editor_is_valid(editor_path) - + var is_valid: bool: get: return edir.path_is_valid(path) - + # TODO type var editors_to_bind: Array: get: return _get_editors_to_bind() - + var is_missing: bool: get: return _external_project_info.is_missing - + var is_loaded: bool: get: return _external_project_info.is_loaded - + var tags: Array: set(value): _external_project_info.tags = value get: return _external_project_info.tags - + var last_modified: int: get: return _external_project_info.last_modified - + # TODO type var features: Array: get: return _external_project_info.features - + var version_hint: String: get: return _external_project_info.version_hint set(value): _external_project_info.version_hint = value @@ -161,9 +161,9 @@ class Item: var _external_project_info: ExternalProjectInfo var _section: ConfigFileSection var _local_editors: LocalEditors.List - + func _init( - section: ConfigFileSection, + section: ConfigFileSection, project_info: ExternalProjectInfo, local_editors: LocalEditors.List ) -> void: @@ -175,20 +175,20 @@ class Item: ) self._local_editors.editor_name_changed.connect(_check_editor_changes) project_info.loaded.connect(func() -> void: loaded.emit()) - + func before_delete_as_ref_counted() -> void: utils.disconnect_all(self) if _external_project_info: _external_project_info.before_delete_as_ref_counted() - + func load(with_icon:=true) -> void: _external_project_info.load(with_icon) - + func editor_is(editor: LocalEditors.Item) -> bool: if has_invalid_editor: return false return self.editor == editor - + func _get_editor_name() -> String: if has_invalid_editor: return '' @@ -198,10 +198,10 @@ class Item: func _check_editor_changes(editor_path: String) -> void: if editor_path == self.editor_path: emit_internals_changed() - + func emit_internals_changed() -> void: internals_changed.emit() - + func as_process(args: PackedStringArray) -> OSProcessSchema: assert(not has_invalid_editor) var editor := _local_editors.retrieve(editor_path) @@ -211,16 +211,16 @@ class Item: ] result_args.append_array(args) return editor.as_process(result_args) - - func fmt_string(string: String) -> String: + + func fmt_string(str: String) -> String: if not has_invalid_editor: var editor := _local_editors.retrieve(editor_path) - string = editor.fmt_string(string) - string = string.replace( + str = editor.fmt_string(str) + str = str.replace( '{{PROJECT_DIR}}', ProjectSettings.globalize_path(self.path).get_base_dir() ) - return string - + return str + func as_fmt_process(process_path: String, args: PackedStringArray) -> OSProcessSchema: var result_path := process_path var result_args: PackedStringArray @@ -234,23 +234,23 @@ class Item: arg = self.fmt_string(arg) result_args.append(arg) return OSProcessSchema.new(result_path, result_args) - + func edit() -> void: var command: Dictionary = _find_custom_command_by_name("Edit", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() _ProjectsCache.set_last_opened_project(path) - + func run() -> void: var command: Dictionary = _find_custom_command_by_name("Run", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() - + # TODO type func _find_custom_command_by_name(name: String, src:=[]) -> Variant: for command: Dictionary in src: if command.name == name: return command return null - + # TODO type func _get_custom_commands(key: String) -> Array: var commands: Array = _section.get_value(key, []) @@ -261,8 +261,8 @@ class Item: 'path': '{{EDITOR_PATH}}', 'args': ['--path', '{{PROJECT_DIR}}' ,'-e'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) @@ -273,13 +273,13 @@ class Item: 'path': '{{EDITOR_PATH}}', 'args': ['--path', '{{PROJECT_DIR}}' ,'-g'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) return commands - + #TODO type func _get_editors_to_bind() -> Array: var options := _local_editors.as_option_button_items() @@ -299,7 +299,7 @@ class _ProjectsCache: class ExternalProjectInfo extends RefCounted: signal loaded - + var icon: Texture2D: get: return _icon @@ -313,15 +313,15 @@ class ExternalProjectInfo extends RefCounted: var err := cfg.load(_project_path) if not err: cfg.set_value( - "application", - "config/name", + "application", + "config/name", _name ) cfg.save(_project_path) - + var has_version_hint: bool: get: return _version_hint != null - + var version_hint: String: get: return '' if _version_hint == null else _version_hint set(value): @@ -332,21 +332,21 @@ class ExternalProjectInfo extends RefCounted: var err := cfg.load(_project_path) if not err: cfg.set_value( - "godots", - "version_hint", + "godots", + "version_hint", _version_hint ) cfg.save(_project_path) var last_modified: int: get: return _last_modified - + var is_loaded: bool: get: return _is_loaded - + var is_missing: bool: get: return _is_missing - + # TODO type var tags: Array: set(value): @@ -360,17 +360,17 @@ class ExternalProjectInfo extends RefCounted: for tag: String in _tags: set.append(tag.to_lower()) cfg.set_value( - "application", - "config/tags", + "application", + "config/tags", PackedStringArray(set.values()) ) cfg.save(_project_path) get: return Set.of(_tags).values() - + # TODO type var features: Array: get: return _features - + var _is_loaded := false var _project_path: String var _default_icon: Texture2D @@ -384,19 +384,19 @@ class ExternalProjectInfo extends RefCounted: var _has_mono_section := false ## Optional[String], TODO type var _version_hint: Variant = null - + func _init(project_path: String, default_icon: Texture2D = null) -> void: _project_path = project_path _default_icon = default_icon _icon = default_icon - + func before_delete_as_ref_counted() -> void: utils.disconnect_all(self) - + func load(with_icon:=true) -> void: var cfg := ConfigFile.new() var err := cfg.load(_project_path) - + _name = cfg.get_value("application", "config/name", "Missing Project") _tags = cfg.get_value("application", "config/tags", []) _features = cfg.get_value("application", "config/features", []) @@ -406,21 +406,21 @@ class ExternalProjectInfo extends RefCounted: _version_hint = cfg.get_value("godots", "version_hint") if _version_hint == '': _version_hint = null - + _last_modified = FileAccess.get_modified_time(_project_path) if with_icon: _icon = _load_icon(cfg) _is_missing = bool(err) - + _is_loaded = true loaded.emit() - + func _load_icon(cfg: ConfigFile) -> Texture2D: var result := _default_icon var icon_path: String = cfg.get_value("application", "config/icon", "") if not icon_path: return result icon_path = icon_path.replace("res://", self._project_path.get_base_dir() + "/") - + if FileAccess.file_exists(icon_path): var icon_image := Image.new() var err := icon_image.load(icon_path) @@ -430,18 +430,18 @@ class ExternalProjectInfo extends RefCounted: ) result = ImageTexture.create_from_image(icon_image) return result - + # TODO type func sort_editor_options(options: Array) -> void: var has_cs_feature := "C#" in features var is_mono := has_cs_feature or _has_mono_section - + var check_stable := func(label: String) -> bool: return label.contains("stable") - + var check_mono := func(label: String) -> bool: return label.contains("mono") - + var check_version := func(label: String) -> bool: if _version_hint != null: if VersionHint.same_version(_version_hint as String, label): @@ -451,7 +451,7 @@ class ExternalProjectInfo extends RefCounted: elif _config_version == 4: return not label.contains("3.0") and not label.contains("4.") elif _config_version > 4: - var is_version := func(feature: String) -> bool: + var is_version := func(feature: String) -> bool: return feature.contains(".") and feature.substr(0, 3).is_valid_float() var version_tags := Array(features).filter(is_version) if len(version_tags) > 0: @@ -460,7 +460,7 @@ class ExternalProjectInfo extends RefCounted: return label.contains("4.") else: return false - + var check_version_hint_similarity := func(version_hint: String) -> int: var score := VersionHint.similarity(_version_hint as String, version_hint) return score @@ -468,7 +468,7 @@ class ExternalProjectInfo extends RefCounted: options.sort_custom(func(item_a: Dictionary, item_b: Dictionary) -> bool: var a := (item_a.version_hint as String).to_lower() var b := (item_b.version_hint as String).to_lower() - + if _version_hint != null: var sim_a: int = check_version_hint_similarity.call(a) var sim_b: int = check_version_hint_similarity.call(b) @@ -490,6 +490,6 @@ class ExternalProjectInfo extends RefCounted: return true if check_stable.call(b) && !check_stable.call(a): return false - + return VersionHint.version_or_nothing(a) > VersionHint.version_or_nothing(b) ) diff --git a/src/services/remote_image_src.gd b/src/services/remote_image_src.gd index c087f5d1..cfd82a37 100644 --- a/src/services/remote_image_src.gd +++ b/src/services/remote_image_src.gd @@ -6,37 +6,34 @@ class I: pass -class AlwaysBroken: - extends I +class AlwaysBroken extends I: var _theme_src: Control - + func _init(theme_src: Control) -> void: _theme_src = theme_src - + func async_load_img(url: String, callback: Callable) -> void: var texture := _theme_src.get_theme_icon("FileBrokenBigThumb", "EditorIcons") callback.call(texture) -class LoadFileBuffer: - extends I +class LoadFileBuffer extends I: var _file_src: FileByUrlSrc var _fallback_texture: Texture2D - + func _init(file_src: FileByUrlSrc, fallback_texture: Texture2D) -> void: _fallback_texture = fallback_texture _file_src = file_src - + func async_load_img(url: String, callback: Callable) -> void: - @warning_ignore("redundant_await") var file_path := await _file_src.async_load(url) - + if file_path.is_empty(): return - + if not callback.is_valid(): return - + # some weird additional check is required due to: # 'Trying to call a lambda with an invalid instance.' # https://github.com/godotengine/godot/blob/c7fb0645af400a1859154bcee9394e63bdabd198/modules/gdscript/gdscript_lambda_callable.cpp#L195 @@ -47,7 +44,7 @@ class LoadFileBuffer: if file == null: callback.call(_fallback_texture) return - + var file_buffer := file.get_buffer(file.get_length()) var img := Image.new() var load_err := _load_img_from_buffer(img, file_buffer) @@ -56,13 +53,13 @@ class LoadFileBuffer: else: var tex := ImageTexture.create_from_image(img) callback.call(tex) - + func _load_img_from_buffer(img: Image, buffer: PackedByteArray) -> int: var png_signature := PackedByteArray([137, 80, 78, 71, 13, 10, 26, 10]) var jpg_signature := PackedByteArray([255, 216, 255]) var webp_signature := PackedByteArray([82, 73, 70, 70]) var bmp_signature := PackedByteArray([66, 77]) - + var load_err := ERR_PARAMETER_RANGE_ERROR if png_signature == buffer.slice(0, 8): load_err = img.load_png_from_buffer(buffer) @@ -81,24 +78,20 @@ class FileByUrlSrc: return "" -class FileByUrlSrcAsIs: - extends FileByUrlSrc - +class FileByUrlSrcAsIs extends FileByUrlSrc: func async_load(url: String) -> String: var file_path := (Config.CACHE_DIR_PATH.ret() as String).path_join(url.md5_text()) - var response := HttpClient.Response.new(await HttpClient.async_http_get(url, [], file_path)) + var response := HttpClient.Response.new( + await HttpClient.async_http_get(url, [], file_path) + ) if response.code != 200: return "" return file_path -class FileByUrlCachedEtag: - extends FileByUrlSrc - +class FileByUrlCachedEtag extends FileByUrlSrc: func async_load(url: String) -> String: - var file_path_base := (Config.CACHE_DIR_PATH.ret() as String).path_join( - "assetimage_" + url.md5_text() - ) + var file_path_base := (Config.CACHE_DIR_PATH.ret() as String).path_join("assetimage_" + url.md5_text()) var etag_path := file_path_base + ".etag" var data_path := file_path_base + ".data" var headers := [] @@ -109,17 +102,12 @@ class FileByUrlCachedEtag: var response := HttpClient.Response.new( await HttpClient.async_http_get(url, headers, data_path) ) - if ( - response.result == HTTPRequest.RESULT_SUCCESS - and response.result < HTTPClient.RESPONSE_BAD_REQUEST - ): + if response.result == HTTPRequest.RESULT_SUCCESS and response.result < HTTPClient.RESPONSE_BAD_REQUEST: if response.code != HTTPClient.RESPONSE_NOT_MODIFIED: for header in response.headers: header = header as String if header.findn("ETag:") == 0: - var new_etag := ( - header.substr(header.find(":") + 1, header.length()).strip_edges() - ) + var new_etag := header.substr(header.find(":") + 1, header.length()).strip_edges() var file := FileAccess.open(etag_path, FileAccess.WRITE) if file: file.store_line(new_etag) diff --git a/src/utils.gd b/src/utils.gd index 9d705a00..7f8fadf5 100644 --- a/src/utils.gd +++ b/src/utils.gd @@ -4,22 +4,20 @@ class_name utils static func guess_editor_name(file_name: String) -> String: var possible_editor_name := file_name.get_file() var tokens_to_replace: Array[String] - tokens_to_replace.append_array( - [ - "x11.64", - "linux.64", - "linux.x86_64", - "linux.x86_32", - "osx.universal", - "macos.universal", - "osx.fat", - "osx32", - "osx64", - "win64", - "win32", - ".%s" % file_name.get_extension() - ] - ) + tokens_to_replace.append_array([ + "x11.64", + "linux.64", + "linux.x86_64", + "linux.x86_32", + "osx.universal", + "macos.universal", + "osx.fat", + "osx32", + "osx64", + "win64", + "win32", + ".%s" % file_name.get_extension() + ]) tokens_to_replace.append_array(["_", "-"]) for token in tokens_to_replace: possible_editor_name = possible_editor_name.replace(token, " ") @@ -29,15 +27,17 @@ static func guess_editor_name(file_name: String) -> String: static func find_project_godot_files(dir_path: String) -> Array[edir.DirListResult]: var project_configs := edir.list_recursive( - ProjectSettings.globalize_path(dir_path), + ProjectSettings.globalize_path(dir_path), false, - func(x: edir.DirListResult) -> bool: return x.is_file and x.file == "project.godot", - func(x: String) -> bool: return not x.get_file().begins_with(".") + (func(x: edir.DirListResult) -> bool: + return x.is_file and x.file == "project.godot"), + (func(x: String) -> bool: + return not x.get_file().begins_with(".")) ) return project_configs -static func response_to_json(response: Variant, safe := true) -> Variant: +static func response_to_json(response: Variant, safe:=true) -> Variant: var body := response[3] as PackedByteArray var string := body.get_string_from_utf8() if safe: @@ -57,13 +57,11 @@ static func parse_json_safe(string: String) -> Variant: static func fit_height(max_height: float, cur_size: Vector2i, callback: Callable) -> void: var scale_ratio := max_height / (cur_size.y * Config.EDSCALE) - if scale_ratio < 1.0: - callback.call( - Vector2i( - cur_size.x * int(Config.EDSCALE) * int(scale_ratio), - cur_size.y * int(Config.EDSCALE) * int(scale_ratio) - ) - ) + if scale_ratio < 1: + callback.call(Vector2i( + cur_size.x * Config.EDSCALE * scale_ratio, + cur_size.y * Config.EDSCALE * scale_ratio + )) static func disconnect_all(obj: Object) -> void: diff --git a/tests/cases/cli/parser/parser_not_ok.gd b/tests/cases/cli/parser/parser_not_ok.gd index 8764007e..56ff9c6e 100644 --- a/tests/cases/cli/parser/parser_not_ok.gd +++ b/tests/cases/cli/parser/parser_not_ok.gd @@ -1,34 +1,34 @@ class_name CliParserNotOkTests extends GdUnitTestSuite -func test_invalid_namespace() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["invalidNamespace"]) +func test_invalid_namespace(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["invalidNamespace"]) assert(result.namesp.is_empty()) assert(result.verb.is_empty()) assert(result.args.names[0] == "invalidNamespace") -func test_invalid_command() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "invalidVerb"]) +func test_invalid_command(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "invalidVerb"]) assert(result.namesp == "namespace1") assert(result.verb.is_empty()) assert(result.args.names[0] == "invalidVerb") -func test_invalid_option() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "--invalidOption"]) +func test_invalid_option(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "--invalidOption"]) assert(result.has_error()) assert(result.errors[0] == "Unsupported option: --invalidOption") -func test_repeated_options() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "--flag1", "value2"]) +func test_repeated_options(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "--flag1", "value2"]) assert(result.has_error()) assert(result.errors[0] == "Only one option with name (`flag1`, `f1`) can be used.") -func test_repeated_short_and_long_options() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "-f1", "value2"]) +func test_repeated_short_and_long_options(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "-f1", "value2"]) assert(result.has_error()) assert(result.errors[0] == "Only one option with name (`flag1`, `f1`) can be used.") diff --git a/tests/cases/cli/parser/parser_ok.gd b/tests/cases/cli/parser/parser_ok.gd index a2fe522d..105b5b7f 100644 --- a/tests/cases/cli/parser/parser_ok.gd +++ b/tests/cases/cli/parser/parser_ok.gd @@ -1,9 +1,9 @@ class_name CliParserOkTests extends GdUnitTestSuite -func test_parse_command() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_command(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "namespace1") assert(result.verb == "verb1") @@ -13,9 +13,9 @@ func test_parse_command() -> void: assert(args.has_options(["bool-flag"])) assert(args.has_options(["a"])) -func test_parse_without_verb() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_without_verb(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "namespace1") assert(result.verb == "") @@ -25,9 +25,9 @@ func test_parse_without_verb() -> void: assert(args.has_options(["bool-flag"])) assert(args.has_options(["a"])) -func test_parse_without_namespace_and_verb() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_without_namespace_and_verb(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "") assert(result.verb == "") diff --git a/tests/cases/cli/parser/test_grammar.gd b/tests/cases/cli/parser/test_grammar.gd index 3e11eeb6..c8ec30df 100644 --- a/tests/cases/cli/parser/test_grammar.gd +++ b/tests/cases/cli/parser/test_grammar.gd @@ -1,6 +1,6 @@ class_name TestGrammar -static var grammar := CliGrammar.new([ +static var grammar = CliGrammar.new([ CliCommand.new( "namespace1", "verb1", diff --git a/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd b/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd index 54d3466a..c6ca0102 100644 --- a/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd +++ b/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd @@ -2,24 +2,19 @@ class_name GdUnitExampleTest extends GdUnitTestSuite -func test_list_dir() -> void: - var result := edir.list_recursive( +func test_list_dir(): + var result = edir.list_recursive( "res://tests/cases/dir_extensions/list_dir_recursive/assets/1/" ) assert_int(len(result)).is_equal(8) - - @warning_ignore("untyped_declaration") # I cannot figure out the type of x - var files := result.filter(func(x): return x.is_file).map(func(x): return x.file) - assert_array(files).contains_exactly( - ["file.txt", "file2.txt", "file3.txt", "file3.txt", "file4.txt"] - ) - - @warning_ignore("untyped_declaration") # I cannot figure out the type of x - var dirs := result.filter(func(x): return x.is_dir).map(func(x): return x.file) + + var files = result.filter(func(x): return x.is_file).map(func(x): return x.file) + assert_array(files).contains_exactly(["file.txt", "file2.txt", "file3.txt", "file3.txt", "file4.txt"]) + + var dirs = result.filter(func(x): return x.is_dir).map(func(x): return x.file) assert_array(dirs).contains_exactly(["sub-dir", "sub-dir-2", "sub-dir-3"]) - - @warning_ignore("untyped_declaration") # I cannot figure out the type of x - var raw_dirs := result.filter(func(x): return x.is_dir) + + var raw_dirs = result.filter(func(x): return x.is_dir) assert_str(raw_dirs[0].path).is_equal( "res://tests/cases/dir_extensions/list_dir_recursive/assets/1/sub-dir" ) diff --git a/tests/cases/services/local_editor_tests.gd b/tests/cases/services/local_editor_tests.gd index 4f751ca5..d3f0a35c 100644 --- a/tests/cases/services/local_editor_tests.gd +++ b/tests/cases/services/local_editor_tests.gd @@ -10,8 +10,8 @@ func test_filter_by_name_pattern(name: String, expected: int, test_parameters:= [" 4.1 s", 1], ["4.1 StAble", 1], ["invalid", 0], -]) -> void: - var editors := LocalEditors.List.new(config_path) +]): + var editors = LocalEditors.List.new(config_path) editors.load() - var result := LocalEditors.Selector.new().by_name(name).select(editors) + var result = LocalEditors.Selector.new().by_name(name).select(editors) assert_int(result.size()).is_equal(expected) diff --git a/theme/fill_icons_registry.gd b/theme/fill_icons_registry.gd index 7fa5553d..72cc5010 100644 --- a/theme/fill_icons_registry.gd +++ b/theme/fill_icons_registry.gd @@ -7,10 +7,10 @@ func _run() -> void: _create_cfg('res://theme/icons-light', 'res://theme/icons-light.cfg') -func _create_cfg(icons_dir: String, result_file_path: String) -> void: - var result := ConfigFile.new() - var dir := EditorInterface.get_resource_filesystem().get_filesystem_path(icons_dir) +func _create_cfg(icons_dir, result_file_path): + var result = ConfigFile.new() + var dir = EditorInterface.get_resource_filesystem().get_filesystem_path(icons_dir) for i in range(dir.get_file_count()): - var path := dir.get_file_path(i) + var path = dir.get_file_path(i) result.set_value(path, "name", path.get_basename().get_file()) result.save(result_file_path) From ab9ce8c86fb244d694fa9ea3f44a65841e8ce409 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 13 Mar 2025 16:29:15 -0300 Subject: [PATCH 06/23] Reverting non feature related changes --- .gitignore | 5 +- export_presets.cfg | 189 +++------------------------------------------ project.godot | 2 +- 3 files changed, 13 insertions(+), 183 deletions(-) diff --git a/.gitignore b/.gitignore index de76f3f2..f95fe259 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Godot 4+ specific ignores .godot/ -# Export ignore -build_dir/ - # Godot-specific ignores .import/ export.cfg @@ -32,4 +29,4 @@ addons/gdUnit # Mac files .DS_Store -/override.cfg +/override.cfg \ No newline at end of file diff --git a/export_presets.cfg b/export_presets.cfg index fed955b6..851bddb1 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -3,20 +3,16 @@ name="macOS" platform="macOS" runnable=false -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.zip" -patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.0.options] @@ -34,11 +30,8 @@ application/short_version="1.0" application/version="1.0" application/copyright="" application/copyright_localized={} -application/min_macos_version_x86_64="10.12" -application/min_macos_version_arm64="11.00" -application/export_angle=0 +application/min_macos_version="10.12" display/high_res=true -application/additional_plist_content="" xcode/platform_build="14C18" xcode/sdk_version="13.1" xcode/sdk_build="22C55" @@ -71,9 +64,7 @@ codesign/entitlements/app_sandbox/files_downloads=0 codesign/entitlements/app_sandbox/files_pictures=0 codesign/entitlements/app_sandbox/files_music=0 codesign/entitlements/app_sandbox/files_movies=0 -codesign/entitlements/app_sandbox/files_user_selected=0 codesign/entitlements/app_sandbox/helper_executables=[] -codesign/entitlements/additional="" codesign/custom_options=PackedStringArray() notarization/notarization=0 privacy/microphone_usage_description="" @@ -98,148 +89,6 @@ privacy/network_volumes_usage_description="" privacy/network_volumes_usage_description_localized={} privacy/removable_volumes_usage_description="" privacy/removable_volumes_usage_description_localized={} -privacy/tracking_enabled=false -privacy/tracking_domains=PackedStringArray() -privacy/collected_data/name/collected=false -privacy/collected_data/name/linked_to_user=false -privacy/collected_data/name/used_for_tracking=false -privacy/collected_data/name/collection_purposes=0 -privacy/collected_data/email_address/collected=false -privacy/collected_data/email_address/linked_to_user=false -privacy/collected_data/email_address/used_for_tracking=false -privacy/collected_data/email_address/collection_purposes=0 -privacy/collected_data/phone_number/collected=false -privacy/collected_data/phone_number/linked_to_user=false -privacy/collected_data/phone_number/used_for_tracking=false -privacy/collected_data/phone_number/collection_purposes=0 -privacy/collected_data/physical_address/collected=false -privacy/collected_data/physical_address/linked_to_user=false -privacy/collected_data/physical_address/used_for_tracking=false -privacy/collected_data/physical_address/collection_purposes=0 -privacy/collected_data/other_contact_info/collected=false -privacy/collected_data/other_contact_info/linked_to_user=false -privacy/collected_data/other_contact_info/used_for_tracking=false -privacy/collected_data/other_contact_info/collection_purposes=0 -privacy/collected_data/health/collected=false -privacy/collected_data/health/linked_to_user=false -privacy/collected_data/health/used_for_tracking=false -privacy/collected_data/health/collection_purposes=0 -privacy/collected_data/fitness/collected=false -privacy/collected_data/fitness/linked_to_user=false -privacy/collected_data/fitness/used_for_tracking=false -privacy/collected_data/fitness/collection_purposes=0 -privacy/collected_data/payment_info/collected=false -privacy/collected_data/payment_info/linked_to_user=false -privacy/collected_data/payment_info/used_for_tracking=false -privacy/collected_data/payment_info/collection_purposes=0 -privacy/collected_data/credit_info/collected=false -privacy/collected_data/credit_info/linked_to_user=false -privacy/collected_data/credit_info/used_for_tracking=false -privacy/collected_data/credit_info/collection_purposes=0 -privacy/collected_data/other_financial_info/collected=false -privacy/collected_data/other_financial_info/linked_to_user=false -privacy/collected_data/other_financial_info/used_for_tracking=false -privacy/collected_data/other_financial_info/collection_purposes=0 -privacy/collected_data/precise_location/collected=false -privacy/collected_data/precise_location/linked_to_user=false -privacy/collected_data/precise_location/used_for_tracking=false -privacy/collected_data/precise_location/collection_purposes=0 -privacy/collected_data/coarse_location/collected=false -privacy/collected_data/coarse_location/linked_to_user=false -privacy/collected_data/coarse_location/used_for_tracking=false -privacy/collected_data/coarse_location/collection_purposes=0 -privacy/collected_data/sensitive_info/collected=false -privacy/collected_data/sensitive_info/linked_to_user=false -privacy/collected_data/sensitive_info/used_for_tracking=false -privacy/collected_data/sensitive_info/collection_purposes=0 -privacy/collected_data/contacts/collected=false -privacy/collected_data/contacts/linked_to_user=false -privacy/collected_data/contacts/used_for_tracking=false -privacy/collected_data/contacts/collection_purposes=0 -privacy/collected_data/emails_or_text_messages/collected=false -privacy/collected_data/emails_or_text_messages/linked_to_user=false -privacy/collected_data/emails_or_text_messages/used_for_tracking=false -privacy/collected_data/emails_or_text_messages/collection_purposes=0 -privacy/collected_data/photos_or_videos/collected=false -privacy/collected_data/photos_or_videos/linked_to_user=false -privacy/collected_data/photos_or_videos/used_for_tracking=false -privacy/collected_data/photos_or_videos/collection_purposes=0 -privacy/collected_data/audio_data/collected=false -privacy/collected_data/audio_data/linked_to_user=false -privacy/collected_data/audio_data/used_for_tracking=false -privacy/collected_data/audio_data/collection_purposes=0 -privacy/collected_data/gameplay_content/collected=false -privacy/collected_data/gameplay_content/linked_to_user=false -privacy/collected_data/gameplay_content/used_for_tracking=false -privacy/collected_data/gameplay_content/collection_purposes=0 -privacy/collected_data/customer_support/collected=false -privacy/collected_data/customer_support/linked_to_user=false -privacy/collected_data/customer_support/used_for_tracking=false -privacy/collected_data/customer_support/collection_purposes=0 -privacy/collected_data/other_user_content/collected=false -privacy/collected_data/other_user_content/linked_to_user=false -privacy/collected_data/other_user_content/used_for_tracking=false -privacy/collected_data/other_user_content/collection_purposes=0 -privacy/collected_data/browsing_history/collected=false -privacy/collected_data/browsing_history/linked_to_user=false -privacy/collected_data/browsing_history/used_for_tracking=false -privacy/collected_data/browsing_history/collection_purposes=0 -privacy/collected_data/search_hhistory/collected=false -privacy/collected_data/search_hhistory/linked_to_user=false -privacy/collected_data/search_hhistory/used_for_tracking=false -privacy/collected_data/search_hhistory/collection_purposes=0 -privacy/collected_data/user_id/collected=false -privacy/collected_data/user_id/linked_to_user=false -privacy/collected_data/user_id/used_for_tracking=false -privacy/collected_data/user_id/collection_purposes=0 -privacy/collected_data/device_id/collected=false -privacy/collected_data/device_id/linked_to_user=false -privacy/collected_data/device_id/used_for_tracking=false -privacy/collected_data/device_id/collection_purposes=0 -privacy/collected_data/purchase_history/collected=false -privacy/collected_data/purchase_history/linked_to_user=false -privacy/collected_data/purchase_history/used_for_tracking=false -privacy/collected_data/purchase_history/collection_purposes=0 -privacy/collected_data/product_interaction/collected=false -privacy/collected_data/product_interaction/linked_to_user=false -privacy/collected_data/product_interaction/used_for_tracking=false -privacy/collected_data/product_interaction/collection_purposes=0 -privacy/collected_data/advertising_data/collected=false -privacy/collected_data/advertising_data/linked_to_user=false -privacy/collected_data/advertising_data/used_for_tracking=false -privacy/collected_data/advertising_data/collection_purposes=0 -privacy/collected_data/other_usage_data/collected=false -privacy/collected_data/other_usage_data/linked_to_user=false -privacy/collected_data/other_usage_data/used_for_tracking=false -privacy/collected_data/other_usage_data/collection_purposes=0 -privacy/collected_data/crash_data/collected=false -privacy/collected_data/crash_data/linked_to_user=false -privacy/collected_data/crash_data/used_for_tracking=false -privacy/collected_data/crash_data/collection_purposes=0 -privacy/collected_data/performance_data/collected=false -privacy/collected_data/performance_data/linked_to_user=false -privacy/collected_data/performance_data/used_for_tracking=false -privacy/collected_data/performance_data/collection_purposes=0 -privacy/collected_data/other_diagnostic_data/collected=false -privacy/collected_data/other_diagnostic_data/linked_to_user=false -privacy/collected_data/other_diagnostic_data/used_for_tracking=false -privacy/collected_data/other_diagnostic_data/collection_purposes=0 -privacy/collected_data/environment_scanning/collected=false -privacy/collected_data/environment_scanning/linked_to_user=false -privacy/collected_data/environment_scanning/used_for_tracking=false -privacy/collected_data/environment_scanning/collection_purposes=0 -privacy/collected_data/hands/collected=false -privacy/collected_data/hands/linked_to_user=false -privacy/collected_data/hands/used_for_tracking=false -privacy/collected_data/hands/collection_purposes=0 -privacy/collected_data/head/collected=false -privacy/collected_data/head/linked_to_user=false -privacy/collected_data/head/used_for_tracking=false -privacy/collected_data/head/collection_purposes=0 -privacy/collected_data/other_data_types/collected=false -privacy/collected_data/other_data_types/linked_to_user=false -privacy/collected_data/other_data_types/used_for_tracking=false -privacy/collected_data/other_data_types/collection_purposes=0 ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -251,27 +100,22 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" -application/min_macos_version="10.12" [preset.1] name="Linux/X11" -platform="Linux" +platform="Linux/X11" runnable=true -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" -export_path="build_dir/Godots.x86_64" -patches=PackedStringArray() +export_path="../builds/godots/Godots.x86_64" encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.1.options] @@ -279,8 +123,10 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/s3tc_bptc=true -texture_format/etc2_astc=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false binary_format/architecture="x86_64" ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" @@ -294,30 +140,22 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false [preset.2] name="Windows Desktop" platform="Windows Desktop" runnable=true -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.exe" -patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.2.options] @@ -325,8 +163,10 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/s3tc_bptc=true -texture_format/etc2_astc=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false binary_format/architecture="x86_64" codesign/enable=false codesign/timestamp=true @@ -345,9 +185,6 @@ application/product_name="" application/file_description="" application/copyright="" application/trademarks="" -application/export_angle=0 -application/export_d3d12=0 -application/d3d12_agility_sdk_multiarch=true ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -365,7 +202,3 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue Remove-Item -Recurse -Force '{temp_dir}'" -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false diff --git a/project.godot b/project.godot index c02892c1..015d2f34 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/expand-region/plugin.cfg", "res://addons/find-everywhere/plugin.cfg", "res://addons/previous-tab/plugin.cfg", "res://addons/script-tabs/plugin.cfg", "res://addons/use-context/plugin.cfg") [filesystem] From 1c6656e7984699a0ce8a4dfae5cde2140a0262bc Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:11:24 -0300 Subject: [PATCH 07/23] Revert "Fix: handle debug builds and fix some vriable naming and comments" This reverts commit 41f28a6afffbbc808e20282422c87f25aa570401. --- .gitignore | 5 +- export_presets.cfg | 189 +++------------------------------------------ src/main/main.gd | 49 +++++------- 3 files changed, 30 insertions(+), 213 deletions(-) diff --git a/.gitignore b/.gitignore index de76f3f2..f95fe259 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Godot 4+ specific ignores .godot/ -# Export ignore -build_dir/ - # Godot-specific ignores .import/ export.cfg @@ -32,4 +29,4 @@ addons/gdUnit # Mac files .DS_Store -/override.cfg +/override.cfg \ No newline at end of file diff --git a/export_presets.cfg b/export_presets.cfg index fed955b6..851bddb1 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -3,20 +3,16 @@ name="macOS" platform="macOS" runnable=false -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.zip" -patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.0.options] @@ -34,11 +30,8 @@ application/short_version="1.0" application/version="1.0" application/copyright="" application/copyright_localized={} -application/min_macos_version_x86_64="10.12" -application/min_macos_version_arm64="11.00" -application/export_angle=0 +application/min_macos_version="10.12" display/high_res=true -application/additional_plist_content="" xcode/platform_build="14C18" xcode/sdk_version="13.1" xcode/sdk_build="22C55" @@ -71,9 +64,7 @@ codesign/entitlements/app_sandbox/files_downloads=0 codesign/entitlements/app_sandbox/files_pictures=0 codesign/entitlements/app_sandbox/files_music=0 codesign/entitlements/app_sandbox/files_movies=0 -codesign/entitlements/app_sandbox/files_user_selected=0 codesign/entitlements/app_sandbox/helper_executables=[] -codesign/entitlements/additional="" codesign/custom_options=PackedStringArray() notarization/notarization=0 privacy/microphone_usage_description="" @@ -98,148 +89,6 @@ privacy/network_volumes_usage_description="" privacy/network_volumes_usage_description_localized={} privacy/removable_volumes_usage_description="" privacy/removable_volumes_usage_description_localized={} -privacy/tracking_enabled=false -privacy/tracking_domains=PackedStringArray() -privacy/collected_data/name/collected=false -privacy/collected_data/name/linked_to_user=false -privacy/collected_data/name/used_for_tracking=false -privacy/collected_data/name/collection_purposes=0 -privacy/collected_data/email_address/collected=false -privacy/collected_data/email_address/linked_to_user=false -privacy/collected_data/email_address/used_for_tracking=false -privacy/collected_data/email_address/collection_purposes=0 -privacy/collected_data/phone_number/collected=false -privacy/collected_data/phone_number/linked_to_user=false -privacy/collected_data/phone_number/used_for_tracking=false -privacy/collected_data/phone_number/collection_purposes=0 -privacy/collected_data/physical_address/collected=false -privacy/collected_data/physical_address/linked_to_user=false -privacy/collected_data/physical_address/used_for_tracking=false -privacy/collected_data/physical_address/collection_purposes=0 -privacy/collected_data/other_contact_info/collected=false -privacy/collected_data/other_contact_info/linked_to_user=false -privacy/collected_data/other_contact_info/used_for_tracking=false -privacy/collected_data/other_contact_info/collection_purposes=0 -privacy/collected_data/health/collected=false -privacy/collected_data/health/linked_to_user=false -privacy/collected_data/health/used_for_tracking=false -privacy/collected_data/health/collection_purposes=0 -privacy/collected_data/fitness/collected=false -privacy/collected_data/fitness/linked_to_user=false -privacy/collected_data/fitness/used_for_tracking=false -privacy/collected_data/fitness/collection_purposes=0 -privacy/collected_data/payment_info/collected=false -privacy/collected_data/payment_info/linked_to_user=false -privacy/collected_data/payment_info/used_for_tracking=false -privacy/collected_data/payment_info/collection_purposes=0 -privacy/collected_data/credit_info/collected=false -privacy/collected_data/credit_info/linked_to_user=false -privacy/collected_data/credit_info/used_for_tracking=false -privacy/collected_data/credit_info/collection_purposes=0 -privacy/collected_data/other_financial_info/collected=false -privacy/collected_data/other_financial_info/linked_to_user=false -privacy/collected_data/other_financial_info/used_for_tracking=false -privacy/collected_data/other_financial_info/collection_purposes=0 -privacy/collected_data/precise_location/collected=false -privacy/collected_data/precise_location/linked_to_user=false -privacy/collected_data/precise_location/used_for_tracking=false -privacy/collected_data/precise_location/collection_purposes=0 -privacy/collected_data/coarse_location/collected=false -privacy/collected_data/coarse_location/linked_to_user=false -privacy/collected_data/coarse_location/used_for_tracking=false -privacy/collected_data/coarse_location/collection_purposes=0 -privacy/collected_data/sensitive_info/collected=false -privacy/collected_data/sensitive_info/linked_to_user=false -privacy/collected_data/sensitive_info/used_for_tracking=false -privacy/collected_data/sensitive_info/collection_purposes=0 -privacy/collected_data/contacts/collected=false -privacy/collected_data/contacts/linked_to_user=false -privacy/collected_data/contacts/used_for_tracking=false -privacy/collected_data/contacts/collection_purposes=0 -privacy/collected_data/emails_or_text_messages/collected=false -privacy/collected_data/emails_or_text_messages/linked_to_user=false -privacy/collected_data/emails_or_text_messages/used_for_tracking=false -privacy/collected_data/emails_or_text_messages/collection_purposes=0 -privacy/collected_data/photos_or_videos/collected=false -privacy/collected_data/photos_or_videos/linked_to_user=false -privacy/collected_data/photos_or_videos/used_for_tracking=false -privacy/collected_data/photos_or_videos/collection_purposes=0 -privacy/collected_data/audio_data/collected=false -privacy/collected_data/audio_data/linked_to_user=false -privacy/collected_data/audio_data/used_for_tracking=false -privacy/collected_data/audio_data/collection_purposes=0 -privacy/collected_data/gameplay_content/collected=false -privacy/collected_data/gameplay_content/linked_to_user=false -privacy/collected_data/gameplay_content/used_for_tracking=false -privacy/collected_data/gameplay_content/collection_purposes=0 -privacy/collected_data/customer_support/collected=false -privacy/collected_data/customer_support/linked_to_user=false -privacy/collected_data/customer_support/used_for_tracking=false -privacy/collected_data/customer_support/collection_purposes=0 -privacy/collected_data/other_user_content/collected=false -privacy/collected_data/other_user_content/linked_to_user=false -privacy/collected_data/other_user_content/used_for_tracking=false -privacy/collected_data/other_user_content/collection_purposes=0 -privacy/collected_data/browsing_history/collected=false -privacy/collected_data/browsing_history/linked_to_user=false -privacy/collected_data/browsing_history/used_for_tracking=false -privacy/collected_data/browsing_history/collection_purposes=0 -privacy/collected_data/search_hhistory/collected=false -privacy/collected_data/search_hhistory/linked_to_user=false -privacy/collected_data/search_hhistory/used_for_tracking=false -privacy/collected_data/search_hhistory/collection_purposes=0 -privacy/collected_data/user_id/collected=false -privacy/collected_data/user_id/linked_to_user=false -privacy/collected_data/user_id/used_for_tracking=false -privacy/collected_data/user_id/collection_purposes=0 -privacy/collected_data/device_id/collected=false -privacy/collected_data/device_id/linked_to_user=false -privacy/collected_data/device_id/used_for_tracking=false -privacy/collected_data/device_id/collection_purposes=0 -privacy/collected_data/purchase_history/collected=false -privacy/collected_data/purchase_history/linked_to_user=false -privacy/collected_data/purchase_history/used_for_tracking=false -privacy/collected_data/purchase_history/collection_purposes=0 -privacy/collected_data/product_interaction/collected=false -privacy/collected_data/product_interaction/linked_to_user=false -privacy/collected_data/product_interaction/used_for_tracking=false -privacy/collected_data/product_interaction/collection_purposes=0 -privacy/collected_data/advertising_data/collected=false -privacy/collected_data/advertising_data/linked_to_user=false -privacy/collected_data/advertising_data/used_for_tracking=false -privacy/collected_data/advertising_data/collection_purposes=0 -privacy/collected_data/other_usage_data/collected=false -privacy/collected_data/other_usage_data/linked_to_user=false -privacy/collected_data/other_usage_data/used_for_tracking=false -privacy/collected_data/other_usage_data/collection_purposes=0 -privacy/collected_data/crash_data/collected=false -privacy/collected_data/crash_data/linked_to_user=false -privacy/collected_data/crash_data/used_for_tracking=false -privacy/collected_data/crash_data/collection_purposes=0 -privacy/collected_data/performance_data/collected=false -privacy/collected_data/performance_data/linked_to_user=false -privacy/collected_data/performance_data/used_for_tracking=false -privacy/collected_data/performance_data/collection_purposes=0 -privacy/collected_data/other_diagnostic_data/collected=false -privacy/collected_data/other_diagnostic_data/linked_to_user=false -privacy/collected_data/other_diagnostic_data/used_for_tracking=false -privacy/collected_data/other_diagnostic_data/collection_purposes=0 -privacy/collected_data/environment_scanning/collected=false -privacy/collected_data/environment_scanning/linked_to_user=false -privacy/collected_data/environment_scanning/used_for_tracking=false -privacy/collected_data/environment_scanning/collection_purposes=0 -privacy/collected_data/hands/collected=false -privacy/collected_data/hands/linked_to_user=false -privacy/collected_data/hands/used_for_tracking=false -privacy/collected_data/hands/collection_purposes=0 -privacy/collected_data/head/collected=false -privacy/collected_data/head/linked_to_user=false -privacy/collected_data/head/used_for_tracking=false -privacy/collected_data/head/collection_purposes=0 -privacy/collected_data/other_data_types/collected=false -privacy/collected_data/other_data_types/linked_to_user=false -privacy/collected_data/other_data_types/used_for_tracking=false -privacy/collected_data/other_data_types/collection_purposes=0 ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -251,27 +100,22 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" -application/min_macos_version="10.12" [preset.1] name="Linux/X11" -platform="Linux" +platform="Linux/X11" runnable=true -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" -export_path="build_dir/Godots.x86_64" -patches=PackedStringArray() +export_path="../builds/godots/Godots.x86_64" encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.1.options] @@ -279,8 +123,10 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/s3tc_bptc=true -texture_format/etc2_astc=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false binary_format/architecture="x86_64" ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" @@ -294,30 +140,22 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false [preset.2] name="Windows Desktop" platform="Windows Desktop" runnable=true -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.exe" -patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.2.options] @@ -325,8 +163,10 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/s3tc_bptc=true -texture_format/etc2_astc=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false binary_format/architecture="x86_64" codesign/enable=false codesign/timestamp=true @@ -345,9 +185,6 @@ application/product_name="" application/file_description="" application/copyright="" application/trademarks="" -application/export_angle=0 -application/export_d3d12=0 -application/d3d12_agility_sdk_multiarch=true ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -365,7 +202,3 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue Remove-Item -Recurse -Force '{temp_dir}'" -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false diff --git a/src/main/main.gd b/src/main/main.gd index dee579f9..19bede85 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -1,8 +1,8 @@ extends Node const DESKTOP_ENTRY_FOLDER = ".local/share/applications" -const APP_FOLDER = ".local/godots.app" -const DESKTOP_ENTRY_NAME = "godots.desktop" +const GVM_APP_FOLDER = ".local/godots.app" +const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" @export_file() var gui_scene_path: String @@ -14,7 +14,7 @@ func _ready() -> void: # Check if running as Flatpak by checking for the .flatpak-info file var is_flatpak := FileAccess.file_exists("/.flatpak-info") - # Check and create Godots desktop entry if needed + # Check and create GVM desktop entry if needed if OS.get_name() == "Linux" and not OS.has_feature("editor") and not is_flatpak: _ensure_desktop_entry() @@ -39,44 +39,32 @@ func _is_cli_mode(args: PackedStringArray) -> bool: func _ensure_desktop_entry() -> void: var home := OS.get_environment("HOME") - var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(DESKTOP_ENTRY_NAME) - var app_path := home.path_join(APP_FOLDER) + var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) + var gvm_app_path := home.path_join(GVM_APP_FOLDER) - # Create godots.app folder and copy executable + # Create gvm.app folder and copy executable var dir := DirAccess.open("user://") - if dir.dir_exists(app_path): + if FileAccess.file_exists(gvm_app_path): return else: - dir.make_dir_recursive(app_path) + dir.make_dir_recursive(gvm_app_path) + # Copy the current executable to gvm.app folder var current_exe := OS.get_executable_path() - var new_exe_path := app_path.path_join("Godots.x86_64") - var run_path := new_exe_path - - var is_debug := OS.is_debug_build() - var script_path := current_exe.get_base_dir().path_join("Godots.sh") - - if is_debug and FileAccess.file_exists(script_path): - var new_script_path := app_path.path_join("Godots.sh") - if DirAccess.copy_absolute(script_path, new_script_path) == OK: - OS.execute("chmod", ["+x", new_script_path]) - run_path = new_script_path - else: - is_debug = false - + var new_exe_path := gvm_app_path.path_join("godots.x86_64") if DirAccess.copy_absolute(current_exe, new_exe_path) == OK: # Make it executable OS.execute("chmod", ["+x", new_exe_path]) # Create desktop entry # Copy and save the icon - var icon_path := app_path.path_join("icon.png") + var icon_path := gvm_app_path.path_join("icon.png") var icon := load("res://icon.svg") as Texture2D var image := icon.get_image() image.save_png(icon_path) # Create desktop entry - var desktop_entry := _create_desktop_entry(run_path, icon_path, is_debug) + var desktop_entry := _create_desktop_entry(new_exe_path, icon_path) var file := FileAccess.open(desktop_entry_path, FileAccess.WRITE) if file: file.store_string(desktop_entry) @@ -89,22 +77,21 @@ func _ensure_desktop_entry() -> void: printerr("Failed to copy executable") -func _create_desktop_entry(exec: String, icon: String, terminal: bool) -> String: +func _create_desktop_entry(exe_path: String, icon_path: String) -> String: return ( - """\ -[Desktop Entry] -Name=Godots + """[Desktop Entry] + Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec="{exec}" %f +Exec="{exe}" %f Icon={icon} -Terminal={terminal} +Terminal=false PrefersNonDefaultGPU=true Type=Application Categories=Development;IDE; StartupWMClass=Godot """ - . format({"exec": exec, "icon": icon, "terminal": terminal}) + . format({"exe": exe_path, "icon": icon_path}) ) From b834d981e897dea8eab19369bd6be8f60b4c67b8 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:12:11 -0300 Subject: [PATCH 08/23] Revert "chore: don't create desktop entry when launching from editor" This reverts commit 05698c0e5105cb87fadb0af1df59f347f8580d36. --- src/main/main.gd | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/main.gd b/src/main/main.gd index 19bede85..2b087a1c 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -7,6 +7,7 @@ const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" @export_file() var gui_scene_path: String + func _ready() -> void: var args := OS.get_cmdline_args() var user_args := OS.get_cmdline_user_args() @@ -15,7 +16,7 @@ func _ready() -> void: var is_flatpak := FileAccess.file_exists("/.flatpak-info") # Check and create GVM desktop entry if needed - if OS.get_name() == "Linux" and not OS.has_feature("editor") and not is_flatpak: + if OS.get_name() == "Linux" and not is_flatpak: _ensure_desktop_entry() if _is_cli_mode(args): @@ -28,7 +29,6 @@ func _ready() -> void: add_child.call_deferred((load(gui_scene_path) as PackedScene).instantiate()) pass - func _is_cli_mode(args: PackedStringArray) -> bool: if args.size() > 1 and OS.has_feature("editor"): return true @@ -36,7 +36,6 @@ func _is_cli_mode(args: PackedStringArray) -> bool: return true return false - func _ensure_desktop_entry() -> void: var home := OS.get_environment("HOME") var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) @@ -78,8 +77,7 @@ func _ensure_desktop_entry() -> void: func _create_desktop_entry(exe_path: String, icon_path: String) -> String: - return ( - """[Desktop Entry] + return """[Desktop Entry] Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! @@ -90,10 +88,9 @@ PrefersNonDefaultGPU=true Type=Application Categories=Development;IDE; StartupWMClass=Godot -""" - . format({"exe": exe_path, "icon": icon_path}) +""".format( + {"exe": exe_path, "icon": icon_path} ) - func _exit() -> void: get_tree().quit() From 215195eb1bf5b61af475591a64d9942a7f5c9108 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:12:13 -0300 Subject: [PATCH 09/23] Revert "chore: fix several erros and warnings" This reverts commit be959ccb5dd62e9d3d84d348130700caffc2eed1. --- plug.gd | 5 +- project.godot | 2 +- .../asset_lib_item_details.gd | 19 +- .../asset_lib_projects/asset_lib_projects.gd | 51 ++-- .../asset_list_item/asset_list_item.gd | 8 +- .../asset_lib_projects/assets_container.gd | 2 +- .../category_option_button.gd | 20 +- .../pagination_container.gd | 18 +- .../version_option_button.gd | 22 +- .../command_viewer/command_viewer.gd | 101 ++++--- .../local/editor_item/show_owners_dialog.gd | 32 +-- .../local/editors_list/editors_list.gd | 3 +- .../editors/local_remote_editors_switch.gd | 6 +- .../remote_editor_install.gd | 18 +- .../remote_editors_tree.gd | 55 ++-- .../remote_editors_tree/sources/github.gd | 256 +++++++----------- .../godots_releases/godots_releases.gd | 24 +- .../new_project_dialog/new_project_dialog.gd | 71 +++-- .../projects/project_item/project_item.gd | 74 ++--- src/components/projects/projects.gd | 32 +-- .../projects/projects_list/projects_list.gd | 3 +- src/components/settings/settings_window.gd | 120 ++++---- src/components/title_bar/title_bar.gd | 16 +- src/extensions/zip.gd | 22 +- src/http_client.gd | 24 +- src/main/gui/auto_updates.gd | 13 +- src/main/gui/gui_main.gd | 70 ++--- src/objects/node_component/comp_scene.gd | 4 +- src/services/godots_recent_releases.gd | 30 +- src/services/godots_releases.gd | 127 ++++----- src/services/local_editors.gd | 116 ++++---- src/services/projects.gd | 170 ++++++------ src/services/remote_image_src.gd | 52 ++-- src/utils.gd | 52 ++-- tests/cases/cli/parser/parser_not_ok.gd | 30 +- tests/cases/cli/parser/parser_ok.gd | 18 +- tests/cases/cli/parser/test_grammar.gd | 2 +- .../list_dir_recursive/list_dir_test.gd | 23 +- tests/cases/services/local_editor_tests.gd | 6 +- theme/fill_icons_registry.gd | 8 +- 40 files changed, 812 insertions(+), 913 deletions(-) diff --git a/plug.gd b/plug.gd index 8d8e42bc..6c722928 100644 --- a/plug.gd +++ b/plug.gd @@ -1,11 +1,10 @@ -@tool extends "res://addons/gd-plug/plug.gd" -func _plugging() -> void: +func _plugging(): plug("MikeSchulze/gdUnit4", {"commit": "8226bc34faaa9fde7829b065fa51b63a8fe140c4"}) plug("MakovWait/godot-use-context") - + if "--include-editor" in OS.get_cmdline_args(): plug("MakovWait/godot-expand-region", {"exclude": ["addons/gdUnit4"]}) plug("MakovWait/godot-find-everywhere") diff --git a/project.godot b/project.godot index b3a381b6..c02892c1 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg", "res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/use-context/plugin.cfg") [filesystem] diff --git a/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd b/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd index a1c85073..7da925c0 100644 --- a/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd +++ b/src/components/asset_lib_projects/asset_lib_item_details/asset_lib_item_details.gd @@ -26,8 +26,7 @@ func _ready() -> void: _preview.custom_minimum_size = Vector2(640, 345) * Config.EDSCALE _preview_bg.custom_minimum_size = Vector2(640, 101) * Config.EDSCALE - - @warning_ignore("redundant_await") + var item := await _asset_lib.async_fetch_one(_item_id) _configure(item) @@ -41,8 +40,7 @@ func _configure(item: AssetLib.Item) -> void: title = item.title var first_preview_selected := false for preview in item.previews: - @warning_ignore("redundant_await") - var btn := await add_preview(preview) + var btn := add_preview(preview) if not first_preview_selected and not preview.is_video: first_preview_selected = true _handle_btn_pressed.bind(preview, btn).call_deferred() @@ -54,11 +52,10 @@ func add_preview(item: AssetLib.ItemPreview) -> Button: btn.toggle_mode = true btn.pressed.connect(_handle_btn_pressed.bind(item, btn)) _previews_container.add_child(btn) - @warning_ignore("redundant_await") - await _images_src.async_load_img(item.thumbnail, func(tex: Texture2D) -> void: + _images_src.async_load_img(item.thumbnail, func(tex: Texture2D) -> void: if not item.is_video: if tex is ImageTexture: - utils.fit_height(85 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(85 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: (tex as ImageTexture).set_size_override(new_size) ) btn.icon = tex @@ -67,13 +64,13 @@ func add_preview(item: AssetLib.ItemPreview) -> Button: var tex_image: Image = tex.get_image() if tex_image == null: tex_image = get_theme_icon("FileBrokenBigThumb", "EditorIcons").get_image() - utils.fit_height(85 * Config.EDSCALE, tex_image.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(85 * Config.EDSCALE, tex_image.get_size(), func(new_size: Vector2i) -> void: tex_image.resize(new_size.x, new_size.y, Image.INTERPOLATE_LANCZOS) ) var thumbnail := tex_image.duplicate() as Image var overlay_pos := Vector2i( - int((thumbnail.get_width() - overlay.get_width()) / 2.0), - int((thumbnail.get_height() - overlay.get_height()) / 2.0) + (thumbnail.get_width() - overlay.get_width()) / 2, + (thumbnail.get_height() - overlay.get_height()) / 2 ) thumbnail.convert(Image.FORMAT_RGBA8) thumbnail.blend_rect(overlay, overlay.get_used_rect(), overlay_pos) @@ -92,7 +89,7 @@ func _handle_btn_pressed(item: AssetLib.ItemPreview, btn: Button) -> void: else: _images_src.async_load_img(item.link, func(tex: Texture2D) -> void: if tex is ImageTexture: - utils.fit_height(397 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: + utils.fit_height(397 * Config.EDSCALE, tex.get_size(), func(new_size: Vector2i) -> void: (tex as ImageTexture).set_size_override(new_size) ) _preview.texture = tex diff --git a/src/components/asset_lib_projects/asset_lib_projects.gd b/src/components/asset_lib_projects/asset_lib_projects.gd index e38e9e9c..d9d2c0c0 100644 --- a/src/components/asset_lib_projects/asset_lib_projects.gd +++ b/src/components/asset_lib_projects/asset_lib_projects.gd @@ -10,7 +10,7 @@ signal download_requested(item: AssetLib.Item, icon: Texture2D) @onready var _assets_container := %AssetsContainer as AssetsContainer @onready var _filter_edit := %FilterEdit as LineEdit @onready var _version_option_button := %VersionOptionButton as GodotVersionOptionButton -#@onready var _sort_option_button := %SortOptionButton as OptionButton +@onready var _sort_option_button := %SortOptionButton as OptionButton @onready var _category_option_button := %CategoryOptionButton as AssetCategoryOptionButton @onready var _site_option_button := %SiteOptionButton as AssetLibProjectsSiteOptionButton @onready var _support_menu_button := %SupportMenuButton as AssetLibProjectsSupportMenuButton @@ -23,8 +23,8 @@ var _params_sources_composed: ParamSources var _asset_lib_factory: AssetLib.Factory var _current_page := 0 -#var _top_pages: HBoxContainer -#var _bottom_pages: HBoxContainer +var _top_pages: HBoxContainer +var _bottom_pages: HBoxContainer var _versions_loaded := false var _config_loaded := false var _initial_fetch := false @@ -33,7 +33,7 @@ var _next_fetch_queued := false func init( - asset_lib_factory: AssetLib.Factory, + asset_lib_factory: AssetLib.Factory, category_src: AssetCategoryOptionButton.Src, version_src: GodotVersionOptionButton.Src, images_src: RemoteImageSrc.I @@ -41,20 +41,20 @@ func init( _category_option_button.init(category_src) _version_option_button.init(version_src) _asset_lib_factory = asset_lib_factory - + _assets_container.init(images_src) _assets_container.title_pressed.connect(func(item: AssetLib.Item) -> void: var asset_lib := _get_asset_lib() var item_details: AssetLibItemDetailsDialog = _item_details_scene.instantiate() - item_details.download_requested.connect(func(asset: AssetLib.Item, icon: Texture2D) -> void: + item_details.download_requested.connect(func(item: AssetLib.Item, icon: Texture2D) -> void: download_requested.emit(item, icon) ) item_details.init(item.id as String, asset_lib, images_src) add_child(item_details) item_details.popup_centered() ) - _assets_container.category_pressed.connect(func(asset: AssetLib.Item) -> void: - _category_option_button.force_select_by_label(asset.category) + _assets_container.category_pressed.connect(func(item: AssetLib.Item) -> void: + _category_option_button.force_select_by_label(item.category) ) if is_visible_in_tree(): @@ -72,23 +72,23 @@ func _init() -> void: func _ready() -> void: _params_sources_composed = ParamSources.new(_params_sources) - - (%LibVb as Control).add_theme_constant_override("separation", int(20 * Config.EDSCALE)) + + (%LibVb as Control).add_theme_constant_override("separation", 20 * Config.EDSCALE) _filter_edit.placeholder_text = tr("Search Templates, Projects, and Demos") - - _assets_container.add_theme_constant_override("h_separation", int(10 * Config.EDSCALE)) - _assets_container.add_theme_constant_override("v_separation", int(10 * Config.EDSCALE)) - + + _assets_container.add_theme_constant_override("h_separation", 10 * Config.EDSCALE) + _assets_container.add_theme_constant_override("v_separation", 10 * Config.EDSCALE) + _params_sources_composed.connect_changed(func() -> void: _current_page = 0 _async_fetch() ) - + _site_option_button.site_selected.connect(func() -> void: _config_loaded = false _async_fetch() ) - + (%TopPagesContainer as PaginationContainer).page_changed.connect(_change_page) (%BotPagesContainer as PaginationContainer).page_changed.connect(_change_page) @@ -102,19 +102,17 @@ func _async_fetch() -> void: _next_fetch_queued = false if not _versions_loaded: - @warning_ignore("redundant_await") var version_error := await __async_load_versions_list() if version_error: return - + if not _config_loaded: var config_error := await __async_load_configuration() if config_error: return - - @warning_ignore("redundant_await") + await __async_fetch_assets() - + _fetching = false if _next_fetch_queued: _async_fetch() @@ -128,7 +126,6 @@ func __async_load_versions_list() -> Error: _assets_container.clear() _clear_pages() - @warning_ignore("redundant_await") var versions_load_errors := await _version_option_button.async_load_versions() var return_error: Error if len(versions_load_errors) > 0: @@ -156,7 +153,6 @@ func __async_load_configuration() -> Error: _scroll_container.dim() _error_container.hide() - @warning_ignore("redundant_await") var config_load_errors := await _category_option_button.async_load_items( _site_option_button.get_selected_site() ) @@ -185,7 +181,6 @@ func __async_fetch_assets() -> void: var asset_lib := _get_asset_lib() var params := _get_asset_lib_params() var errors: Array[String] = [] - @warning_ignore("redundant_await") var items := await asset_lib.async_fetch(params, errors) if len(errors) > 0: @@ -258,15 +253,15 @@ func _set_status(text: String) -> void: class ParamSources: var _elements: Array - + func _init(elements: Array) -> void: _elements = elements - + func enable() -> void: for x: Object in _elements: if x.has_method("_on_fetch_enable"): x.call("_on_fetch_enable") - + func disable() -> void: for x: Object in _elements: if x.has_method("_on_fetch_disable"): @@ -276,7 +271,7 @@ class ParamSources: for x: Object in _elements: if x.has_signal("changed"): x.connect("changed", callback) - + func fill_params(params: AssetLib.Params) -> void: for x: Object in _elements: if x.has_method("fill_params"): diff --git a/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd b/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd index c1369b7d..3fffe404 100644 --- a/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd +++ b/src/components/asset_lib_projects/asset_list_item/asset_list_item.gd @@ -19,7 +19,7 @@ var _original_title_text: String func _init() -> void: custom_minimum_size = Vector2i(DEFAULT_MIN_SIZE_X, 100) * Config.EDSCALE - add_theme_constant_override("separation", int(15 * Config.EDSCALE)) + add_theme_constant_override("separation", 15 * Config.EDSCALE) func _ready() -> void: @@ -34,9 +34,9 @@ func init(item: AssetLib.Item, images: RemoteImageSrc.I) -> void: _category.text = item.category _author.text = item.author _cost.text = item.cost - + _original_title_text = item.title - + _title.pressed.connect(func() -> void: title_pressed.emit(item) ) @@ -69,5 +69,5 @@ func clamp_width(max_width: int) -> void: if text_pixel_width > max_width: # Truncate title text to within the current column width. var max_length := max_width / (text_pixel_width / full_text.length()) - var truncated_text := full_text.left(int(max_length - 3)) + "..." + var truncated_text := full_text.left(max_length - 3) + "..." _title.text = truncated_text diff --git a/src/components/asset_lib_projects/assets_container.gd b/src/components/asset_lib_projects/assets_container.gd index 11612f09..81e452e9 100644 --- a/src/components/asset_lib_projects/assets_container.gd +++ b/src/components/asset_lib_projects/assets_container.gd @@ -45,7 +45,7 @@ func _update_columns() -> void: new_columns = max(1, new_columns) # prints(size.x, new_columns, (size.x / new_columns) - (100 * Config.EDSCALE)) if new_columns != columns: - columns = int(new_columns) + columns = new_columns # for c in get_children(): # if c.has_method('clamp_width'): # c.clamp_width((size.x / new_columns) - (100 * Config.EDSCALE)) diff --git a/src/components/asset_lib_projects/category_option_button.gd b/src/components/asset_lib_projects/category_option_button.gd index 53c74451..e04ee764 100644 --- a/src/components/asset_lib_projects/category_option_button.gd +++ b/src/components/asset_lib_projects/category_option_button.gd @@ -1,8 +1,10 @@ class_name AssetCategoryOptionButton extends OptionButton + signal changed + var _src: Src @@ -17,10 +19,8 @@ func _init() -> void: func async_load_items(url: String) -> Array[String]: clear() - @warning_ignore("redundant_await") - await add_item(tr("All"), 0) + add_item(tr("All"), 0) var errors: Array[String] = [] - @warning_ignore("redundant_await") var json := await _src.async_load(url, errors) for category: Dictionary in json.get("categories", []): add_item(tr(category.name as String), category.id as int) @@ -51,17 +51,15 @@ func force_select_by_label(opt_label: String) -> void: class Src: - func async_load(url: String, errors: Array[String] = []) -> Dictionary: + func async_load(url: String, errors: Array[String]=[]) -> Dictionary: return {} -class SrcRemote: - extends Src - - func async_load(url: String, errors: Array[String] = []) -> Dictionary: - var response := HttpClient.Response.new( - await HttpClient.async_http_get(url.path_join("configure?type=project")) - ) +class SrcRemote extends Src: + func async_load(url: String, errors: Array[String]=[]) -> Dictionary: + var response := HttpClient.Response.new(await HttpClient.async_http_get( + url.path_join("configure?type=project") + )) var info := response.to_response_info(url) if info.error_text: errors.append(info.error_text) diff --git a/src/components/asset_lib_projects/pagination_container.gd b/src/components/asset_lib_projects/pagination_container.gd index e8afab5d..1d7d3c52 100644 --- a/src/components/asset_lib_projects/pagination_container.gd +++ b/src/components/asset_lib_projects/pagination_container.gd @@ -22,25 +22,25 @@ func clear() -> void: func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> HBoxContainer: var hbc := HBoxContainer.new() hbc.alignment = HBoxContainer.ALIGNMENT_CENTER - + if page_count < 2: return hbc - + var from := page - (5 / Config.EDSCALE) if from < 0: from = 0 var to := from + (10 / Config.EDSCALE) if to > page_count: to = page_count - + hbc.add_spacer(false) - hbc.add_theme_constant_override("separation", int(5 * Config.EDSCALE)) - + hbc.add_theme_constant_override("separation", 5 * Config.EDSCALE) + var trigger_search := func(btn: Button, p: int) -> void: btn.pressed.connect(func() -> void: page_changed.emit(p) ) - + var first := Button.new() first.text = tr("First", "Pagination") if page != 0: @@ -49,7 +49,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> first.set_disabled(true) first.set_focus_mode(Control.FOCUS_NONE) hbc.add_child(first) - + var prev := Button.new() prev.text = tr("Previous", "Pagination") if page > 0: @@ -59,7 +59,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> prev.set_focus_mode(Control.FOCUS_NONE) hbc.add_child(prev) hbc.add_child(VSeparator.new()) - + for i in range(from, to): if i == page: var current := Button.new() @@ -76,7 +76,7 @@ func _make_pages(page: int, page_count: int, page_len: int, total_items: int) -> trigger_search.call(current, i) hbc.add_child(current) - + var next := Button.new() next.set_text(tr("Next", "Pagination")) if page < page_count - 1: diff --git a/src/components/asset_lib_projects/version_option_button.gd b/src/components/asset_lib_projects/version_option_button.gd index 5f6f0de6..90a15390 100644 --- a/src/components/asset_lib_projects/version_option_button.gd +++ b/src/components/asset_lib_projects/version_option_button.gd @@ -17,7 +17,6 @@ func init(src: Src) -> void: func async_load_versions() -> Array[String]: clear() var errors: Array[String] = [] - @warning_ignore("redundant_await") var versions := await _src.async_fetch(errors) for i in range(len(versions)): add_item(versions[i]) @@ -30,31 +29,28 @@ func fill_params(params: AssetLib.Params) -> void: class Src: - func async_fetch(errors: Array[String] = []) -> PackedStringArray: + func async_fetch(errors: Array[String]=[]) -> PackedStringArray: return [] -class SrcMock: - extends Src +class SrcMock extends Src: var _data: PackedStringArray - + func _init(data: PackedStringArray) -> void: _data = data - - func async_fetch(errors: Array[String] = []) -> PackedStringArray: + + func async_fetch(errors: Array[String]=[]) -> PackedStringArray: return _data -class SrcGithubYml: - extends Src +class SrcGithubYml extends Src: var _yml_src: RemoteEditorsTreeDataSourceGithub.YmlSource var _name_regex := RegEx.create_from_string('(?m)\\sname:\\s"(?[^"]+)"$') - + func _init(yml_src: RemoteEditorsTreeDataSourceGithub.YmlSource) -> void: _yml_src = yml_src - - func async_fetch(errors: Array[String] = []) -> PackedStringArray: - @warning_ignore("redundant_await") + + func async_fetch(errors: Array[String]=[]) -> PackedStringArray: var yml := await _yml_src.async_load(errors) var versions := _name_regex.search_all(yml) var result: PackedStringArray = [] diff --git a/src/components/command_viewer/command_viewer.gd b/src/components/command_viewer/command_viewer.gd index 7ad7b533..d25477d1 100644 --- a/src/components/command_viewer/command_viewer.gd +++ b/src/components/command_viewer/command_viewer.gd @@ -22,16 +22,16 @@ func _ready() -> void: if not visible: _commands = null ) - + var help := add_button(tr("Help")) help.pressed.connect(func() -> void: OS.shell_open("https://github.com/MakovWait/godots/blob/main/.github/assets/FEATURES.md#edit-commands") ) help.icon = get_theme_icon("ExternalLink", "EditorIcons") - + _create_new_command_btn = add_button(tr("New Command")) _create_new_command_btn.pressed.connect(func() -> void: - _popup_new_command_dialog("", "", [], "Terminal", false, + _popup_new_command_dialog("", "", [], "Terminal", false, func(cmd_name: String, cmd_path: String, cmd_args: PackedStringArray, cmd_icon: String, is_local: bool) -> void: if _commands: var command := _commands.add( @@ -60,7 +60,7 @@ func _update_view(commands: Commands, command_creation_allowed:=false) -> void: if c.has_method("hide"): c.call("hide") c.queue_free() - + for command in commands.all(): _add_view(command, commands) @@ -98,7 +98,7 @@ func _add_view(command: Command, commands: Commands) -> void: var output_text := "" if len(output) > 0: output_text = output[0] - + var rich_text_label := %OutputLabel as RichTextLabel rich_text_label.custom_minimum_size = Vector2i(0, 100) * Config.EDSCALE rich_text_label.clear() @@ -125,8 +125,8 @@ func _add_view(command: Command, commands: Commands) -> void: func _set_text_to_command_view(command: Command, command_view: CommandTextView) -> void: var local_badge := tr("Local") if command.is_local() else tr("Global") command_view.set_text( - "%s (%s):" % [command.name(), local_badge], - "", + "%s (%s):" % [command.name(), local_badge], + "", str(command), command.icon() ) @@ -155,14 +155,14 @@ class Command: var _icon: String var _process_src: OSProcessSchema.Source var _allowed_actions: PackedStringArray - + func _init( name: String, path: String, args: PackedStringArray, icon: String, - is_local: bool, - process_src: OSProcessSchema.Source, + is_local: bool, + process_src: OSProcessSchema.Source, allowed_actions: PackedStringArray ) -> void: _icon = icon @@ -172,36 +172,36 @@ class Command: _is_local = is_local _process_src = process_src _allowed_actions = allowed_actions - + func icon() -> String: return _icon - + func is_local() -> bool: return _is_local - + func is_action_allowed(action: String) -> bool: return action in _allowed_actions - + func args() -> PackedStringArray: return _args - + func path() -> String: return _path - + func name() -> String: return _name - + func execute(output:=[]) -> int: return _process_src.get_os_process_schema(_path, _args).execute( output, true, true ) - + func create_process() -> void: _process_src.get_os_process_schema(_path, _args).create_process(true) - + func remove_from(commands: Commands) -> void: commands.remove(_name, _is_local) - + func _to_string() -> String: return str(_process_src.get_os_process_schema(_path, _args)) @@ -209,11 +209,11 @@ class Command: class Commands: func all() -> Array[Command]: return [] - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: - # assert(true, "Not implemented") <- Why??? assert true is redundant + assert(true, "Not implemented") return null - + func remove(name: String, is_local: bool) -> void: pass @@ -222,10 +222,10 @@ class CustomCommandsSource: var custom_commands: Array: get: return _get_custom_commands() set(value): _set_custom_commands(value) - + func _get_custom_commands() -> Array: return [] - + func _set_custom_commands(value: Array) -> void: pass @@ -248,28 +248,28 @@ class CommandsInMemory extends CommandsWrap: class CustomCommandsSourceArray extends CustomCommandsSource: var _data: Array[Dictionary] = [] - + func _init(data: Array[Dictionary]=[]) -> void: _data = data - + func _get_custom_commands() -> Array: return _data - + func _set_custom_commands(value: Array) -> void: _data = value class CustomCommandsSourceDynamic extends CustomCommandsSource: signal edited - + var _delegate: Object - + func _init(delegate: Object) -> void: _delegate = delegate - + func _get_custom_commands() -> Array: return _delegate.get("custom_commands") - + func _set_custom_commands(value: Array) -> void: _delegate.set("custom_commands", value) edited.emit() @@ -278,23 +278,23 @@ class CustomCommandsSourceDynamic extends CustomCommandsSource: class CommandsDuo extends Commands: var _local: Commands var _global: Commands - + func _init(local: Commands, global: Commands) -> void: _local = local _global = global - + func all() -> Array[Command]: var result: Array[Command] = [] result.append_array(_global.all()) result.append_array(_local.all()) return result - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: if is_local: return _local.add(name, path, args, is_local, icon, allowed_actions) else: return _global.add(name, path, args, is_local, icon, allowed_actions) - + func remove(name: String, is_local: bool) -> void: if is_local: return _local.remove(name, is_local) @@ -304,27 +304,27 @@ class CommandsDuo extends Commands: class CommandsWrap extends Commands: var _origin: Commands - + func _init(origin: Commands) -> void: _origin = origin - + func all() -> Array[Command]: return _origin.all() - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: return _origin.add(name, path, args, is_local, icon, allowed_actions) - + func remove(name: String, is_local: bool) -> void: _origin.remove(name, is_local) class CommandsWithBasic extends CommandsWrap: var _basic: Array[Command] - + func _init(origin: Commands, basic: Array[Command]) -> void: super._init(origin) _basic = basic - + func all() -> Array[Command]: var result: Array[Command] result.append_array(_basic) @@ -336,12 +336,12 @@ class CommandsGeneric extends Commands: var _custom_commands_source: CustomCommandsSource var _base_process_src: OSProcessSchema.Source var _is_local: bool - + func _init(base_process_src: OSProcessSchema.Source, custom_commands_source: CustomCommandsSource, is_local: bool) -> void: _base_process_src = base_process_src _custom_commands_source = custom_commands_source _is_local = is_local - + func all() -> Array[Command]: var result: Array[Command] var commands := _custom_commands_source.custom_commands @@ -354,7 +354,7 @@ class CommandsGeneric extends Commands: _is_local ))) return result - + func add(name: String, path: String, args: PackedStringArray, is_local: bool, icon: String, allowed_actions: PackedStringArray) -> Command: if is_local == _is_local: var commands := _custom_commands_source.custom_commands @@ -382,22 +382,21 @@ class CommandsGeneric extends Commands: _custom_commands_source.custom_commands = commands return _to_command(name, path, args, allowed_actions, icon, is_local) else: - # assert(true, "Not implemented") <- Again? + assert(true, "Not implemented") return null - + func remove(name: String, is_local: bool) -> void: if is_local == _is_local: var commands := _custom_commands_source.custom_commands commands = commands.filter(func(x: Dictionary) -> bool: return x.name != name) _custom_commands_source.custom_commands = commands else: - # assert(true, "Not implemented") <- ;-; - pass - + assert(true, "Not implemented") + func _has_by_name(name: String) -> bool: return len( _custom_commands_source.custom_commands.filter(func(x: Dictionary) -> bool: return x.name == name) ) > 0 - + func _to_command(name: String, path: String, args: PackedStringArray, allowed_actions: PackedStringArray, icon: String, is_local: bool) -> Command: return Command.new(name, path, args, icon, is_local, _base_process_src, allowed_actions) diff --git a/src/components/editors/local/editor_item/show_owners_dialog.gd b/src/components/editors/local/editor_item/show_owners_dialog.gd index 05f2260b..c9fb19c7 100644 --- a/src/components/editors/local/editor_item/show_owners_dialog.gd +++ b/src/components/editors/local/editor_item/show_owners_dialog.gd @@ -19,31 +19,31 @@ func raise(editor: LocalEditors.Item) -> void: var item := _tree.create_item() var icon_image: Image = owner.icon.get_image().duplicate() icon_image.resize( - int(16 * Config.EDSCALE), - int(16 * Config.EDSCALE), + 16 * Config.EDSCALE, + 16 * Config.EDSCALE, Image.INTERPOLATE_LANCZOS ) item.set_icon(0, ImageTexture.create_from_image(icon_image)) item.set_text(0, owner.name) item.add_button( - 0, - get_theme_icon("Play", "EditorIcons"), - Buttons.RUN, - not owner.is_valid, + 0, + get_theme_icon("Play", "EditorIcons"), + Buttons.RUN, + not owner.is_valid, tr("Run") ) item.add_button( - 0, - get_theme_icon("Edit", "EditorIcons"), - Buttons.EDIT, - not owner.is_valid, + 0, + get_theme_icon("Edit", "EditorIcons"), + Buttons.EDIT, + not owner.is_valid, tr("Edit") ) item.add_button( - 0, - get_theme_icon("Folder", "EditorIcons"), - Buttons.OPEN_IN_EXPLORER, - not owner.is_valid, + 0, + get_theme_icon("Folder", "EditorIcons"), + Buttons.OPEN_IN_EXPLORER, + not owner.is_valid, tr("Show in File Manager") ) item.set_metadata(0, owner) @@ -57,7 +57,7 @@ func _ready() -> void: if not visible: queue_free() ) - + _tree.button_clicked.connect(func(item: TreeItem, column: int, id: int, mouse_button_index: int) -> void: var project: Projects.Item = item.get_metadata(0) if id == Buttons.EDIT: @@ -69,6 +69,6 @@ func _ready() -> void: ProjectSettings.globalize_path(project.path) ) ) - + _tree.create_item() _tree.hide_root = true diff --git a/src/components/editors/local/editors_list/editors_list.gd b/src/components/editors/local/editors_list/editors_list.gd index d7fa0f9d..8678d8a7 100644 --- a/src/components/editors/local/editors_list/editors_list.gd +++ b/src/components/editors/local/editors_list/editors_list.gd @@ -29,13 +29,14 @@ func _item_comparator(a: Dictionary, b: Dictionary) -> bool: 1: return a.path < b.path 2: return a.tag_sort_string < b.tag_sort_string _: return a.name < b.name + return a.name < b.name func _fill_sort_options(btn: OptionButton) -> void: btn.add_item(tr("Name")) btn.add_item(tr("Path")) btn.add_item(tr("Tags")) - + var last_checked_sort := Cache.smart_value(self, "last_checked_sort", true) btn.select(last_checked_sort.ret(0) as int) btn.item_selected.connect(func(idx: int) -> void: last_checked_sort.put(idx)) diff --git a/src/components/editors/local_remote_editors_switch.gd b/src/components/editors/local_remote_editors_switch.gd index e9ee320a..b8218d74 100644 --- a/src/components/editors/local_remote_editors_switch.gd +++ b/src/components/editors/local_remote_editors_switch.gd @@ -18,9 +18,9 @@ func _ready() -> void: ctx.go_to_remote() _local.set_pressed_no_signal(true) ) - - add_theme_constant_override("separation", int(48 * Config.EDSCALE)) - + + add_theme_constant_override("separation", 48 * Config.EDSCALE) + _set_theme_to(_local) _set_theme_to(_remote) diff --git a/src/components/editors/remote/remote_editor_install/remote_editor_install.gd b/src/components/editors/remote/remote_editor_install/remote_editor_install.gd index d985cd0b..e692d9b5 100644 --- a/src/components/editors/remote/remote_editor_install/remote_editor_install.gd +++ b/src/components/editors/remote/remote_editor_install/remote_editor_install.gd @@ -7,12 +7,12 @@ signal installed(editor_name: String, editor_exec_path: String) @onready var _editor_name_edit: LineEdit = %EditorNameEdit @onready var _select_exec_file_tree: Tree = %SelectExecFileTree -#@onready var _file_dialog := $FileDialog as FileDialog +@onready var _file_dialog := $FileDialog as FileDialog @onready var _show_all_check_box := %ShowAllCheckBox as CheckBox var _dir_content: Array[edir.DirListResult] -#var _show_all: bool: - #get: return _show_all_check_box.button_pressed +var _show_all: bool: + get: return _show_all_check_box.button_pressed func _ready() -> void: @@ -44,20 +44,20 @@ func init(editor_name: String, editor_exec_path: String) -> void: func _setup_editor_select_tree() -> void: _select_exec_file_tree.clear() var root := _select_exec_file_tree.create_item() - + ## filter: Optional[Callable], should_be_selected: Optional[Callable] - var create_tree_items := func(source: Array[edir.DirListResult], _filter: Variant = null, _should_be_selected: Variant = null) -> void: + var create_tree_items := func(source: Array[edir.DirListResult], filter: Variant = null, should_be_selected: Variant = null) -> void: var selected := false for x in source: - if _filter and not (_filter as Callable).call(x): + if filter and not (filter as Callable).call(x): continue var item := _select_exec_file_tree.create_item(root) item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK) item.set_text(0, x.file) item.set_editable(0, true) item.set_meta("full_path", x.path) - if not selected and _should_be_selected != null: - if (_should_be_selected as Callable).call(x): + if not selected and should_be_selected != null: + if (should_be_selected as Callable).call(x): selected = true item.set_checked(0, true) item.select(0) @@ -83,7 +83,7 @@ func _setup_editor_select_tree() -> void: return x.is_file and ( x.extension.contains("32") or x.extension.contains("64") ) - + create_tree_items.call(_dir_content, filter, should_be_selected) diff --git a/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd b/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd index e898aab0..619c09f8 100644 --- a/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd +++ b/src/components/editors/remote/remote_editors_tree/remote_editors_tree.gd @@ -10,14 +10,14 @@ const uuid = preload("res://addons/uuid.gd") @onready var _check_box_container: HFlowContainer = %CheckBoxContainer var _refresh_button: Button -#var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets +var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets var _src: RemoteEditorsTreeDataSource.I var _i_remote_tree: RemoteEditorsTreeDataSource.RemoteTree var _root_loaded := false var _row_filters: Array[RowFilter] = [NotRelatedFilter.new()] var _current_loadings_number := 0: - set(value): + set(value): _current_loadings_number = value _loadings_number_changed.emit(value) var _remote_editors_checkbox_checked := Cache.smart_section( @@ -27,7 +27,7 @@ var _remote_editors_checkbox_checked := Cache.smart_section( func post_ready(refresh_button: Button) -> void: _refresh_button = refresh_button - + _setup_tree() _setup_checkboxes() @@ -61,7 +61,7 @@ func _refresh() -> void: func _setup_checkboxes() -> void: (%CheckBoxPanelContainer as PanelContainer).add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Tree")) - + var checkbox := func(text: String, filter: RowFilter, button_pressed:=false) -> CheckBox: var box := CheckBox.new() box.text = text @@ -69,7 +69,7 @@ func _setup_checkboxes() -> void: if button_pressed: _row_filters.append(filter) box.toggled.connect(func(pressed: bool) -> void: - if pressed: + if pressed: _row_filters.append(filter) else: var idx := _row_filters.find(filter) @@ -86,7 +86,7 @@ func _setup_checkboxes() -> void: if not button_pressed: _row_filters.append(filter) box.toggled.connect(func(pressed: bool) -> void: - if pressed: + if pressed: var idx := _row_filters.find(filter) if idx >= 0: _row_filters.remove_at(idx) @@ -98,32 +98,32 @@ func _setup_checkboxes() -> void: return box var contains_any := func(words: Array) -> Callable: - return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return words.any(func(x: String) -> bool: return row.get_name().to_lower().contains(x.to_lower())) - + var _not := func(original: Callable) -> Callable: return func(row: RemoteEditorsTreeDataSource.FilterTarget) -> Callable: return not original.call(row) - + _check_box_container.add_child( inverted_checkbox.call( - tr("mono"), + tr("mono"), RowFilter.new(contains_any.call(["mono"]) as Callable), _remote_editors_checkbox_checked.get_value("mono", true) ) as CheckBox ) - + _check_box_container.add_child( inverted_checkbox.call( - tr("unstable"), + tr("unstable"), RowFilter.new(contains_any.call(["rc", "beta", "alpha", "dev", "fixup"]) as Callable), _remote_editors_checkbox_checked.get_value("unstable", false) ) as CheckBox ) - + _check_box_container.add_child( inverted_checkbox.call( - tr("any platform"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("any platform"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_file() and row.is_for_different_platform(_src.get_platform_suffixes())), _remote_editors_checkbox_checked.get_value("any platform", false) ) as CheckBox @@ -141,7 +141,7 @@ func _setup_checkboxes() -> void: if bit: _check_box_container.add_child( checkbox.call( - "%s-bit" % bit, + "%s-bit" % bit, RowFilter.new(contains_any.call([opposite]) as Callable), _remote_editors_checkbox_checked.get_value("%s-bit" % bit, true) ) as CheckBox @@ -149,8 +149,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("4.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("4.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and row.get_name().begins_with("4")), _remote_editors_checkbox_checked.get_value("4.x", true) ) as CheckBox @@ -158,8 +158,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("3.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("3.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and row.get_name().begins_with("3")), _remote_editors_checkbox_checked.get_value("3.x", true) ) as CheckBox @@ -167,8 +167,8 @@ func _setup_checkboxes() -> void: _check_box_container.add_child( inverted_checkbox.call( - tr("x.x"), - RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + tr("x.x"), + RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.is_possible_version_folder() and not (row.get_name().begins_with("4") or row.get_name().begins_with("3"))), _remote_editors_checkbox_checked.get_value("x.x", false) ) as CheckBox @@ -181,9 +181,9 @@ func _delegate_of(item: TreeItem) -> RemoteEditorsTreeDataSource.Item: func _setup_tree() -> void: _i_remote_tree = RemoteEditorsTreeDataSource.RemoteTree.new(_tree, self) - + _tree.item_collapsed.connect( - func(x: TreeItem) -> void: + func(x: TreeItem) -> void: var expanded := not x.collapsed var delegate := _delegate_of(x) var not_loaded_yet := not delegate.is_loaded() @@ -205,7 +205,6 @@ func _setup_tree() -> void: func _expand(remote_tree_item: RemoteEditorsTreeDataSource.Item) -> void: _current_loadings_number += 1 - @warning_ignore("redundant_await") await remote_tree_item.async_expand(_i_remote_tree) _update_whole_tree_visibility(remote_tree_item) _current_loadings_number -= 1 @@ -225,10 +224,10 @@ func _on_visibility_changed() -> void: class RowFilter: var _delegate: Callable - + func _init(delegate: Callable) -> void: _delegate = delegate - + func test(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return _delegate.call(row) @@ -236,7 +235,7 @@ class RowFilter: class SimpleContainsFilter extends RowFilter: func _init(what: String) -> void: super._init( - func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: + func(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool: return row.get_name().to_lower().contains(what) ) diff --git a/src/components/editors/remote/remote_editors_tree/sources/github.gd b/src/components/editors/remote/remote_editors_tree/sources/github.gd index 90197aef..64f1b248 100644 --- a/src/components/editors/remote/remote_editors_tree/sources/github.gd +++ b/src/components/editors/remote/remote_editors_tree/sources/github.gd @@ -1,64 +1,40 @@ class_name RemoteEditorsTreeDataSourceGithub -class Self: - extends RemoteEditorsTreeDataSource.I +class Self extends RemoteEditorsTreeDataSource.I: var _assets: RemoteEditorsTreeDataSource.RemoteAssets const platforms = { - "X11": - { - "suffixes": - [ - "_x11.64.zip", - "_linux.64.zip", - "_linux.x86_64.zip", - "_linux.x86_32.zip", - "_linux_x86_64.zip", - "_linux_x86_32.zip" - ], + "X11": { + "suffixes": ["_x11.64.zip", "_linux.64.zip", "_linux.x86_64.zip", "_linux.x86_32.zip", "_linux_x86_64.zip", "_linux_x86_32.zip"], }, - "OSX": - { - "suffixes": - [ - "_osx.universal.zip", - "_macos.universal.zip", - "_osx.fat.zip", - "_osx32.zip", - "_osx64.zip" - ], + "OSX": { + "suffixes": ["_osx.universal.zip", "_macos.universal.zip", "_osx.fat.zip", "_osx32.zip", "_osx64.zip"], }, - "Windows": - { + "Windows": { "suffixes": ["_win64.exe.zip", "_win32.exe.zip", "_win64.zip", "_win32.zip"], } } - + func _init(assets: RemoteEditorsTreeDataSource.RemoteAssets) -> void: _assets = assets - + func setup(tree: Tree) -> void: var root := tree.create_item() - ( - root - . set_meta( - "delegate", - ( - GithubRootItem - . new( - root, - _assets, - GithubVersionSourceParseYml.new( - YmlSourceGithub.new(), GithubAssetSourceDefault.new() - ), - ) - ) + root.set_meta( + "delegate", + GithubRootItem.new( + root, + _assets, + GithubVersionSourceParseYml.new( + YmlSourceGithub.new(), + GithubAssetSourceDefault.new() + ), ) ) - + func cleanup(tree: Tree) -> void: tree.clear() - + func get_platform_suffixes() -> Array: var current_platform: Dictionary if OS.has_feature("windows"): @@ -68,7 +44,7 @@ class Self: elif OS.has_feature("linux"): current_platform = platforms["X11"] return current_platform["suffixes"] - + func to_remote_item(item: TreeItem) -> RemoteEditorsTreeDataSource.Item: return item.get_meta("delegate") @@ -78,10 +54,10 @@ class GithubVersion: var flavor: String var releases: Array[String] = [] var _assets_src: GithubAssetSource - + func get_flavor_release() -> GodotRelease: return GodotRelease.new(name, flavor, _assets_src) - + func get_recent_releases() -> Array[GodotRelease]: var result: Array[GodotRelease] = [] for r in releases: @@ -93,70 +69,64 @@ class GodotRelease: var name: String var _version: String var _assets_src: GithubAssetSource - + func _init(version: String, name: String, assets_src: GithubAssetSource) -> void: self.name = name _assets_src = assets_src _version = version - + func is_stable() -> bool: return name == "stable" - + func async_load_assets() -> Array[GodotAsset]: - @warning_ignore("redundant_await") return await _assets_src.async_load(_version, name) class GodotAsset: var _json: Dictionary - + var name: String: - get: - return _json.get("name", "") - + get: return _json.get("name", "") + var file_name: String: - get: - return browser_download_url.get_file() - + get: return browser_download_url.get_file() + var browser_download_url: String: - get: - return _json.get("browser_download_url", "") - + get: return _json.get("browser_download_url", "") + var is_zip: bool: - get: - return name.get_extension() == "zip" - + get: return name.get_extension() == "zip" + func _init(json: Dictionary) -> void: _json = json -class GithubItemBase: - extends RemoteEditorsTreeDataSource.Item +class GithubItemBase extends RemoteEditorsTreeDataSource.Item: var _item: TreeItem var _assets: RemoteEditorsTreeDataSource.RemoteAssets - + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets) -> void: _item = item _assets = assets - + func is_loaded() -> bool: return _item.has_meta("loaded") - + func async_expand(tree: RemoteTree) -> void: return - + func handle_item_activated() -> void: pass - + func handle_button_clicked(col: int, id: int, mouse: int) -> void: pass - + func update_visibility(filters: Array) -> void: - var filter_target := _to_filter_target() + var filter_target := _to_filter_target() if filter_target == null: return _item.visible = _should_be_visible(filter_target, filters) - + func _should_be_visible(target: GithubFilterTarget, filters: Array) -> bool: if target.is_file() and not target.is_zip(): return false @@ -164,12 +134,12 @@ class GithubItemBase: for filter: RemoteEditorsTreeControl.RowFilter in filters: if filter.test(target): return false - + return true - + func _to_filter_target() -> GithubFilterTarget: return null - + func _asset_to_item(asset: GodotAsset, tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: var tree_item := tree.create_item(_item) tree_item.set_meta("delegate", GithubAssetItem.new(tree_item, _assets, asset)) @@ -178,7 +148,7 @@ class GithubItemBase: var btn_texture: Texture2D = tree.theme_source.get_theme_icon("AssetLib", "EditorIcons") tree_item.add_button(0, btn_texture) tree_item.collapsed = true - + func get_children() -> Array[RemoteEditorsTreeDataSource.Item]: var result: Array[RemoteEditorsTreeDataSource.Item] = [] for child in _item.get_children(): @@ -187,16 +157,13 @@ class GithubItemBase: return result -class GithubAssetItem: - extends GithubItemBase +class GithubAssetItem extends GithubItemBase: var _asset: GodotAsset - - func _init( - item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, asset: GodotAsset - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, asset: GodotAsset) -> void: super._init(item, assets) _asset = asset - + func _to_filter_target() -> GithubFilterTarget: return GithubFilterTarget.new(_asset.name, false, true, _asset.is_zip) @@ -207,16 +174,13 @@ class GithubAssetItem: _assets.download(_asset.browser_download_url, _asset.file_name) -class GithubReleaseItem: - extends GithubItemBase +class GithubReleaseItem extends GithubItemBase: var _release: GodotRelease - - func _init( - item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, release: GodotRelease - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, release: GodotRelease) -> void: super._init(item, assets) _release = release - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) var assets := await _release.async_load_assets() @@ -228,33 +192,33 @@ class GithubReleaseItem: return GithubFilterTarget.new(_release.name, false, false, false) -class GithubVersionItem: - extends GithubItemBase +class GithubVersionItem extends GithubItemBase: var _version: GithubVersion - - func _init( - item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, version: GithubVersion - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, version: GithubVersion) -> void: super._init(item, assets) _version = version - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) - + var releases: Array[GodotRelease] = [] var flavor := _version.get_flavor_release() if not flavor.is_stable(): releases.append(flavor) releases.append_array(_version.get_recent_releases()) - + for release in releases: var tree_item := tree.create_item(_item) tree_item.visible = false tree_item.set_text(0, release.name) tree.set_as_folder(tree_item) - tree_item.set_meta("delegate", GithubReleaseItem.new(tree_item, _assets, release)) + tree_item.set_meta( + "delegate", + GithubReleaseItem.new(tree_item, _assets, release) + ) tree_item.collapsed = true - + if flavor.is_stable(): var assets := await flavor.async_load_assets() for asset in assets: @@ -266,21 +230,15 @@ class GithubVersionItem: return GithubFilterTarget.new(_version.name, true, false, false) -class GithubRootItem: - extends GithubItemBase +class GithubRootItem extends GithubItemBase: var _versions_source: GithubVersionSource - - func _init( - item: TreeItem, - assets: RemoteEditorsTreeDataSource.RemoteAssets, - versions_source: GithubVersionSource - ) -> void: + + func _init(item: TreeItem, assets: RemoteEditorsTreeDataSource.RemoteAssets, versions_source: GithubVersionSource) -> void: super._init(item, assets) _versions_source = versions_source - + func async_expand(tree: RemoteEditorsTreeDataSource.RemoteTree) -> void: _item.set_meta("loaded", true) - @warning_ignore("redundant_await") var versions := await _versions_source.async_load() for version in versions: var tree_item := tree.create_item(_item) @@ -291,8 +249,7 @@ class GithubRootItem: tree.free_loading_placeholder(_item) -class GithubFilterTarget: - extends RemoteEditorsTreeDataSource.FilterTarget +class GithubFilterTarget extends RemoteEditorsTreeDataSource.FilterTarget: var _name: String var _is_possible_version_folder: bool var _is_file: bool @@ -315,9 +272,7 @@ class GithubFilterTarget: func is_for_different_platform(platform_suffixes: Array) -> bool: var cached_name := get_name() - return not platform_suffixes.any( - func(suffix: String) -> bool: return cached_name.ends_with(suffix) - ) + return not platform_suffixes.any(func(suffix: String) -> bool: return cached_name.ends_with(suffix)) func get_name() -> String: return _name @@ -333,88 +288,79 @@ class GithubAssetSource: return [] -class GithubAssetSourceDefault: - extends GithubAssetSource +class GithubAssetSourceDefault extends GithubAssetSource: const url = "https://api.github.com/repos/godotengine/godot-builds/releases/tags/%s" - + func async_load(version: String, release: String) -> Array[GodotAsset]: var tag := "%s-%s" % [version, release] var response := await HttpClient.async_http_get( - url % tag, ["Accept: application/vnd.github.v3+json"] + url % tag, + ["Accept: application/vnd.github.v3+json"] ) var json: Dictionary = JSON.parse_string( (response[3] as PackedByteArray).get_string_from_utf8() ) var result: Array[GodotAsset] = [] - for asset_json: Dictionary in json.get("assets", []): + for asset_json: Dictionary in json.get('assets', []): result.append(GodotAsset.new(asset_json)) return result -class GithubAssetSourceFileJson: - extends GithubAssetSource +class GithubAssetSourceFileJson extends GithubAssetSource: var _file_path: String - + func _init(file_path: String) -> void: _file_path = file_path - + func async_load(version: String, release: String) -> Array[GodotAsset]: - var json: Dictionary = JSON.parse_string( - FileAccess.open(_file_path, FileAccess.READ).get_as_text() - ) + var json: Dictionary = JSON.parse_string(FileAccess.open(_file_path, FileAccess.READ).get_as_text()) var result: Array[GodotAsset] = [] - for asset_json: Dictionary in json.get("assets", []): + for asset_json: Dictionary in json.get('assets', []): result.append(GodotAsset.new(asset_json)) return result -class GithubVersionSourceFileJson: - extends GithubVersionSource +class GithubVersionSourceFileJson extends GithubVersionSource: var _file_path: String var _assets_src: GithubAssetSource - + func _init(file_path: String, assets_src: GithubAssetSource) -> void: _file_path = file_path _assets_src = assets_src - + func async_load() -> Array[GithubVersion]: - var json: Array = JSON.parse_string( - FileAccess.open(_file_path, FileAccess.READ).get_as_text() - ) + var json: Array = JSON.parse_string(FileAccess.open(_file_path, FileAccess.READ).get_as_text()) var result: Array[GithubVersion] = [] for el: Dictionary in json: var version := GithubVersion.new() version._assets_src = _assets_src version.name = el.name version.flavor = el.flavor - for release: Dictionary in el.get("releases", []): + for release: Dictionary in el.get('releases', []): version.releases.append(release.name) result.append(version) return result class YmlSource: - func async_load(errors: Array[String] = []) -> String: + func async_load(errors: Array[String]=[]) -> String: return "" -class YmlSourceFile: - extends YmlSource +class YmlSourceFile extends YmlSource: var _file_path: String - + func _init(file_path: String) -> void: _file_path = file_path - - func async_load(errors: Array[String] = []) -> String: - var text := FileAccess.open(_file_path, FileAccess.READ).get_as_text() + + func async_load(errors: Array[String]=[]) -> String: + var text := FileAccess.open(_file_path, FileAccess.READ).get_as_text() return text -class YmlSourceGithub: - extends YmlSource +class YmlSourceGithub extends YmlSource: const url = "https://raw.githubusercontent.com/godotengine/godot-website/master/_data/versions.yml" - - func async_load(errors: Array[String] = []) -> String: + func async_load(errors: Array[String]=[]) -> String: var response := HttpClient.Response.new(await HttpClient.async_http_get(url)) var info := response.to_response_info(url) if info.error_text: @@ -423,21 +369,19 @@ class YmlSourceGithub: return text -class GithubVersionSourceParseYml: - extends GithubVersionSource +class GithubVersionSourceParseYml extends GithubVersionSource: var _src: YmlSource var _assets_src: GithubAssetSource - - var _version_regex := RegEx.create_from_string("(?m)^-[\\s\\S]*?(?=^-|\\Z)") + + var _version_regex := RegEx.create_from_string('(?m)^-[\\s\\S]*?(?=^-|\\Z)') var _name_regex := RegEx.create_from_string('(?m)\\sname:\\s"(?[^"]+)"$') var _flavor_regex := RegEx.create_from_string('(?m)\\sflavor:\\s"(?[^"]+)"$') - + func _init(src: YmlSource, assets_src: GithubAssetSource) -> void: _src = src _assets_src = assets_src - + func async_load() -> Array[GithubVersion]: - @warning_ignore("redundant_await") var yml := await _src.async_load() var result: Array[GithubVersion] = [] var versions := _version_regex.search_all(yml) diff --git a/src/components/godots_releases/godots_releases.gd b/src/components/godots_releases/godots_releases.gd index 6c61efd9..b6cbc7cf 100644 --- a/src/components/godots_releases/godots_releases.gd +++ b/src/components/godots_releases/godots_releases.gd @@ -14,23 +14,27 @@ var _fetching := false func init( - releases: GodotsReleases.I, godots_downloads: GodotsDownloads.I, godots_install: GodotsInstall.I + releases: GodotsReleases.I, + godots_downloads: GodotsDownloads.I, + godots_install: GodotsInstall.I ) -> void: self._releases = releases self._godots_install = godots_install self._godots_downloads = godots_downloads - + if visible: _async_refetch_data() func _ready() -> void: _godots_releases_list.set_search_box_text("tag:newest") - _refresh_button.pressed.connect(func() -> void: _async_refetch_data()) - + _refresh_button.pressed.connect(func() -> void: + _async_refetch_data() + ) + _star_git_hub.icon = get_theme_icon("Favorites", "EditorIcons") - _star_git_hub.pressed.connect( - func() -> void: OS.shell_open("https://github.com/MakovWait/godots") + _star_git_hub.pressed.connect(func() -> void: + OS.shell_open("https://github.com/MakovWait/godots") ) @@ -39,16 +43,15 @@ func _async_refetch_data() -> void: return _fetching = true _refresh_button.disabled = true - + _async_refetch_data_body() - + _data_loaded = true _fetching = false _refresh_button.disabled = false func _async_refetch_data_body() -> void: - @warning_ignore("redundant_await") await _releases.async_load() _godots_releases_list.refresh(_releases.all()) @@ -59,7 +62,8 @@ func _on_godots_releases_list_item_selected(item: GodotsReleasesListItemControl) func _on_godots_releases_list_download_and_install_requested(url: String) -> void: _godots_downloads.download( - url, func(abs_zip_path: String) -> void: _godots_install.install(abs_zip_path) + url, + func(abs_zip_path: String) -> void: _godots_install.install(abs_zip_path) ) diff --git a/src/components/projects/new_project_dialog/new_project_dialog.gd b/src/components/projects/new_project_dialog/new_project_dialog.gd index fadb08d1..7d3ec309 100644 --- a/src/components/projects/new_project_dialog/new_project_dialog.gd +++ b/src/components/projects/new_project_dialog/new_project_dialog.gd @@ -1,7 +1,6 @@ class_name NewProjectDialog extends "res://src/components/projects/install_project_dialog/install_project_dialog.gd" -@warning_ignore("unused_signal") signal created(path: String) @onready var _handler_option_button: OptionButton = %HandlerOptionButton @@ -10,15 +9,15 @@ signal created(path: String) func _ready() -> void: super._ready() - + _handler_option_button.item_selected.connect(func(idx: int) -> void: var meta: Dictionary = _handler_option_button.get_item_metadata(idx) _custom_form_tabs.current_tab = _custom_form_tabs.get_tab_idx_from_control(meta.form as Control) ) - + _register_handler(NewProjectGodot4.new()) _register_handler(NewProjectGodot3.new()) - + confirmed.connect(func() -> void: var meta: Dictionary = _handler_option_button.get_item_metadata(_handler_option_button.selected) var handler := meta.self as NewProjectHandler @@ -34,7 +33,7 @@ func _register_handler(handler: NewProjectHandler) -> void: var handler_form := handler.custom_form() handler_form.name = handler.label() _custom_form_tabs.add_child(handler_form) - + _handler_option_button.add_item(handler.label()) _handler_option_button.set_item_metadata( _handler_option_button.item_count - 1, @@ -47,17 +46,17 @@ func _register_handler(handler: NewProjectHandler) -> void: class NewProjectContext: var _ctx_delegate: Object - + var dir: String var project_name: String var form: Control - + func _init(ctx_delegate: Object) -> void: _ctx_delegate = ctx_delegate - + func show_error(msg: String) -> void: _ctx_delegate.call("_error", msg) - + func emit_created(path: String) -> void: _ctx_delegate.emit_signal("created", path) @@ -65,10 +64,10 @@ class NewProjectContext: class NewProjectHandler: func custom_form() -> Control: return Control.new() - - func create_project(args: NewProjectContext) -> void: + + func create_project(args: NewProjectContext) -> void: pass - + func label() -> String: return "" @@ -76,7 +75,7 @@ class NewProjectHandler: class NewProjectGodot3 extends NewProjectHandler: func custom_form() -> Control: return NewProjectGodot3Form.new() - + func create_project(ctx: NewProjectContext) -> void: var dir := ctx.dir var project_file_path := dir.path_join("project.godot") @@ -96,14 +95,14 @@ class NewProjectGodot3 extends NewProjectHandler: var img: Texture2D = preload("res://assets/default_project_icon.svg") img.get_image().save_png(dir.path_join("icon.png")) ctx.emit_created(project_file_path) - + func label() -> String: return "Godot 3.x" class NewProjectGodot3Form extends VBoxContainer: var _renderer: RendererSelect - + func _init() -> void: _renderer = RendererSelect.new({ "GLES3": { @@ -126,9 +125,9 @@ class NewProjectGodot3Form extends VBoxContainer: ]), }, }) - + add_child(_renderer) - + Comp.new(Label).on_init([ CompInit.TEXT(tr("The renderer can be changed later, but scenes may need to be adjusted.")), CompInit.CUSTOM(func(label: Label) -> void: @@ -139,7 +138,7 @@ class NewProjectGodot3Form extends VBoxContainer: pass\ ) ]).add_to(self) - + func renderer_method() -> String: return _renderer.current() @@ -157,7 +156,7 @@ class NewProjectGodot4 extends NewProjectHandler: var initial_settings := ConfigFile.new() initial_settings.set_value("application", "config/name", ctx.project_name) initial_settings.set_value("application", "config/icon", "res://icon.svg") - + # rendering initial_settings.set_value("rendering", "renderer/rendering_method", form.renderer_method()) if form.renderer_method() == "gl_compatibility": @@ -180,7 +179,7 @@ class NewProjectGodot4 extends NewProjectHandler: else: ctx.show_error(tr("Couldn't create .gitignore in project path.")) return - + var gitattributes := FileAccess.open(dir.path_join(".gitattributes"), FileAccess.WRITE) if gitattributes != null: gitattributes.store_line("# Normalize EOL for all files that Git considers text files.") @@ -196,7 +195,7 @@ class NewProjectGodot4 extends NewProjectHandler: file_to.close() ctx.emit_created(project_file_path) - + func label() -> String: return "Godot 4.x" @@ -239,9 +238,9 @@ class NewProjectGodot4Form extends VBoxContainer: ]), } }) - + add_child(_renderer) - + Comp.new(Label).on_init([ CompInit.TEXT(tr("The renderer can be changed later, but scenes may need to be adjusted.")), CompInit.CUSTOM(func(label: Label) -> void: @@ -252,34 +251,34 @@ class NewProjectGodot4Form extends VBoxContainer: pass\ ) ]).add_to(self) - + _vcs_meta = VersionControlMetadata.new() add_child(_vcs_meta) - + func renderer_method() -> String: return _renderer.current() - + func vsc_meta() -> String: return _vcs_meta.current() class VersionControlMetadata extends HBoxContainer: var _options: OptionButton - + func _init() -> void: var label := Label.new() label.text = tr("Version Control Metadata:") - + _options = OptionButton.new() _options.add_item("Git") _options.set_item_metadata(_options.item_count - 1, "git") - + _options.add_item("None") _options.set_item_metadata(_options.item_count - 1, "none") - + add_child(label) add_child(_options) - + func current() -> String: return _options.get_item_metadata(_options.selected) as String @@ -287,7 +286,7 @@ class VersionControlMetadata extends HBoxContainer: class RendererSelect extends VBoxContainer: var _button_group := ButtonGroup.new() - + func _init(options: Dictionary) -> void: var renderer_desc_label := CompRefs.Simple.new() @@ -318,13 +317,13 @@ class RendererSelect extends VBoxContainer: Comp.new(Label).on_init([ CompInit.TEXT(tr("Renderer:")) ]), - + Comp.new(HBoxContainer, [ # checkboxes Comp.new(VBoxContainer, checkboxes), - + Comp.new(VSeparator), - + # checkbox desc Comp.new(VBoxContainer, [ Comp.new(Label).on_init([ @@ -338,6 +337,6 @@ class RendererSelect extends VBoxContainer: ]), ]), ]).add_to(self) - + func current() -> String: return _button_group.get_pressed_button().get_meta("rendering_method") diff --git a/src/components/projects/project_item/project_item.gd b/src/components/projects/project_item/project_item.gd index c4b8738d..c2c84609 100644 --- a/src/components/projects/project_item/project_item.gd +++ b/src/components/projects/project_item/project_item.gd @@ -20,9 +20,9 @@ signal tag_clicked(tag: String) @onready var _tag_container: ItemTagContainer = %TagContainer @onready var _project_features: Label = %ProjectFeatures @onready var _info_body: VBoxContainer = %InfoBody -#@onready var _info_v_box: VBoxContainer = %InfoVBox +@onready var _info_v_box: VBoxContainer = %InfoVBox @onready var _actions_h_box: HBoxContainer = %ActionsHBox -#@onready var _title_container: HBoxContainer = %TitleContainer +@onready var _title_container: HBoxContainer = %TitleContainer @onready var _actions_container: HBoxContainer = %ActionsContainer static var settings := ProjectItemActions.Settings.new( @@ -56,10 +56,10 @@ func init(item: Projects.Item) -> void: item.loaded.connect(func() -> void: _fill_data(item) ) - + _editor_button.pressed.connect(_on_rebind_editor.bind(item)) _editor_button.disabled = item.is_missing - + item.internals_changed.connect(func() -> void: _fill_data(item) ) @@ -74,7 +74,7 @@ func init(item: Projects.Item) -> void: double_clicked.connect(func() -> void: if item.is_missing: return - + if item.has_invalid_editor: _on_rebind_editor(item) else: @@ -84,8 +84,8 @@ func init(item: Projects.Item) -> void: func _setup_actions_view(item: Projects.Item) -> void: var action_views := ProjectItemActions.Menu.new( - _actions.without(['view-command']).all(), - settings, + _actions.without(['view-command']).all(), + settings, CustomCommandsPopupItems.Self.new( _actions.by_key('view-command'), _get_commands(item) @@ -145,11 +145,11 @@ func _fill_actions(item: Projects.Item) -> void: "act": _on_edit_with_editor.bind(item), "label": tr("Edit"), }) - + var run := Action.from_dict({ "key": "run", "icon": Action.IconTheme.new(self, "Play", "EditorIcons"), - "act": _on_run_with_editor.bind(item, func(_item: Projects.Item) -> void: _item.run(), "run", "Run", false), + "act": _on_run_with_editor.bind(item, func(item: Projects.Item) -> void: item.run(), "run", "Run", false), "label": tr("Run"), }) @@ -180,14 +180,14 @@ func _fill_actions(item: Projects.Item) -> void: "act": func() -> void: manage_tags_requested.emit(), "label": tr("Manage Tags"), }) - + var view_command := Action.from_dict({ "key": "view-command", "icon": Action.IconTheme.new(self, "Edit", "EditorIcons"), "act": _view_command.bind(item), "label": tr("Edit Commands"), }) - + var remove := Action.from_dict({ "key": "remove", "icon": Action.IconTheme.new(self, "Remove", "EditorIcons"), @@ -219,7 +219,7 @@ func _fill_data(item: Projects.Item) -> void: if item.is_missing: _explore_button.icon = get_theme_icon("FileBroken", "EditorIcons") modulate = Color(1, 1, 1, 0.498) - + _project_warning.visible = item.has_invalid_editor _favorite_button.button_pressed = item.favorite _title_label.text = item.name @@ -229,13 +229,13 @@ func _fill_data(item: Projects.Item) -> void: _tag_container.set_tags(item.tags) _set_features(item.features) _tags = item.tags - + _sort_data.favorite = item.favorite _sort_data.name = item.name _sort_data.path = item.path _sort_data.last_modified = item.last_modified _sort_data.tag_sort_string = "".join(item.tags) - + for action in _actions.sub_list([ 'duplicate', 'bind-editor', @@ -243,7 +243,7 @@ func _fill_data(item: Projects.Item) -> void: 'rename' ]).all(): action.disable(item.is_missing) - + for action in _actions.sub_list([ 'view-command', 'edit', @@ -284,8 +284,8 @@ func _get_commands(item: Projects.Item) -> CommandViewer.Commands: func _set_features(features: Array) -> void: var features_to_print := features.filter(func(x: String) -> bool: return _is_version(x) or x == "C#") if len(features_to_print) > 0: - var string := ", ".join(features_to_print) - _project_features.text = string + var str := ", ".join(features_to_print) + _project_features.text = str # _project_features.custom_minimum_size = Vector2(25 * 15, 10) * Config.EDSCALE if settings.is_show_features(): _project_features.show() @@ -299,37 +299,37 @@ func _is_version(feature: String) -> bool: func _on_rebind_editor(item: Projects.Item) -> void: var bind_dialog := ConfirmationDialogAutoFree.new() - + var vbox := VBoxContainer.new() bind_dialog.add_child(vbox) - + var hbox := HBoxContainer.new() vbox.add_child(hbox) - + var title := Label.new() hbox.add_child(title) - + var options := OptionButton.new() hbox.add_child(options) - + if item.has_version_hint: var hbox2 := HBoxContainer.new() hbox2.modulate = Color(0.5, 0.5, 0.5, 0.5) hbox2.alignment = BoxContainer.ALIGNMENT_CENTER vbox.add_child(hbox2) - + var version_hint_title := Label.new() version_hint_title.text = tr("version hint:") hbox2.add_child(version_hint_title) - + var version_hint_value := Label.new() version_hint_value.text = item.version_hint hbox2.add_child(version_hint_value) - + vbox.add_spacer(false) - + title.text = "%s: " % tr("Editor") - + options.item_selected.connect(func(idx: int) -> void: bind_dialog.get_ok_button().disabled = false ) @@ -339,14 +339,14 @@ func _on_rebind_editor(item: Projects.Item) -> void: var opt: Dictionary = option_items[i] options.add_item(opt.label as String, i) options.set_item_metadata(i, opt.path) - + bind_dialog.confirmed.connect(func() -> void: if options.selected < 0: return var new_editor_path := options.get_item_metadata(options.selected) as String item.editor_path = new_editor_path edited.emit() ) - + add_child(bind_dialog) bind_dialog.popup_centered() @@ -364,36 +364,36 @@ func _on_rename(item: Projects.Item) -> void: func _on_edit_with_editor(item: Projects.Item) -> void: - _on_run_with_editor(item, func(_item: Projects.Item) -> void: _item.edit(), "edit", "Edit", true) + _on_run_with_editor(item, func(item: Projects.Item) -> void: item.edit(), "edit", "Edit", true) func _on_run_with_editor(item: Projects.Item, editor_flag: Callable, action_name: String, ok_button_text: String, auto_close: bool) -> void: if not item.show_edit_warning: _run_with_editor(item, editor_flag, auto_close) return - + var confirmation_dialog := ConfirmationDialogAutoFree.new() confirmation_dialog.ok_button_text = ok_button_text confirmation_dialog.get_label().hide() - + var label := Label.new() label.text = tr("Are you sure to %s the project with the given editor?") % action_name - + var editor_name := Label.new() editor_name.text = item.editor_name editor_name.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - + var checkbox := CheckBox.new() checkbox.text = tr("do not show again for this project") - + var vb := VBoxContainer.new() vb.add_child(label) vb.add_child(editor_name) vb.add_child(checkbox) vb.add_spacer(false) - + confirmation_dialog.add_child(vb) - + confirmation_dialog.confirmed.connect(func() -> void: var before := item.show_edit_warning item.show_edit_warning = not checkbox.button_pressed diff --git a/src/components/projects/projects.gd b/src/components/projects/projects.gd index 1f7cab34..b1774530 100644 --- a/src/components/projects/projects.gd +++ b/src/components/projects/projects.gd @@ -14,16 +14,16 @@ signal manage_tags_requested(item_tags: Array, all_tags: Array, on_confirm: Call var _projects: Projects.List -#var _load_projects_queue := [] +var _load_projects_queue := [] var _remove_missing_action: Action.Self func init(projects: Projects.List) -> void: self._projects = projects - + var remove_missing_popup := RemoveMissingDialog.new(_remove_missing) add_child(remove_missing_popup) - + var actions := Action.List.new([ Action.from_dict({ "key": "new-project", @@ -67,7 +67,7 @@ func init(projects: Projects.List) -> void: "act": _refresh }) ]) - + _remove_missing_action = actions.by_key('remove-missing') var project_actions := TabActions.Menu.new( @@ -76,9 +76,9 @@ func init(projects: Projects.List) -> void: 'import-project', 'clone-project', 'scan-projects', - ]).all(), + ]).all(), TabActions.Settings.new( - Cache.section_of(self), + Cache.section_of(self), [ 'new-project', 'import-project', @@ -106,34 +106,34 @@ func init(projects: Projects.List) -> void: project.load() _projects_list.add(project) _projects.save() - + if edit: project.edit() AutoClose.close_if_should() - + if callback: (callback as Callable).call(project, projects) - + _projects_list.sort_items() ) - + _clone_project_dialog.cloned.connect(func(path: String) -> void: assert(path.get_file() == "project.godot") import(path) ) - + _new_project_dialog.created.connect(func(project_path: String) -> void: import(project_path) ) - + _scan_dialog.dir_to_scan_selected.connect(func(dir_to_scan: String) -> void: _scan_projects(dir_to_scan) ) - + _duplicate_project_dialog.duplicated.connect(func(project_path: String, callback: Callable) -> void: import(project_path, callback) ) - + _projects_list.refresh(_projects.all()) _load_projects() @@ -182,7 +182,7 @@ func install_zip(zip_reader: ZIPReader, project_name: String) -> void: if len(project_configs) == 0: _install_project_from_zip_dialog.error(tr("No project.godot found.")) return - + var project_file_path := project_configs[0] _install_project_from_zip_dialog.hide() import(project_file_path.path) @@ -255,5 +255,5 @@ func _on_projects_list_item_manage_tags_requested(item_data: Projects.Item) -> v func _on_projects_list_item_duplicate_requested(project: Projects.Item) -> void: if _duplicate_project_dialog.visible: return - + _duplicate_project_dialog.raise(project.name, project) diff --git a/src/components/projects/projects_list/projects_list.gd b/src/components/projects/projects_list/projects_list.gd index 069a85e2..80829c7f 100644 --- a/src/components/projects/projects_list/projects_list.gd +++ b/src/components/projects/projects_list/projects_list.gd @@ -34,6 +34,7 @@ func _item_comparator(a: Dictionary, b: Dictionary) -> bool: 2: return a.path < b.path 3: return a.tag_sort_string < b.tag_sort_string _: return a.name < b.name + return a.name < b.name func _fill_sort_options(btn: OptionButton) -> void: @@ -41,7 +42,7 @@ func _fill_sort_options(btn: OptionButton) -> void: btn.add_item(tr("Name")) btn.add_item(tr("Path")) btn.add_item(tr("Tags")) - + var last_checked_sort := Cache.smart_value(self, "last_checked_sort", true) btn.select(last_checked_sort.ret(1) as int) btn.item_selected.connect(func(idx: int) -> void: last_checked_sort.put(idx)) diff --git a/src/components/settings/settings_window.gd b/src/components/settings/settings_window.gd index c27f00d8..9a0097e0 100644 --- a/src/components/settings/settings_window.gd +++ b/src/components/settings/settings_window.gd @@ -34,24 +34,24 @@ func _prepare_settings() -> Array: Config.USE_SYSTEM_TITLE_BAR, SettingCheckbox ))), func() -> bool: return DisplayServer.has_feature(DisplayServer.FEATURE_EXTEND_TO_TITLE)), - + SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/config/use_native_file_dialog", Config.USE_NATIVE_FILE_DIALOG, SettingCheckbox ))), - + SettingChangeObserved(SettingCfg( "application/config/remember_window_rect", Config.REMEMBER_WINDOW_SIZE, SettingCheckbox, tr("Restore last window size and position on startup.") )), - + SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/preset", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/preset" ).bake_default("Default"), @@ -61,18 +61,18 @@ func _prepare_settings() -> Array: SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/base_color", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/base_color" ).bake_default(Color(0.21, 0.24, 0.29)), SettingColorPicker, tr("Base color for the theme. Affects the background and primary UI elements.") )))), - + SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/accent_color", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/accent_color" ).bake_default(Color(0.44, 0.73, 0.98)), @@ -83,7 +83,7 @@ func _prepare_settings() -> Array: SettingCustomPresetTrigger(SettingRestartRequired(SettingChangeObserved(SettingCfg( "application/theme/contrast", ConfigFileValue.new( - IConfigFileLike.of_config(Config._cfg), + IConfigFileLike.of_config(Config._cfg), "theme", "interface/theme/contrast" ).bake_default(0.3), @@ -152,9 +152,9 @@ func _init() -> void: (%WarningRect as Button).icon = get_theme_icon("StatusWarning", "EditorIcons") (%WarningRect as Button).self_modulate = get_theme_color("warning_color", "Editor") * Color(1, 1, 1, 0.6) (%RestartInfoLabel as Label).self_modulate = get_theme_color("warning_color", "Editor") * Color(1, 1, 1, 0.6) - + (%OpenConfigFileButton as Button).icon = get_theme_icon("Load", "EditorIcons") - + var sections_root := (%SectionsTree as Tree).get_root() if sections_root: for child in sections_root.get_children(): @@ -169,7 +169,7 @@ func _ready() -> void: Config.save() ) - var title_text := tr("Settings") + var title_text := tr("Settings") var set_title_text := func(pattern: String) -> void: title = pattern % title_text title = title_text @@ -179,19 +179,19 @@ func _ready() -> void: Config.saved.connect(func() -> void: set_title_text.call("%s") ) - + get_ok_button().text = tr("Save & Close") - - + + var left_vb := %LeftVB as VBoxContainer left_vb.custom_minimum_size = Vector2(190, 0) * Config.EDSCALE - - + + var right_vb: = %RightVB as VBoxContainer right_vb.custom_minimum_size = Vector2(300, 0) * Config.EDSCALE right_vb.size_flags_horizontal = Control.SIZE_EXPAND_FILL - - + + (%RestartInfoLabel as Label).text = tr("Godots must be restarted for changes to take effect.") (%RestartButton as Button).pressed.connect(func() -> void: Config.save() @@ -205,12 +205,12 @@ func _ready() -> void: (%RestartContainer as PanelContainer).hide() ) (%RestartContainer as Control).hide() - + (%OpenConfigFileButton as Button).pressed.connect(func() -> void: var config_path := ProjectSettings.globalize_path(Config.APP_CONFIG_PATH.get_base_dir()) OS.shell_show_in_file_manager(config_path) ) - + _setup_settings() @@ -223,17 +223,17 @@ func raise_settings() -> void: func _setup_settings() -> void: var settings := _prepare_settings().filter(func(x: Variant) -> bool: return x != null) - + for setting: Setting in settings: setting.bind_settings_window(self) setting.validate() setting.add_control(SettingControlTarget.new(%InspectorVBox, setting.category.raw)) - + var tree := %SectionsTree as Tree tree.item_selected.connect(func() -> void: - var _selected := tree.get_selected() - if _selected: - var section: Variant = _selected.get_metadata(0) + var selected := tree.get_selected() + if selected: + var section: Variant = selected.get_metadata(0) if section is String: _update_settings_visibility(section as String) ) @@ -245,7 +245,7 @@ func _setup_settings() -> void: if not category.first_lvl in categories: categories[category.first_lvl] = Set.new() var second_lvls := categories[category.first_lvl] as Set - second_lvls.append(category.second_lvl) + second_lvls.append(category.second_lvl) var selected := false for first_lvl: String in categories.keys(): var first_lvl_item := tree.create_item(root) @@ -269,10 +269,10 @@ func _update_settings_visibility(section: String) -> void: func SettingCfg(category: String, cfg_value: ConfigFileValue, prop_factory: Variant, tooltip:="") -> Setting: if prop_factory is Script: - prop_factory = func(a1: Variant, a2: Variant, a3: Variant, a4: Variant) -> Setting: + prop_factory = func(a1: Variant, a2: Variant, a3: Variant, a4: Variant) -> Setting: return (prop_factory as Script).call("new", a1, a2, a3, a4) return ((prop_factory as Callable).call( - category, + category, cfg_value.ret(), tooltip, cfg_value.get_baked_default() @@ -281,7 +281,7 @@ func SettingCfg(category: String, cfg_value: ConfigFileValue, prop_factory: Vari func SettingChangeObserved(origin: Setting) -> Setting: return origin.on_value_changed( - func(new_value: Variant) -> void: + func(new_value: Variant) -> void: _setting_changed.emit(origin, new_value) _settings_changed.emit() ) @@ -304,25 +304,25 @@ func SettingCustomPresetTrigger(origin: Setting) -> Setting: class Category: var _category: String - + var name: String: get: return _category.get_file().capitalize() - + var first_lvl: String: get: return _category.split("/")[0] - + var second_lvl: String: get: return _category.split("/")[1] - + var raw: String: get: return _category - + func _init(category: String) -> void: _category = category - + func validate() -> void: assert( - len(_category.split("/")) == 3, + len(_category.split("/")) == 3, "Invalid category %s! Category format is: s/s/s" % _category ) @@ -330,11 +330,11 @@ class Category: class SettingControlTarget: var _target: Node var _category: String - + func _init(target: Node, category: String) -> void: _target = target _category = category - + func add_child(child: Node) -> void: child.set_meta("category", _category) _target.add_child(child) @@ -342,50 +342,50 @@ class SettingControlTarget: class Setting extends RefCounted: signal changed(new_value: Variant) - + var category: Category var _value: Variant var _tooltip: String var _default_value: Variant var _settings_window: SettingsWindow - + func _init(name: String, value: Variant, tooltip: String, default_value: Variant) -> void: self.category = Category.new(name) self._value = value self._tooltip = tooltip self._default_value = default_value - + func add_control(target: SettingControlTarget) -> void: pass - + func on_value_changed(callback: Callable) -> Setting: changed.connect(callback) return self - + func notify_changed() -> void: changed.emit(_value) - + func set_value(value: Variant) -> void: _value = value - + func set_value_and_notify(value: Variant) -> void: set_value(value) notify_changed() - + func validate() -> void: category.validate() assert(_settings_window != null) - + func reset() -> void: set_value_and_notify(_default_value) - + func value_is_not_default() -> bool: return _value != _default_value - + func bind_settings_window(settings_window: SettingsWindow) -> Setting: _settings_window = settings_window return self - + func with_meta(name: StringName, value: Variant) -> Setting: self.set_meta(name, value) return self @@ -462,7 +462,7 @@ class SettingFilePath extends Setting: func add_control(target: SettingControlTarget) -> void: var file_dialog := CompRefs.Simple.new() var line_edit := CompRefs.Simple.new() - var update_value := func(new_value: String) -> void: + var update_value := func(new_value: String) -> void: set_value_and_notify(new_value) line_edit.value.text = new_value self.on_value_changed(func(new_value: String) -> void: @@ -491,8 +491,8 @@ class SettingFilePath extends Setting: CompInit.TREE_ENTERED( CompInit.SET_THEME_ICON("Load", "EditorIcons") ), - CompInit.PRESSED(func(_a: Control) -> void: - var dialog := file_dialog.value as FileDialog + CompInit.PRESSED(func(_a: Control) -> void: + var dialog := file_dialog.value as FileDialog dialog.current_dir = self._value dialog.popup_centered_ratio(0.5)\ ) @@ -596,12 +596,12 @@ class CompSettingPanelContainer extends Comp: class SettingOptionButton extends Setting: var _options: Dictionary var _fallback_option: String - + func _init(name: String, value: Variant, tooltip: String, default_value: Variant, options: Dictionary, fallback_option: String) -> void: super._init(name, value, tooltip, default_value) self._options = options self._fallback_option = fallback_option - + func add_control(target: SettingControlTarget) -> void: var update_selected_value := func(this: OptionButton) -> void: this.clear() @@ -613,11 +613,11 @@ class SettingOptionButton extends Setting: this.selected = item_idx item_to_select_was_found = true item_idx += 1 - + if not item_to_select_was_found: this.add_item(_fallback_option) this.selected = item_idx - + var control := Comp.new(HBoxContainer, [ CompSettingNameContainer.new(self), CompSettingPanelContainer.new(_tooltip, [ @@ -790,13 +790,13 @@ class SettingSlider extends Setting: this.step = 0.1 this.min_value = -1 this.max_value = 1 - + self.on_value_changed(func(new_value: Variant) -> void: this.value = new_value ) - + this.value = self._value - + this.value_changed.connect(func(new_value: Variant) -> void: self.set_value_and_notify(new_value) ) diff --git a/src/components/title_bar/title_bar.gd b/src/components/title_bar/title_bar.gd index ae677768..7f150b6c 100644 --- a/src/components/title_bar/title_bar.gd +++ b/src/components/title_bar/title_bar.gd @@ -3,7 +3,7 @@ extends Control @onready var _left_spacer := %LeftSpacer as Control @onready var _right_spacer := %RightSpacer as Control -#@onready var _gui_base := get_parent() +@onready var _gui_base := get_parent() @onready var _main_container := %MainContainer as HBoxContainer @onready var _buttons_container := %ButtonsContainer as HBoxContainer @@ -41,7 +41,7 @@ func _setup_title_label() -> void: var label := %TitleLabel as Label label.add_theme_font_override("font", get_theme_font("bold", "EditorFonts")) label.add_theme_font_size_override("font_size", get_theme_font_size("bold_size", "EditorFonts")) - + #label.set_text_overrun_behavior(TextServer.OVERRUN_TRIM_ELLIPSIS) #label.set_text_overrun_behavior(TextServer.OVERRUN_TRIM_ELLIPSIS) label.set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER) @@ -53,7 +53,7 @@ func _setup_title_label() -> void: func _gui_input(event: InputEvent) -> void: if not _can_move: return - + if event is InputEventMouseMotion and _moving: if (event as InputEventMouseMotion).button_mask & MOUSE_BUTTON_MASK_LEFT: var w := get_window() @@ -87,8 +87,8 @@ func _gui_input(event: InputEvent) -> void: func _resize() -> void: var buttons_offet := Vector2i( - int(self.global_position.y + (self.size.y / 2)), - int(self.global_position.y + (self.size.y / 2)) + self.global_position.y + (self.size.y / 2), + self.global_position.y + (self.size.y / 2) ) DisplayServer.window_set_window_buttons_offset( buttons_offet, @@ -97,13 +97,13 @@ func _resize() -> void: var margin := DisplayServer.window_get_safe_title_margins( DisplayServer.MAIN_WINDOW_ID ) - if _left_spacer: + if _left_spacer: var w := margin.y if self.is_layout_rtl() else margin.x _left_spacer.custom_minimum_size = Vector2(w, 0) - if _right_spacer: + if _right_spacer: var w := margin.x if self.is_layout_rtl() else margin.y _right_spacer.custom_minimum_size = Vector2(w, 0) self.custom_minimum_size = Vector2( - 0, + 0, maxf(margin.z - self.global_position.y, self.custom_minimum_size.y) ) diff --git a/src/extensions/zip.gd b/src/extensions/zip.gd index 6a1f83d5..d351356a 100644 --- a/src/extensions/zip.gd +++ b/src/extensions/zip.gd @@ -7,11 +7,11 @@ static func unzip(zip_path: String, target_dir: String) -> void: var exit_code: int if OS.has_feature("windows"): exit_code = OS.execute( - "powershell.exe", + "powershell.exe", [ "-command", - "\"Expand-Archive '%s' '%s'\" -Force" % [ - ProjectSettings.globalize_path(zip_path), + "\"Expand-Archive '%s' '%s'\" -Force" % [ + ProjectSettings.globalize_path(zip_path), ProjectSettings.globalize_path(target_dir) ] ], output, true @@ -20,10 +20,10 @@ static func unzip(zip_path: String, target_dir: String) -> void: Output.push("unzip executed with exit code: %s" % exit_code) elif OS.has_feature("macos"): exit_code = OS.execute( - "unzip", + "unzip", [ - "%s" % ProjectSettings.globalize_path(zip_path), - "-d", + "%s" % ProjectSettings.globalize_path(zip_path), + "-d", "%s" % ProjectSettings.globalize_path(target_dir) ], output, true ) @@ -34,7 +34,7 @@ static func unzip(zip_path: String, target_dir: String) -> void: "unzip", [ "-o", - "%s" % ProjectSettings.globalize_path(zip_path), + "%s" % ProjectSettings.globalize_path(zip_path), "-d", "%s" % ProjectSettings.globalize_path(target_dir) ], output, true @@ -45,8 +45,8 @@ static func unzip(zip_path: String, target_dir: String) -> void: ## A procedure that unzips a zip file to a target directory, keeping the ## target directory as root, rather than the zip's root directory. -static func unzip_to_path(_zip: ZIPReader, destiny: String) -> Error: - var files := _zip.get_files() +static func unzip_to_path(zip: ZIPReader, destiny: String) -> Error: + var files := zip.get_files() var err: int for zip_file_name in files: @@ -56,9 +56,9 @@ static func unzip_to_path(_zip: ZIPReader, destiny: String) -> Error: if zip_file_name.ends_with("/"): err = DirAccess.make_dir_recursive_absolute(target_file_name) if err != OK: - return (err as Error) + return err else: - var file_contents: PackedByteArray = _zip.read_file(zip_file_name) + var file_contents := zip.read_file(zip_file_name) var file := FileAccess.open(target_file_name, FileAccess.WRITE) if not file: return FileAccess.get_open_error() diff --git a/src/http_client.gd b/src/http_client.gd index 073982f7..d92ccd0e 100644 --- a/src/http_client.gd +++ b/src/http_client.gd @@ -32,10 +32,10 @@ func async_http_get_using(http_request: HTTPRequest, url: String, headers := Pac class Response: var _resp: Array - + var result: int: get: return _resp[0] - + var code: int: get: return _resp[1] @@ -47,20 +47,20 @@ class Response: func _init(resp: Array) -> void: _resp = resp - + func to_json(safe:=true) -> Variant: return utils.response_to_json(_resp, safe) - + func get_string_from_utf8() -> String: return body.get_string_from_utf8() - + func _to_string() -> String: return "[Response] Result: %s; Code: %s; Headers: %s" % [result, code, headers] - + func to_response_info(host: String, download_file:="") -> ResponseInfo: var error_text := "" var status := "" - + match result: HTTPRequest.RESULT_CHUNKED_BODY_SIZE_MISMATCH, HTTPRequest.RESULT_CONNECTION_ERROR, HTTPRequest.RESULT_BODY_SIZE_LIMIT_EXCEEDED: error_text = tr("Connection error, prease try again.") @@ -90,11 +90,11 @@ class Response: if code != 200: error_text = tr("Request failed, return code") + ": " + str(code) status = tr("Failed") + ": " + str(code) - - var _result := ResponseInfo.new() - _result.error_text = error_text - _result.status = status - return _result + + var result := ResponseInfo.new() + result.error_text = error_text + result.status = status + return result class ResponseInfo: diff --git a/src/main/gui/auto_updates.gd b/src/main/gui/auto_updates.gd index 27657c05..60198359 100644 --- a/src/main/gui/auto_updates.gd +++ b/src/main/gui/auto_updates.gd @@ -1,16 +1,22 @@ class_name AutoUpdates extends Node + @export var _notification_button: NotificationsButton var _godots_releases: GodotsRecentReleases.I var _check_lock := false -func init(godots_releases: GodotsRecentReleases.I, updates_click_callback: Callable) -> void: +func init( + godots_releases: GodotsRecentReleases.I, + updates_click_callback: Callable +) -> void: self._godots_releases = godots_releases _check_updates() - _notification_button.pressed.connect(func() -> void: updates_click_callback.call()) + _notification_button.pressed.connect(func() -> void: + updates_click_callback.call() + ) func _notification(what: int) -> void: @@ -19,7 +25,7 @@ func _notification(what: int) -> void: func _check_updates() -> void: - if _check_lock: + if _check_lock: return _check_lock = true await _async_check_updates() @@ -27,7 +33,6 @@ func _check_updates() -> void: func _async_check_updates() -> void: - @warning_ignore("redundant_await") var has_updates := await _godots_releases.async_has_updates() if has_updates: _notification_button.has_notifications = true diff --git a/src/main/gui/gui_main.gd b/src/main/gui/gui_main.gd index 8137b372..a7829c00 100644 --- a/src/main/gui/gui_main.gd +++ b/src/main/gui/gui_main.gd @@ -52,14 +52,14 @@ func _ready() -> void: else: zip_reader.close() _remote_editors.install_zip( - file, - file.get_file().replace(".zip", ""), + file, + file.get_file().replace(".zip", ""), utils.guess_editor_name(file.replace(".zip", "")) ) else: _local_editors.import(utils.guess_editor_name(file), file) ) - + _title_tabs.add_child(TitleTabButton.new("ProjectList", tr("Projects"), _tab_container, [_projects])) _title_tabs.add_child(TitleTabButton.new("AssetLib", tr("Asset Library"), _tab_container, [_asset_lib_projects])) _title_tabs.add_child(TitleTabButton.new("GodotMonochrome", tr("Editors"), _tab_container, [_local_editors, _remote_editors])) @@ -73,14 +73,14 @@ func _ready() -> void: _gui_base.set_anchor(SIDE_RIGHT, Control.ANCHOR_END) _gui_base.set_anchor(SIDE_BOTTOM, Control.ANCHOR_END) _gui_base.set_end(Vector2.ZERO) - + _main_v_box.set_anchors_and_offsets_preset( - Control.PRESET_FULL_RECT, - Control.PRESET_MODE_MINSIZE, + Control.PRESET_FULL_RECT, + Control.PRESET_MODE_MINSIZE, get_theme_constant("window_border_margin", "Editor") ) _main_v_box.add_theme_constant_override( - "separation", + "separation", get_theme_constant("top_bar_separation", "Editor") ) @@ -105,12 +105,12 @@ func _ready() -> void: _tab_container.current_tab = _tab_container.get_tab_idx_from_control(_updates) ) _version_button.tooltip_text = tr("Click to see other versions.") - + var news_buttons := %NewsButton as LinkButton news_buttons.self_modulate = Color(1, 1, 1, 0.6) news_buttons.underline = LinkButton.UNDERLINE_MODE_ON_HOVER news_buttons.tooltip_text = tr("Click to see the post.") - + _settings_button.flat = true #_settings_button.text = tr("Settings") _settings_button.text = "" @@ -122,7 +122,7 @@ func _ready() -> void: _settings_button.pressed.connect(func() -> void: ($Settings as SettingsWindow).raise_settings() ) - + _local_editors_service.load() _projects_service.load() @@ -135,7 +135,7 @@ func _ready() -> void: _setup_godots_releases() _setup_asset_lib_projects() - + Context.add(self, %CommandViewer) @@ -151,22 +151,22 @@ func _notification(what: int) -> void: func _enter_tree() -> void: theme_source.set_scale(Config.EDSCALE) theme = theme_source.create_custom_theme(null) - + var window := get_window() window.min_size = Vector2(520, 370) * Config.EDSCALE - + var scale_factor := maxf(1, Config.EDSCALE * 0.75) if scale_factor > 1: var window_size := DisplayServer.window_get_size() var screen_rect := DisplayServer.screen_get_usable_rect(DisplayServer.window_get_current_screen()) - + window_size *= scale_factor - + DisplayServer.window_set_size(window_size) if screen_rect.size != Vector2i(): var window_position := Vector2i( - int(screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2.0), - int(screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2.0) + screen_rect.position.x + (screen_rect.size.x - window_size.x) / 2, + screen_rect.position.y + (screen_rect.size.y - window_size.y) / 2 ) DisplayServer.window_set_position(window_position) @@ -179,13 +179,13 @@ func _enter_tree() -> void: if DisplayServer.get_screen_from_rect(rect) != -1: window.size = rect.size window.position = rect.position - + _local_remote_switch_context = LocalRemoteEditorsSwitchContext.new( _local_editors, _remote_editors, _tab_container ) - + _local_editors_service = LocalEditors.List.new( Config.EDITORS_CONFIG_PATH ) @@ -194,15 +194,15 @@ func _enter_tree() -> void: _local_editors_service, preload("res://assets/default_project_icon.svg") ) - + Context.add(self, _local_remote_switch_context) Context.add(self, _local_editors_service) Context.add(self, _projects_service) - + _on_exit_tree_callbacks.append(func() -> void: _local_editors_service.cleanup() _projects_service.cleanup() - + Context.erase(self, _local_editors_service) Context.erase(self, _projects_service) Context.erase(self, _local_remote_switch_context) @@ -228,21 +228,21 @@ func _setup_asset_lib_projects() -> void: RemoteEditorsTreeDataSourceGithub.YmlSourceGithub.new() ) # var version_src = GodotVersionOptionButton.SrcMock.new(["4.1"]) - + var request := HTTPRequest.new() add_child(request) var asset_lib_factory := AssetLib.FactoryDefault.new(request) - + var category_src := AssetCategoryOptionButton.SrcRemote.new() - + _asset_lib_projects.download_requested.connect(func(item: AssetLib.Item, icon: Texture2D) -> void: var asset_download := _asset_download.instantiate() as AssetDownload (%DownloadsContainer as DownloadsContainer).add_download_item(asset_download) if icon != null: asset_download.icon.texture = icon asset_download.start( - item.download_url, - (Config.DOWNLOADS_PATH.ret() as String) + "/", + item.download_url, + (Config.DOWNLOADS_PATH.ret() as String) + "/", "project.zip", item.title ) @@ -266,7 +266,7 @@ func _setup_asset_lib_projects() -> void: ) ) ) - + _asset_lib_projects.init( asset_lib_factory, category_src, @@ -296,8 +296,8 @@ func _setup_godots_releases() -> void: _auto_updates.init( GodotsRecentReleases.Cached.new( GodotsRecentReleases.Default.new(godots_releases) - ), - func() -> void: + ), + func() -> void: _tab_container.current_tab = _tab_container.get_tab_idx_from_control(_godots_releases) ) _godots_releases.init( @@ -309,7 +309,7 @@ func _setup_godots_releases() -> void: class TitleTabButton extends Button: var _icon_name: String - + func _init(icon: String, text: String, tab_container: TabContainer, tab_controls: Array) -> void: _icon_name = icon self.text = text @@ -322,24 +322,24 @@ class TitleTabButton extends Button: ) tab_container.tab_changed.connect(func(idx: int) -> void: set_pressed_no_signal( - tab_controls.any(func(tab_control: Control) -> bool: + tab_controls.any(func(tab_control: Control) -> bool: return tab_container.get_tab_idx_from_control(tab_control) == idx\ ) ) ) toggle_mode = true focus_mode = Control.FOCUS_NONE - + self.ready.connect(func() -> void: set_pressed_no_signal( - tab_controls.any(func(tab_control: Control) -> bool: + tab_controls.any(func(tab_control: Control) -> bool: return tab_container.get_tab_idx_from_control(tab_control) == tab_container.current_tab\ ) ) add_theme_font_override("font", get_theme_font("main_button_font", "EditorFonts")) add_theme_font_size_override("font_size", get_theme_font_size("main_button_font_size", "EditorFonts")) ) - + func _notification(what: int) -> void: if what == NOTIFICATION_THEME_CHANGED: if _icon_name: diff --git a/src/objects/node_component/comp_scene.gd b/src/objects/node_component/comp_scene.gd index e8d8766d..d28444c1 100644 --- a/src/objects/node_component/comp_scene.gd +++ b/src/objects/node_component/comp_scene.gd @@ -2,6 +2,6 @@ class_name CompScene extends _Component -func _init(scene: PackedScene, children: Array =[]) -> void: - super._init(func() -> Node: return scene.instantiate()) +func _init(scene: PackedScene, children=[]): + super._init(func(): return scene.instantiate()) self.children(children) diff --git a/src/services/godots_recent_releases.gd b/src/services/godots_recent_releases.gd index 02d2f7c2..4cfd2351 100644 --- a/src/services/godots_recent_releases.gd +++ b/src/services/godots_recent_releases.gd @@ -6,42 +6,38 @@ class I: return utils.not_implemeted() -class Default: - extends I +class Default extends I: var _releases: GodotsReleases.I - + func _init(releases: GodotsReleases.I) -> void: _releases = releases func async_has_updates() -> bool: - @warning_ignore("redundant_await") var has_updates := await _releases.async_has_newest_version() return has_updates -class Cached: - extends I +class Cached extends I: const HOUR = 60 * 60 const UPDATES_CACHE_LIFETIME_SEC = 8 * HOUR var _origin: I - + func _init(origin: I) -> void: _origin = origin - + func async_has_updates() -> bool: - _actualize_cache() + await _actualize_cache() return Cache.get_value("has_update", "value", false) - + func _actualize_cache() -> void: - var last_checked_unix: int = Cache.get_value("has_update", "last_checked", 0) + var last_checked_unix:int = Cache.get_value("has_update", "last_checked", 0) if int(Time.get_unix_time_from_system()) - last_checked_unix > UPDATES_CACHE_LIFETIME_SEC: - _update_cache() + await _update_cache() elif Cache.get_value("has_update", "current_version", Config.VERSION) != Config.VERSION: - _update_cache() - + await _update_cache() + func _update_cache() -> bool: - @warning_ignore("redundant_await") var has_updates := await _origin.async_has_updates() Cache.set_value("has_update", "value", has_updates) Cache.set_value("has_update", "current_version", Config.VERSION) @@ -50,8 +46,6 @@ class Cached: return has_updates -class MockHasUpdates: - extends I - +class MockHasUpdates extends I: func async_has_updates() -> bool: return true diff --git a/src/services/godots_releases.gd b/src/services/godots_releases.gd index 9633bf04..dc38b1a6 100644 --- a/src/services/godots_releases.gd +++ b/src/services/godots_releases.gd @@ -4,39 +4,37 @@ class_name GodotsReleases class I: func async_load() -> void: pass - + func all() -> Array[Release]: return [] - + func async_has_newest_version() -> bool: return false -class Default: - extends I +class Default extends I: var _src: Src var _data: Array[Release] = [] var _fetched := false - + func _init(src: Src) -> void: _src = src - + func async_load() -> void: - @warning_ignore("redundant_await") var json := await _src.async_all() - - var latest := {"value": null} - var check_is_latest := func(_release: Release) -> void: - if latest.value != null or _release.is_draft or _release.is_prerelease: + + var latest := {'value': null} + var check_is_latest := func(release: Release) -> void: + if latest.value != null or release.is_draft or release.is_prerelease: return - _release._mark_as_latest() - latest.value = _release + release._mark_as_latest() + latest.value = release _data.clear() for el: Dictionary in json: - var _release := Release.new(el) - _data.append(_release) - check_is_latest.call(_release) + var release := Release.new(el) + _data.append(release) + check_is_latest.call(release) var release: Release if Config.ONLY_STABLE_UPDATES.ret() and latest.value: @@ -65,7 +63,7 @@ class Default: func all() -> Array[Release]: return _data - + func _to_release_or_null(json: Variant) -> Release: if json != null: return Release.new(json as Dictionary) @@ -80,19 +78,18 @@ class Src: ## return is Optional[Dictionary] func async_latest() -> Variant: return utils.not_implemeted() - + ## return is Optional[Dictionary] func async_recent() -> Variant: return utils.not_implemeted() -class SrcFileSystem: - extends Src +class SrcFileSystem extends Src: var _filename: String - + func _init(filename: String) -> void: _filename = filename - + func async_all() -> Array: var file := FileAccess.open(_filename, FileAccess.READ) var content := file.get_as_text() @@ -105,7 +102,7 @@ class SrcFileSystem: if !release.is_prerelease and !release.is_draft: return el return null - + func async_recent() -> Variant: var json := self.async_all() for el: Dictionary in json: @@ -113,10 +110,9 @@ class SrcFileSystem: return null -class SrcGithub: - extends Src +class SrcGithub extends Src: const headers = ["Accept: application/vnd.github.v3+json"] - + func async_all() -> Array: var json: Variant = await _get_json(Config.RELEASES_API_ENDPOINT) if json: @@ -128,18 +124,20 @@ class SrcGithub: var json: Variant = await _get_json(Config.RELEASES_LATEST_API_ENDPOINT) if not json is Dictionary: return null - if (json as Dictionary).get("message", "") == "Not Found": + if (json as Dictionary).get('message', '') == 'Not Found': return null return json - + func async_recent() -> Variant: var json: Variant = await _get_json(Config.RELEASES_API_ENDPOINT + "?per_page=1") for el: Variant in json: return el return null - + func _get_json(url: String) -> Variant: - var response := HttpClient.Response.new(await HttpClient.async_http_get(url, headers)) + var response := HttpClient.Response.new( + await HttpClient.async_http_get(url, headers) + ) var json: Variant = response.to_json() return json @@ -148,46 +146,37 @@ class Release: var _json: Dictionary var _is_latest := false var _is_ready_to_update := false - + var name: String: - get: - return _json.name - + get: return _json.name + var tag_name: String: - get: - return _json.get("tag_name", "") - + get: return _json.get('tag_name', '') + var tags: Array[String]: - get: - return _get_tags() - + get: return _get_tags() + var html_url: String: - get: - return _json.html_url - + get: return _json.html_url + var assets: Array[ReleaseAsset]: - get: - return _get_assets() - + get: return _get_assets() + var is_draft: bool: - get: - return _json.get("draft", true) - + get: return _json.get("draft", true) + var is_prerelease: bool: - get: - return _json.get("prerelease", true) - + get: return _json.get("prerelease", true) + var is_latest: bool: - get: - return _is_latest - + get: return _is_latest + var is_ready_to_update: bool: - get: - return _is_ready_to_update - + get: return _is_ready_to_update + func _init(json: Dictionary) -> void: _json = json - + func _get_tags() -> Array[String]: var tags: Array[String] = [] # if len(_json.tag_name) > 1: @@ -201,34 +190,32 @@ class Release: if is_draft: tags.append(tr("draft")) return tags - + func _get_assets() -> Array[ReleaseAsset]: var assets: Array[ReleaseAsset] = [] for asset: Dictionary in _json.get("assets", []): assets.append(ReleaseAsset.new(asset)) return assets - + func _mark_as_latest() -> void: _is_latest = true - + func _mark_as_ready_to_update() -> void: _is_ready_to_update = true class ReleaseAsset: var _json: Dictionary - + var name: String: - get: - return _json.get("name", "") - + get: return _json.get("name", "") + var browser_download_url: String: - get: - return _json.get("browser_download_url", "") - + get: return _json.get("browser_download_url", "") + func _init(json: Dictionary) -> void: _json = json - + func is_godots_bin_for_current_platform() -> bool: var zip_name: String if OS.has_feature("windows"): diff --git a/src/services/local_editors.gd b/src/services/local_editors.gd index ee4a3221..0156de59 100644 --- a/src/services/local_editors.gd +++ b/src/services/local_editors.gd @@ -2,17 +2,17 @@ class_name LocalEditors class List extends RefCounted: const dict = preload("res://src/extensions/dict.gd") - + signal editor_removed(editor_path: String) signal editor_name_changed(editor_path: String) - + var _cfg_path: String var _cfg := ConfigFile.new() var _editors: Dictionary[String, Item] = {} - + func _init(cfg_path: String) -> void: _cfg_path = cfg_path - + func add(name: String, editor_path: String) -> Item: var editor := Item.new( ConfigFileSection.new(editor_path, IConfigFileLike.of_config(_cfg)), @@ -20,8 +20,8 @@ class List extends RefCounted: if OS.has_feature("linux"): var output := [] var exit_code := OS.execute( - "chmod", - ["+x", "%s" % ProjectSettings.globalize_path(editor_path) ], + "chmod", + ["+x", "%s" % ProjectSettings.globalize_path(editor_path) ], output, true ) @@ -33,29 +33,29 @@ class List extends RefCounted: editor.extra_arguments = [] _editors[editor_path] = editor return editor - + func all() -> Array[Item]: var result: Array[Item] = [] for x: Item in _editors.values(): result.append(x) return result - + func retrieve(editor_path: String) -> Item: return _editors[editor_path] - + func has(editor_path: String) -> bool: return _editors.has(editor_path) - + func editor_is_valid(editor_path: String) -> bool: return has(editor_path) and edir.path_is_valid(editor_path) - + func erase(editor_path: String) -> void: var editor := retrieve(editor_path) editor.free() _editors.erase(editor_path) _cfg.erase_section(editor_path) editor_removed.emit(editor_path) - + func as_option_button_items() -> Array[Dictionary]: var result: Array[Dictionary] for x in all(): @@ -66,7 +66,7 @@ class List extends RefCounted: 'version_hint': x.version_hint }) return result - + # TODO type func get_all_tags() -> Array: var set := Set.new() @@ -74,7 +74,7 @@ class List extends RefCounted: for tag: String in editor.tags: set.append(tag.to_lower()) return set.values() - + func load() -> Error: cleanup() var err := _cfg.load(_cfg_path) @@ -86,15 +86,15 @@ class List extends RefCounted: _connect_name_changed(editor) _editors[section] = editor return Error.OK - + func cleanup() -> void: dict.clear_and_free(_editors) - + func save() -> Error: return _cfg.save(_cfg_path) - + func _connect_name_changed(editor: Item) -> void: - editor.name_changed.connect(func(_new_name: String) -> void: + editor.name_changed.connect(func(_new_name: String) -> void: editor_name_changed.emit(editor.path) ) @@ -102,57 +102,57 @@ class List extends RefCounted: class Item extends Object: signal tags_edited signal name_changed(new_name: String) - + var mac_os_editor_path_postfix: String: get: return _section.get_value("mac_os_editor_path_postfix", "/Contents/MacOS/Godot") - + var path: String: get: return _section.name - + var name: String: get: return _section.get_value("name", "") - set(value): + set(value): _section.set_value("name", value) name_changed.emit(value) - + var extra_arguments: PackedStringArray: get: return _section.get_typed_value( - "extra_arguments", - func(x: Variant) -> bool: return x is PackedStringArray, + "extra_arguments", + func(x: Variant) -> bool: return x is PackedStringArray, [] ) - set(value): + set(value): _section.set_value("extra_arguments", value) - + var favorite: bool: get: return _section.get_value("favorite", false) set(value): _section.set_value("favorite", value) - + # TODO type var tags: Array: get: return Set.of(_section.get_value("tags", []) as Array).values() set(value): _section.set_value("tags", value) - + var is_valid: bool: get: return edir.path_is_valid(path) - + var version_hint: String: get: return _section.get_value( - "version_hint", + "version_hint", self.name.to_lower() .replace("godot", "") .strip_edges() .replace(" ", "-") ) set(value): _section.set_value("version_hint", value) - + # TODO type var custom_commands: Array: get: return _get_custom_commands("custom_commands-v2") set(value): _section.set_value("custom_commands-v2", value) var _section: ConfigFileSection - + func _init(section: ConfigFileSection) -> void: self._section = section @@ -160,11 +160,11 @@ class Item extends Object: if NOTIFICATION_PREDELETE == what: utils.disconnect_all(self) - func fmt_string(string: String) -> String: + func fmt_string(str: String) -> String: var bin_path := _bin_path() - string = string.replace("{{EDITOR_PATH}}", bin_path) - string = string.replace("{{EDITOR_DIR}}", bin_path.get_base_dir()) - return string + str = str.replace("{{EDITOR_PATH}}", bin_path) + str = str.replace("{{EDITOR_DIR}}", bin_path.get_base_dir()) + return str func as_process(args: PackedStringArray) -> OSProcessSchema: var process_path := _bin_path() @@ -186,33 +186,33 @@ class Item extends Object: func run() -> void: var command: Dictionary = _find_custom_command_by_name("Run", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() - + func emit_tags_edited() -> void: tags_edited.emit() - + func is_self_contained() -> bool: if not is_valid: return false var sub_file_exists := func(file: String) -> bool: return FileAccess.file_exists(path.get_base_dir().path_join(file)) return sub_file_exists.call("_sc_") or sub_file_exists.call("._sc_") - + func match_name(search: String) -> bool: var sanitazed_name := _sanitize_name(name) var sanitazed_search := _sanitize_name(search) var findn := sanitazed_name.findn(sanitazed_search) return findn > -1 - + func match_version_hint(hint: String, ignore_mono:=false) -> bool: return VersionHint.are_equal(self.version_hint, hint, ignore_mono) - + func get_version() -> String: var parsed := VersionHint.parse(version_hint) if parsed.is_valid: return parsed.version else: return "" - + func get_cfg_file_path() -> String: var cfg_file_name := get_cfg_file_name() if cfg_file_name.is_empty(): @@ -225,7 +225,7 @@ class Item extends Object: if cfg_folder.is_empty(): return "" return cfg_folder.path_join(cfg_file_name) - + func get_cfg_file_name() -> String: var version := get_version() if version.is_empty(): @@ -236,7 +236,7 @@ class Item extends Object: return "editor_settings-4.tres" else: return "" - + func _bin_path() -> String: var process_path: String if OS.has_feature("windows") or OS.has_feature("linux"): @@ -244,17 +244,17 @@ class Item extends Object: elif OS.has_feature("macos"): process_path = ProjectSettings.globalize_path(path + mac_os_editor_path_postfix) return process_path - + func _sanitize_name(name: String) -> String: return name.replace(" ", "") - + # TODO type func _find_custom_command_by_name(name: String, src:=[]) -> Variant: for command: Dictionary in src: if command.name == name: return command return null - + # TODO type func _get_custom_commands(key: String) -> Array: var commands := _section.get_value(key, []) as Array @@ -265,50 +265,50 @@ class Item extends Object: 'path': '{{EDITOR_PATH}}', 'args': ['-p'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) return commands - + func _to_string() -> String: return "%s (%s)" % [name, VersionHint.parse(version_hint)] class Selector: var _filter: Callable - + ## filter: Optional[Callable[[Item], bool]] func _init(filter: Variant =null) -> void: if filter == null: filter = func(x: Variant) -> bool: return true _filter = filter - + func by_name(name: String) -> Selector: return Selector.new(func(el: Item) -> bool: return _filter.call(el) and el.match_name(name) ) - + func by_version_hint(hint: String, ignore_mono:=false) -> Selector: return Selector.new(func(el: Item) -> bool: return _filter.call(el) and el.match_version_hint(hint, ignore_mono) ) - + func select(editors: List) -> Array[Item]: var result: Array[Item] = [] for el in editors.all(): if _filter.call(el): result.append(el) return result - + func select_first_or_null(editors: List) -> Item: var res := select(editors) if len(res) > 0: return res[0] else: return null - + func select_exact_one(editors: List) -> Item: var res := select(editors) if len(res) == 1: @@ -317,7 +317,7 @@ class Selector: if len(res) > 1: Output.push("There is ambiguity between editors to run.\n%s" % "\n".join(res)) return null - + static func from_cmd(cmd: CliParser.ParsedCommandResult) -> Selector: var name := cmd.args.first_option_value(["name", "n"]) var version_hint := cmd.args.first_option_value(["version-hint", "vh"]) diff --git a/src/services/projects.gd b/src/services/projects.gd index 6b935f68..9fe5bf81 100644 --- a/src/services/projects.gd +++ b/src/services/projects.gd @@ -2,18 +2,18 @@ class_name Projects class List extends RefCounted: const dict = preload("res://src/extensions/dict.gd") - + var _cfg := ConfigFile.new() var _projects: Dictionary[String, Item] = {} var _cfg_path: String var _default_icon: Texture2D var _local_editors: LocalEditors.List - + func _init(cfg_path: String, local_editors: LocalEditors.List, default_icon: Texture2D) -> void: _cfg_path = cfg_path _local_editors = local_editors _default_icon = default_icon - + func add(project_path: String, editor_path: String) -> Item: var project := Item.new( ConfigFileSection.new(project_path, IConfigFileLike.of_config(_cfg)), @@ -25,33 +25,33 @@ class List extends RefCounted: project.editor_path = editor_path _projects[project_path] = project return project - + func all() -> Array[Item]: var result: Array[Item] = [] for x: Item in _projects.values(): result.append(x) return result - + func retrieve(project_path: String) -> Item: return _projects[project_path] - + func has(project_path: String) -> bool: return _projects.has(project_path) - + func erase(project_path: String) -> void: _projects.erase(project_path) _cfg.erase_section(project_path) - + func get_editors_to_bind() -> Array[Dictionary]: return _local_editors.as_option_button_items() - + func get_owners_of(editor: LocalEditors.Item) -> Array[Item]: var result: Array[Item] for project in all(): if project.editor_is(editor): result.append(project) return result - + # TODO type func get_all_tags() -> Array: var set := Set.new() @@ -59,7 +59,7 @@ class List extends RefCounted: for tag: String in project.tags: set.append(tag.to_lower()) return set.values() - + func load() -> Error: cleanup() var err := _cfg.load(_cfg_path) @@ -71,13 +71,13 @@ class List extends RefCounted: _local_editors ) return Error.OK - + func cleanup() -> void: dict.clear_and_free(_projects) - + func save() -> Error: return _cfg.save(_cfg_path) - + func get_last_opened() -> Projects.Item: var last_opened := _ProjectsCache.get_last_opened_project() return retrieve(last_opened) if has(last_opened) else null @@ -86,67 +86,67 @@ class List extends RefCounted: class Item: signal internals_changed signal loaded - + var show_edit_warning: bool: get: return _section.get_value("show_edit_warning", true) set(value): _section.set_value("show_edit_warning", value) - + var path: String: get: return _section.name - + var name: String: get: return _external_project_info.name set(value): _external_project_info.name = value - + var editor_name: String: get: return _get_editor_name() - + var icon: Texture2D: get: return _external_project_info.icon var favorite: bool: get: return _section.get_value("favorite", false) set(value): _section.set_value("favorite", value) - + var editor: LocalEditors.Item: - get: + get: if has_invalid_editor: return null return _local_editors.retrieve(editor_path) - + var editor_path: String: get: return _section.get_value("editor_path", "") - set(value): + set(value): show_edit_warning = true _section.set_value("editor_path", value) - + var has_invalid_editor: bool: get: return not _local_editors.editor_is_valid(editor_path) - + var is_valid: bool: get: return edir.path_is_valid(path) - + # TODO type var editors_to_bind: Array: get: return _get_editors_to_bind() - + var is_missing: bool: get: return _external_project_info.is_missing - + var is_loaded: bool: get: return _external_project_info.is_loaded - + var tags: Array: set(value): _external_project_info.tags = value get: return _external_project_info.tags - + var last_modified: int: get: return _external_project_info.last_modified - + # TODO type var features: Array: get: return _external_project_info.features - + var version_hint: String: get: return _external_project_info.version_hint set(value): _external_project_info.version_hint = value @@ -161,9 +161,9 @@ class Item: var _external_project_info: ExternalProjectInfo var _section: ConfigFileSection var _local_editors: LocalEditors.List - + func _init( - section: ConfigFileSection, + section: ConfigFileSection, project_info: ExternalProjectInfo, local_editors: LocalEditors.List ) -> void: @@ -175,20 +175,20 @@ class Item: ) self._local_editors.editor_name_changed.connect(_check_editor_changes) project_info.loaded.connect(func() -> void: loaded.emit()) - + func before_delete_as_ref_counted() -> void: utils.disconnect_all(self) if _external_project_info: _external_project_info.before_delete_as_ref_counted() - + func load(with_icon:=true) -> void: _external_project_info.load(with_icon) - + func editor_is(editor: LocalEditors.Item) -> bool: if has_invalid_editor: return false return self.editor == editor - + func _get_editor_name() -> String: if has_invalid_editor: return '' @@ -198,10 +198,10 @@ class Item: func _check_editor_changes(editor_path: String) -> void: if editor_path == self.editor_path: emit_internals_changed() - + func emit_internals_changed() -> void: internals_changed.emit() - + func as_process(args: PackedStringArray) -> OSProcessSchema: assert(not has_invalid_editor) var editor := _local_editors.retrieve(editor_path) @@ -211,16 +211,16 @@ class Item: ] result_args.append_array(args) return editor.as_process(result_args) - - func fmt_string(string: String) -> String: + + func fmt_string(str: String) -> String: if not has_invalid_editor: var editor := _local_editors.retrieve(editor_path) - string = editor.fmt_string(string) - string = string.replace( + str = editor.fmt_string(str) + str = str.replace( '{{PROJECT_DIR}}', ProjectSettings.globalize_path(self.path).get_base_dir() ) - return string - + return str + func as_fmt_process(process_path: String, args: PackedStringArray) -> OSProcessSchema: var result_path := process_path var result_args: PackedStringArray @@ -234,23 +234,23 @@ class Item: arg = self.fmt_string(arg) result_args.append(arg) return OSProcessSchema.new(result_path, result_args) - + func edit() -> void: var command: Dictionary = _find_custom_command_by_name("Edit", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() _ProjectsCache.set_last_opened_project(path) - + func run() -> void: var command: Dictionary = _find_custom_command_by_name("Run", custom_commands) as_fmt_process(command.path as String, command.args as PackedStringArray).create_process() - + # TODO type func _find_custom_command_by_name(name: String, src:=[]) -> Variant: for command: Dictionary in src: if command.name == name: return command return null - + # TODO type func _get_custom_commands(key: String) -> Array: var commands: Array = _section.get_value(key, []) @@ -261,8 +261,8 @@ class Item: 'path': '{{EDITOR_PATH}}', 'args': ['--path', '{{PROJECT_DIR}}' ,'-e'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) @@ -273,13 +273,13 @@ class Item: 'path': '{{EDITOR_PATH}}', 'args': ['--path', '{{PROJECT_DIR}}' ,'-g'], 'allowed_actions': [ - CommandViewer.Actions.EXECUTE, - CommandViewer.Actions.EDIT, + CommandViewer.Actions.EXECUTE, + CommandViewer.Actions.EDIT, CommandViewer.Actions.CREATE_PROCESS ] }) return commands - + #TODO type func _get_editors_to_bind() -> Array: var options := _local_editors.as_option_button_items() @@ -299,7 +299,7 @@ class _ProjectsCache: class ExternalProjectInfo extends RefCounted: signal loaded - + var icon: Texture2D: get: return _icon @@ -313,15 +313,15 @@ class ExternalProjectInfo extends RefCounted: var err := cfg.load(_project_path) if not err: cfg.set_value( - "application", - "config/name", + "application", + "config/name", _name ) cfg.save(_project_path) - + var has_version_hint: bool: get: return _version_hint != null - + var version_hint: String: get: return '' if _version_hint == null else _version_hint set(value): @@ -332,21 +332,21 @@ class ExternalProjectInfo extends RefCounted: var err := cfg.load(_project_path) if not err: cfg.set_value( - "godots", - "version_hint", + "godots", + "version_hint", _version_hint ) cfg.save(_project_path) var last_modified: int: get: return _last_modified - + var is_loaded: bool: get: return _is_loaded - + var is_missing: bool: get: return _is_missing - + # TODO type var tags: Array: set(value): @@ -360,17 +360,17 @@ class ExternalProjectInfo extends RefCounted: for tag: String in _tags: set.append(tag.to_lower()) cfg.set_value( - "application", - "config/tags", + "application", + "config/tags", PackedStringArray(set.values()) ) cfg.save(_project_path) get: return Set.of(_tags).values() - + # TODO type var features: Array: get: return _features - + var _is_loaded := false var _project_path: String var _default_icon: Texture2D @@ -384,19 +384,19 @@ class ExternalProjectInfo extends RefCounted: var _has_mono_section := false ## Optional[String], TODO type var _version_hint: Variant = null - + func _init(project_path: String, default_icon: Texture2D = null) -> void: _project_path = project_path _default_icon = default_icon _icon = default_icon - + func before_delete_as_ref_counted() -> void: utils.disconnect_all(self) - + func load(with_icon:=true) -> void: var cfg := ConfigFile.new() var err := cfg.load(_project_path) - + _name = cfg.get_value("application", "config/name", "Missing Project") _tags = cfg.get_value("application", "config/tags", []) _features = cfg.get_value("application", "config/features", []) @@ -406,21 +406,21 @@ class ExternalProjectInfo extends RefCounted: _version_hint = cfg.get_value("godots", "version_hint") if _version_hint == '': _version_hint = null - + _last_modified = FileAccess.get_modified_time(_project_path) if with_icon: _icon = _load_icon(cfg) _is_missing = bool(err) - + _is_loaded = true loaded.emit() - + func _load_icon(cfg: ConfigFile) -> Texture2D: var result := _default_icon var icon_path: String = cfg.get_value("application", "config/icon", "") if not icon_path: return result icon_path = icon_path.replace("res://", self._project_path.get_base_dir() + "/") - + if FileAccess.file_exists(icon_path): var icon_image := Image.new() var err := icon_image.load(icon_path) @@ -430,18 +430,18 @@ class ExternalProjectInfo extends RefCounted: ) result = ImageTexture.create_from_image(icon_image) return result - + # TODO type func sort_editor_options(options: Array) -> void: var has_cs_feature := "C#" in features var is_mono := has_cs_feature or _has_mono_section - + var check_stable := func(label: String) -> bool: return label.contains("stable") - + var check_mono := func(label: String) -> bool: return label.contains("mono") - + var check_version := func(label: String) -> bool: if _version_hint != null: if VersionHint.same_version(_version_hint as String, label): @@ -451,7 +451,7 @@ class ExternalProjectInfo extends RefCounted: elif _config_version == 4: return not label.contains("3.0") and not label.contains("4.") elif _config_version > 4: - var is_version := func(feature: String) -> bool: + var is_version := func(feature: String) -> bool: return feature.contains(".") and feature.substr(0, 3).is_valid_float() var version_tags := Array(features).filter(is_version) if len(version_tags) > 0: @@ -460,7 +460,7 @@ class ExternalProjectInfo extends RefCounted: return label.contains("4.") else: return false - + var check_version_hint_similarity := func(version_hint: String) -> int: var score := VersionHint.similarity(_version_hint as String, version_hint) return score @@ -468,7 +468,7 @@ class ExternalProjectInfo extends RefCounted: options.sort_custom(func(item_a: Dictionary, item_b: Dictionary) -> bool: var a := (item_a.version_hint as String).to_lower() var b := (item_b.version_hint as String).to_lower() - + if _version_hint != null: var sim_a: int = check_version_hint_similarity.call(a) var sim_b: int = check_version_hint_similarity.call(b) @@ -490,6 +490,6 @@ class ExternalProjectInfo extends RefCounted: return true if check_stable.call(b) && !check_stable.call(a): return false - + return VersionHint.version_or_nothing(a) > VersionHint.version_or_nothing(b) ) diff --git a/src/services/remote_image_src.gd b/src/services/remote_image_src.gd index c087f5d1..cfd82a37 100644 --- a/src/services/remote_image_src.gd +++ b/src/services/remote_image_src.gd @@ -6,37 +6,34 @@ class I: pass -class AlwaysBroken: - extends I +class AlwaysBroken extends I: var _theme_src: Control - + func _init(theme_src: Control) -> void: _theme_src = theme_src - + func async_load_img(url: String, callback: Callable) -> void: var texture := _theme_src.get_theme_icon("FileBrokenBigThumb", "EditorIcons") callback.call(texture) -class LoadFileBuffer: - extends I +class LoadFileBuffer extends I: var _file_src: FileByUrlSrc var _fallback_texture: Texture2D - + func _init(file_src: FileByUrlSrc, fallback_texture: Texture2D) -> void: _fallback_texture = fallback_texture _file_src = file_src - + func async_load_img(url: String, callback: Callable) -> void: - @warning_ignore("redundant_await") var file_path := await _file_src.async_load(url) - + if file_path.is_empty(): return - + if not callback.is_valid(): return - + # some weird additional check is required due to: # 'Trying to call a lambda with an invalid instance.' # https://github.com/godotengine/godot/blob/c7fb0645af400a1859154bcee9394e63bdabd198/modules/gdscript/gdscript_lambda_callable.cpp#L195 @@ -47,7 +44,7 @@ class LoadFileBuffer: if file == null: callback.call(_fallback_texture) return - + var file_buffer := file.get_buffer(file.get_length()) var img := Image.new() var load_err := _load_img_from_buffer(img, file_buffer) @@ -56,13 +53,13 @@ class LoadFileBuffer: else: var tex := ImageTexture.create_from_image(img) callback.call(tex) - + func _load_img_from_buffer(img: Image, buffer: PackedByteArray) -> int: var png_signature := PackedByteArray([137, 80, 78, 71, 13, 10, 26, 10]) var jpg_signature := PackedByteArray([255, 216, 255]) var webp_signature := PackedByteArray([82, 73, 70, 70]) var bmp_signature := PackedByteArray([66, 77]) - + var load_err := ERR_PARAMETER_RANGE_ERROR if png_signature == buffer.slice(0, 8): load_err = img.load_png_from_buffer(buffer) @@ -81,24 +78,20 @@ class FileByUrlSrc: return "" -class FileByUrlSrcAsIs: - extends FileByUrlSrc - +class FileByUrlSrcAsIs extends FileByUrlSrc: func async_load(url: String) -> String: var file_path := (Config.CACHE_DIR_PATH.ret() as String).path_join(url.md5_text()) - var response := HttpClient.Response.new(await HttpClient.async_http_get(url, [], file_path)) + var response := HttpClient.Response.new( + await HttpClient.async_http_get(url, [], file_path) + ) if response.code != 200: return "" return file_path -class FileByUrlCachedEtag: - extends FileByUrlSrc - +class FileByUrlCachedEtag extends FileByUrlSrc: func async_load(url: String) -> String: - var file_path_base := (Config.CACHE_DIR_PATH.ret() as String).path_join( - "assetimage_" + url.md5_text() - ) + var file_path_base := (Config.CACHE_DIR_PATH.ret() as String).path_join("assetimage_" + url.md5_text()) var etag_path := file_path_base + ".etag" var data_path := file_path_base + ".data" var headers := [] @@ -109,17 +102,12 @@ class FileByUrlCachedEtag: var response := HttpClient.Response.new( await HttpClient.async_http_get(url, headers, data_path) ) - if ( - response.result == HTTPRequest.RESULT_SUCCESS - and response.result < HTTPClient.RESPONSE_BAD_REQUEST - ): + if response.result == HTTPRequest.RESULT_SUCCESS and response.result < HTTPClient.RESPONSE_BAD_REQUEST: if response.code != HTTPClient.RESPONSE_NOT_MODIFIED: for header in response.headers: header = header as String if header.findn("ETag:") == 0: - var new_etag := ( - header.substr(header.find(":") + 1, header.length()).strip_edges() - ) + var new_etag := header.substr(header.find(":") + 1, header.length()).strip_edges() var file := FileAccess.open(etag_path, FileAccess.WRITE) if file: file.store_line(new_etag) diff --git a/src/utils.gd b/src/utils.gd index 9d705a00..7f8fadf5 100644 --- a/src/utils.gd +++ b/src/utils.gd @@ -4,22 +4,20 @@ class_name utils static func guess_editor_name(file_name: String) -> String: var possible_editor_name := file_name.get_file() var tokens_to_replace: Array[String] - tokens_to_replace.append_array( - [ - "x11.64", - "linux.64", - "linux.x86_64", - "linux.x86_32", - "osx.universal", - "macos.universal", - "osx.fat", - "osx32", - "osx64", - "win64", - "win32", - ".%s" % file_name.get_extension() - ] - ) + tokens_to_replace.append_array([ + "x11.64", + "linux.64", + "linux.x86_64", + "linux.x86_32", + "osx.universal", + "macos.universal", + "osx.fat", + "osx32", + "osx64", + "win64", + "win32", + ".%s" % file_name.get_extension() + ]) tokens_to_replace.append_array(["_", "-"]) for token in tokens_to_replace: possible_editor_name = possible_editor_name.replace(token, " ") @@ -29,15 +27,17 @@ static func guess_editor_name(file_name: String) -> String: static func find_project_godot_files(dir_path: String) -> Array[edir.DirListResult]: var project_configs := edir.list_recursive( - ProjectSettings.globalize_path(dir_path), + ProjectSettings.globalize_path(dir_path), false, - func(x: edir.DirListResult) -> bool: return x.is_file and x.file == "project.godot", - func(x: String) -> bool: return not x.get_file().begins_with(".") + (func(x: edir.DirListResult) -> bool: + return x.is_file and x.file == "project.godot"), + (func(x: String) -> bool: + return not x.get_file().begins_with(".")) ) return project_configs -static func response_to_json(response: Variant, safe := true) -> Variant: +static func response_to_json(response: Variant, safe:=true) -> Variant: var body := response[3] as PackedByteArray var string := body.get_string_from_utf8() if safe: @@ -57,13 +57,11 @@ static func parse_json_safe(string: String) -> Variant: static func fit_height(max_height: float, cur_size: Vector2i, callback: Callable) -> void: var scale_ratio := max_height / (cur_size.y * Config.EDSCALE) - if scale_ratio < 1.0: - callback.call( - Vector2i( - cur_size.x * int(Config.EDSCALE) * int(scale_ratio), - cur_size.y * int(Config.EDSCALE) * int(scale_ratio) - ) - ) + if scale_ratio < 1: + callback.call(Vector2i( + cur_size.x * Config.EDSCALE * scale_ratio, + cur_size.y * Config.EDSCALE * scale_ratio + )) static func disconnect_all(obj: Object) -> void: diff --git a/tests/cases/cli/parser/parser_not_ok.gd b/tests/cases/cli/parser/parser_not_ok.gd index 8764007e..56ff9c6e 100644 --- a/tests/cases/cli/parser/parser_not_ok.gd +++ b/tests/cases/cli/parser/parser_not_ok.gd @@ -1,34 +1,34 @@ class_name CliParserNotOkTests extends GdUnitTestSuite -func test_invalid_namespace() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["invalidNamespace"]) +func test_invalid_namespace(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["invalidNamespace"]) assert(result.namesp.is_empty()) assert(result.verb.is_empty()) assert(result.args.names[0] == "invalidNamespace") -func test_invalid_command() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "invalidVerb"]) +func test_invalid_command(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "invalidVerb"]) assert(result.namesp == "namespace1") assert(result.verb.is_empty()) assert(result.args.names[0] == "invalidVerb") -func test_invalid_option() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "--invalidOption"]) +func test_invalid_option(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "--invalidOption"]) assert(result.has_error()) assert(result.errors[0] == "Unsupported option: --invalidOption") -func test_repeated_options() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "--flag1", "value2"]) +func test_repeated_options(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "--flag1", "value2"]) assert(result.has_error()) assert(result.errors[0] == "Only one option with name (`flag1`, `f1`) can be used.") -func test_repeated_short_and_long_options() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "-f1", "value2"]) +func test_repeated_short_and_long_options(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "--flag1", "value1", "-f1", "value2"]) assert(result.has_error()) assert(result.errors[0] == "Only one option with name (`flag1`, `f1`) can be used.") diff --git a/tests/cases/cli/parser/parser_ok.gd b/tests/cases/cli/parser/parser_ok.gd index a2fe522d..105b5b7f 100644 --- a/tests/cases/cli/parser/parser_ok.gd +++ b/tests/cases/cli/parser/parser_ok.gd @@ -1,9 +1,9 @@ class_name CliParserOkTests extends GdUnitTestSuite -func test_parse_command() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "verb1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_command(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "verb1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "namespace1") assert(result.verb == "verb1") @@ -13,9 +13,9 @@ func test_parse_command() -> void: assert(args.has_options(["bool-flag"])) assert(args.has_options(["a"])) -func test_parse_without_verb() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["namespace1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_without_verb(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["namespace1", "just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "namespace1") assert(result.verb == "") @@ -25,9 +25,9 @@ func test_parse_without_verb() -> void: assert(args.has_options(["bool-flag"])) assert(args.has_options(["a"])) -func test_parse_without_namespace_and_verb() -> void: - var parser := CliParser.CommandParser.new(TestGrammar.grammar) - var result := parser.parse_command(["just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) +func test_parse_without_namespace_and_verb(): + var parser = CliParser.CommandParser.new(TestGrammar.grammar) + var result = parser.parse_command(["just_name", "--flag1", "value1", "value2", "--bool-flag", "-a"]) var args: CliParser.ParsedArguments = result.args assert(result.namesp == "") assert(result.verb == "") diff --git a/tests/cases/cli/parser/test_grammar.gd b/tests/cases/cli/parser/test_grammar.gd index 3e11eeb6..c8ec30df 100644 --- a/tests/cases/cli/parser/test_grammar.gd +++ b/tests/cases/cli/parser/test_grammar.gd @@ -1,6 +1,6 @@ class_name TestGrammar -static var grammar := CliGrammar.new([ +static var grammar = CliGrammar.new([ CliCommand.new( "namespace1", "verb1", diff --git a/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd b/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd index 54d3466a..c6ca0102 100644 --- a/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd +++ b/tests/cases/dir_extensions/list_dir_recursive/list_dir_test.gd @@ -2,24 +2,19 @@ class_name GdUnitExampleTest extends GdUnitTestSuite -func test_list_dir() -> void: - var result := edir.list_recursive( +func test_list_dir(): + var result = edir.list_recursive( "res://tests/cases/dir_extensions/list_dir_recursive/assets/1/" ) assert_int(len(result)).is_equal(8) - - @warning_ignore("untyped_declaration") # I cannot figure out the type of x - var files := result.filter(func(x): return x.is_file).map(func(x): return x.file) - assert_array(files).contains_exactly( - ["file.txt", "file2.txt", "file3.txt", "file3.txt", "file4.txt"] - ) - - @warning_ignore("untyped_declaration") # I cannot figure out the type of x - var dirs := result.filter(func(x): return x.is_dir).map(func(x): return x.file) + + var files = result.filter(func(x): return x.is_file).map(func(x): return x.file) + assert_array(files).contains_exactly(["file.txt", "file2.txt", "file3.txt", "file3.txt", "file4.txt"]) + + var dirs = result.filter(func(x): return x.is_dir).map(func(x): return x.file) assert_array(dirs).contains_exactly(["sub-dir", "sub-dir-2", "sub-dir-3"]) - - @warning_ignore("untyped_declaration") # I cannot figure out the type of x - var raw_dirs := result.filter(func(x): return x.is_dir) + + var raw_dirs = result.filter(func(x): return x.is_dir) assert_str(raw_dirs[0].path).is_equal( "res://tests/cases/dir_extensions/list_dir_recursive/assets/1/sub-dir" ) diff --git a/tests/cases/services/local_editor_tests.gd b/tests/cases/services/local_editor_tests.gd index 4f751ca5..d3f0a35c 100644 --- a/tests/cases/services/local_editor_tests.gd +++ b/tests/cases/services/local_editor_tests.gd @@ -10,8 +10,8 @@ func test_filter_by_name_pattern(name: String, expected: int, test_parameters:= [" 4.1 s", 1], ["4.1 StAble", 1], ["invalid", 0], -]) -> void: - var editors := LocalEditors.List.new(config_path) +]): + var editors = LocalEditors.List.new(config_path) editors.load() - var result := LocalEditors.Selector.new().by_name(name).select(editors) + var result = LocalEditors.Selector.new().by_name(name).select(editors) assert_int(result.size()).is_equal(expected) diff --git a/theme/fill_icons_registry.gd b/theme/fill_icons_registry.gd index 7fa5553d..72cc5010 100644 --- a/theme/fill_icons_registry.gd +++ b/theme/fill_icons_registry.gd @@ -7,10 +7,10 @@ func _run() -> void: _create_cfg('res://theme/icons-light', 'res://theme/icons-light.cfg') -func _create_cfg(icons_dir: String, result_file_path: String) -> void: - var result := ConfigFile.new() - var dir := EditorInterface.get_resource_filesystem().get_filesystem_path(icons_dir) +func _create_cfg(icons_dir, result_file_path): + var result = ConfigFile.new() + var dir = EditorInterface.get_resource_filesystem().get_filesystem_path(icons_dir) for i in range(dir.get_file_count()): - var path := dir.get_file_path(i) + var path = dir.get_file_path(i) result.set_value(path, "name", path.get_basename().get_file()) result.save(result_file_path) From 84e746d64564f215010925594b71e537ae803a25 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:14:06 -0300 Subject: [PATCH 10/23] Revert "feat: add desktop integration" This reverts commit a720bdb87ca8d6740ed442d0c1252ad565117b80. --- project.godot | 2 +- src/main/main.gd | 69 ------------------------------------------------ 2 files changed, 1 insertion(+), 70 deletions(-) diff --git a/project.godot b/project.godot index c02892c1..015d2f34 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/expand-region/plugin.cfg", "res://addons/find-everywhere/plugin.cfg", "res://addons/previous-tab/plugin.cfg", "res://addons/script-tabs/plugin.cfg", "res://addons/use-context/plugin.cfg") [filesystem] diff --git a/src/main/main.gd b/src/main/main.gd index 2b087a1c..c4bcf327 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -1,24 +1,11 @@ extends Node -const DESKTOP_ENTRY_FOLDER = ".local/share/applications" -const GVM_APP_FOLDER = ".local/godots.app" -const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" - @export_file() var gui_scene_path: String - - func _ready() -> void: var args := OS.get_cmdline_args() var user_args := OS.get_cmdline_user_args() - # Check if running as Flatpak by checking for the .flatpak-info file - var is_flatpak := FileAccess.file_exists("/.flatpak-info") - - # Check and create GVM desktop entry if needed - if OS.get_name() == "Linux" and not is_flatpak: - _ensure_desktop_entry() - if _is_cli_mode(args): Output.push("Run cli mode") var adjusted_args := args.slice(1) if OS.has_feature("editor") else args @@ -36,61 +23,5 @@ func _is_cli_mode(args: PackedStringArray) -> bool: return true return false -func _ensure_desktop_entry() -> void: - var home := OS.get_environment("HOME") - var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) - var gvm_app_path := home.path_join(GVM_APP_FOLDER) - - # Create gvm.app folder and copy executable - var dir := DirAccess.open("user://") - if FileAccess.file_exists(gvm_app_path): - return - else: - dir.make_dir_recursive(gvm_app_path) - - # Copy the current executable to gvm.app folder - var current_exe := OS.get_executable_path() - var new_exe_path := gvm_app_path.path_join("godots.x86_64") - if DirAccess.copy_absolute(current_exe, new_exe_path) == OK: - # Make it executable - OS.execute("chmod", ["+x", new_exe_path]) - - # Create desktop entry - # Copy and save the icon - var icon_path := gvm_app_path.path_join("icon.png") - var icon := load("res://icon.svg") as Texture2D - var image := icon.get_image() - image.save_png(icon_path) - - # Create desktop entry - var desktop_entry := _create_desktop_entry(new_exe_path, icon_path) - var file := FileAccess.open(desktop_entry_path, FileAccess.WRITE) - if file: - file.store_string(desktop_entry) - file.close() - # Make desktop entry executable - OS.execute("chmod", ["+x", desktop_entry_path]) - else: - printerr("Failed to create desktop entry") - else: - printerr("Failed to copy executable") - - -func _create_desktop_entry(exe_path: String, icon_path: String) -> String: - return """[Desktop Entry] - Name=Godots -GenericName=Libre game engine version manager -Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec="{exe}" %f -Icon={icon} -Terminal=false -PrefersNonDefaultGPU=true -Type=Application -Categories=Development;IDE; -StartupWMClass=Godot -""".format( - {"exe": exe_path, "icon": icon_path} - ) - func _exit() -> void: get_tree().quit() From 2b0445ec05f8c911e35b35a5f3a6fd91aaade5a8 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:16:53 -0300 Subject: [PATCH 11/23] Fix: Reverting everything and addig an installation script I think instead of adding a desktop file creation feature inside of the app, we could just add an installation script the user can execute. The same way bun, deno and kitty do. --- README.md | 19 +++++++++++++++---- install.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 install.sh diff --git a/README.md b/README.md index 8467d6f4..e41c5ba0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -## Godots +## Godots + 🚀 **Introducing Godots: Elevating Your Godot Experience!** 🚀 Welcome to a world where style meets functionality, where pixels pop and creativity soars! Presenting **Godots**, your ultimate go-to hub for managing your Godot versions and projects in the most stylish and efficient way possible. 🎮✨ @@ -8,7 +9,9 @@ Welcome to a world where style meets functionality, where pixels pop and creativ

## Unleash the Power on MacOS! 💥 + For all the macOS aficionados out there, unleashing the power of Godots is just a command away. Ready to run the app? Just add it to your quarantine with a swift and stylish command: + ```shell sudo xattr -r -d com.apple.quarantine /Applications/Godots.app ``` @@ -25,7 +28,14 @@ Fear not Linux users, unleashing the power of Godots on any distribution is just Don't have Flatpak? Just download the [latest release](https://github.com/MakovWait/godots/releases)! +Or use the installation script: + +```shell +curl -sSL https://raw.githubusercontent.com/MakovWait/godots/main/install.sh | sh +``` + ## Features That Redefine Cool 😎 + - **HIDPI Magic**: Feast your eyes on Godots like never before! With pixel-perfect support for Retina displays, zero blur, and stunning visuals, it's a visual extravaganza. - **Sleek & Native**: Dive into the elegance of the native Godot theme, seamlessly integrated into Godots. Get ready to be awed by the fluid aesthetics that keep you engaged. @@ -37,9 +47,10 @@ Don't have Flatpak? Just download the [latest release](https://github.com/MakovW ![image](https://github.com/MakovWait/godots/blob/main/.github/assets/screenshot1.png) - **Theming Support**: Customize your Godots experience with theming support. Make it truly your own with personalized themes that match your style and mood. [Theming readme](https://github.com/MakovWait/godots/blob/main/.github/assets/THEMING.md) -![image](https://github.com/MakovWait/godots/blob/main/.github/assets/screenshot3.png) -> Used theme: https://github.com/bitbrain/godot-dash + ![image](https://github.com/MakovWait/godots/blob/main/.github/assets/screenshot3.png) + > Used theme: https://github.com/bitbrain/godot-dash - **Cli Support**: Embrace the power of the command line! Enjoy the flexibility and efficiency of using Godots through the [command line interface](https://github.com/MakovWait/godots/blob/main/.github/assets/FEATURES.md#cli). Manage your projects and versions effortlessly, even when your fingers are dancing on the keys. -***** +--- + Godots is your ticket to a world of creativity, style, and control. Elevate your Godot journey today with Godots, where innovation and design collide. Your Godot experience will never be the same again! 🌟🎉 diff --git a/install.sh b/install.sh new file mode 100644 index 00000000..3443ce2e --- /dev/null +++ b/install.sh @@ -0,0 +1,29 @@ +#!/bin/env bash + +DOWNLOAD_URL="https://github.com/MakovWait/godots/releases/latest/download/LinuxX11.zip" + +# Download the latest version of Godots +wget -O /tmp/godots.zip $DOWNLOAD_URL + +# Unzip the downloaded file to ~/.local/godots.app/ +unzip /tmp/godots.zip -d ~/.local/godots.app/ + +# download Icon +wget -O ~/.local/godots.app/icon.svg https://github.com/MakovWait/godots/raw/master/icon.svg + +# Create a desktop entry for Godots +cat < ~/.local/share/applications/godots.desktop +[Desktop Entry] +Name=Godots +GenericName=Libre game engine version manager +Comment=Ultimate go-to hub for managing your Godot versions and projects! +Exec=~/.local/godots.app/godots +Icon=~/.local/godots.app/icon.svg +PrefersNonDefaultGPU=true +Terminal=false +Type=Application +Categories=Development;IDE; +StartupWMClass=Godot +EOF + +echo "Installation completed successfully!" From b0d0e8482286187b363da508f9ce01a829bff7fb Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:32:27 -0300 Subject: [PATCH 12/23] Revert "Reverting non feature related changes" This reverts commit ff6c9528436a94406fef685c37668245156b02f3. --- project.godot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.godot b/project.godot index 015d2f34..b3a381b6 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/expand-region/plugin.cfg", "res://addons/find-everywhere/plugin.cfg", "res://addons/previous-tab/plugin.cfg", "res://addons/script-tabs/plugin.cfg", "res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg", "res://addons/use-context/plugin.cfg") [filesystem] From fcdd5f023fd54ff961b2049751e161205b93d82e Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:32:30 -0300 Subject: [PATCH 13/23] Revert "Reverting all the desktop integration code" This reverts commit 61160dd3acf28bfe70dd4fa64fb68a8c77b3fa96. --- .gitignore | 5 +- export_presets.cfg | 189 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 182 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index f95fe259..de76f3f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Godot 4+ specific ignores .godot/ +# Export ignore +build_dir/ + # Godot-specific ignores .import/ export.cfg @@ -29,4 +32,4 @@ addons/gdUnit # Mac files .DS_Store -/override.cfg \ No newline at end of file +/override.cfg diff --git a/export_presets.cfg b/export_presets.cfg index 851bddb1..fed955b6 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -3,16 +3,20 @@ name="macOS" platform="macOS" runnable=false +advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.zip" +patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" +seed=0 encrypt_pck=false encrypt_directory=false +script_export_mode=2 [preset.0.options] @@ -30,8 +34,11 @@ application/short_version="1.0" application/version="1.0" application/copyright="" application/copyright_localized={} -application/min_macos_version="10.12" +application/min_macos_version_x86_64="10.12" +application/min_macos_version_arm64="11.00" +application/export_angle=0 display/high_res=true +application/additional_plist_content="" xcode/platform_build="14C18" xcode/sdk_version="13.1" xcode/sdk_build="22C55" @@ -64,7 +71,9 @@ codesign/entitlements/app_sandbox/files_downloads=0 codesign/entitlements/app_sandbox/files_pictures=0 codesign/entitlements/app_sandbox/files_music=0 codesign/entitlements/app_sandbox/files_movies=0 +codesign/entitlements/app_sandbox/files_user_selected=0 codesign/entitlements/app_sandbox/helper_executables=[] +codesign/entitlements/additional="" codesign/custom_options=PackedStringArray() notarization/notarization=0 privacy/microphone_usage_description="" @@ -89,6 +98,148 @@ privacy/network_volumes_usage_description="" privacy/network_volumes_usage_description_localized={} privacy/removable_volumes_usage_description="" privacy/removable_volumes_usage_description_localized={} +privacy/tracking_enabled=false +privacy/tracking_domains=PackedStringArray() +privacy/collected_data/name/collected=false +privacy/collected_data/name/linked_to_user=false +privacy/collected_data/name/used_for_tracking=false +privacy/collected_data/name/collection_purposes=0 +privacy/collected_data/email_address/collected=false +privacy/collected_data/email_address/linked_to_user=false +privacy/collected_data/email_address/used_for_tracking=false +privacy/collected_data/email_address/collection_purposes=0 +privacy/collected_data/phone_number/collected=false +privacy/collected_data/phone_number/linked_to_user=false +privacy/collected_data/phone_number/used_for_tracking=false +privacy/collected_data/phone_number/collection_purposes=0 +privacy/collected_data/physical_address/collected=false +privacy/collected_data/physical_address/linked_to_user=false +privacy/collected_data/physical_address/used_for_tracking=false +privacy/collected_data/physical_address/collection_purposes=0 +privacy/collected_data/other_contact_info/collected=false +privacy/collected_data/other_contact_info/linked_to_user=false +privacy/collected_data/other_contact_info/used_for_tracking=false +privacy/collected_data/other_contact_info/collection_purposes=0 +privacy/collected_data/health/collected=false +privacy/collected_data/health/linked_to_user=false +privacy/collected_data/health/used_for_tracking=false +privacy/collected_data/health/collection_purposes=0 +privacy/collected_data/fitness/collected=false +privacy/collected_data/fitness/linked_to_user=false +privacy/collected_data/fitness/used_for_tracking=false +privacy/collected_data/fitness/collection_purposes=0 +privacy/collected_data/payment_info/collected=false +privacy/collected_data/payment_info/linked_to_user=false +privacy/collected_data/payment_info/used_for_tracking=false +privacy/collected_data/payment_info/collection_purposes=0 +privacy/collected_data/credit_info/collected=false +privacy/collected_data/credit_info/linked_to_user=false +privacy/collected_data/credit_info/used_for_tracking=false +privacy/collected_data/credit_info/collection_purposes=0 +privacy/collected_data/other_financial_info/collected=false +privacy/collected_data/other_financial_info/linked_to_user=false +privacy/collected_data/other_financial_info/used_for_tracking=false +privacy/collected_data/other_financial_info/collection_purposes=0 +privacy/collected_data/precise_location/collected=false +privacy/collected_data/precise_location/linked_to_user=false +privacy/collected_data/precise_location/used_for_tracking=false +privacy/collected_data/precise_location/collection_purposes=0 +privacy/collected_data/coarse_location/collected=false +privacy/collected_data/coarse_location/linked_to_user=false +privacy/collected_data/coarse_location/used_for_tracking=false +privacy/collected_data/coarse_location/collection_purposes=0 +privacy/collected_data/sensitive_info/collected=false +privacy/collected_data/sensitive_info/linked_to_user=false +privacy/collected_data/sensitive_info/used_for_tracking=false +privacy/collected_data/sensitive_info/collection_purposes=0 +privacy/collected_data/contacts/collected=false +privacy/collected_data/contacts/linked_to_user=false +privacy/collected_data/contacts/used_for_tracking=false +privacy/collected_data/contacts/collection_purposes=0 +privacy/collected_data/emails_or_text_messages/collected=false +privacy/collected_data/emails_or_text_messages/linked_to_user=false +privacy/collected_data/emails_or_text_messages/used_for_tracking=false +privacy/collected_data/emails_or_text_messages/collection_purposes=0 +privacy/collected_data/photos_or_videos/collected=false +privacy/collected_data/photos_or_videos/linked_to_user=false +privacy/collected_data/photos_or_videos/used_for_tracking=false +privacy/collected_data/photos_or_videos/collection_purposes=0 +privacy/collected_data/audio_data/collected=false +privacy/collected_data/audio_data/linked_to_user=false +privacy/collected_data/audio_data/used_for_tracking=false +privacy/collected_data/audio_data/collection_purposes=0 +privacy/collected_data/gameplay_content/collected=false +privacy/collected_data/gameplay_content/linked_to_user=false +privacy/collected_data/gameplay_content/used_for_tracking=false +privacy/collected_data/gameplay_content/collection_purposes=0 +privacy/collected_data/customer_support/collected=false +privacy/collected_data/customer_support/linked_to_user=false +privacy/collected_data/customer_support/used_for_tracking=false +privacy/collected_data/customer_support/collection_purposes=0 +privacy/collected_data/other_user_content/collected=false +privacy/collected_data/other_user_content/linked_to_user=false +privacy/collected_data/other_user_content/used_for_tracking=false +privacy/collected_data/other_user_content/collection_purposes=0 +privacy/collected_data/browsing_history/collected=false +privacy/collected_data/browsing_history/linked_to_user=false +privacy/collected_data/browsing_history/used_for_tracking=false +privacy/collected_data/browsing_history/collection_purposes=0 +privacy/collected_data/search_hhistory/collected=false +privacy/collected_data/search_hhistory/linked_to_user=false +privacy/collected_data/search_hhistory/used_for_tracking=false +privacy/collected_data/search_hhistory/collection_purposes=0 +privacy/collected_data/user_id/collected=false +privacy/collected_data/user_id/linked_to_user=false +privacy/collected_data/user_id/used_for_tracking=false +privacy/collected_data/user_id/collection_purposes=0 +privacy/collected_data/device_id/collected=false +privacy/collected_data/device_id/linked_to_user=false +privacy/collected_data/device_id/used_for_tracking=false +privacy/collected_data/device_id/collection_purposes=0 +privacy/collected_data/purchase_history/collected=false +privacy/collected_data/purchase_history/linked_to_user=false +privacy/collected_data/purchase_history/used_for_tracking=false +privacy/collected_data/purchase_history/collection_purposes=0 +privacy/collected_data/product_interaction/collected=false +privacy/collected_data/product_interaction/linked_to_user=false +privacy/collected_data/product_interaction/used_for_tracking=false +privacy/collected_data/product_interaction/collection_purposes=0 +privacy/collected_data/advertising_data/collected=false +privacy/collected_data/advertising_data/linked_to_user=false +privacy/collected_data/advertising_data/used_for_tracking=false +privacy/collected_data/advertising_data/collection_purposes=0 +privacy/collected_data/other_usage_data/collected=false +privacy/collected_data/other_usage_data/linked_to_user=false +privacy/collected_data/other_usage_data/used_for_tracking=false +privacy/collected_data/other_usage_data/collection_purposes=0 +privacy/collected_data/crash_data/collected=false +privacy/collected_data/crash_data/linked_to_user=false +privacy/collected_data/crash_data/used_for_tracking=false +privacy/collected_data/crash_data/collection_purposes=0 +privacy/collected_data/performance_data/collected=false +privacy/collected_data/performance_data/linked_to_user=false +privacy/collected_data/performance_data/used_for_tracking=false +privacy/collected_data/performance_data/collection_purposes=0 +privacy/collected_data/other_diagnostic_data/collected=false +privacy/collected_data/other_diagnostic_data/linked_to_user=false +privacy/collected_data/other_diagnostic_data/used_for_tracking=false +privacy/collected_data/other_diagnostic_data/collection_purposes=0 +privacy/collected_data/environment_scanning/collected=false +privacy/collected_data/environment_scanning/linked_to_user=false +privacy/collected_data/environment_scanning/used_for_tracking=false +privacy/collected_data/environment_scanning/collection_purposes=0 +privacy/collected_data/hands/collected=false +privacy/collected_data/hands/linked_to_user=false +privacy/collected_data/hands/used_for_tracking=false +privacy/collected_data/hands/collection_purposes=0 +privacy/collected_data/head/collected=false +privacy/collected_data/head/linked_to_user=false +privacy/collected_data/head/used_for_tracking=false +privacy/collected_data/head/collection_purposes=0 +privacy/collected_data/other_data_types/collected=false +privacy/collected_data/other_data_types/linked_to_user=false +privacy/collected_data/other_data_types/used_for_tracking=false +privacy/collected_data/other_data_types/collection_purposes=0 ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -100,22 +251,27 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" +application/min_macos_version="10.12" [preset.1] name="Linux/X11" -platform="Linux/X11" +platform="Linux" runnable=true +advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" -export_path="../builds/godots/Godots.x86_64" +export_path="build_dir/Godots.x86_64" +patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" +seed=0 encrypt_pck=false encrypt_directory=false +script_export_mode=2 [preset.1.options] @@ -123,10 +279,8 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false +texture_format/s3tc_bptc=true +texture_format/etc2_astc=false binary_format/architecture="x86_64" ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" @@ -140,22 +294,30 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false [preset.2] name="Windows Desktop" platform="Windows Desktop" runnable=true +advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.exe" +patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" +seed=0 encrypt_pck=false encrypt_directory=false +script_export_mode=2 [preset.2.options] @@ -163,10 +325,8 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false +texture_format/s3tc_bptc=true +texture_format/etc2_astc=false binary_format/architecture="x86_64" codesign/enable=false codesign/timestamp=true @@ -185,6 +345,9 @@ application/product_name="" application/file_description="" application/copyright="" application/trademarks="" +application/export_angle=0 +application/export_d3d12=0 +application/d3d12_agility_sdk_multiarch=true ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -202,3 +365,7 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue Remove-Item -Recurse -Force '{temp_dir}'" +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false From 435a59b2d0f381389d9e211c2b324868225f33aa Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:32:31 -0300 Subject: [PATCH 14/23] Revert "Fix: handle debug builds and fix some vriable naming and comments" This reverts commit 41f28a6afffbbc808e20282422c87f25aa570401. --- .gitignore | 5 +- export_presets.cfg | 189 +++------------------------------------------ src/main/main.gd | 49 +++++------- 3 files changed, 30 insertions(+), 213 deletions(-) diff --git a/.gitignore b/.gitignore index de76f3f2..f95fe259 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Godot 4+ specific ignores .godot/ -# Export ignore -build_dir/ - # Godot-specific ignores .import/ export.cfg @@ -32,4 +29,4 @@ addons/gdUnit # Mac files .DS_Store -/override.cfg +/override.cfg \ No newline at end of file diff --git a/export_presets.cfg b/export_presets.cfg index fed955b6..851bddb1 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -3,20 +3,16 @@ name="macOS" platform="macOS" runnable=false -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.zip" -patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.0.options] @@ -34,11 +30,8 @@ application/short_version="1.0" application/version="1.0" application/copyright="" application/copyright_localized={} -application/min_macos_version_x86_64="10.12" -application/min_macos_version_arm64="11.00" -application/export_angle=0 +application/min_macos_version="10.12" display/high_res=true -application/additional_plist_content="" xcode/platform_build="14C18" xcode/sdk_version="13.1" xcode/sdk_build="22C55" @@ -71,9 +64,7 @@ codesign/entitlements/app_sandbox/files_downloads=0 codesign/entitlements/app_sandbox/files_pictures=0 codesign/entitlements/app_sandbox/files_music=0 codesign/entitlements/app_sandbox/files_movies=0 -codesign/entitlements/app_sandbox/files_user_selected=0 codesign/entitlements/app_sandbox/helper_executables=[] -codesign/entitlements/additional="" codesign/custom_options=PackedStringArray() notarization/notarization=0 privacy/microphone_usage_description="" @@ -98,148 +89,6 @@ privacy/network_volumes_usage_description="" privacy/network_volumes_usage_description_localized={} privacy/removable_volumes_usage_description="" privacy/removable_volumes_usage_description_localized={} -privacy/tracking_enabled=false -privacy/tracking_domains=PackedStringArray() -privacy/collected_data/name/collected=false -privacy/collected_data/name/linked_to_user=false -privacy/collected_data/name/used_for_tracking=false -privacy/collected_data/name/collection_purposes=0 -privacy/collected_data/email_address/collected=false -privacy/collected_data/email_address/linked_to_user=false -privacy/collected_data/email_address/used_for_tracking=false -privacy/collected_data/email_address/collection_purposes=0 -privacy/collected_data/phone_number/collected=false -privacy/collected_data/phone_number/linked_to_user=false -privacy/collected_data/phone_number/used_for_tracking=false -privacy/collected_data/phone_number/collection_purposes=0 -privacy/collected_data/physical_address/collected=false -privacy/collected_data/physical_address/linked_to_user=false -privacy/collected_data/physical_address/used_for_tracking=false -privacy/collected_data/physical_address/collection_purposes=0 -privacy/collected_data/other_contact_info/collected=false -privacy/collected_data/other_contact_info/linked_to_user=false -privacy/collected_data/other_contact_info/used_for_tracking=false -privacy/collected_data/other_contact_info/collection_purposes=0 -privacy/collected_data/health/collected=false -privacy/collected_data/health/linked_to_user=false -privacy/collected_data/health/used_for_tracking=false -privacy/collected_data/health/collection_purposes=0 -privacy/collected_data/fitness/collected=false -privacy/collected_data/fitness/linked_to_user=false -privacy/collected_data/fitness/used_for_tracking=false -privacy/collected_data/fitness/collection_purposes=0 -privacy/collected_data/payment_info/collected=false -privacy/collected_data/payment_info/linked_to_user=false -privacy/collected_data/payment_info/used_for_tracking=false -privacy/collected_data/payment_info/collection_purposes=0 -privacy/collected_data/credit_info/collected=false -privacy/collected_data/credit_info/linked_to_user=false -privacy/collected_data/credit_info/used_for_tracking=false -privacy/collected_data/credit_info/collection_purposes=0 -privacy/collected_data/other_financial_info/collected=false -privacy/collected_data/other_financial_info/linked_to_user=false -privacy/collected_data/other_financial_info/used_for_tracking=false -privacy/collected_data/other_financial_info/collection_purposes=0 -privacy/collected_data/precise_location/collected=false -privacy/collected_data/precise_location/linked_to_user=false -privacy/collected_data/precise_location/used_for_tracking=false -privacy/collected_data/precise_location/collection_purposes=0 -privacy/collected_data/coarse_location/collected=false -privacy/collected_data/coarse_location/linked_to_user=false -privacy/collected_data/coarse_location/used_for_tracking=false -privacy/collected_data/coarse_location/collection_purposes=0 -privacy/collected_data/sensitive_info/collected=false -privacy/collected_data/sensitive_info/linked_to_user=false -privacy/collected_data/sensitive_info/used_for_tracking=false -privacy/collected_data/sensitive_info/collection_purposes=0 -privacy/collected_data/contacts/collected=false -privacy/collected_data/contacts/linked_to_user=false -privacy/collected_data/contacts/used_for_tracking=false -privacy/collected_data/contacts/collection_purposes=0 -privacy/collected_data/emails_or_text_messages/collected=false -privacy/collected_data/emails_or_text_messages/linked_to_user=false -privacy/collected_data/emails_or_text_messages/used_for_tracking=false -privacy/collected_data/emails_or_text_messages/collection_purposes=0 -privacy/collected_data/photos_or_videos/collected=false -privacy/collected_data/photos_or_videos/linked_to_user=false -privacy/collected_data/photos_or_videos/used_for_tracking=false -privacy/collected_data/photos_or_videos/collection_purposes=0 -privacy/collected_data/audio_data/collected=false -privacy/collected_data/audio_data/linked_to_user=false -privacy/collected_data/audio_data/used_for_tracking=false -privacy/collected_data/audio_data/collection_purposes=0 -privacy/collected_data/gameplay_content/collected=false -privacy/collected_data/gameplay_content/linked_to_user=false -privacy/collected_data/gameplay_content/used_for_tracking=false -privacy/collected_data/gameplay_content/collection_purposes=0 -privacy/collected_data/customer_support/collected=false -privacy/collected_data/customer_support/linked_to_user=false -privacy/collected_data/customer_support/used_for_tracking=false -privacy/collected_data/customer_support/collection_purposes=0 -privacy/collected_data/other_user_content/collected=false -privacy/collected_data/other_user_content/linked_to_user=false -privacy/collected_data/other_user_content/used_for_tracking=false -privacy/collected_data/other_user_content/collection_purposes=0 -privacy/collected_data/browsing_history/collected=false -privacy/collected_data/browsing_history/linked_to_user=false -privacy/collected_data/browsing_history/used_for_tracking=false -privacy/collected_data/browsing_history/collection_purposes=0 -privacy/collected_data/search_hhistory/collected=false -privacy/collected_data/search_hhistory/linked_to_user=false -privacy/collected_data/search_hhistory/used_for_tracking=false -privacy/collected_data/search_hhistory/collection_purposes=0 -privacy/collected_data/user_id/collected=false -privacy/collected_data/user_id/linked_to_user=false -privacy/collected_data/user_id/used_for_tracking=false -privacy/collected_data/user_id/collection_purposes=0 -privacy/collected_data/device_id/collected=false -privacy/collected_data/device_id/linked_to_user=false -privacy/collected_data/device_id/used_for_tracking=false -privacy/collected_data/device_id/collection_purposes=0 -privacy/collected_data/purchase_history/collected=false -privacy/collected_data/purchase_history/linked_to_user=false -privacy/collected_data/purchase_history/used_for_tracking=false -privacy/collected_data/purchase_history/collection_purposes=0 -privacy/collected_data/product_interaction/collected=false -privacy/collected_data/product_interaction/linked_to_user=false -privacy/collected_data/product_interaction/used_for_tracking=false -privacy/collected_data/product_interaction/collection_purposes=0 -privacy/collected_data/advertising_data/collected=false -privacy/collected_data/advertising_data/linked_to_user=false -privacy/collected_data/advertising_data/used_for_tracking=false -privacy/collected_data/advertising_data/collection_purposes=0 -privacy/collected_data/other_usage_data/collected=false -privacy/collected_data/other_usage_data/linked_to_user=false -privacy/collected_data/other_usage_data/used_for_tracking=false -privacy/collected_data/other_usage_data/collection_purposes=0 -privacy/collected_data/crash_data/collected=false -privacy/collected_data/crash_data/linked_to_user=false -privacy/collected_data/crash_data/used_for_tracking=false -privacy/collected_data/crash_data/collection_purposes=0 -privacy/collected_data/performance_data/collected=false -privacy/collected_data/performance_data/linked_to_user=false -privacy/collected_data/performance_data/used_for_tracking=false -privacy/collected_data/performance_data/collection_purposes=0 -privacy/collected_data/other_diagnostic_data/collected=false -privacy/collected_data/other_diagnostic_data/linked_to_user=false -privacy/collected_data/other_diagnostic_data/used_for_tracking=false -privacy/collected_data/other_diagnostic_data/collection_purposes=0 -privacy/collected_data/environment_scanning/collected=false -privacy/collected_data/environment_scanning/linked_to_user=false -privacy/collected_data/environment_scanning/used_for_tracking=false -privacy/collected_data/environment_scanning/collection_purposes=0 -privacy/collected_data/hands/collected=false -privacy/collected_data/hands/linked_to_user=false -privacy/collected_data/hands/used_for_tracking=false -privacy/collected_data/hands/collection_purposes=0 -privacy/collected_data/head/collected=false -privacy/collected_data/head/linked_to_user=false -privacy/collected_data/head/used_for_tracking=false -privacy/collected_data/head/collection_purposes=0 -privacy/collected_data/other_data_types/collected=false -privacy/collected_data/other_data_types/linked_to_user=false -privacy/collected_data/other_data_types/used_for_tracking=false -privacy/collected_data/other_data_types/collection_purposes=0 ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -251,27 +100,22 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" -application/min_macos_version="10.12" [preset.1] name="Linux/X11" -platform="Linux" +platform="Linux/X11" runnable=true -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" -export_path="build_dir/Godots.x86_64" -patches=PackedStringArray() +export_path="../builds/godots/Godots.x86_64" encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.1.options] @@ -279,8 +123,10 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/s3tc_bptc=true -texture_format/etc2_astc=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false binary_format/architecture="x86_64" ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" @@ -294,30 +140,22 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") rm -rf \"{temp_dir}\"" -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false [preset.2] name="Windows Desktop" platform="Windows Desktop" runnable=true -advanced_options=false dedicated_server=false custom_features="" export_filter="all_resources" include_filter="theme/icons.cfg, theme/icons-light.cfg" exclude_filter="" export_path="../builds/godots/Godots.exe" -patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" -seed=0 encrypt_pck=false encrypt_directory=false -script_export_mode=2 [preset.2.options] @@ -325,8 +163,10 @@ custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 binary_format/embed_pck=true -texture_format/s3tc_bptc=true -texture_format/etc2_astc=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false binary_format/architecture="x86_64" codesign/enable=false codesign/timestamp=true @@ -345,9 +185,6 @@ application/product_name="" application/file_description="" application/copyright="" application/trademarks="" -application/export_angle=0 -application/export_d3d12=0 -application/d3d12_agility_sdk_multiarch=true ssh_remote_deploy/enabled=false ssh_remote_deploy/host="user@host_ip" ssh_remote_deploy/port="22" @@ -365,7 +202,3 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue Remove-Item -Recurse -Force '{temp_dir}'" -texture_format/bptc=true -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false diff --git a/src/main/main.gd b/src/main/main.gd index dee579f9..19bede85 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -1,8 +1,8 @@ extends Node const DESKTOP_ENTRY_FOLDER = ".local/share/applications" -const APP_FOLDER = ".local/godots.app" -const DESKTOP_ENTRY_NAME = "godots.desktop" +const GVM_APP_FOLDER = ".local/godots.app" +const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" @export_file() var gui_scene_path: String @@ -14,7 +14,7 @@ func _ready() -> void: # Check if running as Flatpak by checking for the .flatpak-info file var is_flatpak := FileAccess.file_exists("/.flatpak-info") - # Check and create Godots desktop entry if needed + # Check and create GVM desktop entry if needed if OS.get_name() == "Linux" and not OS.has_feature("editor") and not is_flatpak: _ensure_desktop_entry() @@ -39,44 +39,32 @@ func _is_cli_mode(args: PackedStringArray) -> bool: func _ensure_desktop_entry() -> void: var home := OS.get_environment("HOME") - var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(DESKTOP_ENTRY_NAME) - var app_path := home.path_join(APP_FOLDER) + var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) + var gvm_app_path := home.path_join(GVM_APP_FOLDER) - # Create godots.app folder and copy executable + # Create gvm.app folder and copy executable var dir := DirAccess.open("user://") - if dir.dir_exists(app_path): + if FileAccess.file_exists(gvm_app_path): return else: - dir.make_dir_recursive(app_path) + dir.make_dir_recursive(gvm_app_path) + # Copy the current executable to gvm.app folder var current_exe := OS.get_executable_path() - var new_exe_path := app_path.path_join("Godots.x86_64") - var run_path := new_exe_path - - var is_debug := OS.is_debug_build() - var script_path := current_exe.get_base_dir().path_join("Godots.sh") - - if is_debug and FileAccess.file_exists(script_path): - var new_script_path := app_path.path_join("Godots.sh") - if DirAccess.copy_absolute(script_path, new_script_path) == OK: - OS.execute("chmod", ["+x", new_script_path]) - run_path = new_script_path - else: - is_debug = false - + var new_exe_path := gvm_app_path.path_join("godots.x86_64") if DirAccess.copy_absolute(current_exe, new_exe_path) == OK: # Make it executable OS.execute("chmod", ["+x", new_exe_path]) # Create desktop entry # Copy and save the icon - var icon_path := app_path.path_join("icon.png") + var icon_path := gvm_app_path.path_join("icon.png") var icon := load("res://icon.svg") as Texture2D var image := icon.get_image() image.save_png(icon_path) # Create desktop entry - var desktop_entry := _create_desktop_entry(run_path, icon_path, is_debug) + var desktop_entry := _create_desktop_entry(new_exe_path, icon_path) var file := FileAccess.open(desktop_entry_path, FileAccess.WRITE) if file: file.store_string(desktop_entry) @@ -89,22 +77,21 @@ func _ensure_desktop_entry() -> void: printerr("Failed to copy executable") -func _create_desktop_entry(exec: String, icon: String, terminal: bool) -> String: +func _create_desktop_entry(exe_path: String, icon_path: String) -> String: return ( - """\ -[Desktop Entry] -Name=Godots + """[Desktop Entry] + Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec="{exec}" %f +Exec="{exe}" %f Icon={icon} -Terminal={terminal} +Terminal=false PrefersNonDefaultGPU=true Type=Application Categories=Development;IDE; StartupWMClass=Godot """ - . format({"exec": exec, "icon": icon, "terminal": terminal}) + . format({"exe": exe_path, "icon": icon_path}) ) From 59c9efb86e05b2e759e7e943aa1ebd325790b97c Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:32:31 -0300 Subject: [PATCH 15/23] Revert "chore: don't create desktop entry when launching from editor" This reverts commit 05698c0e5105cb87fadb0af1df59f347f8580d36. --- src/main/main.gd | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/main.gd b/src/main/main.gd index 19bede85..2b087a1c 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -7,6 +7,7 @@ const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" @export_file() var gui_scene_path: String + func _ready() -> void: var args := OS.get_cmdline_args() var user_args := OS.get_cmdline_user_args() @@ -15,7 +16,7 @@ func _ready() -> void: var is_flatpak := FileAccess.file_exists("/.flatpak-info") # Check and create GVM desktop entry if needed - if OS.get_name() == "Linux" and not OS.has_feature("editor") and not is_flatpak: + if OS.get_name() == "Linux" and not is_flatpak: _ensure_desktop_entry() if _is_cli_mode(args): @@ -28,7 +29,6 @@ func _ready() -> void: add_child.call_deferred((load(gui_scene_path) as PackedScene).instantiate()) pass - func _is_cli_mode(args: PackedStringArray) -> bool: if args.size() > 1 and OS.has_feature("editor"): return true @@ -36,7 +36,6 @@ func _is_cli_mode(args: PackedStringArray) -> bool: return true return false - func _ensure_desktop_entry() -> void: var home := OS.get_environment("HOME") var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) @@ -78,8 +77,7 @@ func _ensure_desktop_entry() -> void: func _create_desktop_entry(exe_path: String, icon_path: String) -> String: - return ( - """[Desktop Entry] + return """[Desktop Entry] Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! @@ -90,10 +88,9 @@ PrefersNonDefaultGPU=true Type=Application Categories=Development;IDE; StartupWMClass=Godot -""" - . format({"exe": exe_path, "icon": icon_path}) +""".format( + {"exe": exe_path, "icon": icon_path} ) - func _exit() -> void: get_tree().quit() From 1fd8807a3a35f1b36db5fde5e25608a4914e0bb8 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:32:31 -0300 Subject: [PATCH 16/23] Revert "chore: fix several erros and warnings" This reverts commit be959ccb5dd62e9d3d84d348130700caffc2eed1. --- project.godot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.godot b/project.godot index b3a381b6..c02892c1 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg", "res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/use-context/plugin.cfg") [filesystem] From 1354edeacae4fcbef5d0448175c69e02cb8ea9af Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 15:32:31 -0300 Subject: [PATCH 17/23] Revert "feat: add desktop integration" This reverts commit a720bdb87ca8d6740ed442d0c1252ad565117b80. --- project.godot | 2 +- src/main/main.gd | 69 ------------------------------------------------ 2 files changed, 1 insertion(+), 70 deletions(-) diff --git a/project.godot b/project.godot index c02892c1..015d2f34 100644 --- a/project.godot +++ b/project.godot @@ -47,7 +47,7 @@ window/subwindows/embed_subwindows=false [editor_plugins] -enabled=PackedStringArray("res://addons/use-context/plugin.cfg") +enabled=PackedStringArray("res://addons/expand-region/plugin.cfg", "res://addons/find-everywhere/plugin.cfg", "res://addons/previous-tab/plugin.cfg", "res://addons/script-tabs/plugin.cfg", "res://addons/use-context/plugin.cfg") [filesystem] diff --git a/src/main/main.gd b/src/main/main.gd index 2b087a1c..c4bcf327 100644 --- a/src/main/main.gd +++ b/src/main/main.gd @@ -1,24 +1,11 @@ extends Node -const DESKTOP_ENTRY_FOLDER = ".local/share/applications" -const GVM_APP_FOLDER = ".local/godots.app" -const GVM_DESKTOP_ENTRY_NAME = "godots.desktop" - @export_file() var gui_scene_path: String - - func _ready() -> void: var args := OS.get_cmdline_args() var user_args := OS.get_cmdline_user_args() - # Check if running as Flatpak by checking for the .flatpak-info file - var is_flatpak := FileAccess.file_exists("/.flatpak-info") - - # Check and create GVM desktop entry if needed - if OS.get_name() == "Linux" and not is_flatpak: - _ensure_desktop_entry() - if _is_cli_mode(args): Output.push("Run cli mode") var adjusted_args := args.slice(1) if OS.has_feature("editor") else args @@ -36,61 +23,5 @@ func _is_cli_mode(args: PackedStringArray) -> bool: return true return false -func _ensure_desktop_entry() -> void: - var home := OS.get_environment("HOME") - var desktop_entry_path := home.path_join(DESKTOP_ENTRY_FOLDER).path_join(GVM_DESKTOP_ENTRY_NAME) - var gvm_app_path := home.path_join(GVM_APP_FOLDER) - - # Create gvm.app folder and copy executable - var dir := DirAccess.open("user://") - if FileAccess.file_exists(gvm_app_path): - return - else: - dir.make_dir_recursive(gvm_app_path) - - # Copy the current executable to gvm.app folder - var current_exe := OS.get_executable_path() - var new_exe_path := gvm_app_path.path_join("godots.x86_64") - if DirAccess.copy_absolute(current_exe, new_exe_path) == OK: - # Make it executable - OS.execute("chmod", ["+x", new_exe_path]) - - # Create desktop entry - # Copy and save the icon - var icon_path := gvm_app_path.path_join("icon.png") - var icon := load("res://icon.svg") as Texture2D - var image := icon.get_image() - image.save_png(icon_path) - - # Create desktop entry - var desktop_entry := _create_desktop_entry(new_exe_path, icon_path) - var file := FileAccess.open(desktop_entry_path, FileAccess.WRITE) - if file: - file.store_string(desktop_entry) - file.close() - # Make desktop entry executable - OS.execute("chmod", ["+x", desktop_entry_path]) - else: - printerr("Failed to create desktop entry") - else: - printerr("Failed to copy executable") - - -func _create_desktop_entry(exe_path: String, icon_path: String) -> String: - return """[Desktop Entry] - Name=Godots -GenericName=Libre game engine version manager -Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec="{exe}" %f -Icon={icon} -Terminal=false -PrefersNonDefaultGPU=true -Type=Application -Categories=Development;IDE; -StartupWMClass=Godot -""".format( - {"exe": exe_path, "icon": icon_path} - ) - func _exit() -> void: get_tree().quit() From 4ddf93b7526d0561a5d7de259314b1047b5f52dc Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Tue, 1 Apr 2025 18:51:21 -0300 Subject: [PATCH 18/23] add exit conditions and fix desktop exec and icon paths --- install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) mode change 100644 => 100755 install.sh diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index 3443ce2e..a4059144 --- a/install.sh +++ b/install.sh @@ -1,15 +1,15 @@ -#!/bin/env bash +#!/usr/bin/env bash DOWNLOAD_URL="https://github.com/MakovWait/godots/releases/latest/download/LinuxX11.zip" # Download the latest version of Godots -wget -O /tmp/godots.zip $DOWNLOAD_URL +wget -O /tmp/godots.zip $DOWNLOAD_URL || exit -# Unzip the downloaded file to ~/.local/godots.app/ -unzip /tmp/godots.zip -d ~/.local/godots.app/ +# Unzip the downloaded file to ~/.local/godots.app/ and replace if exists +unzip -o /tmp/godots.zip -d ~/.local/godots.app/ || exit # download Icon -wget -O ~/.local/godots.app/icon.svg https://github.com/MakovWait/godots/raw/master/icon.svg +wget -O ~/.local/godots.app/icon.svg https://github.com/MakovWait/godots/raw/main/icon.svg || exit # Create a desktop entry for Godots cat < ~/.local/share/applications/godots.desktop @@ -17,8 +17,8 @@ cat < ~/.local/share/applications/godots.desktop Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec=~/.local/godots.app/godots -Icon=~/.local/godots.app/icon.svg +Exec=$HOME/.local/godots.app/Godots.x86_64 +Icon=$HOME/.local/godots.app/icon.svg PrefersNonDefaultGPU=true Terminal=false Type=Application From 3cae8d9c1d154a53e83fb676e7dcbada6259c79f Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Mon, 15 Sep 2025 13:00:02 -0300 Subject: [PATCH 19/23] Handle edge cases and update desktop database after install This commit handles a few edge cases for downloading files and unzipping. I used the python3 method as the default for unzipping because I think most systems should have python installed, since it is a dependacy for a lot widely used applications. I also added some lines to update the desktop database after installing. This was added mostly because of my personal Hyprland configuration, where it doesn't do this automatically, although on most DE's like Gnome or Plasma doing this would be unnecessary. --- README.md | 4 +-- install.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index e41c5ba0..0358fbcc 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Don't have Flatpak? Just download the [latest release](https://github.com/MakovW Or use the installation script: ```shell -curl -sSL https://raw.githubusercontent.com/MakovWait/godots/main/install.sh | sh +curl -fsSL https://raw.githubusercontent.com/MakovWait/godots/main/install.sh | bash ``` ## Features That Redefine Cool 😎 @@ -48,7 +48,7 @@ curl -sSL https://raw.githubusercontent.com/MakovWait/godots/main/install.sh | s - **Theming Support**: Customize your Godots experience with theming support. Make it truly your own with personalized themes that match your style and mood. [Theming readme](https://github.com/MakovWait/godots/blob/main/.github/assets/THEMING.md) ![image](https://github.com/MakovWait/godots/blob/main/.github/assets/screenshot3.png) - > Used theme: https://github.com/bitbrain/godot-dash + > Used theme: https://github.com/bitbrain/godot-dash - **Cli Support**: Embrace the power of the command line! Enjoy the flexibility and efficiency of using Godots through the [command line interface](https://github.com/MakovWait/godots/blob/main/.github/assets/FEATURES.md#cli). Manage your projects and versions effortlessly, even when your fingers are dancing on the keys. --- diff --git a/install.sh b/install.sh index a4059144..db7fc68d 100755 --- a/install.sh +++ b/install.sh @@ -1,24 +1,74 @@ -#!/usr/bin/env bash +#!/bin/env bash -DOWNLOAD_URL="https://github.com/MakovWait/godots/releases/latest/download/LinuxX11.zip" +GODOTS_DOWNLOAD_URL="https://github.com/MakovWait/godots/releases/latest/download/LinuxX11.zip" +GODOTS_TMP_DIR="/tmp/godots" -# Download the latest version of Godots -wget -O /tmp/godots.zip $DOWNLOAD_URL || exit +GODOTS_INSTALL_DIR="$HOME/.local/godots.app" +GODOTS_BIN_PATH="$GODOTS_INSTALL_DIR/Godots.x86_64" -# Unzip the downloaded file to ~/.local/godots.app/ and replace if exists -unzip -o /tmp/godots.zip -d ~/.local/godots.app/ || exit +ICON_DOWNLOAD_URL="https://raw.githubusercontent.com/MakovWait/godots/refs/heads/main/icon.svg" +ICON_PATH="$HOME/.local/godots.app/icon.svg" -# download Icon -wget -O ~/.local/godots.app/icon.svg https://github.com/MakovWait/godots/raw/main/icon.svg || exit +try_download() { + download_url=$1 + path=$2 + if command -v wget &>/dev/null; then + wget --show-progress --tries=3 -q -O "$path" "$download_url" + elif command -v curl &>/dev/null; then + curl -fSL --progress-bar -o "$path" "$download_url" + else + printf "Error: Neither wget nor curl is available to download files, please install one of them and try again.\n" + exit 1 + fi +} -# Create a desktop entry for Godots -cat < ~/.local/share/applications/godots.desktop +printf "Downloading Godots...\n" +try_download "$GODOTS_DOWNLOAD_URL" "$GODOTS_TMP_DIR" + +printf "\nExtracting Godots...\n" +if command -v python3 &>/dev/null; then + python3 -c " +import zipfile +import os +import sys + +zip_path = '$GODOTS_TMP_DIR' +extract_dir = os.path.expanduser('$GODOTS_INSTALL_DIR') + +# Create target directory if it doesn't exist +os.makedirs(extract_dir, exist_ok=True) + +# Extract the zip file +with zipfile.ZipFile(zip_path, 'r') as zip_ref: + zip_ref.extractall(extract_dir) + +print('Extraction completed successfully!') +" +elif command -v unzip &>/dev/null; then + mkdir -p "$GODOTS_INSTALL_DIR" + unzip -o "$GODOTS_TMP_DIR" -d "$GODOTS_INSTALL_DIR" + printf "Extraction completed successfully!\n" +else + printf "Error: Neither python3 nor unzip is available to extract the zip file, please install one of them and try again.\n" + exit 1 +fi + +chmod +x "$GODOTS_INSTALL_DIR/"* +ln -sf "$GODOTS_BIN_PATH" "$HOME/.local/bin/godots" + +printf "\nDownloading icon...\n" +try_download "$ICON_DOWNLOAD_URL" "$ICON_PATH" + +printf "\nCreating desktop entry..." +mkdir -p ~/.local/share/applications + +cat <~/.local/share/applications/godots.desktop [Desktop Entry] Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! -Exec=$HOME/.local/godots.app/Godots.x86_64 -Icon=$HOME/.local/godots.app/icon.svg +Exec=$GODOTS_BIN_PATH %U +Icon=$ICON_PATH PrefersNonDefaultGPU=true Terminal=false Type=Application @@ -26,4 +76,16 @@ Categories=Development;IDE; StartupWMClass=Godot EOF -echo "Installation completed successfully!" +if command -v update-desktop-database &>/dev/null; then + update-desktop-database -q +fi + +if command gtk-upate-icon-cache &>/dev/null; then + gtk-update-icon-cache +fi + +if command -v kbuildsycoca5 &>/dev/null; then + kbuildsycoca5 --noincremental &>/dev/null +fi + +printf "\nInstallation completed successfully!\n" From 3768d7670dedca635326a33ed26affdd53fb9442 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Mon, 15 Sep 2025 13:19:43 -0300 Subject: [PATCH 20/23] fix typo --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index db7fc68d..57215e2f 100755 --- a/install.sh +++ b/install.sh @@ -80,7 +80,7 @@ if command -v update-desktop-database &>/dev/null; then update-desktop-database -q fi -if command gtk-upate-icon-cache &>/dev/null; then +if command -v gtk-upate-icon-cache &>/dev/null; then gtk-update-icon-cache fi From e56337ec5999549e17afc8081507a1cb2ae18d94 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 18 Dec 2025 20:22:20 -0300 Subject: [PATCH 21/23] chore: add install script instruction on README --- README.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 73ba73fd..332aafe2 100644 --- a/README.md +++ b/README.md @@ -10,30 +10,40 @@ Everything you need is in one place — downloading editors, keeping multiple ve ## **Installation** ### **Windows** + - Download the ZIP, extract it, and run the executable. - No additional setup required. ### **Linux** + - Unzip and launch the binary directly. Alternatively: + - Install from Flathub (**community maintained**):
Download on Flathub
-- Arch Linux users can install via AUR (**community maintained**): - - [`godots-bin`](https://aur.archlinux.org/packages/godots-bin) +- Arch Linux users can install via AUR (**community maintained**): + - [`godots-bin`](https://aur.archlinux.org/packages/godots-bin) - [`godots-git`](https://aur.archlinux.org/packages/godots-git) +- You can also use the installation script: + +```shell +curl -fsSL https://raw.githubusercontent.com/MakovWait/godots/main/install.sh | bash +``` + ### **macOS** + - Unzip and run **Godots.app**. - macOS may require removing the quarantine flag: ```sh sudo xattr -r -d com.apple.quarantine /Applications/Godots.app ``` -Download any build directly from: +Download any build directly from: 👉 **[Latest Releases](https://github.com/MakovWait/godots/releases)** --- @@ -41,29 +51,35 @@ Download any build directly from: ## **Features** ### **Download & manage any Godot version** + - Fetch any official release from GitHub. - Keep multiple versions side-by-side. - Add custom local Godot binaries. ### **Full project manager** + - Add, import, organize, and launch projects. - Bind specific engine versions to individual projects. - Launch/edit projects directly with their assigned version. - Drag & drop `project.godot` or entire project folders. ### **HiDPI / Retina support** + - Sharp, crisp UI on high-resolution displays. ### **Theming** + - Supports custom themes compatible with Godot’s own theming system. - Guide: 👉 **[Theming Documentation](.github/assets/THEMING.md)** -![image](https://github.com/MakovWait/godots/blob/main/.github/assets/screenshot3.png) + ![image](https://github.com/MakovWait/godots/blob/main/.github/assets/screenshot3.png) ### **CLI interface** -- Manage projects and versions through the command line. + +- Manage projects and versions through the command line. Details: 👉 **[CLI Features](.github/assets/FEATURES.md#cli)** --- ## **License** + MIT License — see `LICENSE.md`. From e7b21f98c3949cbbfca1cfdbd64410893e62578b Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 18 Dec 2025 20:23:50 -0300 Subject: [PATCH 22/23] fix: fix gtk-update-icon-cache command --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 57215e2f..130e6804 100755 --- a/install.sh +++ b/install.sh @@ -80,7 +80,7 @@ if command -v update-desktop-database &>/dev/null; then update-desktop-database -q fi -if command -v gtk-upate-icon-cache &>/dev/null; then +if command -v gtk-update-icon-cache &>/dev/null; then gtk-update-icon-cache fi From 3f89b0fbbd97c4ca03a047489531f068216ed707 Mon Sep 17 00:00:00 2001 From: reisaraujo-miguel Date: Thu, 18 Dec 2025 21:20:54 -0300 Subject: [PATCH 23/23] feat: verifies checksum and adds some error handleling --- install.sh | 112 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/install.sh b/install.sh index 130e6804..a654c500 100755 --- a/install.sh +++ b/install.sh @@ -3,28 +3,89 @@ GODOTS_DOWNLOAD_URL="https://github.com/MakovWait/godots/releases/latest/download/LinuxX11.zip" GODOTS_TMP_DIR="/tmp/godots" -GODOTS_INSTALL_DIR="$HOME/.local/godots.app" +GODOTS_CHECKSUM_URL="https://github.com/MakovWait/godots/releases/latest/download/SHA512-SUMS.txt" + +if [[ -z "$XDG_DATA_HOME" ]]; then + GODOTS_INSTALL_DIR="$XDG_DATA_HOME/godots" +else + GODOTS_INSTALL_DIR="$HOME/.local/share/godots" +fi + GODOTS_BIN_PATH="$GODOTS_INSTALL_DIR/Godots.x86_64" ICON_DOWNLOAD_URL="https://raw.githubusercontent.com/MakovWait/godots/refs/heads/main/icon.svg" -ICON_PATH="$HOME/.local/godots.app/icon.svg" try_download() { download_url=$1 path=$2 if command -v wget &>/dev/null; then - wget --show-progress --tries=3 -q -O "$path" "$download_url" + wget --show-progress --tries=3 -q -P "$path" "$download_url" || { + printf "Error: Download failed.\n" + exit 1 + } elif command -v curl &>/dev/null; then - curl -fSL --progress-bar -o "$path" "$download_url" + curl -fSL --progress-bar -O --output-dir "$path" "$download_url" || { + printf "Error: Download failed.\n" + exit 1 + } else printf "Error: Neither wget nor curl is available to download files, please install one of them and try again.\n" exit 1 fi } +rm -rf "$GODOTS_TMP_DIR" || { + printf "Error: Failed to clean up temporary directory.\n" + exit 1 +} + +mkdir -p "$GODOTS_TMP_DIR" || { + printf "Error: Failed to create temporary directory.\n" + exit 1 +} + +cd "$GODOTS_TMP_DIR" || { + printf "Error: Failed to access temporary directory.\n" + exit 1 +} + printf "Downloading Godots...\n" try_download "$GODOTS_DOWNLOAD_URL" "$GODOTS_TMP_DIR" +prompt_continue=0 + +if command -v sha512sum &>/dev/null; then + printf "\nDownloading checksum...\n" + try_download "$GODOTS_CHECKSUM_URL" "$GODOTS_TMP_DIR" + + printf "\nVerifying checksum...\n" + sha512sum --check --ignore-missing "$GODOTS_TMP_DIR/SHA512-SUMS.txt" || prompt_continue=1 + +else + # I think it is part of coreutils, so it should be available on most systems. But just in case. + printf "Error: sha512sum is not available to verify the checksum. Skipping.\n" + prompt_continue=1 +fi + +if [[ $prompt_continue -eq 1 ]]; then + read -r -p "Checksum verification failed or was skipped. Do you want to continue the installation? (y/N): " choice + case "$choice" in + y | Y) + printf "Continuing installation...\n" + ;; + *) + printf "Installation aborted.\n" + exit 1 + ;; + esac +fi + +# Create installation directory +mkdir -p "$GODOTS_INSTALL_DIR" || { + printf "Error: Failed to create installation directory.\n" + exit 1 +} + printf "\nExtracting Godots...\n" if command -v python3 &>/dev/null; then python3 -c " @@ -32,7 +93,7 @@ import zipfile import os import sys -zip_path = '$GODOTS_TMP_DIR' +zip_path = '$GODOTS_TMP_DIR/LinuxX11.zip' extract_dir = os.path.expanduser('$GODOTS_INSTALL_DIR') # Create target directory if it doesn't exist @@ -43,24 +104,44 @@ with zipfile.ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall(extract_dir) print('Extraction completed successfully!') -" +" || { + printf "Error: Extraction failed.\n" + exit 1 + } elif command -v unzip &>/dev/null; then - mkdir -p "$GODOTS_INSTALL_DIR" - unzip -o "$GODOTS_TMP_DIR" -d "$GODOTS_INSTALL_DIR" + unzip -o "$GODOTS_TMP_DIR/LinuxX11.zip" -d "$GODOTS_INSTALL_DIR" || { + printf "Error: Extraction failed.\n" + exit 1 + } printf "Extraction completed successfully!\n" else printf "Error: Neither python3 nor unzip is available to extract the zip file, please install one of them and try again.\n" exit 1 fi -chmod +x "$GODOTS_INSTALL_DIR/"* -ln -sf "$GODOTS_BIN_PATH" "$HOME/.local/bin/godots" +chmod +x "$GODOTS_INSTALL_DIR/"* || { + printf "Error: Failed to set executable permissions.\n" + exit 1 +} + +mkdir -p "$HOME/.local/bin" || { + printf "Error: Failed to create ~/.local/bin directory.\n" + exit 1 +} + +ln -sf "$GODOTS_BIN_PATH" "$HOME/.local/bin/godots" || { + printf "Error: Failed to create symlink in ~/.local/bin.\n" + exit 1 +} printf "\nDownloading icon...\n" -try_download "$ICON_DOWNLOAD_URL" "$ICON_PATH" +try_download "$ICON_DOWNLOAD_URL" "$GODOTS_INSTALL_DIR" printf "\nCreating desktop entry..." -mkdir -p ~/.local/share/applications +mkdir -p ~/.local/share/applications || { + printf "Error: Failed to create applications directory.\n" + exit 1 +} cat <~/.local/share/applications/godots.desktop [Desktop Entry] @@ -68,7 +149,7 @@ Name=Godots GenericName=Libre game engine version manager Comment=Ultimate go-to hub for managing your Godot versions and projects! Exec=$GODOTS_BIN_PATH %U -Icon=$ICON_PATH +Icon=$GODOTS_INSTALL_DIR/icon.svg PrefersNonDefaultGPU=true Terminal=false Type=Application @@ -76,6 +157,11 @@ Categories=Development;IDE; StartupWMClass=Godot EOF +if [[ ! -f ~/.local/share/applications/godots.desktop ]]; then + printf "Error: Failed to create desktop entry.\n" + exit 1 +fi + if command -v update-desktop-database &>/dev/null; then update-desktop-database -q fi