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
+
+
+
+
+
+
+
+
+
+
+
+
+## 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
+
+
+
+
+See the [Editor Imports](./demo/editor_imports_example.tscn) example scene.
+
+ Editor Imports Example
+
+
+
+
+
+
+### 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:
+
+
+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
+
+
+
+
+
+## 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**)
+
+
+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()