dlete songs

This commit is contained in:
notdraimdev
2024-10-27 14:14:21 +01:00
parent c418b417ec
commit f14a8170d6
22 changed files with 274 additions and 31 deletions
+7 -2
View File
@@ -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"]
+21
View File
@@ -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.
+139
View File
@@ -0,0 +1,139 @@
# Godot GIF
<br>
<p align="center">
<img src="./docs-images/logo.gif" alt="Logo" width="128" height="128" />
</p>
<p align="center">
<a href="https://github.com/BOTLANNER/godot-gif/actions/workflows/build_releases.yml"><img alt="GitHub Build" src="https://github.com/BOTLANNER/godot-gif/actions/workflows/build_releases.yml/badge.svg" height="20"/></a>
<a href="https://github.com/BOTLANNER/godot-gif/blob/develop/LICENSE.txt"><img alt="MIT License" src="https://img.shields.io/github/license/BOTLANNER/godot-gif" height="20"/></a>
</p>
## 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.
<details open>
<summary>Editor Imports Options</summary>
![Editor Imports Options](./docs-images/EditorImportSettings.gif)
</details>
See the [Editor Imports](./demo/editor_imports_example.tscn) example scene.
<details open>
<summary>Editor Imports Example</summary>
![Editor Imports](./docs-images/EditorImports.gif)
</details>
<hr/>
### 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.
<details open>
<summary>Runtime Imports Example</summary>
![Runtime Imports](./docs-images/RuntimeImports.gif)
</details>
## 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=<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
+23
View File
@@ -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"
+36
View File
@@ -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:
+31 -28
View File
@@ -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))
+4
View File
@@ -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)
+1
View File
@@ -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"]
+6
View File
@@ -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)
+6 -1
View File
@@ -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()