loading songs

This commit is contained in:
Bucket Of Chicken
2025-08-30 13:31:07 +02:00
parent 702013f9f8
commit e758d1df2b
8 changed files with 323 additions and 31 deletions
+51 -2
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=12 format=3 uid="uid://mfcbf2sfino6"]
[gd_scene load_steps=14 format=3 uid="uid://mfcbf2sfino6"]
[ext_resource type="Texture2D" uid="uid://0jo87vtoeheu" path="res://Images/pole2.jpg" id="1_6bp64"]
[ext_resource type="Texture2D" uid="uid://df2e70jxwrmjs" path="res://Icons/BackOne.png" id="1_8gbba"]
@@ -8,7 +8,9 @@
[ext_resource type="Texture2D" uid="uid://myq6n4bshduj" path="res://Icons/search.png" id="2_ynf5e"]
[ext_resource type="Script" uid="uid://bq55jftgugexl" path="res://Scripts/Context.cs" id="3_8gbba"]
[ext_resource type="Texture2D" uid="uid://38c8dfym0svn" path="res://Icons/Loop.png" id="4_21xkr"]
[ext_resource type="Script" uid="uid://dq3yj21reqk80" path="res://Scripts/SearchDisplay.cs" id="4_hptm8"]
[ext_resource type="Texture2D" uid="uid://cekkhyppj88xi" path="res://Icons/Headphones.png" id="4_kry3j"]
[ext_resource type="PackedScene" uid="uid://c21wc1bq2pnm" path="res://Scenes/song_display.tscn" id="5_d1ilt"]
[sub_resource type="GDScript" id="GDScript_bo1nx"]
resource_name = "OpenDirGlue"
@@ -49,6 +51,7 @@ grow_horizontal = 2
grow_vertical = 2
[node name="Background" type="TextureRect" parent="."]
z_index = -2
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -133,10 +136,48 @@ layout_mode = 2
icon = ExtResource("2_344ge")
expand_icon = true
[node name="Control" type="Control" parent="Padding/VBoxContainer"]
[node name="Center" type="Control" parent="Padding/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="SearchResults" type="Panel" parent="Padding/VBoxContainer/Center"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 1
anchors_preset = -1
anchor_left = 0.28500003
anchor_right = 0.71500003
anchor_bottom = 0.93700004
offset_left = 0.20996094
offset_right = -0.21002197
offset_bottom = 0.12197876
grow_horizontal = 2
[node name="ScrollContainer" type="ScrollContainer" parent="Padding/VBoxContainer/Center/SearchResults"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
follow_focus = true
horizontal_scroll_mode = 0
[node name="VBoxContainer" type="VBoxContainer" parent="Padding/VBoxContainer/Center/SearchResults/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/separation = 0
[node name="UpperMargin" type="Control" parent="Padding/VBoxContainer/Center/SearchResults/ScrollContainer/VBoxContainer"]
layout_mode = 2
[node name="SongContainer" type="VBoxContainer" parent="Padding/VBoxContainer/Center/SearchResults/ScrollContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 0
[node name="LowerMargin" type="Control" parent="Padding/VBoxContainer/Center/SearchResults/ScrollContainer/VBoxContainer"]
layout_mode = 2
[node name="Bottom" type="Control" parent="Padding/VBoxContainer"]
custom_minimum_size = Vector2(0, 42)
layout_mode = 2
@@ -214,3 +255,11 @@ offset_top = -23.0
grow_horizontal = 0
grow_vertical = 0
text = "v2.0"
[node name="SearchDisplay" type="Node" parent="." node_paths=PackedStringArray("UpperMargin", "SongContainer", "LowerMargin", "Scroll")]
script = ExtResource("4_hptm8")
display = ExtResource("5_d1ilt")
UpperMargin = NodePath("../Padding/VBoxContainer/Center/SearchResults/ScrollContainer/VBoxContainer/UpperMargin")
SongContainer = NodePath("../Padding/VBoxContainer/Center/SearchResults/ScrollContainer/VBoxContainer/SongContainer")
LowerMargin = NodePath("../Padding/VBoxContainer/Center/SearchResults/ScrollContainer/VBoxContainer/LowerMargin")
Scroll = NodePath("../Padding/VBoxContainer/Center/SearchResults/ScrollContainer")
+81
View File
@@ -0,0 +1,81 @@
[gd_scene load_steps=4 format=3 uid="uid://c21wc1bq2pnm"]
[ext_resource type="Script" uid="uid://bs55rsv7eh4l5" path="res://Scripts/SongDisplay.cs" id="1_76jf4"]
[sub_resource type="LabelSettings" id="LabelSettings_swnt4"]
font_size = 20
shadow_size = 2
shadow_color = Color(0, 0, 0, 0.5647059)
[sub_resource type="LabelSettings" id="LabelSettings_8tgr4"]
font_color = Color(0.7919991, 0.79199916, 0.7919991, 1)
shadow_size = 2
shadow_color = Color(0, 0, 0, 0.5647059)
[node name="SongDisplay" type="Control" node_paths=PackedStringArray("background", "NameLabel", "ArtistLabel")]
custom_minimum_size = Vector2(0, 75)
layout_mode = 3
anchor_right = 1.0
grow_horizontal = 2
script = ExtResource("1_76jf4")
background = NodePath("TextureRect")
NameLabel = NodePath("VBoxContainer/Name")
ArtistLabel = NodePath("VBoxContainer/Artist")
[node name="Panel" type="Panel" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="TextureRect" type="TextureRect" parent="."]
custom_minimum_size = Vector2(0, 75)
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
expand_mode = 3
stretch_mode = 6
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
mouse_filter = 2
[node name="Name" type="Label" parent="VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 6
text = "Name"
label_settings = SubResource("LabelSettings_swnt4")
clip_text = true
text_overrun_behavior = 3
[node name="Artist" type="Label" parent="VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 6
text = "Artist"
label_settings = SubResource("LabelSettings_8tgr4")
clip_text = true
text_overrun_behavior = 3
[node name="Playbutton" type="Button" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
flat = true
+28 -7
View File
@@ -1,22 +1,43 @@
using Godot;
using Instances;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
public partial class Context : Node
{
Song[] Songs;
public Thread processingThread;
public static Context instance;
public IEnumerable<Song> Songs;
AudioStreamPlayer[] StreamPlayers;
DirectoryManager manager = new();
DirectoryLoader manager = new();
public event EventHandler SongsUpdated;
public delegate void SongsUpdatedEventHandler(object sender, SongsUpdatedEventArgs e);
public override void _Ready()
{
base._Ready();
instance = this;
}
public void LoadDirectory(String path){
GD.Print(path);
Songs = manager.LoadDirectory(path);
GD.Print("got here");
foreach (Song song in Songs){
GD.Print("got ", song.Name);
GD.Print("Songs loaded");
SongsUpdatedEventArgs args = new();
args.songs = Songs;
OnSongsUpdated(args);
}
protected virtual void OnSongsUpdated(SongsUpdatedEventArgs e){
SongsUpdated.Invoke(this,e);
}
}
}
public class SongsUpdatedEventArgs : EventArgs
{
public IEnumerable<Song> songs;
}
+44 -21
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
@@ -11,54 +12,76 @@ using TagLib.Riff;
public class Song{
public String Name;
public bool LoadedMetadata;
public String[] Artists;
public String Album;
public float Length;
public String Comment;
public String Directory;
public void LoadMetadata(){
var TLfile = TagLib.File.Create(Directory);
Album ??= TLfile.Tag.Album;
Artists ??= TLfile.Tag.Performers;
Name ??= TLfile.Tag.Title;
Length = TLfile.Length;
Comment ??= TLfile.Tag.Comment;
TLfile.Dispose();
}
public Image LoadImage(){
var TLfile = TagLib.File.Create(Directory);
if (TLfile.Tag.Pictures.Count() == 0){
return null;
}
String type = TLfile.Tag.Pictures[0].MimeType;
byte[] pictureData = TLfile.Tag.Pictures[0].Data.Data;
Image image = new Image();
Error error = Error.Failed;
switch (type)
{
case "image/jpeg":
error = image.LoadJpgFromBuffer(pictureData);
break;
case "image/png":
error = image.LoadPngFromBuffer(pictureData);
break;
case "image/webp":
error = image.LoadWebpFromBuffer(pictureData);
break;
}
GD.Print(image);
return image;
}
}
public class DirectoryManager{
public class DirectoryLoader{
Task LoadTask;
Song[] LoadedSongs;
public Song[] LoadDirectory(String Path){
IEnumerable<Song> LoadedSongs;
public IEnumerable<Song> LoadDirectory(String Path){
LoadTask = new Task(() => ParseDirectory(Path));
LoadTask.Start();
Task.WhenAll([LoadTask]).Wait();
GD.Print("Finished");
return LoadedSongs;
return ParseDirectory(Path);
//if (file.EndsWith(".mp3"))
}
private void ParseDirectory(String Path){
private IEnumerable<Song> ParseDirectory(String Path){
System.Collections.Generic.IEnumerable<string> Files = Directory.EnumerateFiles(Path);
Song[] Songs = [];
IEnumerable<Song> Songs = [];
foreach (String file in Files){
if (!(file.EndsWith(".mp3") || file.EndsWith(".ogg") || file.EndsWith(".wav"))){
continue;
}
var TLfile = TagLib.File.Create(file);
Song song = new()
{
Album = TLfile.Tag.Album,
Artists = TLfile.Tag.Performers,
Name = TLfile.Tag.Title,
Length = TLfile.Length,
Directory = file,
Comment = TLfile.Tag.Comment
};
if (file.EndsWith(".mp3")){
song.Comment = TLfile.GetTag(TagLib.TagTypes.Id3v2, true).Comment;
}
//TLfile.Tag.CopyTo(Tag)
//GD.Print("File Valid, file path ",song.Directory);
Songs.Append(song);
Songs = Songs.Append(song);
//if (file.EndsWith(".mp3"))
}
LoadedSongs = Songs;
return Songs;
}
}
+91
View File
@@ -0,0 +1,91 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public partial class SearchDisplay : Node
{
[Export] PackedScene display;
[Export] Control UpperMargin;
[Export] Control SongContainer;
[Export] Control LowerMargin;
[Export] ScrollContainer Scroll;
public override void _Ready()
{
base._Ready();
Context.instance.SongsUpdated += UpdateDisplay;
}
IEnumerable<Song> DisplayedSongs = [];
void UpdateDisplay(object sender,EventArgs eventArgs){
SongsUpdatedEventArgs args = (SongsUpdatedEventArgs)eventArgs;
DisplayedSongs = args.songs;
GD.Print("Updated, songs ",args.songs.Count());
}
public override void _Process(double delta)
{
base._Process(delta);
int CurrentIndex = (int)(Scroll.ScrollVertical/ 75);
int MaxIndex = (int)((Scroll.Size.Y / 75)+CurrentIndex+1);
IEnumerable<SongDisplay> DisplayRemove =[];
IEnumerable<int> ids = [];
IEnumerable<SongDisplay> displays = [];
foreach(Node child in SongContainer.GetChildren()){
if (child is SongDisplay display1)
{
displays = displays.Append(display1);
}
}
if (displays.Any())
{
foreach (SongDisplay display in displays){
if (display.DisplayId < CurrentIndex || display.DisplayId > MaxIndex){
DisplayRemove = DisplayRemove.Append(display);
}
else{
ids = ids.Append(display.DisplayId);
}
}
}
for (int i = CurrentIndex; i >= CurrentIndex && i <= MaxIndex;i++)
{
if (!ids.Contains(i)){
if (i > DisplayedSongs.Count()-1){
break;
}
Song Songinfo = DisplayedSongs.ElementAt(i);
if (!Songinfo.LoadedMetadata){
Songinfo.LoadMetadata();
}
SongDisplay scene = (SongDisplay)display.Instantiate();
SongContainer.AddChild(scene);
scene.Setup(Songinfo);
scene.DisplayId = i;
SongContainer.MoveChild(scene,i - CurrentIndex);
GD.Print("IDKENX ", i - CurrentIndex );
GD.Print("CurrentIndex ", CurrentIndex);
displays = displays.Append(scene);
}
}
foreach (SongDisplay display in DisplayRemove)
{
display.QueueFree();
}
update_margins(CurrentIndex);
}
void update_margins(int CurrentIndex){
int ChildSize = SongContainer.GetChildren().Count * 75;
int TotalSize = 75 * DisplayedSongs.Count();
int TopMarginSize = CurrentIndex*75;
int LowMarginSize = TotalSize-ChildSize-TopMarginSize;
UpperMargin.CustomMinimumSize = new Vector2(0,TopMarginSize);
LowerMargin.CustomMinimumSize = new Vector2(0, LowMarginSize);
}
}
+1
View File
@@ -0,0 +1 @@
uid://dq3yj21reqk80
+25
View File
@@ -0,0 +1,25 @@
using Godot;
using System;
using System.Linq;
public partial class SongDisplay : Control
{
public int DisplayId;
Song SavedInfo;
[Export] TextureRect background;
[Export] Label NameLabel;
[Export] Label ArtistLabel;
public void Setup(Song info){
SavedInfo = info;
Image image = info.LoadImage();
if (image != null){
ImageTexture tex = ImageTexture.CreateFromImage(image);
background.Texture = tex;
}
NameLabel.Text = SavedInfo.Name;
if (SavedInfo.Artists.Any()){
ArtistLabel.Text = SavedInfo.Artists[0];
}
}
}
+1
View File
@@ -0,0 +1 @@
uid://bs55rsv7eh4l5