diff --git a/Main.tscn b/Main.tscn index 3c423e0..b7dca78 100644 --- a/Main.tscn +++ b/Main.tscn @@ -783,10 +783,11 @@ layout_mode = 1 anchors_preset = -1 anchor_left = 0.0 anchor_right = 1.0 +anchor_bottom = 1.0 offset_left = 264.5 offset_top = 84.225 offset_right = -264.5 -offset_bottom = 384.225 +offset_bottom = -263.775 [node name="VolumeButton" type="Button" parent="."] texture_filter = 1 @@ -847,7 +848,7 @@ offset_left = -64.0 offset_top = -23.0 grow_horizontal = 0 grow_vertical = 0 -text = "v1.4.7" +text = "v1.5.0" horizontal_alignment = 2 [node name="SettingsButton" type="Button" parent="."] @@ -1116,6 +1117,10 @@ grow_vertical = 2 label_settings = SubResource("LabelSettings_ivhc6") horizontal_alignment = 1 +[node name="deleteConfirm" type="ConfirmationDialog" parent="."] +initial_position = 2 +dialog_text = "Are you sure you want to delete" + [connection signal="toggled" from="SelectPlaylist" to="SelectPlaylist" method="_on_toggled"] [connection signal="pressed" from="PlaylistPanelHolder/PlaylistsPanel/PlaylistsContainer/VBoxContainer/HBoxContainer/CreatePlaylist" to="PlaylistPanelHolder/PlaylistsPanel" method="_on_create_playlist_pressed"] [connection signal="toggled" from="PlaylistPanelHolder/PlaylistsPanel/PlaylistsContainer/VBoxContainer/HBoxContainer/PlayAll" to="PlaylistPanelHolder/PlaylistsPanel" method="_on_play_all_toggled"] diff --git a/addons/godotgif/LICENSE.txt b/addons/godotgif/LICENSE.txt new file mode 100644 index 0000000..f8a2334 --- /dev/null +++ b/addons/godotgif/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 B0TLANNER Games + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/godotgif/README.md b/addons/godotgif/README.md new file mode 100644 index 0000000..019419b --- /dev/null +++ b/addons/godotgif/README.md @@ -0,0 +1,139 @@ +# Godot GIF +
+ +

+ Logo +

+ +

+ GitHub Build + MIT License +

+ + +## Description +GDExtension for Godot 4+ to load GIF files as [AnimatedTexture](https://docs.godotengine.org/en/stable/classes/class_animatedtexture.html) and/or [SpriteFrames](https://docs.godotengine.org/en/stable/classes/class_spriteframes.html). + +NOTE: ~~**AnimatedTexture**~~ has been marked as deprecated according to development docs and could be removed in a future version of Godot. + + +## Usage + +### Editor + +Gif files can be imported at edit time as one of the supported types via Import options. + +
+ Editor Imports Options + +![Editor Imports Options](./docs-images/EditorImportSettings.gif) +
+ +See the [Editor Imports](./demo/editor_imports_example.tscn) example scene. +
+ Editor Imports Example + +![Editor Imports](./docs-images/EditorImports.gif) +
+ +
+ +### Runtime + +Gif files can be loaded at runtime as one of the supported types via the `GifManager` singleton. + +`GifManager` exposes the following methods for loading gifs either from file or from bytes directly: +![GifManager Methods](./docs-images/methods.png) + +e.g. to load from file +```py +get_node("AnimFromRuntimeFile").texture = GifManager.animated_texture_from_file("res://examples/file/optic.gif") + +get_node("AnimatedSprite2RuntimeFile").sprite_frames = GifManager.sprite_frames_from_file("res://examples/file/optic.gif") +``` + +See the [Runtime Imports](./demo/main.tscn) example scene. +
+ Runtime Imports Example + +![Runtime Imports](./docs-images/RuntimeImports.gif) +
+ + +## Installation + +Download the `gdextension` artifact from the [latest successful build](https://github.com/BOTLANNER/godot-gif/actions/workflows/build_releases.yml). (It should be right at the bottom of the **Summary**) +![image](https://github.com/BOTLANNER/godot-gif/assets/16349308/f28867c6-f669-45f2-9309-dbb17cec2031) + +Extract the contents to your Godot project directory. + +You should have an `addons` directory at the root with the following structure: +```bash +└───addons + └───godotgif + │ godotgif.gdextension + │ LICENSE.txt + │ README.md + │ + └───bin + │ godotgif.windows.template_debug.x86_32.dll + │ godotgif.windows.template_debug.x86_64.dll + │ godotgif.windows.template_release.x86_32.dll + │ godotgif.windows.template_release.x86_64.dll + │ libgodotgif.android.template_debug.arm64.so + │ libgodotgif.android.template_release.arm64.so + │ libgodotgif.linux.template_debug.x86_32.so + │ libgodotgif.linux.template_debug.x86_64.so + │ libgodotgif.linux.template_release.x86_32.so + │ libgodotgif.linux.template_release.x86_64.so + │ + ├───godotgif.macos.template_debug.framework + │ libgodotgif.macos.template_debug + │ + └───godotgif.macos.template_release.framework + libgodotgif.macos.template_release +``` + +Open your project. Any exisitng gifs should auto-import. New gifs in the project directory will automatically import as `SpriteFrames`. To convert them into `AnimatedTexture`, update the [import settings](#editor). + +The `GifManager` class should also now be available for access within GDScript. + +## Contributing + +### Setup + +Ensure **SCons** is setup. Refer to [Introduction to the buildsystem](https://docs.godotengine.org/en/stable/contributing/development/compiling/introduction_to_the_buildsystem.html) + +* If using a different version of Godot, be sure to dump the bindings e.g. + ```sh + godot --dump-extension-api extension_api.json + ``` +* Compile with + ```sh + scons platform= custom_api_file=extension_api.json + ``` + +### Debugging + +This repository is configured for use with [VSCode](https://code.visualstudio.com/) + +[Launch configurations](./.vscode/launch.json) have been setup for both debugging in editor and in runtime provided certain **VSCode** extensions are present and environment variables are defined. + +The following environment variables are required: + +1. `GODOT_PATH` - The directory in which Godot is installed +1. `GODOT_EXECUTABLE` - The executable name of the Godot installation + +### More Details +Refer to [GDExtension C++ example](https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/gdextension_cpp_example.html) + + +## License + +Unless otherwise specified, the extension is released under the +[MIT license](LICENSE.txt). + +See the full list of third-party libraries with their licenses used by this +extension at [src/thirdparty/README.md](src/thirdparty/README.md). + +This implementation heavily borrowed inspiration from the [gif module](https://github.com/goostengine/goost/tree/gd3/modules/gif) for [Goost](https://github.com/goostengine/goost) that is currently only based on Godot 3 diff --git a/addons/godotgif/bin/godotgif.macos.template_debug.framework/libgodotgif.macos.template_debug b/addons/godotgif/bin/godotgif.macos.template_debug.framework/libgodotgif.macos.template_debug new file mode 100644 index 0000000..1c6c773 Binary files /dev/null and b/addons/godotgif/bin/godotgif.macos.template_debug.framework/libgodotgif.macos.template_debug differ diff --git a/addons/godotgif/bin/godotgif.macos.template_release.framework/libgodotgif.macos.template_release b/addons/godotgif/bin/godotgif.macos.template_release.framework/libgodotgif.macos.template_release new file mode 100644 index 0000000..dcbb2ea Binary files /dev/null and b/addons/godotgif/bin/godotgif.macos.template_release.framework/libgodotgif.macos.template_release differ diff --git a/addons/godotgif/bin/godotgif.windows.template_debug.x86_32.dll b/addons/godotgif/bin/godotgif.windows.template_debug.x86_32.dll new file mode 100644 index 0000000..84b492d Binary files /dev/null and b/addons/godotgif/bin/godotgif.windows.template_debug.x86_32.dll differ diff --git a/addons/godotgif/bin/godotgif.windows.template_debug.x86_64.dll b/addons/godotgif/bin/godotgif.windows.template_debug.x86_64.dll new file mode 100644 index 0000000..503c2d6 Binary files /dev/null and b/addons/godotgif/bin/godotgif.windows.template_debug.x86_64.dll differ diff --git a/addons/godotgif/bin/godotgif.windows.template_release.x86_32.dll b/addons/godotgif/bin/godotgif.windows.template_release.x86_32.dll new file mode 100644 index 0000000..021e7bd Binary files /dev/null and b/addons/godotgif/bin/godotgif.windows.template_release.x86_32.dll differ diff --git a/addons/godotgif/bin/godotgif.windows.template_release.x86_64.dll b/addons/godotgif/bin/godotgif.windows.template_release.x86_64.dll new file mode 100644 index 0000000..4ffd517 Binary files /dev/null and b/addons/godotgif/bin/godotgif.windows.template_release.x86_64.dll differ diff --git a/addons/godotgif/bin/libgodotgif.android.template_debug.arm64.so b/addons/godotgif/bin/libgodotgif.android.template_debug.arm64.so new file mode 100644 index 0000000..a5d8f53 Binary files /dev/null and b/addons/godotgif/bin/libgodotgif.android.template_debug.arm64.so differ diff --git a/addons/godotgif/bin/libgodotgif.android.template_release.arm64.so b/addons/godotgif/bin/libgodotgif.android.template_release.arm64.so new file mode 100644 index 0000000..6f34958 Binary files /dev/null and b/addons/godotgif/bin/libgodotgif.android.template_release.arm64.so differ diff --git a/addons/godotgif/bin/libgodotgif.linux.template_debug.x86_32.so b/addons/godotgif/bin/libgodotgif.linux.template_debug.x86_32.so new file mode 100644 index 0000000..ed99762 Binary files /dev/null and b/addons/godotgif/bin/libgodotgif.linux.template_debug.x86_32.so differ diff --git a/addons/godotgif/bin/libgodotgif.linux.template_debug.x86_64.so b/addons/godotgif/bin/libgodotgif.linux.template_debug.x86_64.so new file mode 100644 index 0000000..1368208 Binary files /dev/null and b/addons/godotgif/bin/libgodotgif.linux.template_debug.x86_64.so differ diff --git a/addons/godotgif/bin/libgodotgif.linux.template_release.x86_32.so b/addons/godotgif/bin/libgodotgif.linux.template_release.x86_32.so new file mode 100644 index 0000000..eb9dc8d Binary files /dev/null and b/addons/godotgif/bin/libgodotgif.linux.template_release.x86_32.so differ diff --git a/addons/godotgif/bin/libgodotgif.linux.template_release.x86_64.so b/addons/godotgif/bin/libgodotgif.linux.template_release.x86_64.so new file mode 100644 index 0000000..d53992d Binary files /dev/null and b/addons/godotgif/bin/libgodotgif.linux.template_release.x86_64.so differ diff --git a/addons/godotgif/godotgif.gdextension b/addons/godotgif/godotgif.gdextension new file mode 100644 index 0000000..fb241a2 --- /dev/null +++ b/addons/godotgif/godotgif.gdextension @@ -0,0 +1,23 @@ +[configuration] + +entry_symbol = "godot_gif_library_init" +compatibility_minimum = "4.1" + +[libraries] + +macos.debug = "bin/godotgif.macos.template_debug.framework/libgodotgif.macos.template_debug" +macos.release = "bin/godotgif.macos.template_release.framework/libgodotgif.macos.template_release" +windows.debug.x86_32 = "bin/godotgif.windows.template_debug.x86_32.dll" +windows.release.x86_32 = "bin/godotgif.windows.template_release.x86_32.dll" +windows.debug.x86_64 = "bin/godotgif.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "bin/godotgif.windows.template_release.x86_64.dll" +linux.debug.x86_64 = "bin/libgodotgif.linux.template_debug.x86_64.so" +linux.release.x86_64 = "bin/libgodotgif.linux.template_release.x86_64.so" +linux.debug.arm64 = "bin/libgodotgif.linux.template_debug.arm64.so" +linux.release.arm64 = "bin/libgodotgif.linux.template_release.arm64.so" +linux.debug.rv64 = "bin/libgodotgif.linux.template_debug.rv64.so" +linux.release.rv64 = "bin/libgodotgif.linux.template_release.rv64.so" +android.debug.x86_64 = "bin/libgodotgif.android.template_debug.x86_64.so" +android.release.x86_64 = "bin/libgodotgif.android.template_release.x86_64.so" +android.debug.arm64 = "bin/libgodotgif.android.template_debug.arm64.so" +android.release.arm64 = "bin/libgodotgif.android.template_release.arm64.so" diff --git a/main.gd b/main.gd index 0c3c1c7..95481be 100644 --- a/main.gd +++ b/main.gd @@ -29,6 +29,8 @@ extends Control @onready var album_name: Label = $Album @onready var playlist_or_song: ConfirmationDialog = $PlaylistOrSong @onready var search_results: SearchResults = $SearchResults +@onready var delete_confirm: ConfirmationDialog = $deleteConfirm +@onready var search_bar: LineEdit = $SearchBar @@ -64,6 +66,9 @@ var PlayAllLists:bool @export var LoopPressed:Texture2D @export var LoopNotPressed:Texture2D +signal ContinueDelete +var deleteSong:bool + # Called when the node enters the scene tree for the first time. func _ready() -> void: get_tree().root.min_size = Vector2(850,492) @@ -77,6 +82,7 @@ func _ready() -> void: skip.pressed.connect(Skip) go_back.pressed.connect(GoBack) search_results.index_pressed.connect(SetSong) + search_results.song_deleted.connect(deletesong) var Strin:String for Arg in OS.get_cmdline_args(): if Arg.to_lower().ends_with(".mp3") or Arg.to_lower().ends_with(".wav"): @@ -191,6 +197,36 @@ func _ready() -> void: # Always refresh after changing the values! DiscordRPC.refresh() +func deletesong(idx:int): + var currentDir:String= CurrentDir + currentDir += "/" + textSongs[idx] + delete_confirm.show() + delete_confirm.dialog_text = "are you sure you want to delete \n" + textSongs[idx] +"?" + delete_confirm.confirmed.connect(deleteConfirmed) + delete_confirm.canceled.connect(deleteCancelled) + await ContinueDelete + delete_confirm.canceled.disconnect(deleteCancelled) + delete_confirm.confirmed.disconnect(deleteConfirmed) + if deleteSong: + print("deleted + " + currentDir) + deleteSong = false + var dir = DirAccess.remove_absolute(currentDir) + print("error code " +str(dir) + " (zero is good)") + if dir == 0: + textSongs.remove_at(idx) + if search_bar.visible: + search_bar.updateResults() + else: + songs_menu._pressed() + Playlists[CurrentPlaylist].erase(textSongs[idx]) + +func deleteCancelled(): + deleteSong = false + ContinueDelete.emit() + +func deleteConfirmed(): + deleteSong = true + ContinueDelete.emit() func SongDragStopped(Changed:bool): if Changed: diff --git a/search_bar.gd b/search_bar.gd index 7a04a47..ae147d5 100644 --- a/search_bar.gd +++ b/search_bar.gd @@ -16,34 +16,37 @@ func _process(delta: float) -> void: currentTime -= delta if TextChanged: if currentTime < 0: - release_focus() - TextChanged = false - search_results.clear() - values.clear() - currentTime = updatetime - var _i:int = 0 - var _s:int = 0 - for song:String in owner.textSongs: - var margin:float - var fragments:Array - #print(int((text.length() / 2.0) + 0.5)) - for num in range(int((text.length() / 2.0) + 0.5)): - if text.to_lower().substr(int(num*2),2): - fragments.append(text.to_lower().substr(int(num*2),2)) - elif text.to_lower().substr(int(num*2),1): - fragments.append(text.to_lower().substr(int(num*2),1)) - var amountOfFrags:int - for fragment:String in fragments: - - if song.to_lower().containsn(fragment): - amountOfFrags +=1 - - margin = float(amountOfFrags) / fragments.size() - if margin > ErrorMargin: - search_results.add_item(song) - values[_i] = _s - _i += 1 - _s += 1 + updateResults() + +func updateResults(): + release_focus() + TextChanged = false + search_results.clear() + values.clear() + currentTime = updatetime + var _i:int = 0 + var _s:int = 0 + for song:String in owner.textSongs: + var margin:float + var fragments:Array + #print(int((text.length() / 2.0) + 0.5)) + for num in range(int((text.length() / 2.0) + 0.5)): + if text.to_lower().substr(int(num*2),2): + fragments.append(text.to_lower().substr(int(num*2),2)) + elif text.to_lower().substr(int(num*2),1): + fragments.append(text.to_lower().substr(int(num*2),1)) + var amountOfFrags:int + for fragment:String in fragments: + + if song.to_lower().containsn(fragment): + amountOfFrags +=1 + + margin = float(amountOfFrags) / fragments.size() + if margin > ErrorMargin: + search_results.add_item(song) + values[_i] = _s + _i += 1 + _s += 1 func _on_search_results_index_pressed(index: int) -> void: print("index " + str(index)) diff --git a/search_item.gd b/search_item.gd index 03f4a57..05b3b60 100644 --- a/search_item.gd +++ b/search_item.gd @@ -19,3 +19,7 @@ func _process(delta: float) -> void: func _on_songname_pressed() -> void: PlayPressed.emit(idx) + + +func _on_delete_pressed() -> void: + DeletePressed.emit(idx) diff --git a/search_item.tscn b/search_item.tscn index 28e78c7..ad9c71f 100644 --- a/search_item.tscn +++ b/search_item.tscn @@ -42,4 +42,5 @@ focus_mode = 0 flat = true alignment = 0 +[connection signal="pressed" from="HBoxContainer/delete" to="." method="_on_delete_pressed"] [connection signal="pressed" from="HBoxContainer/Songname" to="." method="_on_songname_pressed"] diff --git a/search_results.gd b/search_results.gd index a87425e..defce9a 100644 --- a/search_results.gd +++ b/search_results.gd @@ -2,6 +2,7 @@ class_name SearchResults extends Control signal index_pressed +signal song_deleted const SEARCH_ITEM = preload("res://search_item.tscn") @@ -26,9 +27,11 @@ func add_item(text:String): child.idx = parent.textSongs.find(text) SongsAmount+=1 child.PlayPressed.connect(songSelected) + child.DeletePressed.connect(deletePressed) item_container.add_child(child) func clear(): + SongsAmount = 0 for child in item_container.get_children(): child.queue_free() @@ -40,3 +43,6 @@ func _input(event): var evLocal = make_input_local(event) if !Rect2(Vector2(0,0),Vector2(size.x,size.y)).has_point(evLocal.position): hide() + +func deletePressed(idx:int): + song_deleted.emit(idx) diff --git a/songs_menu.gd b/songs_menu.gd index 802a104..67e73d7 100644 --- a/songs_menu.gd +++ b/songs_menu.gd @@ -1,7 +1,7 @@ extends Button @onready var search_results: SearchResults = $"../SearchResults" - +@onready var parent:MainScene = owner # Called when the node enters the scene tree for the first time. func _ready() -> void: pass # Replace with function body. @@ -12,4 +12,9 @@ func _process(delta: float) -> void: pass func _pressed() -> void: + if search_results.SongsAmount != parent.textSongs.size(): + search_results.clear() + for song in parent.textSongs: + var nam = song + search_results.add_item(nam) search_results.show()