From fa4c9c3f87279a26b0025f5992e1c57aa29d40c7 Mon Sep 17 00:00:00 2001 From: captainerd <58100748+captainerd@users.noreply.github.com> Date: Mon, 13 May 2024 04:58:05 +0300 Subject: [PATCH 01/29] Update mod.rs Adding a "Left-Right Hand" information column to card --- neothesia-iced-widgets/src/track_card/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/neothesia-iced-widgets/src/track_card/mod.rs b/neothesia-iced-widgets/src/track_card/mod.rs index 369a5adf..ac67c9c9 100644 --- a/neothesia-iced-widgets/src/track_card/mod.rs +++ b/neothesia-iced-widgets/src/track_card/mod.rs @@ -6,6 +6,7 @@ mod theme; pub struct TrackCard<'a, MSG> { title: String, subtitle: String, + hand_info: String, body: Option>, track_color: Color, on_icon_press: Option, @@ -22,6 +23,7 @@ impl<'a, MSG: 'a + Clone> TrackCard<'a, MSG> { Self { title: String::new(), subtitle: String::new(), + hand_info: String::new(), body: None, track_color: Color::from_rgba8(210, 89, 222, 1.0), on_icon_press: None, @@ -33,6 +35,11 @@ impl<'a, MSG: 'a + Clone> TrackCard<'a, MSG> { self } + pub fn hand_info(mut self, text: impl ToString) -> Self { + self.hand_info = text.to_string(); + self + } + pub fn subtitle(mut self, text: impl ToString) -> Self { self.subtitle = text.to_string(); self @@ -65,6 +72,7 @@ impl<'a, M: Clone + 'a> From> for Element<'a, M> { .on_press_maybe(card.on_icon_press), iced_widget::column(vec![ iced_widget::text(card.title).size(16).into(), + iced_widget::text(card.hand_info).size(16).into(), iced_widget::text(card.subtitle).size(14).into(), ]) .spacing(4) From 446e7dd38f4ec1de190ba0c05fc19e0c1e8cff96 Mon Sep 17 00:00:00 2001 From: captainerd <58100748+captainerd@users.noreply.github.com> Date: Mon, 13 May 2024 04:58:58 +0300 Subject: [PATCH 02/29] Adding a (Left/Right Hand) information card column From c3735a57372d4fc2e7df2640cdd3c6e919217ec1 Mon Sep 17 00:00:00 2001 From: captainerd <58100748+captainerd@users.noreply.github.com> Date: Mon, 13 May 2024 05:02:23 +0300 Subject: [PATCH 03/29] Utilizing the hand information in card + reverse iteration to display orderly bass/Melody as expected in menu --- .../src/scene/menu_scene/iced_menu/tracks.rs | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs index 8711a45e..0cb67a40 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs @@ -57,10 +57,17 @@ impl Page for TracksPage { PageMessage::none() } - fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { + fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut tracks = Vec::new(); if let Some(song) = ctx.song.as_ref() { - for track in song.file.tracks.iter().filter(|t| !t.notes.is_empty()) { + let mut piano_count = 0; + for track in song + .file + .tracks + .iter() + .filter(|t| !t.notes.is_empty()) + .rev() + { let config = &song.config.tracks[track.track_id]; let visible = config.visible; @@ -78,17 +85,35 @@ impl Page for TracksPage { let color = &ctx.config.color_schema[color_id].base; iced_core::Color::from_rgb8(color.0, color.1, color.2) }; + let instrument_id = track + .programs + .last() + .map(|p| p.program as usize) + .unwrap_or(0); let name = if track.has_drums && !track.has_other_than_drums { "Percussion" } else { - let instrument_id = track - .programs - .last() - .map(|p| p.program as usize) - .unwrap_or(0); midi_file::INSTRUMENT_NAMES[instrument_id] }; + + + + // Check if the instrument is Grand Piano (id 0, 1, or 2) + let hand_info = if instrument_id <= 2 { + // Increment the piano counter + piano_count += 1; + + // Determine if it's the first or second occurrence of Grand Piano + if piano_count % 2 == 0 { + "Right Hand" + } else { + "Left Hand" + } + } else { + // For other instruments, no hand information + "" + }; let body = neothesia_iced_widgets::SegmentButton::new() .button( @@ -110,6 +135,7 @@ impl Page for TracksPage { .title(name) .subtitle(format!("{} Notes", track.notes.len())) .track_color(color) + .hand_info(hand_info) // Use hand_info field .body(body); let card = if track.has_drums && !track.has_other_than_drums { From e6e6b8a339bc8d7b001d8e8c479fdf77180e7d5e Mon Sep 17 00:00:00 2001 From: captainerd Date: Tue, 14 May 2024 08:26:05 +0300 Subject: [PATCH 04/29] Fixes bug of jumping/ignoring non-pressed notes, adding accuracy to score/midi --- .../src/scene/playing_scene/midi_player.rs | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index c1f23a6b..8b64b465 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -221,28 +221,33 @@ impl PlayAlong { } fn update(&mut self) { - // Instead of calling .elapsed() per item let's fetch `now` once, and subtract it ourselves let now = Instant::now(); - - while let Some(item) = self.user_pressed_recently.front_mut() { + let threshold = Duration::from_millis(500); + + // Retain only the items that are within the threshold + self.user_pressed_recently.retain(|item| { let elapsed = now - item.timestamp; - - // If older than 500ms - if elapsed.as_millis() > 500 { - self.user_pressed_recently.pop_front(); - } else { - // All subsequent items will by younger than front item, so we can break - break; - } - } + elapsed <= threshold + }); } fn user_press_key(&mut self, note_id: u8, active: bool) { - let timestamp = Instant::now(); - if active { - self.user_pressed_recently - .push_back(UserPress { timestamp, note_id }); + let timestamp = Instant::now(); + // Check if note_id already exists in the collection + if let Some(item) = self.user_pressed_recently.iter_mut().find(|item| item.note_id == note_id) { + // Update the timestamp for existing note_id + item.timestamp = timestamp; + } else { + // Push a new UserPress + self.user_pressed_recently.push_back(UserPress { timestamp, note_id }); + } + + // Check if note_id is in required_notes + if self.required_notes.contains(¬e_id) { + // If it's in required_notes, remove it from presed_recently to avoid skips/repeated count + self.user_pressed_recently.retain(|item| item.note_id != note_id); + } self.required_notes.remove(¬e_id); } } @@ -260,9 +265,10 @@ impl PlayAlong { self.required_notes.insert(note_id); } } else { - self.required_notes.remove(¬e_id); + self.required_notes.remove(¬e_id); } } + fn press_key(&mut self, src: MidiEventSource, note_id: u8, active: bool) { if !self.user_keyboard_range.contains(note_id) { From 912f7b35c5f5e855b5275c52a86158d97a9835f9 Mon Sep 17 00:00:00 2001 From: captainerd Date: Tue, 14 May 2024 09:08:22 +0300 Subject: [PATCH 05/29] cargo fmt + hand_info non-piano column hide --- neothesia-iced-widgets/src/track_card/mod.rs | 35 ++++++++++--------- .../src/scene/menu_scene/iced_menu/tracks.rs | 6 ++-- .../src/scene/playing_scene/midi_player.rs | 19 ++++++---- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/neothesia-iced-widgets/src/track_card/mod.rs b/neothesia-iced-widgets/src/track_card/mod.rs index ac67c9c9..964ff641 100644 --- a/neothesia-iced-widgets/src/track_card/mod.rs +++ b/neothesia-iced-widgets/src/track_card/mod.rs @@ -60,26 +60,29 @@ impl<'a, MSG: 'a + Clone> TrackCard<'a, MSG> { self } } - impl<'a, M: Clone + 'a> From> for Element<'a, M> { fn from(card: TrackCard<'a, M>) -> Self { - let header = { - iced_widget::row![ - iced_widget::button(iced_widget::text("")) - .width(40) - .height(40) - .style(theme::track_icon_button(card.track_color)) - .on_press_maybe(card.on_icon_press), - iced_widget::column(vec![ - iced_widget::text(card.title).size(16).into(), - iced_widget::text(card.hand_info).size(16).into(), - iced_widget::text(card.subtitle).size(14).into(), - ]) + let mut header_content = vec![ + iced_widget::text(card.title).size(16).into(), + iced_widget::text(card.subtitle).size(14).into(), + ]; + + // Only add hand_info if it's not empty + if !card.hand_info.is_empty() { + header_content.insert(1, iced_widget::text(card.hand_info).size(16).into()); + } + + let header = iced_widget::row![ + iced_widget::button(iced_widget::text("")) + .width(40) + .height(40) + .style(theme::track_icon_button(card.track_color)) + .on_press_maybe(card.on_icon_press), + iced_widget::column(header_content) .spacing(4) .align_items(Alignment::Start), - ] - .spacing(16) - }; + ] + .spacing(16); let mut children = vec![header.into()]; if let Some(body) = card.body { diff --git a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs index 0cb67a40..6c250877 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs @@ -57,7 +57,7 @@ impl Page for TracksPage { PageMessage::none() } - fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { + fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut tracks = Vec::new(); if let Some(song) = ctx.song.as_ref() { let mut piano_count = 0; @@ -96,14 +96,12 @@ impl Page for TracksPage { } else { midi_file::INSTRUMENT_NAMES[instrument_id] }; - - // Check if the instrument is Grand Piano (id 0, 1, or 2) let hand_info = if instrument_id <= 2 { // Increment the piano counter piano_count += 1; - + // Determine if it's the first or second occurrence of Grand Piano if piano_count % 2 == 0 { "Right Hand" diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 8b64b465..15223061 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -223,7 +223,7 @@ impl PlayAlong { fn update(&mut self) { let now = Instant::now(); let threshold = Duration::from_millis(500); - + // Retain only the items that are within the threshold self.user_pressed_recently.retain(|item| { let elapsed = now - item.timestamp; @@ -235,18 +235,24 @@ impl PlayAlong { if active { let timestamp = Instant::now(); // Check if note_id already exists in the collection - if let Some(item) = self.user_pressed_recently.iter_mut().find(|item| item.note_id == note_id) { + if let Some(item) = self + .user_pressed_recently + .iter_mut() + .find(|item| item.note_id == note_id) + { // Update the timestamp for existing note_id item.timestamp = timestamp; } else { // Push a new UserPress - self.user_pressed_recently.push_back(UserPress { timestamp, note_id }); + self.user_pressed_recently + .push_back(UserPress { timestamp, note_id }); } - + // Check if note_id is in required_notes if self.required_notes.contains(¬e_id) { // If it's in required_notes, remove it from presed_recently to avoid skips/repeated count - self.user_pressed_recently.retain(|item| item.note_id != note_id); + self.user_pressed_recently + .retain(|item| item.note_id != note_id); } self.required_notes.remove(¬e_id); } @@ -265,10 +271,9 @@ impl PlayAlong { self.required_notes.insert(note_id); } } else { - self.required_notes.remove(¬e_id); + self.required_notes.remove(¬e_id); } } - fn press_key(&mut self, src: MidiEventSource, note_id: u8, active: bool) { if !self.user_keyboard_range.contains(note_id) { From 834597818d07e68d03a8ae51afc63fe997534c7a Mon Sep 17 00:00:00 2001 From: captainerd Date: Tue, 14 May 2024 09:24:00 +0300 Subject: [PATCH 06/29] Fix Percussion getting hand_info --- neothesia/src/scene/menu_scene/iced_menu/tracks.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs index 6c250877..0c8836a6 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs @@ -97,12 +97,12 @@ impl Page for TracksPage { midi_file::INSTRUMENT_NAMES[instrument_id] }; - // Check if the instrument is Grand Piano (id 0, 1, or 2) - let hand_info = if instrument_id <= 2 { + // Check if the instrument is a Piano (id 0, 1, or 2) + let hand_info = if instrument_id <= 2 && name != "Percussion" { // Increment the piano counter piano_count += 1; - // Determine if it's the first or second occurrence of Grand Piano + // Determine if it's the first or second occurrence of Piano if piano_count % 2 == 0 { "Right Hand" } else { From ca4317bf920aed7323859c0ac3a80ccda99496ae Mon Sep 17 00:00:00 2001 From: captainerd Date: Thu, 16 May 2024 11:18:36 +0300 Subject: [PATCH 07/29] Gameplay accuracy+stats --- .../src/scene/playing_scene/midi_player.rs | 289 ++++++++++++++++-- 1 file changed, 260 insertions(+), 29 deletions(-) diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 15223061..cd1cc907 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -5,7 +5,8 @@ use crate::{ song::{PlayerConfig, Song}, }; use std::{ - collections::{HashSet, VecDeque}, + collections::HashMap, + collections::VecDeque, time::{Duration, Instant}, }; @@ -50,6 +51,9 @@ impl MidiPlayer { pub fn update(&mut self, delta: Duration) -> Vec<&midi_file::MidiEvent> { self.play_along.update(); + let playback_time = self.playback.time(); + let playback_length = self.playback.length(); + let events = self.playback.update(delta); events.iter().for_each(|event| { @@ -61,9 +65,6 @@ impl MidiPlayer { .midi_event(u4::new(event.channel), event.message); } PlayerConfig::Human => { - // Let's play the sound, in case the user does not want it they can just set - // no-output output in settings - // TODO: Perhaps play on midi-in instead self.output .midi_event(u4::new(event.channel), event.message); self.play_along @@ -73,6 +74,11 @@ impl MidiPlayer { } }); + // Check if the song has finished based on the playback time + if playback_time >= playback_length { + self.play_along.finished(); + } + events } @@ -198,17 +204,55 @@ pub enum MidiEventSource { struct UserPress { timestamp: Instant, note_id: u8, + time_key_up: Instant, + occurrence: usize, +} +#[derive(Debug)] +pub struct NoteStats { + notes_missed: usize, + notes_hit: usize, + wrong_notes: i32, + note_durations: Vec, +} +#[derive(Debug)] +pub struct NoteDurations { + user_note_dur: usize, + file_note_dur: usize, +} +impl Default for NoteStats { + fn default() -> Self { + NoteStats { + notes_missed: 0, + notes_hit: 0, + wrong_notes: 0, + note_durations: Vec::new(), + } + } +} + +impl Default for NoteDurations { + fn default() -> Self { + NoteDurations { + user_note_dur: 0, + file_note_dur: 0, + } + } } #[derive(Debug)] pub struct PlayAlong { user_keyboard_range: piano_math::KeyboardRange, - required_notes: HashSet, - + required_notes: VecDeque, + finished: bool, // List of user key press events that happened in last 500ms, // used for play along leeway logic user_pressed_recently: VecDeque, + user_stats: NoteStats, // struct to finalize the stats log + + user_notes: VecDeque, // log all user notes to get durrations + file_notes: VecDeque, // log all file notes to compare against user + occurrence: HashMap, // Keeping user to file log incremental pointer rewind immune } impl PlayAlong { @@ -217,6 +261,12 @@ impl PlayAlong { user_keyboard_range, required_notes: Default::default(), user_pressed_recently: Default::default(), + user_stats: Default::default(), + occurrence: HashMap::new(), + finished: Default::default(), + + user_notes: Default::default(), + file_notes: Default::default(), } } @@ -224,54 +274,171 @@ impl PlayAlong { let now = Instant::now(); let threshold = Duration::from_millis(500); + // Track the count of items before retain + let count_before = self.user_pressed_recently.len(); + // Retain only the items that are within the threshold self.user_pressed_recently.retain(|item| { let elapsed = now - item.timestamp; elapsed <= threshold }); + + // Calculate the count of deleted items + let count_deleted = count_before - self.user_pressed_recently.len(); + if count_deleted > 0 { + self.user_stats.wrong_notes += count_deleted as i32; + // println!("Update() Sum mistakes: {}", count_deleted); + } } fn user_press_key(&mut self, note_id: u8, active: bool) { + let timestamp = Instant::now(); + let occurrence = self.occurrence.entry(note_id).or_insert(0); + if active { - let timestamp = Instant::now(); - // Check if note_id already exists in the collection - if let Some(item) = self - .user_pressed_recently - .iter_mut() - .find(|item| item.note_id == note_id) + // Check if note_id has reached required_notes, then remove it now + if let Some(index) = self + .required_notes + .iter() + .position(|item| item.note_id == note_id) { - // Update the timestamp for existing note_id - item.timestamp = timestamp; + if let None = self + .user_pressed_recently + .iter_mut() + .find(|item| item.note_id == note_id) + { + // println!("{}", "One wrong note, turned out to be correct note"); + // Remove/take back. -1 a count_deleted (WRONG NOTE) added by update() if reached file_press_key(); /// + self.user_stats.wrong_notes -= 1; + } + + if timestamp + .duration_since(self.required_notes[index].timestamp) + .as_millis() + > 160 + { + //160 to forgive touching the bottom + + // println!("{}", "Note miss detected"); + self.user_stats.notes_missed += 1; + } else { + // println!("{}", "Note hit detected"); + self.user_stats.notes_hit += 1; + } + self.required_notes.remove(index); + + self.user_notes.push_back(UserPress { + timestamp: timestamp, + note_id, + occurrence: *occurrence, + time_key_up: timestamp, + }); } else { - // Push a new UserPress - self.user_pressed_recently - .push_back(UserPress { timestamp, note_id }); + // Haven't reached required_notes yet, place a possible later validation in 'user_pressed_recently' / file_press_key() + if let Some(item) = self + .user_pressed_recently + .iter_mut() + .find(|item| item.note_id == note_id) + { + // already exists, update timestamp + item.timestamp = timestamp; + // println!("{}", " 'EXTRA NOTE', 'NOTE MISS' or 'WRONG NOTE'"); + self.user_stats.wrong_notes += 1; + } else { + // Not found, push a new UserPress + self.user_pressed_recently.push_back(UserPress { + timestamp, + note_id, + occurrence: *occurrence, + time_key_up: timestamp, + }); + } } - - // Check if note_id is in required_notes - if self.required_notes.contains(¬e_id) { - // If it's in required_notes, remove it from presed_recently to avoid skips/repeated count - self.user_pressed_recently - .retain(|item| item.note_id != note_id); + } else { + // Update user_notes log time_key_up + if let Some(item) = self + .user_notes + .iter_mut() + .rev() + .find(|item| item.note_id == note_id && item.occurrence == *occurrence) + { + item.time_key_up = Instant::now(); } - self.required_notes.remove(¬e_id); } } fn file_press_key(&mut self, note_id: u8, active: bool) { + let occurrence = self.occurrence.entry(note_id).or_insert(0); + let timestamp = Instant::now(); if active { - if let Some((id, _)) = self + *occurrence += 1; + + // Check if note got pressed earlier 500ms (user_pressed_recently) + if let Some((_id, item)) = self .user_pressed_recently .iter() .enumerate() .find(|(_, item)| item.note_id == note_id) { - self.user_pressed_recently.remove(id); + // Note was pressed earlier, remove it from user_pressed_recently + // println!("{}", "Note hit detected"); + self.user_stats.notes_hit += 1; + + // log user_note by user_pressed_recently.timestamp as keydown value, update occurence + self.user_notes.push_back(UserPress { + timestamp: item.timestamp, + note_id, + occurrence: *occurrence, + time_key_up: item.time_key_up, + }); + self.user_pressed_recently + .retain(|item| item.note_id != note_id); } else { - self.required_notes.insert(note_id); + // Player never pressed that note, let it reach required_notes, check if note_id already exists in required_notes, update timestamp else push. + + // Catch possible clone-note velocity overlay, update the new occurence and exit the function + if let Some((_id, item)) = + self.file_notes.iter_mut().enumerate().find(|(_, item)| { + item.note_id == note_id && item.time_key_up == item.timestamp + }) + { + item.occurrence = *occurrence; + return; // Everything bellow already done before by its clone + } + if let Some(user_press) = self + .required_notes + .iter_mut() + .find(|item| item.note_id == note_id) + { + // Update the timestamp of the existing note + user_press.timestamp = timestamp; + } else { + self.required_notes.push_back(UserPress { + timestamp: timestamp, + note_id, + occurrence: *occurrence, + time_key_up: timestamp, + }); + } } + + // Log the note + self.file_notes.push_back(UserPress { + timestamp: timestamp, + note_id, + occurrence: *occurrence, // Set the occurrence count + time_key_up: timestamp, + }); } else { - self.required_notes.remove(¬e_id); + // update time_key_up + if let Some(item) = self + .file_notes + .iter_mut() + .rev() + .find(|item| item.note_id == note_id && item.occurrence == *occurrence) + { + item.time_key_up = timestamp; + } } } @@ -295,9 +462,73 @@ impl PlayAlong { } pub fn clear(&mut self) { - self.required_notes.clear() + self.required_notes.clear(); + self.file_notes + .retain(|item| item.time_key_up != item.timestamp); + self.user_pressed_recently.clear(); } + pub fn finished(&mut self) { + if !self.finished { + println!("The song has finished"); + // TO-DO: Move to a stats screen, somehow save songname date and stats, a button restart song, etc + // Loop through user_notes and file_notes and match entries with the same occurrence[note] = num + for user_note in &self.user_notes { + for file_note in &self.file_notes { + if user_note.occurrence == file_note.occurrence + && user_note.note_id == file_note.note_id + { + // Subtract timestamp from time_key_up to get total seconds + let user_note_dur = user_note + .time_key_up + .duration_since(user_note.timestamp) + .as_secs(); + let file_note_dur = file_note + .time_key_up + .duration_since(file_note.timestamp) + .as_secs(); + + // Add this information to user_stats.note_durations + let note_duration = NoteDurations { + user_note_dur: user_note_dur as usize, + file_note_dur: file_note_dur as usize, + }; + self.user_stats.note_durations.push(note_duration); + } + } + } + // Clean negative self.user_stats.wrong_notes + if self.user_stats.wrong_notes < 0 { + self.user_stats.wrong_notes = 0; + } + // Loop through user_stats.note_durations items, compare user_note_dur to file_note_dur + let mut correct_note_times = 0; + let mut wrong_note_times = 0; + for duration in &self.user_stats.note_durations { + // Compare user_note_dur to file_note_dur + let duration_difference = + (duration.user_note_dur as f64 - duration.file_note_dur as f64).abs(); + let percentage_difference = + duration_difference / duration.user_note_dur as f64 * 100.0; + + // Increment correctNoteTimes if it is close to 90%, otherwise increment wrongNoteTimes + if percentage_difference <= 10.0 { + correct_note_times += 1; + } else { + wrong_note_times += 1; + } + } + + println!("Correct Note Timing: {}", correct_note_times); + println!("Wrong Note Timing: {}", wrong_note_times); + println!("Notes Missed: {}", self.user_stats.notes_missed); + println!("Notes Hit: {}", self.user_stats.notes_hit); + println!("Wrong Notes: {}", self.user_stats.wrong_notes); + // Maybe cook everything together for a total score + + self.finished = true; + } + } pub fn are_required_keys_pressed(&self) -> bool { self.required_notes.is_empty() } From 06223cd2e6879450732ffb35d6fcef15c1d13472 Mon Sep 17 00:00:00 2001 From: captainerd Date: Mon, 20 May 2024 20:37:19 +0300 Subject: [PATCH 08/29] Added Game Stats screen, Added Folder select/song list, prepairing icons for styles --- Cargo.lock | 88 ++++- midi-io/src/lib.rs | 2 +- neothesia-core/src/config.rs | 2 + neothesia-core/src/gamesave.rs | 53 +++ neothesia-core/src/lib.rs | 1 + neothesia-core/src/utils/resources.rs | 11 + neothesia-iced-widgets/Cargo.toml | 1 + neothesia-iced-widgets/src/lib.rs | 2 + .../src/stats_container/img/first_place.png | Bin 0 -> 1244 bytes .../src/stats_container/img/second_place.png | Bin 0 -> 1408 bytes .../src/stats_container/img/third_place.png | Bin 0 -> 1465 bytes .../img/trophy_placeholder.png | Bin 0 -> 669 bytes .../src/stats_container/mod.rs | 181 ++++++++++ .../src/stats_container/theme.rs | 25 ++ .../src/track_card/img/brasses.png | Bin 0 -> 12598 bytes .../src/track_card/img/guitars.png | Bin 0 -> 24088 bytes .../src/track_card/img/piano-left.png | Bin 0 -> 4265 bytes .../src/track_card/img/piano-right.png | Bin 0 -> 4633 bytes .../src/track_card/img/sercussions.png | Bin 0 -> 36452 bytes .../src/track_card/img/uncategorized.png | Bin 0 -> 23234 bytes .../src/track_card/img/violins.png | Bin 0 -> 43330 bytes neothesia/Cargo.toml | 3 +- neothesia/src/main.rs | 12 +- .../src/scene/menu_scene/iced_menu/main.rs | 16 +- .../src/scene/menu_scene/iced_menu/mod.rs | 26 +- .../scene/menu_scene/iced_menu/selectsong.rs | 310 ++++++++++++++++++ .../src/scene/menu_scene/iced_menu/stats.rs | 235 +++++++++++++ .../src/scene/menu_scene/iced_menu/theme.rs | 39 ++- neothesia/src/scene/menu_scene/icons.rs | 3 + neothesia/src/scene/menu_scene/mod.rs | 6 +- .../src/scene/playing_scene/midi_player.rs | 134 +++++--- neothesia/src/scene/playing_scene/mod.rs | 13 +- neothesia/src/scene/playing_scene/top_bar.rs | 6 +- 33 files changed, 1103 insertions(+), 66 deletions(-) create mode 100644 neothesia-core/src/gamesave.rs create mode 100755 neothesia-iced-widgets/src/stats_container/img/first_place.png create mode 100755 neothesia-iced-widgets/src/stats_container/img/second_place.png create mode 100755 neothesia-iced-widgets/src/stats_container/img/third_place.png create mode 100755 neothesia-iced-widgets/src/stats_container/img/trophy_placeholder.png create mode 100644 neothesia-iced-widgets/src/stats_container/mod.rs create mode 100644 neothesia-iced-widgets/src/stats_container/theme.rs create mode 100755 neothesia-iced-widgets/src/track_card/img/brasses.png create mode 100755 neothesia-iced-widgets/src/track_card/img/guitars.png create mode 100755 neothesia-iced-widgets/src/track_card/img/piano-left.png create mode 100755 neothesia-iced-widgets/src/track_card/img/piano-right.png create mode 100755 neothesia-iced-widgets/src/track_card/img/sercussions.png create mode 100755 neothesia-iced-widgets/src/track_card/img/uncategorized.png create mode 100755 neothesia-iced-widgets/src/track_card/img/violins.png create mode 100644 neothesia/src/scene/menu_scene/iced_menu/selectsong.rs create mode 100644 neothesia/src/scene/menu_scene/iced_menu/stats.rs diff --git a/Cargo.lock b/Cargo.lock index 775eacbe..712577ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,6 +101,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -594,6 +600,20 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e53693616d3075149f4ead59bdeecd204ac6b8192d8969757601b74bddf00f" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.0", +] + [[package]] name = "clang-sys" version = "1.7.0" @@ -940,6 +960,26 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -1640,6 +1680,29 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "iced_core" version = "0.12.0" @@ -2031,6 +2094,16 @@ dependencies = [ "redox_syscall 0.4.1", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.4.2", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -2283,7 +2356,9 @@ name = "neothesia" version = "0.1.0" dependencies = [ "async-thread", + "chrono", "cpal", + "dirs", "embed-resource", "env_logger", "fluidlite", @@ -2562,7 +2637,7 @@ version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox", + "libredox 0.0.2", ] [[package]] @@ -2988,6 +3063,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox 0.1.3", + "thiserror", +] + [[package]] name = "regex" version = "1.10.3" diff --git a/midi-io/src/lib.rs b/midi-io/src/lib.rs index 87811330..d1c83bca 100644 --- a/midi-io/src/lib.rs +++ b/midi-io/src/lib.rs @@ -123,7 +123,7 @@ impl std::fmt::Display for MidiInputPort { write!(f, "{}", self.0) } } - +#[allow(dead_code)] pub struct MidiInputConnection(midir::MidiInputConnection<()>); pub struct MidiOutputConnection(midir::MidiOutputConnection); diff --git a/neothesia-core/src/config.rs b/neothesia-core/src/config.rs index 702d3f13..14e7b98a 100644 --- a/neothesia-core/src/config.rs +++ b/neothesia-core/src/config.rs @@ -37,6 +37,7 @@ pub struct Config { pub soundfont_path: Option, pub last_opened_song: Option, + pub song_directory: Option, #[serde(default = "default_piano_range")] pub piano_range: (u8, u8), @@ -78,6 +79,7 @@ impl Config { input: None, soundfont_path: None, last_opened_song: None, + song_directory: None, piano_range: default_piano_range(), }) } diff --git a/neothesia-core/src/gamesave.rs b/neothesia-core/src/gamesave.rs new file mode 100644 index 00000000..609aaff7 --- /dev/null +++ b/neothesia-core/src/gamesave.rs @@ -0,0 +1,53 @@ +use serde::{Deserialize, Serialize}; +use std::time::SystemTime; + +#[derive(Serialize, Deserialize, Debug)] +pub struct SavedStats { + pub songs: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SongStats { + pub song_name: String, + pub correct_note_times: u32, + pub wrong_note_times: u32, + pub notes_missed: u32, + pub notes_hit: u32, + pub wrong_notes: u32, + pub date: SystemTime, +} + +impl SavedStats { + pub fn load() -> Option { + if let Some(path) = crate::utils::resources::gamestats_ron() { + if let Ok(file) = std::fs::read_to_string(&path) { + match ron::from_str(&file) { + Ok(stats) => Some(stats), + Err(err) => { + log::error!("Error loading game stats: {:#?}", err); + None + } + } + } else { + None + } + } else { + None + } + } + + pub fn save(&self) { + if let Ok(s) = ron::ser::to_string_pretty(self, Default::default()) { + if let Some(path) = crate::utils::resources::gamestats_ron() { + std::fs::create_dir_all(path.parent().unwrap()).ok(); + std::fs::write(path, s).ok(); + } + } + } +} + +impl Default for SavedStats { + fn default() -> Self { + SavedStats { songs: Vec::new() } + } +} diff --git a/neothesia-core/src/lib.rs b/neothesia-core/src/lib.rs index d03d9599..2709ba4a 100644 --- a/neothesia-core/src/lib.rs +++ b/neothesia-core/src/lib.rs @@ -3,5 +3,6 @@ pub use wgpu_jumpstart::{Color, Gpu, TransformUniform, Uniform}; pub mod config; +pub mod gamesave; pub mod render; pub mod utils; diff --git a/neothesia-core/src/utils/resources.rs b/neothesia-core/src/utils/resources.rs index e4170bf4..bef4323c 100644 --- a/neothesia-core/src/utils/resources.rs +++ b/neothesia-core/src/utils/resources.rs @@ -61,6 +61,17 @@ pub fn settings_ron() -> Option { return bundled_resource_path("settings", "ron").map(PathBuf::from); } +pub fn gamestats_ron() -> Option { + #[cfg(all(target_family = "unix", not(target_os = "macos")))] + return xdg_config().map(|p| p.join("gamestats.ron")); + + #[cfg(target_os = "windows")] + return Some(PathBuf::from("./gamestats.ron")); + + #[cfg(target_os = "macos")] + return bundled_resource_path("gamestats", "ron").map(PathBuf::from); +} + #[cfg(target_os = "macos")] fn bundled_resource_path(name: &str, extension: &str) -> Option { use objc::runtime::{Class, Object}; diff --git a/neothesia-iced-widgets/Cargo.toml b/neothesia-iced-widgets/Cargo.toml index b6064c5f..835f5890 100644 --- a/neothesia-iced-widgets/Cargo.toml +++ b/neothesia-iced-widgets/Cargo.toml @@ -10,4 +10,5 @@ iced_core.workspace = true iced_wgpu.workspace = true iced_widget.workspace = true + piano-math = { workspace = true } diff --git a/neothesia-iced-widgets/src/lib.rs b/neothesia-iced-widgets/src/lib.rs index ae80fff5..23352016 100644 --- a/neothesia-iced-widgets/src/lib.rs +++ b/neothesia-iced-widgets/src/lib.rs @@ -4,6 +4,7 @@ pub mod piano_range; pub mod preferences_group; pub mod scroll_listener; pub mod segment_button; +pub mod stats_container; pub mod track_card; pub mod wrap; @@ -13,6 +14,7 @@ pub use piano_range::PianoRange; pub use preferences_group::{ActionRow, PreferencesGroup}; pub use scroll_listener::ScrollListener; pub use segment_button::SegmentButton; +pub use stats_container::StatsContainer; pub use track_card::TrackCard; pub use wrap::Wrap; diff --git a/neothesia-iced-widgets/src/stats_container/img/first_place.png b/neothesia-iced-widgets/src/stats_container/img/first_place.png new file mode 100755 index 0000000000000000000000000000000000000000..179661b48ec9c79173a68bb4a6930e9659845dd7 GIT binary patch literal 1244 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 TX-zje00000NkvXXu0mjfk6)Y= literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/stats_container/img/trophy_placeholder.png b/neothesia-iced-widgets/src/stats_container/img/trophy_placeholder.png new file mode 100755 index 0000000000000000000000000000000000000000..b957a6d61d80f5719168c179c86ee296b5a7b2f5 GIT binary patch literal 669 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%C&rs6b?Si}&H|6fVg?4j zBOuH;Rhv&5D0nZxC&U#tLPpdj#n-(N)EszZq2a_PSmvsY>gs1^32C^X} zSV4`CO*2@ezBKYIh+$b9?J*C+@Udws`7$V|f zSqroXVmm|xiCybw3vx41#Lu=BCR^`i-FTs6Q47$AUL`?(!3^9}wr!iv+) z=h+KBI|n|mAHL>iMbkNf0nFs-;uumf=k1mA-HeGc$3MPT@1D`pqT zPk9&Rww*`}FDwk2wBn>!UG9ywTQ|2>?z``}JN*31mtXfRe{NkYaiN#{IPZav3#_l+ zSsrY4KQH9+z9Sbl?rQ)3A?wBM?uEq*XVq)Bz1x{}kl*mjnHjCuoL2bmY@P1(!gz

6#BccRc<6dCtPV1B*@0J^jkt@zr1RO=4dFFpL>IUHx3vIVCg! E06S?SQ~&?~ literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/stats_container/mod.rs b/neothesia-iced-widgets/src/stats_container/mod.rs new file mode 100644 index 00000000..8ab4f941 --- /dev/null +++ b/neothesia-iced-widgets/src/stats_container/mod.rs @@ -0,0 +1,181 @@ +use super::Element; +use iced_core::{image::Handle as ImageHandle, Alignment}; + +mod theme; + +pub struct StatsContainer<'a, MSG> { + image: Option, + date: String, + place: String, + score: String, + notes_hits: String, + notes_missed: String, + wrong_notes: String, + correct_notes_duration: String, + body: Option>, + + header: bool, +} + +impl<'a, MSG: 'a + Clone> Default for StatsContainer<'a, MSG> { + fn default() -> Self { + Self::new() + } +} + +impl<'a, MSG: 'a + Clone> StatsContainer<'a, MSG> { + pub fn new() -> Self { + Self { + image: None, + date: String::new(), + place: String::new(), + score: String::new(), + notes_hits: String::new(), + notes_missed: String::new(), + wrong_notes: String::new(), + correct_notes_duration: String::new(), + body: None, + + header: false, + } + } + + pub fn image(mut self, image: u32) -> Self { + self.image = match image { + 0 => Some(ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/stats_container/img/trophy_placeholder.png" + )) + .to_vec(), + )), + 1 => Some(ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/stats_container/img/first_place.png" + )) + .to_vec(), + )), + 2 => Some(ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/stats_container/img/second_place.png" + )) + .to_vec(), + )), + 3 => Some(ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/stats_container/img/third_place.png" + )) + .to_vec(), + )), + _ => None, + }; + self + } + + pub fn date(mut self, date: impl ToString) -> Self { + self.date = date.to_string(); + self + } + + pub fn place(mut self, place: impl ToString) -> Self { + self.place = place.to_string(); + self + } + + pub fn score(mut self, score: impl ToString) -> Self { + self.score = score.to_string(); + self + } + + pub fn notes_hits(mut self, hits: impl ToString) -> Self { + self.notes_hits = hits.to_string(); + self + } + + pub fn notes_missed(mut self, missed: impl ToString) -> Self { + self.notes_missed = missed.to_string(); + self + } + + pub fn wrong_notes(mut self, wrong: impl ToString) -> Self { + self.wrong_notes = wrong.to_string(); + self + } + + pub fn correct_notes_duration(mut self, duration: impl ToString) -> Self { + self.correct_notes_duration = duration.to_string(); + self + } + + pub fn body(mut self, body: impl Into>) -> Self { + self.body = Some(body.into()); + self + } + pub fn header(mut self, header: bool) -> Self { + self.header = header; + self + } +} + +impl<'a, M: Clone + 'a> From> for Vec> { + fn from(card: StatsContainer<'a, M>) -> Self { + let columns = vec![ + (card.place, 40), + (card.date, 80), + (card.score, 40), + (card.notes_hits, 30), + (card.notes_missed, 45), + (card.wrong_notes, 60), + (card.correct_notes_duration, 55), + ]; + + let header_row = columns + .iter() + .map(|(text, width)| { + let container = + iced_widget::container(iced_widget::text(text.clone()).size(12)).width(*width); + + // Set background color + + container.into() + }) + .collect::>(); + + let header = iced_widget::row(header_row) + .spacing(3) + .align_items(Alignment::Start); + + let image_container = if let Some(image) = card.image { + iced_widget::container(iced_widget::image(image).width(40)).into() + } else { + iced_widget::container(iced_widget::text("")) + .width(0) + .into() + }; + + let text_container = + iced_widget::container(iced_widget::column(vec![header.into()]).spacing(6)); + + let centered_container = iced_widget::container( + iced_widget::row(vec![image_container, text_container.padding(10).into()]) + .align_items(Alignment::Center), + ); + + let mut children = vec![]; + + if card.header { + let centered_with_style = iced_widget::container(centered_container) + .padding(10) + .style(theme::card()) + .into(); + children.push(centered_with_style); + } else { + children.push(centered_container.padding(10).into()); + } + + children + } +} diff --git a/neothesia-iced-widgets/src/stats_container/theme.rs b/neothesia-iced-widgets/src/stats_container/theme.rs new file mode 100644 index 00000000..efcfeee8 --- /dev/null +++ b/neothesia-iced-widgets/src/stats_container/theme.rs @@ -0,0 +1,25 @@ +use iced_core::border::{Border, Radius}; + +pub fn card() -> iced_style::theme::Container { + iced_style::theme::Container::Custom(Box::new(ContainerStyle)) +} + +struct ContainerStyle; + +impl iced_style::container::StyleSheet for ContainerStyle { + type Style = iced_style::Theme; + + fn appearance(&self, _style: &Self::Style) -> iced_style::container::Appearance { + iced_style::container::Appearance { + background: Some(iced_core::Background::from(iced_core::Color::from_rgba8( + 44, 59, 102, 1.0, + ))), + border: Border { + radius: Radius::from(0), + + ..Default::default() + }, + ..Default::default() + } + } +} diff --git a/neothesia-iced-widgets/src/track_card/img/brasses.png b/neothesia-iced-widgets/src/track_card/img/brasses.png new file mode 100755 index 0000000000000000000000000000000000000000..f00208b6d8e38f0ceb1bcfae11fedc499f22ebbd GIT binary patch literal 12598 zcmd6Ni9eLx8~2&9MUkXrpUOztvNKsGvW$HRm9>au3xl#wo29Zew(KKgJRy75EJYz} zBTM!t!VoH3_V?)dz3<=f`h5Cy&wcLmJ=eL;wO=RF*if65g@*+Iz>3qkWC{QhJ|e*Z zM)=>#-7lN)Kju3+SA76rYuf*ZXz~2V5x(TcYhJ;dc{<_!uY2DF{{H?FE*`Ev4%hG8 zl<@R+PF+;y0RRPXmo8quo3=1|FOAQdTn8UfVj$m`eA*H z)%zm5@%vK~Ve@_CQCsTgA4J$%-$~ND)O@1i#DfE+8o(hog8jkC2S=_V+w}c|Lqmn` zJ5rPJmX@op@^;_aN!~R$H#(!-E3_ixn`eZBIr#72)U*4D} zHB`I8scE^d-qv@-?ZdC3Pjq{m5d-?0xq5m+;<58yNylr-vFM!~>pnaAy|A4N9`XPy zZw!VyzOTJ+DSwmjCOg?L-Zi|nJiFR2zP#yR`yp%dCEH8 zXyAB+UvEc_cvrK@m{N7(KDML%X_>>fX=Z}Ihrie0(4*xYzQcZI3mZ)fYl1*0rF zB(T*&+#(vSnT8tFzF0Z_dONovk6+JJA~fE}r1G^Gz0>AUoZ!#L#KL%4_vY!%Y=a6B zJQmD4auQa5`UGdsg$-#?RlOJFjC;p~-FYyUZ0=`hd`VsRe!J`h|6u zIp3Dxez(p-ryhT>JxRaXffdV*tuI@2wthLQF+Z6O)jHJxPtNQJ$(CtRt= zo+i!KH)JkoKW3u?n$#l<*wB8oaC*MsM#$5dDB&Ha&sRexk2-G&WHkZo5zbxK&uTME ziM040rPzp_QQzU0>sv;d%DviQaQZ!qS>!}q-Kl{j^%?9-ead7$TIJ7r*|uBe?DwAg z02RYx0~~pZj`8-8?1Mfy>2pa0BrIOJo4Ed{3r;rsfkZ8EV}R+pAbKGEY1fL;9eDtF zELV^}^Lh|H$D2l0zBe@JDo83e+3{iyfvJln2MPJ2c>40^uHB}%b=BPvHDNp_Xsx-y z1@L@vwkK(&E!``g9qF^9S<3)xVFHXV3HLI|^Jjg1YP9}ZJsd$0dkILbYXTy)eukxW z8+9fGp&$#8W^Jv!M}M!&Y?FE}0+gNzn59qELU-QXK9qR^a{xFpFo5)TeG3#jG38z( zR(=LhN#0)xDU$70x;%n zIeLOBO)&@f>47>4kmAgBsoxJ8t*h+Q;g=0az3wNHLv||Hx7M;A0_+7709@w1%^Ph0 zoE%3%&|6$A0EMHB&1wcK;GqJ-pFc|{H}0YchES9G@$beBmu)n{0ioOk5ad`zQ$u!J zajMF2rp{3YaAo+!FgEirKN3(cA;6qh@E_0IjgTw{fW0OHu)#URmC+67t>S%RSvi6I zsI47sAbcN9))){@zF0|SaQ@?}F#`x>h@Ry>Ar~x;KLB)iAhKZZ1p$@5bvAxFK!n&l z6X;+xo)PG9Fo0Vf^)VUK;o)oufXjj&#+w$Z?hG*?=EsF!t*`1sXW2n4Jqzf0MpQk5 zK?0%sNFY07ymViFPK-*+k^$KK{pXIAMM$EkIwZmZ0ti=^d*#@*gmodnYZ3rb zFXq4Wa0AjYPJm)e@(Xk%#;~N*fp0J2P_?WSBq-u35;Xf;&jP^C#Q-8azdYy-(ueD_ zGeJTxcKTkLJ@nsm=gBNOfaT)^B)P3Fm0krl$h8zr1i03#5`>*phfHyTOgMfOH*)F( zb`g?dp*aKv6Wlruff8IQ|1wevkhmd&Z__8bAvwsZTZ{}qN1d#qt_`Pi)`3e|bR?Oo zm5=*0bAONklw5Uftn+!7r2qSZIs(-|N(2D!oI!?0-zYMdMhjMZaJ$4TD7EJ#AelUt z0PtR6S^jcVB}htR>by|IA|=n*-{Pa56MuaC6-a`L$gSGCqBJBf?+^=GtK z6^=*n47xWCY~DyW(<#iC-z>GM+clXFT$|jrsAdyXwj2F1uY%f`aG*TV%Pmk{;~7s> zxT{YbxTo^Ai;hXq)zR(V@J#B_>iW91L-Un$XnD)NoY449-x))-k~5Rf7(mo)6_U^| zo-)Pj=UI@$Nq974?C=Y0;Rla0dIkfbY6UIbpKsx7IEabXw<-=KVK7!zq_SsFlujRnLWb;A7FoeWy; zQ39NF44^fpu<&|-8I*-5Q2wSOsw-I15m+gBvdU88%>4g7ZvXs8Zy6rG@gXQ-XY^}= zJJ4&FX8Hb`@|fn6bsC67>q6<`nb`c7SK^JUdJ8b-OGALtrQcLxj0%*25AV4Fsx~8b zey?uVGWyR%yYlo9wUAPCGo54?pECjL z)Kc3%8?(!!)<%ndk*trp=sAy6p3v+)Zt$D6R-vETH{RTTS8bUw=G8BS)^{yD+*Shi zsslDfTNw-WYhov!v@aAo;PGwv8oe#OIiiric${pz4cCHHXCZ4Uhsg0R0C3X2;nA@Q zp=q;LBWBd^!u(fqGg*`HkCLOSd|vM51y&i3te&YTUpRRm`Rx=Ih5I=E%4x)>z*DB6 zz)Fa}YK$p0+O}R_VfQ}oDMaK%s0EgocJqzasMKfe8W#%LgjKDre7G1fdS`2RCxM2h z!$8LCSSaBM%2i8u$1AM+4ZNcwf31v}Y7Te_gIlZ&0Bbes|JKv$wMzv#eKPuAQ$c4a z9>xHack;Jv`n@^kxqAV9-nz(q<$^9?KfM3_h*yE9rO6G?-Taj&9H3bp0b*-vg*RQ# zQN9vwlivS~hqi$Q5H63(eYP_zB(F_3=oWp7|EsCsRrQSGc)fLhltf(xYp)5CAPkox zf6JH*3VbSSMd2S-6i0(w>~NWHi%MOUN%M!@LzeAw2HJld1qJ)7zg*mu94{5Jai#hp z99Dc+%Z$KzX!r@uBmNIOFUxoSbgEc4I1Kl25&{be=h1H90v~miq|_IFPh$pi&_3!k zr%i6t#~B_<&yF7Zr#TtepNI1kM?=#ZET|u{d=6z5m0HW3MKrcU`F>#iyN6png6yd? zq==7RwO0aH_Iai^&9}s)hdGCj)~fn4k6vR2LQvpE;>7S_e!tsniSzG!lv4i9FJxAH z@Ezdg;TXx#3Rx9eADy@o28X8SL=QVFf%GUOK*=Yma$q#v3deZb5wrGC>@TL5)8E+( z-LNIDK^oDbx&RL7{BK|aU3UQ=cBz<;zy^(FPx;r$x2I_7Sw2Exa3K`j2*tf5eJ!rs ze3mcLd$qsW8(^U2#rBF(ce7;3?{ex*6(AbaE@0pz>V&xRs`6YSopI3q@2k}tMv04m zk{IEOyZbMy_pZB3x;*SrqE4G;mhcgf(5T&dGO)7Q!#(tmf8$j)tQ7R0vLDC;VO>2= zb#z_c;7K?Vkj{Dx$>PJnX2H|%fKv~R2P7T+fX=4e%?|U1HO6&@XBNRGaj7)sBoC>9 zgbQ}JjnJ8;a??X(A9-clraT$M(Y5sJM&WF9<#{rDJlW`{!W&_uysosl)Um=}sxzzt zW;+TxMazx*`d2$v|28?pbD<=uW~EO-Ial(lZ2oH%(-Z6bOJ?X`x7`oCcsMH4CXW0|Ioh%vp{#=R9sT42;W02PR zrcHx!X8s#;dKyfv1XXhpM5_Wk%)?9fesT&5Vjc;#tpv>;;J(O=EriZ0?Wc|)bNWT1 z?(^eeU9l(OD$rN8GRyE+-FeA0eqZv*%0LgdG^P72qV*(15p2pF))@|CD=8=lH{Uz8 zX{g2g*U|C4(&2sFRXo%E<7)MEc-Qlb5Qqf=JvTLYs_q;sl&})sb3{6?yB)sYx2p$x zH7@KlXB^_!AWm@-POfOe_W-_+$qZvF);&voLzFJNaGlWv8G8>3k>GLMrq(Qb{>t|I z-G2*t)n{52b%8V#M91+`A}u{T#J>A6TPb7j&8*W?01c9%l$E-hwBZ}O)QYV%n79k_ z?UMAqg(=Q!Gh>C}rp2UH#9T`CvP=I=OX6zv%VtJb7kZSu-@#1^crZPqcwLw{ITNT) z4IIe$e)CPz?i+bg+Qxn2@n_Y|87FQ(D|it|jNzLdI8C&zvAWJQ!lt+uuKc?8|^qrv_hI8l>l+N@#1!kHDATb|+`n z+te;~azZ2yUD|{(iKzy2L=*?%3sf?4-nw+^Ts%Qh z1fg>bLdVrHY?q z*=;)}5A(i@d(`i`8c~TFEVA3(~3IJ|+`RY$j^g{Oix;Eety0XIF}#OQ1*x z+fird2u`^sNIyF-VFE|bTid1nCAbXKjK%=p!vh28I;ZcF+U8979hIZOm#E7>LXr)R zwIjS%@~j4S62Ajk7%bT9_!zDPPhsx${F~uj>2X5|b-{X$_oFvR!6HDhVOh()98Q`Q zv7pN{hUY}jkLsgW*;?5X>3a4JyYJBNzD)vIf%R9c37rj1oT=&xTf}{c3wcf|+=^N5 z99Prmw`c}klVpHt3vM=6!z z!;QJ9b8vJNo>Kqs8UL+*>GZy-UM*I<%Nl;%KKIB$YYX^9e`2HvbcWviPU6n&~`QGcKrU zG3w3b-QQAnJBYCfDV*w`#=Mq4J%0lh$NF$rIsUh6Vo|^H64ey`i*%a#vyUB4n;4H< z84D<~868;831!7p3~@=Qkn-5JV_eoQm%8L!i2mg>>N}Qlv}k8M|M`;UwXJUL)8lsE zmS4O6aGK7SStB|4AHFR6Z!7m2K0WuPhB4@oWx?t$*KI%6tI?+J)hUvm`tL-F+XTi> zjrx?v%;wEW;hN&afM|pMYx)ttXPK^r%OXG{#%AUOn$%Q64;*8vzsyhv!u)AjOyiTD zE-mDQ6vHH0<(z*5FMlqOO{80UJ3>+1mlpH9ls0ed4AkbY6;TPY^O8%y=z7x}cfYE3 zSUXdc!pQ;&reX*;UOpx?=^->*KX@rbiO`AQ-Mn()E4$C46XO3I+j1@8)N7PHi;!A1 zXB0ueiUgQyI-ZcH8rMG|KzryCRd?Jh#tc~+#?f;h#s-EjXn$&j?^#kOcQ;h(Gxh6m zF&D`3dIYGM#z@SeeGA+vPczz$!sLAzUoAq%6U633&5#(FqqN2mD-67=whVtpIbtwv zQmN|9t*3Oc;V^{0$Ki61*pxudM!OTIUKm)JAU$*)h9^`)UCgTP8;b>h&vPnqzf%IY zz*q7_0O$Rdh*u|0zOldjD!!}YooD@f3eOh3Y`2^rsk!2vCX}Y%4)5k0oR^6_Ze5YP zw{c8Da<<5Tmz>@75i*c(30q1>jW0vL0E2B*+pik(QR{POl$?-S3A(fq%{xV+Zh3G& z&lV)TxZa(D+}${zTV5hz=#8!HNZS<@d-I)82leUccLEX)UY!XbTTqAnb}48-#Kg{- zdok7yL>@^76_Y2KZ0B?7W!o*qn10d-NEn83Pg9T0^$R%Edmbe6RZa!C5+`%WxlU&j z2%_#!L=Xl(uZrHLaTs%su$?fN^lQ}UQn05y&S%p!Il7FKw(K+5i?FV|huc%w4D?$c zI$iFu7#WhJ7u@;QPkfB+Zj@xoTbo6?n?^Gh??Z!XGevvvJ)E{uv3TyuG}1FT|6<8Q z@Z;-8%h5;z#RT-L*a>wG(`pmHo6T>wNAAucT(X4Pafn#`!vW-9f%;`1d!Jk!$-@SAf;X0lAwaXOc77G7iwNa7Kh-xXjGgCf*S@B7(&uP-_^ZX zi$ub_r>;XLA>Zv>B}ep4wJ(=hc3!{3n~V%w3@~GDhCuwkj;) z>ydzEj8Ea}1_%auCa_9T=+>Xb?%*GfCbK^?#0$j0L zAb)PX%uMm<`H&ieBhJWgv%Df@SB*{K#*Vlbqzjp=x3pe})3Rj5Yw)1$NB)x0j$nog z&)_ImcM>1=l0@%Fy~0bPFNadX8Ji#ia4+c{p;^7=ltqUM{a>bSy3yVew90h%VT;hl z1YN$sq{iRUM(jpL{L1PZ=X+OIs10*Yuaf5@ZPZ>ME-1jg(&=ET{3y1KMw zweVESwzj6ona-gl!^m}S{q}zN&mUUP^iqPqYFsujudCNedP_uYz-FdSxuk!)GB;~PwV^F!H( z7P`-Dic2qyehGRgfJOYHmI*ygS@dt8PG12A()|)kH7(|d$7q1cx8BmCb{OT1XZ&!M-F#HNv??xC zB9U?`DL{AUY$8}=zLk;hse~q-g{GTHfAgb8?jKj)05>wfX*6AqHPQ(Rme;Ddf-W{2 zo{TD9yUp7Dr`x>FRnV9Od`;6oK zenKl~)fM=-!e;!Tej4HcNqc8==SNfA_?d}DZut*s!N?o4yiRVs$}s(oJ@a`}a?uBh z6e_#jre>GYL{vL^r?F4o{BKw@Ry418)L8JZ-%Bi5I%!RR;&RNnvl+}2jOx(Pd%ke( zFIt<>-;at=YKhN6EMkh5F2W@{WNR+}tB<9;_!ywzjAVqGy5W^zP&QIyG+;qCGap^6Um`qiC_+Nw#>Gi{eyqhmc##sfS7Kb7T3(t`_If^Hq(@ zwT|}bNadjZU(L7!F0tODa<#1zmlV(2NA3Gzl7MOY@OY1{sm8M_}w~(sAo3o zyQ^orxp2#Vn}tzV0~6O?_!I3G3nL%i=-b=1*n0VVpm1^iYvW+aOfP29PH-|~jXTvd zV*uayC*R#G{eXD#y?;V=C`EdImEga$c`;{(_16q3YolMzuXK6Tio54g_EPccVws5$ zED$n$6GKeByCpgwCM$6$?aph1W5bLsQWZlv$?1OAQP9M2WP_>ZTYB^F8(rP=s-Pt= z=_~B2IUfu4UhkWyh>n4gc+Nq(GuBP2Fyiv9cCuCKx^P2A9NHW9Mqh-HRFA^PH^Pu{UwF(`K%D%2V_TcBkTuOm* zaq$Efn9isUU^IOzOo%xk-}Z$UqyBfG%8M0y1dD0`i)F;D3uJ? zj|>3L$2b+b9DE`jTlE;l7|COH?(Apr)UthNa>)@EL>Pt6EO6LUTjB&N?^yf8BA_tb zC}&}mhBmg8Du!UPbGD0Hi6pm($D;LW6Xl1wi;4%Znv>urV*C#M@1u2GuCf@@WHF*>mALijdu2I9`*Sjj^~V$^bR;G*{Ubv<=w=6x>FIRjMA z6=ZbPm~bk-lzd;P#iML1@7UP3C3J3@>|TsOlG|o=O6`;gF1)i`@Eq03=F_B>lK-kD zzQ;>pNKJ#OjRl@Ku;^!m5^EN4uJEc$JfX?6*j1UjOFVu?#qXMR3b(mzhQgj49z56&doGpx zcL64rc+KU;$Y+T!$t^~W2b}`OFL;!$^T`ZsYJ|6)+Mkre;SBR;2>nap+Un2ouiBk> z0=WUL5^`{HMJMp>r0{&XcvLE^?6MHhpg{XJ8cSr$bZH39qS&C*CC^S74eL!|7VfLv z>h>SI;X^mw%J7#IZct!nRGnzctT?R|xZ8TwuMnpqy`x3UmFmW9x94>CGp=m)<9)Ah%za*ERJiqSK)s(j%;)fRoV9r(B8`s3kI)|+Oy z8bkEX_JYDt8vRQ@SPL-*624bw*;`}e696t?Uf)W{C6D|{=Ho`|ZQNE$d69MYWh$F@ zofftDqEVohs66jAH%hp5K&$n-=CM)yikROoJyx@Ge47Ucy~>f!sJp)O7ji8a4n z98zw6+p1F0zVNqb>=E$&{rcu{_sqd^pW&HHi`BGlC}w=nHy3}uxiHYRv6wPtBV1RV z?(_0Q2gH8{gPA`08@*q%UaVv;q-A|ux#~He{Sc_!nng=2G zQ*HKv(jG)<2e}*SsonE6<>$2JZ>I?nGmjrul^AMg1C&5EC}@eGN(akzGEb-f*lPbn z6Z}=Ra(DL7fu~5qUF&uY?biFff~tK+Mh+AEf&O%guphXjFKoEyk6{7d0;FJjC^&T5P>P(IPW?$3NvXPL~pvIZ4)bBOD zIX1)-htu10G$F5`czpZzE$d@~_2zH*)wr^BoAw9piTa~K*$}h)5;clgfs+@&JjWS5 z?jjUdJr=nk<-%NxkZZ}wzWtnSYyQ=4aM2twUGhy}|9Vk z5h8#;21&S*CIh_8M|@LsG48v8!S~5D;-XJ4(qF~Q&wYv-(JH4)(YQ^`@b3C@^4>Hj z!4MKJCLtc#V8muIWJ|qD6tXK>GA^IPNBLJ-5NQtxsb=li)baV=h?j0A=UdVHNaPq1>E4apa7us(P)nZP#KnKo_p~t z>af*zV}eH@0``D7w`{+;;R!F#LCeMo${TaEVOP0FS@i=QY`ph(9OMUBu^-SvfNT5m z7c_PdhCo1B!NZ1dQ%@y|hO%Ff! zb}@usrv>p^S2CaQU9h4fv*ay;Qz=~ zDC61w4&3Qv;YT#~SO=i+jE=Cs(l*=Q_s!V})ti=np#b&MS8*Lf!lBI#rEYNszCO^V9f#}6eG96!DrACp z2#UkTmsC1!5Ah@SKmM(s^f)^9fS(-pViildYDkomuXc7MoFRI=A~i8&}v$E-XkqCzUiFifx_YisdYQX?EI zZvtXjQr&ihcSP{fiN%M3cUR7mpxmhKfpogBmk`+7%2YJ*Wseep?Yl)U8p77X^*SxM zhJtW1>N62h-BPF)>&?!0GVUR>e612JfO-=niKizWO~{c9>ms8wyWFaT{!z z1kLgp{OdqyO-lKc!iS;%{SXdtd)*H?8<}ZHz;C;~Ka|S#zt>X9sq=C0XH(Y zN2*s;Yhwa`KZzMc8bG$aIKnm8LUelEg_t7F*B&i=lM1gbgh0#utnIB(`bn3ovtqs_ zN7zf}1)Fp?FF`iJ9@m4RIrUUY+CjLF>KmIA^)f$bJyNlroPd5kPkhB3R~Zh`?&Ago zWSb-orqgXej^C00nrA|e6RKm!wDVLQVE?+T|GJM^Fy;>@tF`|v&iN=AR$31dP%npFmpZv>QD z^d)CG?B6?RjkmP1-;0HQ{@SdVH67vE9iMdX*3~t~S(FG=18L{^gYFfgbd~bod4OZn z22)2dca{d}E}TeyZTCtNS0j&SLls-e+Y}f*X1jmmB|ycwm1_1qiS~C1nH9sLjH+oi zwWIDM7~WTqin5B-+k3x>(bBZ>i^w~y;C-Y}`ke{Sg{7>Aq$-G6ZfR#98fo2fu37Uw zBnCUOIu2KyhbIinw6XVwtsMu>&R4QAa(ts?3fz4IFYd5$!eqF*xKq>bzV%F{uW2Ia z@u1YopD4t^{mDRf@mhuI2_~#$!*iB>QQm6fIUJZ$cLH;8zn@=yU3$F6E;r9+n8Ak? z41HM9e?xAnnmxP#m8@_OEpHsT!Zx|~P9*xKMBOTBd~gSnSq3pLSlPIBHw+eO=+~U? zi>zVNf9&QJi? zEA}c>Y{sxhM}}5tfW#mi95904GKJ=r0X#nM{X{(2PmdpcwtDrl1oF~*{mqr#-i4=7 z8lXdAC~bF~4_!ULKVP_XMjFM1IHmMFS+zA)t@Kf*m$A;l?%#*6kc+lR#ChMbFFXJ1 zTG-Ag4Dfs!Q0-sa&s=4eUpxGuO!MNE`-A>pA9!pdPr!v*H9nN%OQC=8?;*hAQv37= zQWEy>B%1{u$$(p?eg#V@mnl2?hePIAbFtVdZmhsC&{EZpQs!znJ=0vPPmm#aNYG|wys zKHhoV#g6rWN>WT+8!s96^M7SY5zOD+qQfM+CR+=RITx%=b_!}X!V6i^EnPo@vvs)i z0-FJ^C7N%zQ{QH6HX?;OInv8_|3f0pXr0`r=3;J{k zapgv#&-(705J%}QmMmit*icmVOY}6GADFp`!I?%Pdq!Zf!>k86A-q#{?X&iJs*_RQ zJ&{;=!-;h9py9IAb9{z%xE?1#t0h_`^T9E~1#v3Vdi|%}D>Emt*I~vetm2&_cy3_E zdMG$*oCLn`!)0#=BJOtB2##;*?g-{?eP)I^%pr+NZNuK@-q0=&CNP}^z8@jnkOj!_ zrsZ4oe+V=xS^O>fiz$ke>HK9~u#63mD%=sGWG$ikligH`v)Fz3%=N-CH z(Uflt;2y#|S5{l`XLC0ZF!E1%49kXzsfLO88gjY?e=aDm1KaO%o*qxce~{`euyE!f zorbAq{Dz~X%3EV5S559eMoD32faisg_%VX>$ZA~aO1es6akXz4BSrw;yUW%#{N2e| zgD=p8R@pW`+6-`<1SQrzb=mdf?m##cnF-(pox=JRUliU$zu>Tn(L6fL1e5P-? zpwzi*J@X3m!wX!F9S>xJmbsE#AK=1qn9GIFOr^yQ>(VzkbwgyEy_FU zIW3Cl7yl)p1o^X^+)yKHN!bz_ZFrlf1P?xx^_MtO2LUt2f8a$OX>TTXtEc7JxC=F| z+M+I2)moP*uRG;T3y)kg=dj=^0&h_Rz0%@%mlExO5#0dw=K`;BhX-m_2Nd=O6NR?j zkr7aa@Kx1EgB^G&2Ag_AWXGZA{GpCdqPyevg_c#96NUUWkGp&r+bBdNX9$YWU~9oS o4A%{>J#5m2@Phwe|GaiWt3zH#>6t$b-zO2LX?Uqn-TuM<0U6E>a{vGU literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/track_card/img/guitars.png b/neothesia-iced-widgets/src/track_card/img/guitars.png new file mode 100755 index 0000000000000000000000000000000000000000..e8aa924d7e6719a87c98d9b1868344cf6b745faa GIT binary patch literal 24088 zcmXtgby$?&^Y*h#cS=Yvt#n9-unG!@lz_4Vih^{v>?$1+f}(&RAs`?iNT-5;A|Z`* zNK4leyYJc0_xJwc1sCUe&Y3f3&dfdc%wzQJTRJq97bzhKqPd}qG=?BJ_!SP3lY$@n z{zE6=2Zg(?r56Ozwh{ipI^7EGz#rMYuUUATxIOmvv-Nxg`T6-tJaKjMdT8tZNW#t2 zK7CX5A_Vb5H;`9N{WCVE0{l&f&o#D>>SV_icqu3ZNSW>QT1l>HR*P(osL_u;clqZy zED_>#ZW};+@E=;dB$}!MGSC>zF2ntYDdZu1Rzjw^PNCrhpM9<=i*XhGO&aZ+olV1NK=1HU zIqiM45T6HmTJepwYUOl#vd=9Ay`M|Qo^)i9F|cbFN?=4@PnjEMy43s#=5UYEi-Ge! zQV;7&)y#xWh`MlVc*O6kkPo9`A;re)`bqxqG4Z^yk2hRcH>Mi6sAAX6SZ^>Fvq4e% zrp6UxS2&eO(onRoBwV8C9~6dhB6uUH7YDdObcdk0VGG;Q9 z?`@KQ^hnmKD3(9Qn;JsG>KEb-=RIltXhS7B9gTS|hqF=5ia|e$oMIW&pesbj%!yf! z_5Vz~g+iA6PcwXn!x^qIl0pc{n>Se|uJhV6%XwsC*yy@EpzHHp^U4*p!kA02V6kwk zPdA>@T)$O3&kRqp2kUgYPc|xZsiBeu+Oft_6c|-9&9t?85fO1{1nwzsb8me7S&Ytf znzx0I5%SJgNK^XXbn&HumrQ>Hl=oNZA24D(6tN6SF|-m82Z>#H*kN|QQtGZKam*uX zh}mRQ)bdrz0$R0DY;D{P*6yCu}(1JSV-#6vEsu31s}O}eGl1k615%{rL*U^A<3 zo?176f>?sFRRD@Eazf~>CALzMV_{bQ==>o~wu5FiQkRul0KnGq(g(46|H{V~XVo4EU)&Ou|4C z3d10NO1hm%b(VJaVOptm^@-nqERBAUM%8+gysoxWkOg1r{PQY!6dMb}h;3!QG`sO6 zZT%)i07uJea(Eq7@>;8LY*>QDvkz9GObS&9bbk5ZyErEK3SM(lv<1eUrk(Tw1-adL zmRgKD#rITFb;YnjUB)3OV`;0(I@d7f%CEzx%rpXr6kRg5OlUu`jNK1wo>7x*kZxU2 zS&^=u{*Yd_?G*u`!qUht|KS4bh_4v&QahI+kp6248S-`qzH zY3psFDKV6N?lGP7!@5u+;sMZa_^aGJnfs#`%U&n?Me+BoGkw4E%uul1`W~t}HB%&g zEW4gFh70J7C4M00S-tl;MDGW6-9gbM{nZ_!FgUB~l)!g2k%({t(M{vu{M>L;|Iu#5qpdkJ*pE`_#9qK|)2Pks=Q$OdX8XpCy@0 zyDNs3g0&>5Av-pm8;=_GoWw4)KE-fm*K_BHRL~?EI^8(2_7`Db4~Jp2e7DRlJc+(h zIsrT5qz@=s=Zm?&3lZZ=eAWz=r$tkq@mlbn+=C;ziPv3RrtQ6pc9}@k%%g-pUZOWN8|}2`IiQ<@15+e*d>sGE-LVq-QWpuxE;x!LZ9AkJiuA)(%6vN1qaR z>mGM&m51D9+&n`lKx4i_lKt>y_XbLz+ZkYRH?B zU?@#3E>|#0^j+pCItG$YcW&-zzL-3MCkW&-Nkjb}oU(WHN5g|TTOEe0=#z|)G`t}) ze!ugMOwF}Mz{Q0iof}w@)Ce6C_qw&aQC*yj{yN`$k3wU6XNu}sj1yqI9p^=MW|=52 zb&+QikONR4V$g?TR@62D|7qdXj(AZlpAQ@KV2H~vm@#!?@{maL7g1tn_R({Gc8?J8k-cbl5U+(T8f_vi=ntViaeZ^NRt|S@avVfTx|&1 zd!&yz(oP&mvbNhv_u62pw4Q~M4ou)qh!=mqe8F4kPSWuj0Xwy`n)6 z6h-|u7RLKi>E@lxj}umSI>v`)qgqIY1wD%Mi9HsBd&TwiGIT_mDfI<*X2xkNSeme7 zb|@Vjw#d9Le6@!>9Wfnu+ zZ67{6F;a}keC^{WJa6Bh-`5HzJ8KX`JbZQF?T5zu;WMV+gQZB*ktuIvAAVQh-PeF2 z48f+DKP|#2{!ItO3bhp0Gg5L9X@;Ge{U}m3@WNR_=0#wU2Oa6Xioy8o)PfBY6gdgd z|MMPEl!rJko-|q?oS@OKCofx%mc`R{i`KM66saMG6@oii%~`e;ZBHO#H~4;3T3xO-%a(wYt6v+kzeUsgR>hp7vWc(9zf;q zty4{@N9E3apj=ZRICGAH@nC6sjl1!OHLVr@40t)4&gyQloPjmb6*MA-wk@m_y+~Nj zhtFFz9bXzW%IW!yvubw5 z5>~Lg^z84g-)ei=;e&LA5`rVrkjT;-%aCf?MpBz{V3Sebv>wz9wbSg~f7f{3NAz=? z6U1DPUW%FUeh(*XP>*;wJf(a2mk2(7&G-Sk4#Zr$SK-HW@;FbOhyvGbi2S_yp{@SB z!7#;O<2FjS#1ms_Ifpb8Q(g^2IF|U5>tBMMN(Y&we?7z1$4blND9SiZC3t`s?-hj#YmBON*}% zJ*n5@(l?)|uo4(*!r@q2Tzuam4-R0fNJ4-`3VL%hM(IO07v_u%qc}WF&u|S=;l-V$ zvv+5~1qwbIv};%;PX>%PP&^$p!P8=dA22YG6zJ=DPA$E$p8Qy!=+F+?z;%8Uh1B<8 zl@qoF5tQSX47^bPEG(?bz-Sv}Bh_he`PLxnn3Y$j5LmCsP3PY(ySrqp`coy~fp3rv zFK{o4s5TX-f?%7>s72UECv)KE&pxi*%pqZgU2He1e~?x>M^uhwVtA{$NNymJF8k2( zGhvhn16%rKu|tFUc?9JZ6Q+;(pyjZo_*kOF!iVoS2F8m#>Jw=p(Q2jz&H!jvn%6SY zKj_wKjFTBF<0>1ZB?UYVH{Uh_Y9O5M16|cTE4c!1tp0E~Qic@6+w;~E=cTJkE0HIF zFy^B*Zj=FoHKweLAK9SiQU%`M@i2d+4;PrYmsAwzi~qIT049!RgWzD6IwE8Bl6qPM z0w8dhsLyG~0GA+r3Oa3nNUFgcoQx z1Q-9Tc1^h?4%Qm0B>NiAtfiVykb&||Si9e{MCPu-aJa<fl1VJ>v{kIlV|RrqK3=AzO(85wOb4mgVh`f zB4SvkFupyL*OI4AP*Ja>AkH?Ag8l58$>!4W?l(a$W?o()|$cYbu z&|CSPS3CLHe>bv-ilX2RB^3X1*Qh??6#)-`U5kCVw&pp|Sn&}g3yc!dmE_y0H7Ruc z@{MG`iy@RP>-*d9#lQSe2VPEnLk`7T>M{LO^JfBR6_{vO1?hU)VV^~Ss+15MGi{4z zX{{?-=S3ijnHEm-3)DW;$GAtGK2QAKU>3Oc|y|C z8QMr>#OhGkmGPamJVR5~2d@ihAOh}vY!!Sa43QG9QxwAZQ+{2CG7HOSu|zwykrK&m zkkvd+NU(+oqEg;}RyuKCT-1{DRm0NtM-ZE!Cl5>OcY-)MQGRnGNh;<(43DGgMWN2P zT_^8nqYUBriKr-DijNe(+#8i2MXzbaF`F6ejtX9AlQ+P#Y1R{VC{n~Z;vMIgV(`%z z6=jt3n6lMlZ_V3aaE3TtgMoov(qQ!Vl89v*h+Vlz1E`-6JJ?DICLVJ)*SiOow}yyg zykG*w5A1SyN6Y-D0BZUQ@6BQp){heWrVKm~r-Ee9=(}o3Xx{|5RA5L#2BW?1DF#Jm zC|wamAZ6=ZV%p}H7V`i0n5ABy-@?3lN`&-=`in1b64`xTQwCBl>9g~BqKoRIZX-9C zTh9eAcTgIX!s*NES%4%r)Y9T_#8-&&04L7IpakEpyf-6m>m1!~=LM za1?qlt4{<)<=m&R@<6ZdrkkeDl|{XQyQh?_6*#GxVY-Y6GbZW4X>R>S9sdVMQ|I-N zanQ<@eD6?apR+RDzRbYD06D+~QUv3lYh_m{E8$NEnaiL`e%dT^aLc3d_5yQx_FB%W>Ib{w`28u z-edX$5#itOKSM8y5;$&G<-=5p)3ew0iCB_Llu!vU5hGOBXEAyB?3=o?2VC<{36}d& z>hPPD74{Qf|Cd>`d`;CpCl~ve(J=MYcPSfo#?)Sv>USBnUKv;`$OOuqXsii0fd!G{ zuF{~$YCa{+{H=B7C)cN2&UZ(nehwdu?SAL0&7dZVG280XRbMDWs}<<@@L|I9A@ASY zCLq2VQ7bnnc5W}xK{r17W=Pj*^uC$o;c~g8 zA}W}e41BxzrCGq09!nzL{~+9)cOEv&)qn3Ozp^L#(|UUOYUOp)Pfs-cQZEN96tEPG zsQsdhB(a=VI-QrE2_|h-By2Q%&~nhz{lKqn;tbZxU6zdwk-46k9!-(DJeOkoqtoH?6t9Zcjhd=q zC@xNRsc5~m-I9PuCZok--{1!3>ZE!@SCP!z_6Ak=_sB4{{xog9n~_wHsduq#i12n& zzD!e8*g(hno4Wa%Fnx1NA_gPHcS`bP=IFk_o|#W|%~XATs03}FcSU;9j#{(Nm1KWP z8d-)`K(lYEhf1~8bJoB`nY$AB;7Td3bf@_I#kVD%$6Bg)j4Le0@2Wn6wZ3v{;cC@2 zI}%1v7UWQj*KS6(Y5iI3)OW^R>dIlLp1fx^h5FGFP4N2%v=c&5L1C>1K?ZOhrC8i* zz8oHvez)B3-enmXCij!^bDK(%kc9lucm5%pq;gz#d*(LF*{?_D`WpQL%xm3B?D%=j z3l90eE*T=FTT7Ou=i&NsHQ7uXzb)WUrXuNB{$J=is;gY zZ%+ryNukacdX;%8ws@W!NakDN3zhCubiXXOg$2u(&YQTc4fS`_DkrRF!m)e73V5Km z^6^h~4$^J(+711`4}i(A7cXM;pn~{y-I7o1t9)M{TR$ zZ$xg3sKkIwWha3wxa?4}IU5r6qv?F1!9fzldE`hH8b_SksFI;TJu$QPbTs4*1z!k# z=_vz4_`Tm@&Q|zb+kAO6RNncdi{sDfQDM?Th16V(YC_h5-&o6W1YEx%8-miLBIC;d`d1!Kq|T|f^GT#l zTFXSg?8$t7RszyWRU7kTV8KVtd2rG8?WD(l9=eyy2I9>Tky~pNOF0{Bw8c+Wn)SuN7~o z-+k1sva{em*|m>;$o0R(O$D|ueR`i@8=h7yH#aYG4{Zj`(XSjfUun=>HN5^{Z2Y{j z*{w~7%;<3FI{(eQX|4fp^JlpwwZp&C->Ac9J$=t1g1-!p5wc4gID4n2oVM1$`)GS~ z+ph}$+3HsGHNzpBz2#}0tXLttT)gPC4wZ<&Q=gtI6C3Gol;gb!=uY6fuvpmaHrP?t zi!8Yuyy%avUcD=effA|hXzQuy@Ps?I!!3ui$#h5A)~?2_qjZmwc~Gf^cLywX2W*t&V)2 z{e5Yp&{2K0N`7nWFUvPuKD6u7umKemUOnjqJN846Fc=Y2$rBH4xpWrbrDc?W)M;csiLw4w_6!&!E-e>0<;?w9S4Yo(TWxYNrrus7L^Z8t4 zB}5w1>wl2QI}5ZhK|ihlWnOxphCfXb#~jK+ZR^YF9N@CB!fO{tOn_fyP$@RV-Pwu; z+SnO!HEpb#*y>C4uu8+3Ko=fcO{6ejPWA4@g|`#SmKq@K%)Z7G?{^fwmmJbsXOq|!?E@t`?kC2cWk2CAn;97h#nQQM zV>xjjYTm`{q#lMSzweQdats#oby1GX4@If3^MBY#b9F=A$DVoeOFBA0|4|5xObgbe zt>QTV9$!dhwwe4+bi1

jGR|^jTWfi;zeN4SazOZt_5}wqa^HD5zeLQrPb6jfanR+~W%9MoUwWrL=u&{OVsL2D0Kb z9j|9}9wm~H?{B5Q_I;O>Dkle#KilF6Py^YChXT6BJsgwUgEqHO*&cRv{@P6!Lz|86lIrG<+q*4krwhHgE4Qwsxya!m4pd0~1=|pQ5q|arrv;f$hFm;(ENt61(i*W9 zRPVDf?#Tvx*tf50I5i{95k5>v_vNfCo;4pWTBt?hBbx+q2pN;_1;AnmjxBAmIFoPJ zV6D}I$U9J~^aWYttp6h4!6Km;2a@l(u0fA1hpApcU#3T|T1n9s0C+#Z%S+*%WT{pVEXc znJZ|Hs%0Hr7A)UM24L{xQGL@^bPs+k3rvy0cdmoNnVOlsO%2U!qFR;KY-%}|A*bFx zzlA`o%hqGv?vF;9^OQZS)H%Z5Pu0uW!7TGXeO6Y(v-#q5Hp?r2&)n0QK7jw)=Kk$c z`akNB*7U`JWx$?jJ=!}Owbxtk_wM)7rH9w<-qR+)>9)-qEJF0gbhOIQWRTgliA_}eZHdt~wY!oU-R_R+h4|EHa(5@lcU9pl6)sAm#-?%ogM zmHzF+g~_wg0ABopic{JSu3Lq=Ze+>lg-DPizg6%1g2zpc%45-J)pG90HPuKc-N5FT z-R3_YB4ck`{Pl7ku)Z#zE9GG&F!ai`cT;?kkZiIc2q9 z{3kR!^_E9TcC#_*wR)A-tiP6{qD(y%(2(vwrUc6)Rz4NU@pbz~1F~{#a`>3lRB18% z{Pye%tDoycIBJF@t*-ao2~lF=DN9=& z^qNWflmX!_TQqhwt$(i$0V0%T8O^V;xU}{9k1%&~X|KZKUF4hqtYs8-d;t&`uM=QW zA}cX~LX+ExQMC%*vuP`>@j2&f+{0J1`KskeDfbX6cDTmhWzekW+(7>tA3`RQp$*sh zryfVoqJH;9rmOmzPSTGL6K8AVI0G2D6|=EC5-Fs({LShLIwu)BT=^70a!@aYD{AZq zMn%O{J(=PwYgzWO`TxBD1t%oWd$MxEq5P9Q#rInb7+M!fi~xTO0wH6p_mDL+tATHk zzIDmaNJvnY-{pCk0+t#wrliF)B|QReZ0t<*;tkZv##A#Aw2Y7Lntx6MbH*`$I$NE( zPlO@xd{8b;F(6uW`Fnf9@&nXc<@*1d&9!79?ZeZ?rmv^u824K{SZ)L&*`WRsj{?qH z!1Z{?-J!Z)8(776$iVPR0IGGXs&2iN`5~xEQU1y+-u3ux5DJ3`*+tvC>~KJ1#az$| z+?rFr4oMC7J4Qvp-JSRRs04}2u_j_k+tY1oIM&750H6BJ4Oe0t*~Uu<1W%w7uCvGr zl_1#X9JcwAdnS2W5>~m)46r35SQcS#A33s>R3pT-`R`gEKLkqTKnF<5V@I5(4L>Xk z=cYk;D(FFsS7QOI8YzTgO8)gRGO9}!oz`-1?pTbFWTxcty5~b;#{vWRY>Co zo<&&2irlS5Zke1kB|zk$3W&^4_cl|Pcw=NUc2FJcLC%A>&$1omk0DL#5Bj&t%>w)B z@t8#$Y1dwk|4bOC;wg@(j4VEnju-rWntGBf)XiD>T4;@{x((XMH@}9Ie)3bkVD{U< z)d-Z^Uj6mP6Mvd?4Wq5VF9PQE4?{ebKWnH45WnxaLJD#NyPOW9clZ6asoGyl(gI>D zfHjhKqL2ygZw&Rz2i);r+_~`Kd2;=}d73}J76YRkV z+D{G&l7wkya>WBW>OX5k!gl511WJ?iy@)eF(nEUd99stmn*Tk2yCb8Pf7SzkyO4$r z&MR6X2*xjgbW!7^ZM=&kZRy}CE&|w3&ifC_m%9^!_Lpj*_f*UgHQb1pJKq%mj-nya z)vsOv>2(Aru=Z%JhofH>0?&4wAc0$f`j{w@+nXQ~JCfV%2~)n)`w50TV44^hCQ6F{ zd#J7e6J%o7cG%{G1iV3m24z|Sc-(<}Y~PYUT_efp7TaHq`U~aY=$itsU9KfhjCwv> zjO8h=oQh`UDQeFYk2ENaiHiTN?Du=oTT^%T4Fjg^4p{{td0OF5a2Py43~5(r+S${+ zJBfFfgB*O7ObyhK%s=2RI9Fg?l(ic=LFc1RkoOB95}Xm-iihO9l#;0_O~goWWaeTQvmrEuKuzPwj`Mdwvs5A4x!l{xu9-7HW8!!E8s?i}v!$6L!z07g<+qely9tEAiX!hl*STk*Fn- zRbSnX3`0y)Acbb)l9W}Tm^tpH&$v4#EOu1c`9$$32d4P&Cb}fVP4Z526WKeL-tx%_ zo_f9cVGYxVOKSX5!Oo9$NB=aIGQ?(0b}bp^Y38I9K#F-V3~feEEjOZ@9{$Gvk$N+} z%hDD&s~E#_Tf%kQEa?4;HD7AuW<9=0R9TzB7@Jx6wZo9(c{6F`dGyf0-=xek7{(6b zg+l`QV@4-~NwtfwzedHHPxvPr|EoQI{q^`OzrF1W`_oq=o+baq-Xs!TX2_ZZ0!Bjq zU6@}A(#baTeK5AU?vnjbiVsvNyAbWt{1B$g+>$EE z@!T_c`yE-I<|eNf>q$6)F4%7C?EMBjb@sScF!k5S&#a3N4&AQv^Zi)bQF|6fC_Jpw zD+)m?iA2M%wexP>o$;SM?AEfg6D*YYUT{pzAyNNCs`-%|CD*ws0Yt3C{U zdVCZ+LFCx@A6n7EsND)pd6|AjZ~4Y#y?0pdo*{ZToIX66zSYc+`b9n9cbD(WK{Idt zNKgI>VGnScX&SRL-k3@q`#s@`TL1QChbz&}gf|A22FZBQ4ryyL`uuXoRpIXMduDpF z=rxfe`FeIv^%$ROHhvjP$LpLDVqAIk)PtObE^TK49Q`4+o$II94S&%VVH++`8+P^_ z#cKt_wIL(qz;B&UJjJFVuiV4sRP; zr_!I%GAA+XX{pX9k;G4*G66Sd0ETI_JSj0b_gf|f;*>N_Mj8l?P%1CPjuOKUF(35e zuiqbfdU{lYEqL5MH!yKaz685f;@Z(oXP(^<+mi))i^g?AQ$B*ymW)Yo4o$A`_0bwM z8Zc*Ht{lyNm|@>@X#xwDse+Kryeg2G1N)Z2|2<0V!G8NjVc=sm0zmAe4N))qYKzWs zcv%A5cI%ePA(uaVzM`~#=?!q~HwkedMgoqwK_s99i8%gc&f}H5>3dEH*(6Ma_>q&C z_#*@UzK}(H26yg)vu9mKcwvsNHfa(tuu;lOFedUiVNmL^@uJ(=g4>?P@;ClYj+sri z7aPG_bHLHYx`yJxj05{^5C#A8J zgWck$$Az09gb5Ks*mrV@bW+|x?nI%JpNqwNG!s~f$v6j`>$5Nnc5lS1H%r8Kj2#kL zBlzHNJC;S= z9IQ=D6j25nMP%hu5EgA$J=y~2>g5=p-GkN{PHH+ocf>6OqT^%$0mHG$$?dT&7PTU9 ziw0xja{-ynh91|XRuwn%VGp5L)SVHx<^&X{ulDA8-!!hX7aNqUB0^$Pw$~Ja0i6b% z>@XYXeblR@SD5*i@Zm?tf{DOQfCxxnd}uc*#EFlAVBa!Y6q3u-NdmM7wTfb+m|qTj zgsqsO$c&`IpiB2p8M!WEXonxs zlRTWifMt`ZFI$rdrmO}Q&H;xz;?zOHU(HCb2_bhB5p%#>B+Kc9j>% zwCJ|Sqh6gg`Y)D<1_q-!CHs9gC3HV2GUIv5dyt36kbiN)5O(qM%>$hu37=XRr)HKk zKz=m2zh@+Z-Er5}!mxYcG99iw({odi&vT+rf*XJFqQrniu=POWV#F`ljUv6BONmS9 zAD?tCt`zQ7XwkyvoN=xN7Y?Gw23eyYyb4=nhOWJib>oh+wLdUHMVNn;Bc!327{KVS zx)dPPzn;WON3Rt6(rA4tDt+F?^H8$ud;8@*v(z~=5kM=wp?_b2CDQ4&edB&Da}E%P zUgQAgR=FRBL%pEcGD#t~7jT?FWm=V+jV%oSBcjgtk_pu;<3n8L<}Fr7^(UIfMOC{Jlt=W@>(Qu_ww)#v?Srt-XjHT#z$%3Wp~f z9USOCC5=D?7W?=X@An^%coCtxa!-uyA>Q?i9=C)5hfjNtSq@K;dO8E%p@2H@%|H`W(NF(A2ix$XMUKvcVuZ#8Njw%dokx+bnpaPc zsA;!T0g^m>qF@meYuU1VR`yH5IXA;-`O#dkM&|R|<7Y5l(c$>tOsALY6c_;B&#@fL z@E|i|)gp#~ac(z7_I)|amx1+QXJp38Pd9-tPeX4VoNy2K%>2us@=BS`ifSCpTgNo1 zeD!JNo@5t9M)b=)qcC5b14+s2`x|6oe&AvPf4Q^UX7<|R-&Vpi?SX#4FVYV0lp7)R zViL+KJGXqfhP<4Wp<929#@@+@aS>QKQtDe~s2Ib?s%y&$E*xp)vq_isy@NuUr*HP~ zC|1Nj9I6#73AV3UGmcuZEB)E4Mw14bnV2+l*BnKv1q!~;Rah3x-J^?(E&|uDhX&P; z;`ZI5=m)M?EclCZ4k!_QyvAOn$D4Ei$4Ny6yTlPugAY`qwsX@c+wcxt$V!@?5E#^@ zWe(%%@~}jjf7b$`RvN#E>HwoWn$xU88-HcFbSW`Fpcu8opmOv%ooC8VPmy{WMfnTM z)^8($3w}NQdkguDz^-U(<`MW9-HL4MTa0T*yN%L_%Sk%T`#cm7e5^C>*7fzQtT^xn zo3F11wQA2v+nMnH-R7KZY{R2vVOfaYG7dU~0fZ=efTB;@`xIC5(a;yM8=24Nrb|h{ z(3V8WW~t0yh^k!t=dRB5XjB=h-c7GpYvy(!kIDx+IQL{UOVvaQCskpBC^g$8+{rPG z;G`D!6$L(wC4r0Xna1_Bf-x!SLISQJkJnB2(#yel)6^&AetT|CJJV;edX(;Ue6Wgfj9MN&{ihxt%!fWt-WW@*GLq&$XPx82CdJhkE1sV;ae+F9+TC=u zz9%}xHt8+tD#XWkH!SMvx%D!~{r7*@I=F%i*nq3vi*?%!I-b%fP=IEQr`X;aj%I>_t%`8`bsr ztX!C;maCBoRe0N5laqzWgv{`({Ia*DRJjypR48{SGPO0^aI~uU)Nh_F9Fo=UY4+p zm1QI(gjC$0A}WOgxtY~KHDn0DD}917N&ZdJa02vxz%DbUe3cq9dJJkEZ`=biM~{wW z8Oz;*E{}wi_pR)vtgN}ufwE8V6+G4Bu#vN=m&O~l2hCdh-3GhZX$MCf)L&kvw&Ic! z-NkwFOEM8=lQ{z(g&=rtQw2?mlPH`u<5Kh^zWd5}@>3 zZQpJCMb1C#dUQ1~@QKTy85S6Lg_2<=yqxvcI0c5u*NE5eHf8DQ*K&;S=AJxPzyJF| z`-M2-SH&ES&D?9{_~ z_aE%PX7zm8{#=b+PKIa{H|w2Hrqjj*La3@ep!*iQzbJinQ3E;l2Xa%`{K}q=uy1sc zRH`EPxwX!>mLahb{>h-x+t;g;0@Vng4;9KRLoMZBAfbA171+! z(2)xX9Z8Ho0IW1TTqUh&176E66Qhh~D~qjO1`__DdP%PY4AwjL1JQiUWpz zoO1>pZaJHvNEzOh926Iv$16)fDX)6mVHP|iFT0p=VHnVoL*T4*67v5U+`3A66D_k_ zySL7d@(qz`#;zmU0I!O-{Hb6e3it*c)xos*M_+#+^-z@x}D8Ndt~ zXsmXh-*~ss+dXZtlAamJrn!$lOn^T<6`tQ6FTgrqhx#=%*vXE*1fjNB^#FGdetn2* zq;YUrJ3QtN%7}QY!489P=)Hv9CG`7h8oa-an({^S(oukKlv{(7iLW1M;)pYiZf zFM1~a4oG-D^d(=2)|JO%C$E|GDen|Cxv@!>ckBmt(T@k{_*Qc$Nl<~7ks~Fp*&8Ja z=-G7*BDY+gUha22JcNwtSJt|k7(anu=+TC}(AH~T2 zHk!@DRY)Ss=OW0#)i*r2A3qbje)IjtYFhGj`8?tx4OdOP$;+g7sm?2ECLkZ%C}|!$ z3rOyq+YA%ncs!{F=kJZ~9me$>ppKWpF2`Tq_4cVXP1Q!iUNUwssVf}+oxZO1pB6U;|XsRvrP0Hq@?Y9=# zL++BYLT!`tq$)B{s%8WDIRAcXg8Fz8`sRFeV7+$Y)MV zUhs4AOX=u)dUT){<%RIp3Gr6Tmv?}!P~QI{^aZ`RdM%;l#~s%*oui=~OLG`Pnf7^t z@kc<@1wN==llg`K2zu_}Y4+Lzskh&ux|p~ip)2t%(aS`ypFf=VSNwx&svZE1HtsC< zjGbZm640ec=4Zs}xT)t<_>I*^Wu1)_QJxeT4};C@QaaALiuA}YA58<7@q5rG8m(SK zai}Q1Rx?j?-N{5jU9zmr9z6N} z<+=K7D2Z{b@<8g=Wf@;t&f@M~J@tCagaV>qZ`AyOeS#|P;^jdBVNWH&E5Y9M-PSYV z5l@|uk<#tqu1{apDEOm#zLczOahb$EwkEQ{WIsyEt{@e#?eC%{BG6 zEqbJj>3a&#ks@|3bN2jf zKU_n|?)MpXv<@1B43%|C@H1$(v%sCWI-isbnY(D%J^^PgT|hg?I{rVG9v++Vqn^tReXaq;t<<&VRkLPHr+#FB#L zUrJcIUk_dMq(jH=`qT;FumwHbhS>{mb0TI=q6^Ij1gDRdpN4?4dd@rz zR2^x`@V2NxuM$b_%H5sRQ}s@JJ@8#lcvOkgdg!C% zD<^x`TNI8NT3eo%MSingC}_$`u@^k|Y@(}+R3Ub_V%yd9s~Qxhj!!crjapLIJ)*m0 zVU4R>LFaT(nhjK5Ymgca-H{E5y^6OdK%MLVs#y_}CVn@D{y9dL>Mc^=eAe@=4X-w(%%Wx# z+OvKUe9whs&?5hQ{LEaqZ~y2V_Vhd{&HwWDOOcF`GS#R|iFLXQ!Uf-L0m?X?Y_M5< zc^CAgMe-dDIm7EhO{BKJnCdAILL-an-S41W3j6JY_2u276M@E*QEt%eorf$VeT1@tvBuQ@CSOMyrkpVIg(_eKxVP+3%9k<;5P5}|^Q1zUKq*ty1g7PJ^9{7@+h+Ca{jn9E1g=9~OGAsU$usU{2eQ>K1ZO>6O zGL#!qwk#e(#Nfman|dcfuxh~e8};W!2!0LjEgOUky>W%(6E5&0-Y)3soRRrNJm_ze zdem?)Rd2q^{>t3ca!rn>kJ<>%p670Qkkn#abN`qAP1aN!ZBT)B#^zAC^kmXCj)PWn z*uz^4rhj`{oWCC4lsMtfdGDjr(9nW1+I#Tl$juLexLy$cUw~Gsmgkhv1+%^yL(vR1 zBXVk*r9EbDAX?s0tj=_zTw57xXUVk$do;ZeQVodRHD5oQ#oAxx5f~iy$4XWf=fJrs zp*{U<`PF|=x9hOiEtOe==NDNhj#N_aGw)cR@o`CT5S@4G&S}?3@Sjs5c|s>X2-)uJ z?tP126o1vXbS-eDG5#o*`@>FDKbD&CpDHp$_4#d_+w2r`;^Drc=I+& z7(^F`W1psfd90iC{R90McAtLxm+N=5ZKr{tG`kmMwXE_rL~#Y$9@9(x0wX`^U{=T9 z`!cwF?eR6HN|1x~(%W<}N4^DA#b?mdOhD&dMIVM!zvxL z$q5bqyw~HY(Bz6c3||3kk!XJ8-Ze^B0L&wHv$rb{nH(jiJE*<(^{P1BdtGCiWZu+j=UhguY#X2l65%)8J5zeM0!Q|7Ra=WE-j~{ao^v9^Cn2W!!TgJ|I7BtWk zzE{W_Ql#b@WCb{ZykZYw53>P5r%bJeqL*9!PzTAEIEMPfQ(IhAB(~ya!RHfNR3xKR z<$i}Y><#lzpRQnuRAi7I9U!{pHqz3Bq}Ces-0NT77EvK>{-3LrG4KG`6sEsENH7Kv1@tpf5F?p|h=c7nhIav(JezJKev2xLe;D zvh91_7IEKXkht`GPAY5gzkKP(V23^#@)9BVsO>4(BXSCbeQbmHhGN4wA~rh)o$vv1xH{E)-Qfu*-3jt39FYd+M^(X z7{W__jASwoP2&mgg3mYakt}v!w~GC>yzzUdPs25$`^njDRc*~JU(+kOpT6(C?m!}O z43dh|>Ya&$qtq(DbXMk-+@)>W$7*sf{Kd=J%ckX05%nG5+OLXx2p@@eg-w>4brDWvGI$+*>@8~Q`VKYDd#tZE?e3xH`MT))4c_vigQ?`OQ<&-?R!o>$F<(X)RYq`}6>lnM;=K3z1DT34r|^e8I+ zo%33JQxfuiJ;NqlC#Sx%aonkcm^#2pqjB%pZE8*gk?!tdcpCtaiElputk0(R9yA?4 zhc|wCSTJ?x40y$c*^ECK}XKnEVp3<2gD@|Lsc&A9jbHmc~RaMFBtDVPwL?zexfCD`l@@|}q z>A|}{%Wv`a%B)%_)%Y=&;iKkfi(=Ymf#4IOoRWd2;R6YSgTOj36{~&3SER~8d*Q|-CPxIG5@Sq-S}%lAa;sHpbtfWSEK z{YU44^snv`Qlnt5Kq+G!=?gJ3YqWccn?Am8^yL$cgvv4c%vg2IACN0Dy;j%6wB=^l zZ@$%JV+pj*rJw*&jL2*QPg+TB5!g8`BW_Ilb3$V8 z@X%sA;wlrr6OyfJ8~l;Z{`QI1vmmCUk6=Rw_=tP{x-5J-jqbdBfrO~Z=(lAN=!j3Q zzYFzv`UkhX*Wud3&O{GFL+N5@|MSUf&JY{3K8E+h^iMyk+jumr-CYE)OO#yWqeWLy z=mi$m1~ZJxH!^sAKUl1YiZ_h+*m+91Oxk&63-IN9+-Dgay4dV=IlLQcpm>aPGW@pn zm*>pzMWB8yYpn}X^LjhWPF&<=WWD!%^0Y~=z}LE_v*6Po<>5i*bXr(YP~+6Q6Rg%! zH?Q9=dOmf%wDq&-Gpp5i=Dq<`(1OtI7P}U(4y@4JFs_NOsJmNR&ocJD6S*0|b8T#S zS7{0?p1W;NMH|ygdGct;%p?k7dGGcH%+xyayxC59#03EWaO(iNsb^ax(keEQLgZP~ zIA&{t`@b$Q@dMLgVWZGtJ^iuDuay7mtpH_ ze~xF(TTbf6-%GW`KXb`fiqvqw0urJOM&dE&iiPnZIYv+ksH$ee>&d-!rC?L@9TrVB zsr9V1Kik<1=MKe9&K=FBHt&0>7~AYt>6q^I&~gU0TP-Q@`roHhJepBBSZaPF9o#H{ zIQ_fFJ;@H^#v`=O1@?X+M-)EJw30d8Y(Fjy{^cC33WOi3?nB0QRoa9nmG4G8g zGvg~}fi68+*Nu9ENkPYJi=&^OnKh%C0GpGrvks2qhn7c50SGi{uGR812pfD#&8iWm z=Gy!ezpQi4dSW$O^oLiUIzYDH-4zMImrjPjLS*7U2gt49GXk?uwdTdMjK+dBrN|nFQM%zkDGGCVgEcE8pq0R zY_x>Kp9BX>%e?XR)BUR(T;^&i0LA5gBl)ZhlovmYxy*oHSLI@bv+YWeWzvTGUU0gS z0MFgGj_X%qTNbpa7;9H^RyT8Pe`f6ZHZKY!?L^Od!uH=pJz1wwYbJ3#ZYyP;2)s8- z$lrBv*^^y;2jL=lB1|eevUz4*#84y3{03>I+LMmIY{;~U72HRJRO3x0Km#w9q@**U z*0j4qd#&7xfz@V%FR03cenbC`LiQK(gTUayfbr;QH@Vt>9(&Joi1C%sUX~Z2Db=J;~pDmrP0( zFyV{a!3;3YHy$onX_;_U{R_evA=NV`iz-y2_eKER% zd)9bSz}Aw3>#~yVc@M8(PWMS9qtXkT)TU>?LkzX=z)fP1kh!qWGeW(~Gttt83HL~m zUuRRbH^N&VPNZ~OI=FGENR$;nE>jRDWwKKORd%kS*?p;!Ja#$=`X+kKf|UFRKa+NP z(&c&wVAU7WxnIDJFu$`Z>=8FrEAQiSjj@$3Cl$@0k+C0X{A1;GH+>ds8+H=5)1ex+ z|4r3;De6_+SP6kgC-AGt(T7@NNvClILYg)z)KP0G%C$1~ptSov0N~m;x65CxaN)U< zj!3J<(ao@Z)TydcSdWCB+Zvb2=J91cAatbK{*zZF^@2uBsaeoB*Jg5Zfw_v&4g-8L0Ps{60o`_pGbe z9JK6U0N}i(0l~mKFMuSj-IN{YW`ew}3BMAs))PIph!Us9DO7_6;UVz=vRE3Sg7@xH@zn7MIduL-?eSzykn-=cP}fgUqEAn)lsLw=aI{R@!d8 zAtwnG*y)zRCU5cM03iA3ZSrOs{sLFBCz##j?w2M5ZzXz)ai_P<}r6gQB)Vy>9sD7n`sxuIeG`prfum~!>f8L@Wqi7U+%!|~Jf(QTC z_@U%C0nE%~Zoa4%CEHQVAgBAJ-@rPfrhkda56z5=4cSVi^&chCWBBkO3`kPq135$% zi=uf-Dvx@0st_ou-EHUR%HGl#mw$B6i$8z(Z0*i5FKhw;hWCbtB&z%$%ZCCgh28B4 zGZU|mP23a{c6_AvXhnngAHQiKYdQt<%;r8`^-Z9cRk{x^f`}+J6hXTK?jGl4o8Pfh zS7pQm*uS4z2$ZG8iBc99S(;o{ez*!Ap1AoAy`4QutuQq_X``&Z#fy&6#2gHSuY%7B=AMljkxVG>&1Ms>38}EK=n8PC%O$Xv> zuqdW$cMQPtc<;Yv*n-ZmW1UF*X+X|QY!K)fSvmfXPg1n#LG5sW`EY@*Qf~ftnIKqv zNaN|?AbTd)rE5A8)53!v#9#P4CNC%| z3wY}#TsT3T=>#19X-d5M?8-o?W=z&oF1E{@Kz4%m<*YDU#)CQ}KQ?f1j`wk5@`sXA zb?h5z8=<$!5x-YjOUU&|0PzN2Fs+b+{{YSfQJQDz4M)k-G z7K0r5%*;qEsER6zQJM5Zk1P4#A2g#iliY#T+fv3PCz|q46p}aF=UjfS)&Y5e6^3lMPL*}}!l_3TmsQA>zieja-;BOpK0}9u2^wyS z6gTu!B3W7edII7!c9sq)G$~cL7{GsUOEw2=AQZ_N6&%j@u?SnZ$b`{Nmn|m+A`2kG zRiNL9>hbZWULM|rm8pBM!f@OTPn>s6S^drm6%nzK}oI9?@FxG)W_1vfx_4n5(-nm7L z4{U=BcDRaHaL;8bGRz2ry2dJg5{&NXZwTt_HpcTEz8?7G^XYEdf60B47wFEY1f+*M zFc;0yjB>=zb+i&e)~^)o+hyccHZD<}yrS?fXR|TahP^+hX#C(Q;ceW30LC?6$~~~J zOfT&Wx%CSFGl@_KskD2OwBhDm3svPAgaB4V zbcymrly<0XJVnC_KSef9BE9&ZaH+Y>1Kki+zn?F1+qpT~WJ)c-lX(7c5Mk*RVBZeI z^VK+U0&<|l4e2F78dXjh`Yh|v(;B2#)unXJE%DPy93=j6h`aHffOdO8wiC3$QudV5 z(Dqe>{0g%$y`#-5I8OGwALN!_i1&iUtyDR9C6v)dflQLK0vJe>-`Fvn((cZEqkQjZ zZB)QDiOLdlJRGZ}l!xVC%ZCX8a@Wk#-Vw~B=Z!XNK*`}rT^5$xl1&GHq_cp9h=}>c zWNLpNOb{rxu-i}hwzv>VD6x!tDnh#1zk4ap-?RM&(XMyp!!~^Y3KXnwW+G0H+t@LR z9MKhWU02s2>t}hfO7)XPR@_D@c+)Vw(K$LKH@!hbS9;*^V6d_Xi}^l_zV5To6^_xX z$7~YhLr|H1;^$2~GZEUMbCiv#=R!qM>JL$=O$|KXNRTW*kNch4YS1)Y;G*(!1qC#h z1%wM%)rmgema-1Gf8|EX$1uNG>Kx3Z5!lEjIZC<#AV9a)&lARUeKlPTcFmUbNJcY0 zfx(cFbXjlL3xa!Bk#Urebs|L;A2(p7HnC{BCkPnwCH-v^_+i`HJ)|r3;B;eHc-5LZ z{Ii&}*U0+etWszMbqs{AyQ`c6)pG@1m7xCe=?Kv{Q7ZpxnMF4@3<$b+-Fr&JYDX97G6w}s_3JAlzZ=*d zj+F(LPDLatqPc$WwXzIaKmw;gA>>{1)k4PfKX5M&94=SO0);xNhi~6rubZ{iZ$2AX zc3ofGj5$HUasdD3mE)5byd;MXCs1Q?8q~I`+-%{0%2GT^ecpzkj&d1i{CV`yJ??v( zfRI~NY_7vRkmLPjuk`T5e-F>|{0xgmzkT7<=);AANlAg0A^A5R)Gz=&#-u(Y4+L23 zv%s%g9TW|N{D(s%jj03g4*g_lrpF?)U=&r2*kv-So(HLW3jG zZ9NU`pNMAs4PydU&Z!*sE(z(G*o{>Ct2nY(ZfpUYS8C{c%-kLtac1#(>BnKJ7t zH9xJ(_}PJ-x;4HYNFP8hKsaq=R&6I z?)`APqT=6UPQ2I?%n2kJgQ{g)mk!j*O=Z}~p4sPx%eV1|Y7^Kx3#OAVeCm@AqlcYt zUA`fcI-v63U0=FPZ44Ox%=+hkGTi*Dv{u%g)bfZ+9rP4T@5w$*_0i6=Wn*#CX&Nt% zgP^;IcliqSlVP@Jo4Fb6vj%OrP@yrwLk4-1H(N+E=O_L2nyGLspgNU4@*p=W4Ns4F z4eP!(zHv}s0wVM7Pl;S#H##E@T&G3y5U*gF#u#TrWK{@UW+X+G$W&}NHHKdT)c8j? zVR<+f0UVseuz|zgpMe)r+4=X@E3?}5)S1Fq|I)*N-$|ERP9}5a-p+X%Jt;kN57J(m zQJ7OJdfkL0SvQKCSxP_}99fG1N0#Os=fBKl7=YG1#8kW#qE6!C!_Z*t%`LSe2UZQs zLCrR?L>FD02{;$TUOfF(=y6Uqn*DdO4q#t0w`}i{{+)R)HxLIw`h9F_l9J|x1$Jop zUP1MP2wdQ>JRc}2vpAr08TU)o-nSafqHjW(5Rqwd>*mfU5FpYRW3UlHHU3#l&q&=X z_EiQvZ{E!e#)=kV0z`!=rfQdt-WaS<-8DkCFivTj7ODXiRHUc7QbKQ3gJ)Z}isGLG zda4XPB_y>--M#)egX9D%L0ksiw(*%Z+f5QSGGje()o-fyerPl`#sQ}4XKXDi^R*<} zpzSVICN!rNjX>Yy!i2I|&NOAT=HK~dy#|&wmErYK`fU(o4TEY9lh)$dU0q$agG9Io z8|D!ZSvIj`XbxCXHH3;bB8?Hc_k>a)So|ZDeg_0OqMB+=zPCBk7jp+k+|)hU6!lQV zJcjJlx?W|m;5B9HFhC;Ycr1*V>%)2SwMHa40hFcSd6iSZmusqDRakeRgAAfUfY{3%l^sLsxkT&J z8W-T=>8>>uvxX9H9}9s#nKo29V#PlECNiICj%cJOguCrq{e}Um0i{Kc0c|0`*wA8KmGJI zXQ!iT%38_*0JY=C4!Zy#hcxAYA{sHTivQk*7!=Xvs6A?+eJ_M`l){gB5D{n2r;4)w z?tUx+PC7fBI)d2$i&6x-|C4q8Z~#+@%y*1*adHJJyYU{xjAG`%63nvuHo8UD8iTS( z=e$cZKb-x+#;{6B5BainAtH-;&3DIjD|^{*;~072i2(AE7LY zPCqT72fEb+6kat``r+L9YcFqZR#JLqwX%{dWiY5QKMI7Zxp7o|`#&@{4nD^FZukrp zxR#W=)M4|}u2+QZZn0cGl<|;`TUvc@3txc78;nYtE^oe|H<;}KR^Kp%`rp(UlrTe< zpi6@71Q%6bvy=oSK{`LoJ;UNU`v%CcS+^1nJ8x6lMDT{g69I2*RpGtr{y&dNqMM3V zfJ4fHRAE@Hk1Nw)&L?(jvkEpVb0fM`IQ|)g<#j0)6u+#YG-(IsqlK3;xpVTq2cB%` zUGW)h;XSNj)_u(yD`zLD#E;#-O5=0Sphx}JDyjDi6b@*>zb731B)1cXbv&o&nVMVwWmY_xRO!D#7 zWECV);Q&|6g>0&}mx77d`>e>`ae1-(BIyL!ZN4Od8np5}Bsq{0tJFff5gS;TNHCIA zD*86k(#b>bWCN+0>sXW|xeN{_?BYhkb-;Hvv?#{@ZFR#&Tc;e^n5Y10yyYmgC2KUPD5Pr{)6koBwMnq@KvwWH#aOq zEW6wPloJD%{X6E2$xZKOyr%xCNIXwR+f{9-d_y>uGpyN4dd@-=hfGj&F%$SBZL6I zS@hDq?D@2$yZ*8V6GjIwtTYjYjOtO*4~t$_P#>f-s&FTKH$i%J^Winfw`NU8!J>(?i#Lbm#$r|)M2oBByUO6?k+V8io zV-VQW{v7D<--DXUZSwb8Aog23lbU;-AGbnOc{1gx7MYkyY5j_pa`|nud*g-N8Bku~ zhVHTw#|gy_8nZZt-=HN2<$JbNar9IsO}VOmz$94WFvi&^F_Qa?QaZ199?}>*MQZ+; z=Y>Hc{*Bxdl=R)L*?@jOYi7cO@k~{~YB{}yb@$};&a>sA&-w6`PwSC05nw!e#kW~Q#;Ra69BJj;c+bIA70OTNi957*{cB08R09Z9NYoIX+ZlPFM07eH->VXU* zXal1v0EEwds}5SMz&WrW55V))-!Oou15CjhLdjkm?PzkuCZGvOU($Wq%r8gfzjF}= zH|0ld901k91PuAk+zjZdOw&B&>Hc~ag|du%LIzbNT8TOj|QGHS7cJuM_h|M zGxT2w?2RBR9e8c5r1--|{UAy;9daXG+mlCuOzE)=pP@)Pw`_guj={L$#)+&uf>J)F z+(uHxzj1q>Bq@q}d(epM-lv{l#naCsJP5|hoW~2f&q#!KfSflb$RZSbg|%?ApYwUGy*UkkP1<)` z1S3xFeX3+OTcamwFUdA#j{qJ)UZ0=TP&sh$Le+F+=GEM$<@ml%Xe2-^yF@`vMW*pc zf&`i_<@Z-4H+`7D8r>nn25q(zJi%!^UYA#QtCA%UhcIMigz(NW)WHsf2HQybU=Ko$ zx5T#K6hfIhmlDAvuoG?faRWG`>=ejvM5uf@gmmu;(01|&H=1(41o*NC|NC>`(ZBUN z&eAW}T@BRC)5H(ftkVh{o85KH*`*5PGoq8w8IsIQwRPOkM{pv>Vi-8j$h2uYXz3>X z1X6Q#gwKA^TMzMFgyLY0elJpUP)l6jC!hAt8=V(le!M(xSe*8;d)NsBR_195q`I}_ zZwsKVSlw3I?uNWj@Q4V{9^oa^UYXC#B|L$4_svD3?I;`A3wU#S|8{dVkFpQ1gA0c| z6v6&^8r)Vt9-(-Us=>(^!RJgR)uZwm(qHl{G7J^;QrL9bQx0))ka0Ms7lnk_hOw9q>=H$gu2+6RVCknY7Sx>Snfz@q@@+@NHMJH3pEM>gZ= zYHCr!p~6mi;M^fgjqQks@!W;CY-@7UL-WkkTN7IhKyNu@{Nv0LGxgaB|FgCY%2QT} z3w?qnQ%3OH8Z`g>Qmlv~|3E3zeKJ#6Fle1Je zN9rdeP;IL5eWDOoi$gUQwzZPr7k>~B_PF1#!v^M8T;$>^`Rz@+2o@1Y>TQNx(|Tpr z7z3yM99zP?Lj2TUpOzLSy7QTuB~9&hZiL$g3os1LOno&z!4Jd!8YbMP9(T-A zv>Jxx8WqagXwTnpQE}McCt_5lYehm2ar$I8!Dtc*Uu9qNb%%SQpIm%Nt|0qM-Fg^1{7-_ow=nQ%>(5wX)FO|j9 zRvc4UhvdZ7_?9T!N>8{)CSG%WvNFWLy3Un!{BF9ewsTi`(y!ZX!qiesmbw^ECW!c-zu|`b osenDpb;yXAO81v+Uw9}}7d?zw)S=up`1DObe#Gf8-QG9(FK;Ky`Tzg` literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/track_card/img/piano-right.png b/neothesia-iced-widgets/src/track_card/img/piano-right.png new file mode 100755 index 0000000000000000000000000000000000000000..1fbdbc8e0e6e97c26c0cbbad292b0e7bf73dd28e GIT binary patch literal 4633 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 literal 0 HcmV?d00001 diff --git a/neothesia/Cargo.toml b/neothesia/Cargo.toml index b1e413b6..4e18f30d 100644 --- a/neothesia/Cargo.toml +++ b/neothesia/Cargo.toml @@ -23,6 +23,7 @@ neothesia-iced-widgets.workspace = true piano-math.workspace = true midi-file.workspace = true midi-io.workspace = true +dirs = "3.0" iced_style.workspace = true iced_graphics.workspace = true @@ -35,7 +36,7 @@ fps_ticker = "1" winit = { version = "0.29", features = ["rwh_05"] } rfd = "0.14" async-thread = "0.1" - +chrono = "0.4.19" cpal = { version = "0.15", optional = true } fluidlite = { version = "0.2", features = ["builtin"], optional = true } oxisynth = { version = "0.0.5", optional = true } diff --git a/neothesia/src/main.rs b/neothesia/src/main.rs index 8e6376df..acfa00d5 100644 --- a/neothesia/src/main.rs +++ b/neothesia/src/main.rs @@ -16,6 +16,7 @@ use iced_core::Renderer; use scene::{menu_scene, playing_scene, Scene}; use utils::window::WindowState; +use menu_scene::Step; use midi_file::midly::MidiMessage; use neothesia_core::{config, render}; use wgpu_jumpstart::Surface; @@ -30,7 +31,9 @@ pub enum NeothesiaEvent { /// Go to playing scene Play(song::Song), /// Go to main menu scene - MainMenu, + MainMenu { + page: Step, + }, MidiInput { /// The MIDI channel that this message is associated with. channel: u8, @@ -52,7 +55,7 @@ struct Neothesia { impl Neothesia { fn new(mut context: Context, surface: Surface) -> Self { - let game_scene = menu_scene::MenuScene::new(&mut context); + let game_scene = menu_scene::MenuScene::new(&mut context, Step::Main); context.resize(); context.gpu.submit(); @@ -144,10 +147,11 @@ impl Neothesia { let to = playing_scene::PlayingScene::new(&self.context, song); self.game_scene = Box::new(to); } - NeothesiaEvent::MainMenu => { - let to = menu_scene::MenuScene::new(&mut self.context); + NeothesiaEvent::MainMenu { page } => { + let to = menu_scene::MenuScene::new(&mut self.context, page); self.game_scene = Box::new(to); } + NeothesiaEvent::MidiInput { channel, message } => { self.game_scene .midi_event(&mut self.context, channel, &message); diff --git a/neothesia/src/scene/menu_scene/iced_menu/main.rs b/neothesia/src/scene/menu_scene/iced_menu/main.rs index c0554a58..78e4a5d4 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/main.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/main.rs @@ -49,8 +49,8 @@ impl Page for MainPage { fn view<'a>(data: &'a Data, ctx: &Context) -> neothesia_iced_widgets::Element<'a, Self::Event> { let buttons = column![ - NeoBtn::new_with_label("Select File") - .on_press(Event::MidiFilePicker(MidiFilePickerMessage::open())) + NeoBtn::new_with_label("Select Song") + .on_press(Event::GoToPage(Step::SelectsongPage)) .width(Length::Fill) .height(Length::Fixed(80.0)), NeoBtn::new_with_label("Settings") @@ -105,11 +105,21 @@ impl Page for MainPage { bottom: 10.0, left: 0.0, }); + // + let song_name = if let Some(song_name) = + song.file.name.to_lowercase().strip_suffix(".mid") + { + song_name.to_string() + } else if let Some(song_name) = song.file.name.to_lowercase().strip_suffix(".midi") { + song_name.to_string() + } else { + song.file.name.clone() + }; layout = layout.bottom( BarLayout::new() .center( - text(&song.file.name) + text(song_name) .width(Length::Fill) .vertical_alignment(Vertical::Center) .horizontal_alignment(Horizontal::Center), diff --git a/neothesia/src/scene/menu_scene/iced_menu/mod.rs b/neothesia/src/scene/menu_scene/iced_menu/mod.rs index 9b060a9f..951e1044 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/mod.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/mod.rs @@ -23,13 +23,17 @@ use crate::{ mod exit; mod main; mod page; +mod selectsong; mod settings; +pub mod stats; mod theme; mod tracks; use exit::ExitPage; use page::Page; +use selectsong::SelectsongPage; use settings::SettingsPage; +use stats::StatsPage; use tracks::TracksPage; type InputDescriptor = midi_io::MidiInputPort; @@ -43,6 +47,8 @@ pub enum Message { ExitPage(::Event), SettingsPage(::Event), TracksPage(::Event), + StatsPage(::Event), + SelectsongPage(::Event), } pub struct Data { @@ -63,9 +69,9 @@ pub struct AppUi { } impl AppUi { - pub fn new(_ctx: &Context) -> Self { + pub fn new(_ctx: &Context, goto: Step) -> Self { let mut page_stack = VecDeque::new(); - page_stack.push_front(Step::Main); + page_stack.push_front(goto); Self { page_stack, @@ -135,6 +141,14 @@ impl Program for AppUi { let msg = TracksPage::update(&mut self.data, msg, ctx); return self.handle_page_msg(ctx, msg); } + Message::StatsPage(msg) => { + let msg = StatsPage::update(&mut self.data, msg, ctx); + return self.handle_page_msg(ctx, msg); + } + Message::SelectsongPage(msg) => { + let msg = SelectsongPage::update(&mut self.data, msg, ctx); + return self.handle_page_msg(ctx, msg); + } Message::ExitPage(msg) => { let msg = ExitPage::update(&mut self.data, msg, ctx); return self.handle_page_msg(ctx, msg); @@ -162,6 +176,8 @@ impl Program for AppUi { Step::Main => MainPage::keyboard_input(event, ctx), Step::Settings => SettingsPage::keyboard_input(event, ctx), Step::TrackSelection => TracksPage::keyboard_input(event, ctx), + Step::SelectsongPage => SelectsongPage::keyboard_input(event, ctx), + Step::Stats => StatsPage::keyboard_input(event, ctx), } } @@ -175,6 +191,10 @@ impl Program for AppUi { Step::Main => MainPage::view(&self.data, ctx).map(Message::MainPage), Step::Settings => SettingsPage::view(&self.data, ctx).map(Message::SettingsPage), Step::TrackSelection => TracksPage::view(&self.data, ctx).map(Message::TracksPage), + Step::SelectsongPage => { + SelectsongPage::view(&self.data, ctx).map(Message::SelectsongPage) + } + Step::Stats => StatsPage::view(&self.data, ctx).map(Message::StatsPage), } } @@ -215,7 +235,9 @@ pub enum Step { Exit, Main, Settings, + Stats, TrackSelection, + SelectsongPage, } fn play(data: &Data, ctx: &mut Context) { diff --git a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs new file mode 100644 index 00000000..1a0fa0c8 --- /dev/null +++ b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs @@ -0,0 +1,310 @@ +use iced_core::{ + alignment::{Horizontal, Vertical}, + Alignment, Length, Padding, +}; +use iced_widget::{button, column as col, container, row, vertical_space}; + +use rfd::FileDialog; + +use super::{ + centered_text, + page::{Page, PageMessage}, + theme, Data, Message, +}; +use crate::{context::Context, scene::menu_scene::icons, song::Song}; +use neothesia_iced_widgets::{BarLayout, Element, Layout, NeoBtn}; +use std::fs; +use std::path::{Path, PathBuf}; + +#[derive(Debug, Clone)] +pub enum Event { + GoBack, + OpenFolderPicker, + SetSongPath { last_opened_song: Option }, + Play, +} + +use crate::menu_scene::Step; + +pub struct SelectsongPage; + +impl Page for SelectsongPage { + type Event = Event; + + fn update(data: &mut Data, event: Event, ctx: &mut Context) -> PageMessage { + match event { + Event::GoBack => PageMessage::go_to_page(Step::Main), + Event::Play => PageMessage::go_to_page(Step::TrackSelection), + Event::OpenFolderPicker => { + let mut page_message = PageMessage::none(); + data.is_loading = true; + if let Some(folder) = FileDialog::new().pick_folder() { + // Save the selected folder to the context or data as needed + ctx.config.song_directory = Some(folder); + page_message = PageMessage::go_to_page(Step::SelectsongPage); + } + data.is_loading = false; + page_message + } + Event::SetSongPath { last_opened_song } => { + // Handle the event here, update the context or data accordingly + + match last_opened_song { + Some(song_path) => { + ctx.config.last_opened_song = Some(song_path.clone()); + match midi_file::MidiFile::new(&song_path) { + Ok(midi) => { + ctx.song = Some(Song::new(midi)); + // Trigger navigation or any other necessary action + PageMessage::go_to_page(Step::SelectsongPage) + } + Err(err) => { + log::error!("Failed to load MIDI file: {}", err); + // Handle the error here + // For now, let's return None as a placeholder + PageMessage::go_to_page(Step::SelectsongPage) + } + } + } + None => { + ctx.config.last_opened_song = None; + + PageMessage::go_to_page(Step::SelectsongPage) + } + } + } + } + } + + fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { + let dir_path = match dirs::home_dir() { + Some(mut path) => { + if let Some(folder) = &ctx.config.song_directory { + path.push(folder); + } + path + } + None => { + println!("Unable to determine home directory"); + let mut path = PathBuf::new(); + path.push("~/Music"); + path + } + }; + let mut elements = Vec::new(); + if let Ok(entries) = fs::read_dir(&dir_path) { + for entry in entries { + if let Ok(entry) = entry { + if let Some(file_name) = entry.file_name().to_str() { + if let Some(extension) = Path::new(file_name).extension() { + if extension == "mid" || extension == "midi" { + let song_name = + if let Some(stripped_name) = file_name.strip_suffix(".mid") { + stripped_name.to_string() + } else { + file_name.to_string() + }; + + // Create a button with the song name + let button = button(centered_text(&song_name)) + .on_press(Event::SetSongPath { + last_opened_song: Some(entry.path().clone()), + }) + .style(theme::filelist_button()) + .width(10000); + + elements.push(button.into()); + } + } + } + } + } + } + + // Now add the final container + let column = iced_widget::scrollable(iced_widget::column(elements)); + + let mut elements = Vec::new(); + + let center_text = centered_text("Song list") + .size(20) + .width(Length::Fill) + .horizontal_alignment(Horizontal::Center); + + let center_text_container = container(center_text) + .width(Length::Fill) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(Padding { + top: 25.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }); + elements.push(center_text_container.into()); + let mut song_file_name = String::new(); + + if let Some(path_buf) = &ctx.config.last_opened_song { + if let Some(file_name) = path_buf.file_name() { + if let Some(name) = file_name.to_str() { + if let Some(stripped_name) = name.strip_suffix(".mid") { + song_file_name = stripped_name.to_string(); + } else { + // If the file name doesn't end with ".mid", use the original file name + song_file_name = name.to_string(); + } + } + } + } + let center_text = centered_text(format!("Selected song: {}", song_file_name)) + .size(12) + .width(Length::Fill) + .horizontal_alignment(Horizontal::Center); + + let center_text_container = container(center_text) + .width(Length::Fill) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(Padding { + top: 25.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }); + elements.push(center_text_container.into()); + + elements.push( + col![vertical_space().height(Length::Fixed(10.0)), column] + .align_items(Alignment::Center) + .width(Length::Fill) + .into(), + ); + + let mut song_directory = String::new(); + + if let Some(_path_buf) = &ctx.config.song_directory { + if let Some(path_buf) = &ctx.config.song_directory { + song_directory = path_buf.to_string_lossy().to_string(); + } + } + let center_text = centered_text(format!("Midi directory path: {}", song_directory)) + .size(12) + .width(Length::Fill) + .horizontal_alignment(Horizontal::Center); + + let center_text_container = container(center_text) + .width(Length::Fill) + .align_x(Horizontal::Left) + .align_y(Vertical::Bottom) + .padding(Padding { + top: 80.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }); + elements.push(center_text_container.into()); + + let column = iced_widget::scrollable(iced_widget::column(elements)); + + let right = { + let play = NeoBtn::new( + icons::play_icon() + .size(30.0) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center), + ) + .height(Length::Fixed(60.0)) + .min_width(80.0) + .on_press(Event::Play); + + if ctx.song.is_some() { + row![play] + } else { + row![] + } + .spacing(10) + .width(Length::Shrink) + .align_items(Alignment::Center) + }; + + let right = container(right) + .width(Length::Fill) + .align_x(Horizontal::Right) + .align_y(Vertical::Center) + .padding(Padding { + top: 0.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }); + + let left = { + let back = NeoBtn::new( + icons::left_arrow_icon() + .size(30.0) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center), + ) + .height(Length::Fixed(60.0)) + .min_width(80.0) + .on_press(Event::GoBack); + + row![back].align_items(Alignment::Start) + }; + + let left = container(left) + .width(Length::Fill) + .align_x(Horizontal::Left) + .align_y(Vertical::Center) + .padding(Padding { + top: 0.0, + right: 10.0, + bottom: 10.0, + left: 10.0, + }); + + let center = { + let folderbtn = NeoBtn::new( + icons::folder_icon() + .size(30.0) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center), + ) + .height(Length::Fixed(60.0)) + .min_width(80.0) + .on_press(Event::OpenFolderPicker); + + container(folderbtn) + .width(Length::Fill) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(Padding { + top: 0.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }) + }; + + Layout::new() + .body(column) + .bottom(BarLayout::new().left(left).center(center).right(right)) + .into() + } + + fn keyboard_input(event: &iced_runtime::keyboard::Event, _ctx: &Context) -> Option { + use iced_runtime::keyboard::{key::Named, Event, Key}; + + match event { + Event::KeyPressed { + key: Key::Named(key), + .. + } => match key { + Named::Enter => Some(Message::SelectsongPage(self::Event::Play)), + Named::Escape => Some(Message::GoToPage(Step::Main)), + _ => None, + }, + _ => None, + } + } +} diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs new file mode 100644 index 00000000..52c6925a --- /dev/null +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -0,0 +1,235 @@ +use crate::{context::Context, scene::menu_scene::icons}; +use chrono::{DateTime, Local}; +use iced_core::{ + alignment::{Horizontal, Vertical}, + Alignment, Length, Padding, +}; +use iced_widget::{column as col, container, row, vertical_space}; +use neothesia_core::gamesave::{SavedStats, SongStats}; +use neothesia_iced_widgets::{BarLayout, Element, Layout, NeoBtn}; + +use super::{ + centered_text, + page::{Page, PageMessage}, + Data, Message, +}; + +#[derive(Debug, Clone)] +pub enum Event { + GoBack, + Play, +} + +use crate::menu_scene::Step; +pub struct StatsPage; + +impl Page for StatsPage { + type Event = Event; + + fn update(data: &mut Data, event: Event, ctx: &mut Context) -> PageMessage { + match event { + Event::GoBack => return PageMessage::go_to_page(Step::Main), + Event::Play => { + super::play(data, ctx); + } + } + + PageMessage::none() + } + + fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { + let mut songhistory = Vec::new(); + + let mut songname = String::new(); + if let Some(song) = ctx.song.as_ref() { + songname = song.file.name.clone(); + // Clear out .ext + if let Some(stripped_name) = songname.to_lowercase().strip_suffix(".mid") { + songname = stripped_name.to_string(); + } + } + + // Add header + let first_place_card = neothesia_iced_widgets::StatsContainer::new() + .image(0) + .date("Date") + .place("Place") + .score("Score") + .notes_hits("Hits") + .notes_missed("Misses") + .wrong_notes("Mistakes") + .correct_notes_duration("Durations") + .header(true); + songhistory.push(Vec::>::from( + first_place_card, + )); + + // Load saved stats and filter stats for the current song + if let Some(saved_stats) = SavedStats::load() { + // Filter stats for the current song + let filtered_stats: Vec<&SongStats> = saved_stats + .songs + .iter() + .filter(|stats| stats.song_name == songname) + .collect(); + + // Sort stats by fewer wrong_notes, fewer notes_missed, and max note_hits + let mut sorted_stats = filtered_stats.clone(); + sorted_stats.sort_by(|a, b| { + let score_a = a.wrong_notes + a.notes_missed - a.notes_hit; + let score_b = b.wrong_notes + b.notes_missed - b.notes_hit; + score_a.cmp(&score_b) + }); + + // Populate data into tracks + for (index, stats) in sorted_stats.iter().enumerate() { + let datetime: DateTime = stats.date.into(); + let score = (index + 1) as u32; + let trophy_image = if score <= 2 { score } else { 0 }; + let card = neothesia_iced_widgets::StatsContainer::new() + .image(trophy_image) + .date(datetime.format("%d/%m/%y %H:%M:%S").to_string()) + .place(&(index + 1).to_string()) // Index starts from 1 + .score(&(stats.notes_hit * 10).to_string()) // Example scoring logic + .notes_hits(stats.notes_hit) + .notes_missed(stats.notes_missed) + .wrong_notes(stats.wrong_notes) + .correct_notes_duration(&format!("{}", stats.correct_note_times)); // Assuming this is a time duration + songhistory.push(Vec::>::from(card)); + } + } + + let mut elements = Vec::new(); + for children in songhistory { + elements.extend(children); + } + + // Now add the final container + let column = iced_widget::scrollable(iced_widget::column(elements)); + + let mut elements = Vec::new(); + + let center_text = centered_text(songname) + .size(20) + .width(Length::Fill) + .horizontal_alignment(Horizontal::Center); + + let center_text_container = container(center_text) + .width(Length::Fill) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(Padding { + top: 25.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }); + elements.push(center_text_container.into()); + + elements.push( + col![vertical_space().height(Length::Fixed(10.0)), column] + .align_items(Alignment::Center) + .width(Length::Fill) + .into(), + ); + + let column = iced_widget::scrollable(iced_widget::column(elements)); + + let right = { + let play = NeoBtn::new( + icons::play_icon() + .size(30.0) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center), + ) + .height(Length::Fixed(60.0)) + .min_width(80.0) + .on_press(Event::Play); + + if ctx.song.is_some() { + row![play] + } else { + row![] + } + .spacing(10) + .width(Length::Shrink) + .align_items(Alignment::Center) + }; + + let right = container(right) + .width(Length::Fill) + .align_x(Horizontal::Right) + .align_y(Vertical::Center) + .padding(Padding { + top: 0.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }); + + let left = { + let back = NeoBtn::new( + icons::left_arrow_icon() + .size(30.0) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center), + ) + .height(Length::Fixed(60.0)) + .min_width(80.0) + .on_press(Event::GoBack); + + row![back].align_items(Alignment::Start) + }; + + let left = container(left) + .width(Length::Fill) + .align_x(Horizontal::Left) + .align_y(Vertical::Center) + .padding(Padding { + top: 0.0, + right: 10.0, + bottom: 10.0, + left: 10.0, + }); + + let center = { + container( + centered_text("Hit enter to play again") + .size(20) + .width(Length::Fill) + .horizontal_alignment(Horizontal::Center) + .vertical_alignment(Vertical::Center), + ) + .width(Length::Fill) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(Padding { + top: 0.0, + right: 10.0, + bottom: 10.0, + left: 0.0, + }) + }; + + Layout::new() + .body(column) + .bottom(BarLayout::new().left(left).center(center).right(right)) + .into() + } + + fn keyboard_input(event: &iced_runtime::keyboard::Event, _ctx: &Context) -> Option { + use iced_runtime::keyboard::{key::Named, Event, Key}; + + match event { + Event::KeyPressed { + key: Key::Named(key), + .. + } => match key { + Named::Enter => Some(Message::StatsPage(self::Event::Play)), + Named::Escape => Some(Message::GoToPage(Step::Main)), + _ => None, + }, + _ => None, + } + } +} diff --git a/neothesia/src/scene/menu_scene/iced_menu/theme.rs b/neothesia/src/scene/menu_scene/iced_menu/theme.rs index 4de0425c..29c1c857 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/theme.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/theme.rs @@ -139,7 +139,7 @@ impl iced_style::button::StyleSheet for RoundButtonStyle { pub fn _checkbox() -> iced_style::theme::Checkbox { iced_style::theme::Checkbox::Custom(Box::new(CheckboxStyle)) } - +#[allow(dead_code)] struct CheckboxStyle; impl iced_style::checkbox::StyleSheet for CheckboxStyle { @@ -224,3 +224,40 @@ impl iced_style::toggler::StyleSheet for TogglerStyle { } } } + +pub fn filelist_button() -> iced_style::theme::Button { + iced_style::theme::Button::Custom(Box::new(FilelistButton)) +} + +struct FilelistButton; + +impl iced_style::button::StyleSheet for FilelistButton { + type Style = iced_style::Theme; + + fn active(&self, _style: &Self::Style) -> button::Appearance { + button::Appearance { + text_color: Color::WHITE, + border: Border { + width: 1.0, // + radius: Radius::from(0.0), + color: Color::from_rgba8(40, 10, 60, 1.0), // Very dark purple background + }, + background: Some(iced_core::Background::Color(Color::from_rgba8( + 30, 0, 50, 1.0, // Very very dark purple background + ))), + ..Default::default() + } + } + + fn hovered(&self, style: &Self::Style) -> button::Appearance { + let mut active = self.active(style); + + if let Some(iced_core::Background::Color(ref mut color)) = active.background { + color.r = (color.r + 0.05).min(1.0); // Slightly lighter on hover + color.g = (color.g + 0.05).min(1.0); + color.b = (color.b + 0.05).min(1.0); + } + + active + } +} diff --git a/neothesia/src/scene/menu_scene/icons.rs b/neothesia/src/scene/menu_scene/icons.rs index a0bb5a89..3b35cf0b 100644 --- a/neothesia/src/scene/menu_scene/icons.rs +++ b/neothesia/src/scene/menu_scene/icons.rs @@ -15,3 +15,6 @@ pub fn note_list_icon<'a>() -> iced_widget::Text<'a, Theme, Renderer> { pub fn left_arrow_icon<'a>() -> iced_widget::Text<'a, Theme, Renderer> { iced_widget::text('\u{f12f}').font(ICONS) } +pub fn folder_icon<'a>() -> iced_widget::Text<'a, Theme, Renderer> { + iced_widget::text('\u{F3D1}').font(ICONS) +} diff --git a/neothesia/src/scene/menu_scene/mod.rs b/neothesia/src/scene/menu_scene/mod.rs index bcff1588..aef12dd0 100644 --- a/neothesia/src/scene/menu_scene/mod.rs +++ b/neothesia/src/scene/menu_scene/mod.rs @@ -18,6 +18,7 @@ use crate::{ }, scene::Scene, }; +pub use iced_menu::Step; type Renderer = iced_wgpu::Renderer; @@ -30,8 +31,9 @@ pub struct MenuScene { } impl MenuScene { - pub fn new(ctx: &mut Context) -> Self { - let menu = AppUi::new(ctx); + pub fn new(ctx: &mut Context, goto: Step) -> Self { + let menu = AppUi::new(ctx, goto); + let iced_state = iced_state::State::new(menu, ctx.iced_manager.viewport.logical_size(), ctx); diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index cd1cc907..fd1d66fc 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -1,9 +1,10 @@ -use midi_file::midly::{num::u4, MidiMessage}; - use crate::{ output_manager::OutputConnection, song::{PlayerConfig, Song}, }; +use midi_file::midly::{num::u4, MidiMessage}; +use neothesia_core::gamesave::{SavedStats, SongStats}; +use std::time::SystemTime; use std::{ collections::HashMap, collections::VecDeque, @@ -17,19 +18,61 @@ pub struct MidiPlayer { play_along: PlayAlong, } +pub struct NoteStats { + song_name: String, + notes_missed: usize, + notes_hit: usize, + wrong_notes: i32, + note_durations: Vec, +} +#[derive(Debug)] +pub struct NoteDurations { + user_note_dur: usize, + file_note_dur: usize, +} +impl Default for NoteStats { + fn default() -> Self { + NoteStats { + song_name: String::new(), + notes_missed: 0, + notes_hit: 0, + wrong_notes: 0, + note_durations: Vec::new(), + } + } +} + +impl Default for NoteDurations { + fn default() -> Self { + NoteDurations { + user_note_dur: 0, + file_note_dur: 0, + } + } +} + impl MidiPlayer { pub fn new( output: OutputConnection, song: Song, user_keyboard_range: piano_math::KeyboardRange, ) -> Self { + let mut user_stats = NoteStats::default(); + if let Some(song_name) = song.file.name.to_lowercase().strip_suffix(".mid") { + user_stats.song_name = song_name.to_string(); + } else if let Some(song_name) = song.file.name.to_lowercase().strip_suffix(".midi") { + user_stats.song_name = song_name.to_string(); + } else { + user_stats.song_name = song.file.name.clone(); + } + let mut player = Self { playback: midi_file::PlaybackState::new( Duration::from_secs(3), song.file.tracks.clone(), ), output, - play_along: PlayAlong::new(user_keyboard_range), + play_along: PlayAlong::new(user_keyboard_range, user_stats), song, }; // Let's reset programs, @@ -40,7 +83,12 @@ impl MidiPlayer { player } - + pub fn on_finish(&mut self, callback: F) + where + F: Fn() + 'static, + { + self.play_along.set_on_finish(callback); + } pub fn song(&self) -> &Song { &self.song } @@ -207,39 +255,7 @@ struct UserPress { time_key_up: Instant, occurrence: usize, } -#[derive(Debug)] -pub struct NoteStats { - notes_missed: usize, - notes_hit: usize, - wrong_notes: i32, - note_durations: Vec, -} -#[derive(Debug)] -pub struct NoteDurations { - user_note_dur: usize, - file_note_dur: usize, -} -impl Default for NoteStats { - fn default() -> Self { - NoteStats { - notes_missed: 0, - notes_hit: 0, - wrong_notes: 0, - note_durations: Vec::new(), - } - } -} - -impl Default for NoteDurations { - fn default() -> Self { - NoteDurations { - user_note_dur: 0, - file_note_dur: 0, - } - } -} -#[derive(Debug)] pub struct PlayAlong { user_keyboard_range: piano_math::KeyboardRange, @@ -253,22 +269,31 @@ pub struct PlayAlong { user_notes: VecDeque, // log all user notes to get durrations file_notes: VecDeque, // log all file notes to compare against user occurrence: HashMap, // Keeping user to file log incremental pointer rewind immune + on_finish: Option>, } impl PlayAlong { - fn new(user_keyboard_range: piano_math::KeyboardRange) -> Self { + fn new(user_keyboard_range: piano_math::KeyboardRange, user_stats: NoteStats) -> Self { Self { user_keyboard_range, required_notes: Default::default(), user_pressed_recently: Default::default(), - user_stats: Default::default(), + occurrence: HashMap::new(), finished: Default::default(), user_notes: Default::default(), file_notes: Default::default(), + on_finish: None, + user_stats, } } + pub fn set_on_finish(&mut self, callback: F) + where + F: Fn() + 'static, + { + self.on_finish = Some(Box::new(callback)); + } fn update(&mut self) { let now = Instant::now(); @@ -470,8 +495,6 @@ impl PlayAlong { pub fn finished(&mut self) { if !self.finished { - println!("The song has finished"); - // TO-DO: Move to a stats screen, somehow save songname date and stats, a button restart song, etc // Loop through user_notes and file_notes and match entries with the same occurrence[note] = num for user_note in &self.user_notes { for file_note in &self.file_notes { @@ -497,7 +520,7 @@ impl PlayAlong { } } } - // Clean negative self.user_stats.wrong_notes + // Clear negative self.user_stats.wrong_notes if self.user_stats.wrong_notes < 0 { self.user_stats.wrong_notes = 0; } @@ -519,13 +542,30 @@ impl PlayAlong { } } - println!("Correct Note Timing: {}", correct_note_times); - println!("Wrong Note Timing: {}", wrong_note_times); - println!("Notes Missed: {}", self.user_stats.notes_missed); - println!("Notes Hit: {}", self.user_stats.notes_hit); - println!("Wrong Notes: {}", self.user_stats.wrong_notes); - // Maybe cook everything together for a total score + let mut saved_stats = SavedStats::load().unwrap_or_default(); + + // Create the new stats object + let new_stats = SongStats { + song_name: self.user_stats.song_name.clone(), + correct_note_times, + wrong_note_times, + notes_missed: self.user_stats.notes_missed as u32, + notes_hit: self.user_stats.notes_hit as u32, + wrong_notes: self.user_stats.wrong_notes as u32, + date: SystemTime::now(), + }; + // Push the new stats object to the existing SavedStats + saved_stats.songs.push(new_stats); + + // Save the modified SavedStats object + saved_stats.save(); + // better save right here keeping things simple, since stats could be loaded from song list when select folder for a file list is implemented + + // Maybe cook everything together for a total score + if let Some(callback) = &self.on_finish { + callback(); // Call on finish callback + } self.finished = true; } } diff --git a/neothesia/src/scene/playing_scene/mod.rs b/neothesia/src/scene/playing_scene/mod.rs index 446128d1..8cdc91ce 100644 --- a/neothesia/src/scene/playing_scene/mod.rs +++ b/neothesia/src/scene/playing_scene/mod.rs @@ -26,6 +26,7 @@ use toast_manager::ToastManager; mod animation; mod top_bar; +use crate::menu_scene::Step; const EVENT_CAPTURED: bool = true; const EVENT_IGNORED: bool = false; @@ -75,11 +76,17 @@ impl PlayingScene { keyboard_layout.clone(), ); - let player = MidiPlayer::new( + let mut player = MidiPlayer::new( ctx.output_manager.connection().clone(), song, keyboard_layout.range.clone(), ); + let weak_ctx = ctx.proxy.clone(); + player.on_finish(move || { + weak_ctx + .send_event(NeothesiaEvent::MainMenu { page: Step::Stats }) + .ok(); + }); waterfall.update(&ctx.gpu.queue, player.time_without_lead_in()); Self { @@ -222,7 +229,9 @@ fn handle_back_button(ctx: &Context, event: &WindowEvent) { ); if is_back_event { - ctx.proxy.send_event(NeothesiaEvent::MainMenu).ok(); + ctx.proxy + .send_event(NeothesiaEvent::MainMenu { page: Step::Main }) + .ok(); } } diff --git a/neothesia/src/scene/playing_scene/top_bar.rs b/neothesia/src/scene/playing_scene/top_bar.rs index 8d0058b2..04607734 100644 --- a/neothesia/src/scene/playing_scene/top_bar.rs +++ b/neothesia/src/scene/playing_scene/top_bar.rs @@ -18,8 +18,8 @@ use super::{ }; mod button; +use crate::menu_scene::Step; use button::Button; - #[derive(Default, Clone, Copy)] enum Element { StartTick, @@ -171,7 +171,9 @@ impl TopBar { scene.top_bar.settings_active = !scene.top_bar.settings_active; } Element::BackButton => { - ctx.proxy.send_event(NeothesiaEvent::MainMenu).ok(); + ctx.proxy + .send_event(NeothesiaEvent::MainMenu { page: Step::Main }) + .ok(); return EVENT_CAPTURED; } Element::StartTick | Element::EndTick => { From 324d0bae5d31a5b6bd847aa71182d3466cdb357b Mon Sep 17 00:00:00 2001 From: captainerd Date: Tue, 21 May 2024 13:41:22 +0300 Subject: [PATCH 09/29] gamestats adjustments --- neothesia/src/scene/menu_scene/iced_menu/stats.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index 52c6925a..bad9fc7b 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -80,21 +80,24 @@ impl Page for StatsPage { let score_b = b.wrong_notes + b.notes_missed - b.notes_hit; score_a.cmp(&score_b) }); + // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { + + let scores = stats.notes_hit + stats.correct_note_times * 10 - (stats.notes_missed + stats.wrong_note_times + stats.notes_missed); // There are many ways to cook let datetime: DateTime = stats.date.into(); let score = (index + 1) as u32; - let trophy_image = if score <= 2 { score } else { 0 }; + let trophy_image = if score <= 3 { score } else { 0 }; let card = neothesia_iced_widgets::StatsContainer::new() .image(trophy_image) .date(datetime.format("%d/%m/%y %H:%M:%S").to_string()) .place(&(index + 1).to_string()) // Index starts from 1 - .score(&(stats.notes_hit * 10).to_string()) // Example scoring logic + .score(scores) // Example scoring logic .notes_hits(stats.notes_hit) .notes_missed(stats.notes_missed) .wrong_notes(stats.wrong_notes) - .correct_notes_duration(&format!("{}", stats.correct_note_times)); // Assuming this is a time duration + .correct_notes_duration( stats.correct_note_times); songhistory.push(Vec::>::from(card)); } } From def57e7f7432ef397878583b6f07efb5f7af6886 Mon Sep 17 00:00:00 2001 From: captainerd Date: Tue, 21 May 2024 16:45:34 +0300 Subject: [PATCH 10/29] New screens UI Resposiveness+themeing --- .../scene/menu_scene/iced_menu/selectsong.rs | 55 ++++++++++------ .../src/scene/menu_scene/iced_menu/stats.rs | 63 ++++++++++++------- .../src/scene/menu_scene/iced_menu/theme.rs | 24 ++++--- 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs index 1a0fa0c8..d1c27142 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs @@ -91,6 +91,23 @@ impl Page for SelectsongPage { path } }; + + let mut song_file_name = String::new(); + + if let Some(path_buf) = &ctx.config.last_opened_song { + if let Some(file_name) = path_buf.file_name() { + if let Some(name) = file_name.to_str() { + if let Some(stripped_name) = name.strip_suffix(".mid") { + song_file_name = stripped_name.to_string(); + } else { + // If the file name doesn't end with ".mid", use the original file name + song_file_name = name.to_string(); + } + } + } + } + + let mut elements = Vec::new(); if let Ok(entries) = fs::read_dir(&dir_path) { for entry in entries { @@ -104,13 +121,17 @@ impl Page for SelectsongPage { } else { file_name.to_string() }; - + let button_color = if song_file_name == song_name { + iced_core::Color::from_rgb8(106, 0, 163) + } else { + iced_core::Color::from_rgb8(54, 0, 107) + }; // Create a button with the song name let button = button(centered_text(&song_name)) .on_press(Event::SetSongPath { last_opened_song: Some(entry.path().clone()), }) - .style(theme::filelist_button()) + .style(theme::filelist_button(button_color)) .width(10000); elements.push(button.into()); @@ -121,10 +142,19 @@ impl Page for SelectsongPage { } } - // Now add the final container - let column = iced_widget::scrollable(iced_widget::column(elements)); + // Add the list into another scrollable for a responsive UI + let inner_scrollable = iced_widget::Scrollable::new( + iced_widget::Column::with_children(elements) + .spacing(5) + .align_items(Alignment::Start), + ) .height(ctx.window_state.logical_size.height as u16 - 400).width(ctx.window_state.logical_size.width as u16 - 421); - let mut elements = Vec::new(); + let inner_scrollable_element: Element<'_, Event> = inner_scrollable.into(); + + + let column = iced_widget::scrollable(iced_widget::column(vec![inner_scrollable_element])); + + let mut elements = Vec::new(); let center_text = centered_text("Song list") .size(20) @@ -142,20 +172,7 @@ impl Page for SelectsongPage { left: 0.0, }); elements.push(center_text_container.into()); - let mut song_file_name = String::new(); - - if let Some(path_buf) = &ctx.config.last_opened_song { - if let Some(file_name) = path_buf.file_name() { - if let Some(name) = file_name.to_str() { - if let Some(stripped_name) = name.strip_suffix(".mid") { - song_file_name = stripped_name.to_string(); - } else { - // If the file name doesn't end with ".mid", use the original file name - song_file_name = name.to_string(); - } - } - } - } + let center_text = centered_text(format!("Selected song: {}", song_file_name)) .size(12) .width(Length::Fill) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index bad9fc7b..c8755b97 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -49,21 +49,6 @@ impl Page for StatsPage { } } - // Add header - let first_place_card = neothesia_iced_widgets::StatsContainer::new() - .image(0) - .date("Date") - .place("Place") - .score("Score") - .notes_hits("Hits") - .notes_missed("Misses") - .wrong_notes("Mistakes") - .correct_notes_duration("Durations") - .header(true); - songhistory.push(Vec::>::from( - first_place_card, - )); - // Load saved stats and filter stats for the current song if let Some(saved_stats) = SavedStats::load() { // Filter stats for the current song @@ -80,12 +65,11 @@ impl Page for StatsPage { let score_b = b.wrong_notes + b.notes_missed - b.notes_hit; score_a.cmp(&score_b) }); - // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { - - let scores = stats.notes_hit + stats.correct_note_times * 10 - (stats.notes_missed + stats.wrong_note_times + stats.notes_missed); // There are many ways to cook + let scores = stats.notes_hit + stats.correct_note_times * 10 + - (stats.notes_missed + stats.wrong_note_times + stats.notes_missed); // There are many ways to cook let datetime: DateTime = stats.date.into(); let score = (index + 1) as u32; let trophy_image = if score <= 3 { score } else { 0 }; @@ -93,21 +77,54 @@ impl Page for StatsPage { .image(trophy_image) .date(datetime.format("%d/%m/%y %H:%M:%S").to_string()) .place(&(index + 1).to_string()) // Index starts from 1 - .score(scores) // Example scoring logic + .score(scores) .notes_hits(stats.notes_hit) .notes_missed(stats.notes_missed) .wrong_notes(stats.wrong_notes) - .correct_notes_duration( stats.correct_note_times); + .correct_notes_duration(stats.correct_note_times); songhistory.push(Vec::>::from(card)); } } - let mut elements = Vec::new(); + // Collect all elements from songhistory into a single Vec + let mut all_elements = Vec::new(); for children in songhistory { - elements.extend(children); + all_elements.extend(children); } - // Now add the final container + // Create a Scrollable widget with the collected elements + let scrollable = iced_widget::Scrollable::new( + iced_widget::Column::with_children(all_elements) + .spacing(10) + .align_items(Alignment::Start), + ) + .height(ctx.window_state.logical_size.height as u16 - 400); + + + let mut elements = Vec::new(); + let scrollable_element: Element<'_, Event> = scrollable.into(); + + // Insert the header of the "List" and the Scrollable element "items" into the elements vector for a more list-like responsive UI + let mut songhistory_header = Vec::new(); + let first_place_card = neothesia_iced_widgets::StatsContainer::new() + .image(0) + .date("Date") + .place("Place") + .score("Score") + .notes_hits("Hits") + .notes_missed("Misses") + .wrong_notes("Mistakes") + .correct_notes_duration("Durations") + .header(true); + songhistory_header.push(Vec::>::from( + first_place_card, + )); + + for children in songhistory_header { + elements.extend(children); + } + elements.push(scrollable_element.into()); + let column = iced_widget::scrollable(iced_widget::column(elements)); let mut elements = Vec::new(); diff --git a/neothesia/src/scene/menu_scene/iced_menu/theme.rs b/neothesia/src/scene/menu_scene/iced_menu/theme.rs index 29c1c857..7c75117f 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/theme.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/theme.rs @@ -225,11 +225,19 @@ impl iced_style::toggler::StyleSheet for TogglerStyle { } } -pub fn filelist_button() -> iced_style::theme::Button { - iced_style::theme::Button::Custom(Box::new(FilelistButton)) +pub fn filelist_button(color: Color) -> iced_style::theme::Button { + iced_style::theme::Button::Custom(Box::new(FilelistButton::new(color))) } -struct FilelistButton; +struct FilelistButton { + color: Color, +} + +impl FilelistButton { + pub fn new(color: Color) -> Self { + Self { color } + } +} impl iced_style::button::StyleSheet for FilelistButton { type Style = iced_style::Theme; @@ -238,13 +246,13 @@ impl iced_style::button::StyleSheet for FilelistButton { button::Appearance { text_color: Color::WHITE, border: Border { - width: 1.0, // + width: 0.0, // + radius: Radius::from(0.0), - color: Color::from_rgba8(40, 10, 60, 1.0), // Very dark purple background + color: Color::TRANSPARENT, }, - background: Some(iced_core::Background::Color(Color::from_rgba8( - 30, 0, 50, 1.0, // Very very dark purple background - ))), + + background: Some(iced_core::Background::Color(self.color)), ..Default::default() } } From 537960393435fb6badf9f08a67c0353faa6c30e3 Mon Sep 17 00:00:00 2001 From: captainerd Date: Tue, 21 May 2024 16:47:51 +0300 Subject: [PATCH 11/29] fmt --- .../scene/menu_scene/iced_menu/selectsong.rs | 22 +++++++++---------- .../src/scene/menu_scene/iced_menu/stats.rs | 11 +++++----- .../src/scene/menu_scene/iced_menu/theme.rs | 6 ++--- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs index d1c27142..4df6cf3b 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs @@ -107,7 +107,6 @@ impl Page for SelectsongPage { } } - let mut elements = Vec::new(); if let Ok(entries) = fs::read_dir(&dir_path) { for entry in entries { @@ -121,11 +120,11 @@ impl Page for SelectsongPage { } else { file_name.to_string() }; - let button_color = if song_file_name == song_name { - iced_core::Color::from_rgb8(106, 0, 163) - } else { - iced_core::Color::from_rgb8(54, 0, 107) - }; + let button_color = if song_file_name == song_name { + iced_core::Color::from_rgb8(106, 0, 163) + } else { + iced_core::Color::from_rgb8(54, 0, 107) + }; // Create a button with the song name let button = button(centered_text(&song_name)) .on_press(Event::SetSongPath { @@ -143,18 +142,19 @@ impl Page for SelectsongPage { } // Add the list into another scrollable for a responsive UI - let inner_scrollable = iced_widget::Scrollable::new( + let inner_scrollable = iced_widget::Scrollable::new( iced_widget::Column::with_children(elements) .spacing(5) .align_items(Alignment::Start), - ) .height(ctx.window_state.logical_size.height as u16 - 400).width(ctx.window_state.logical_size.width as u16 - 421); + ) + .height(ctx.window_state.logical_size.height as u16 - 400) + .width(ctx.window_state.logical_size.width as u16 - 421); let inner_scrollable_element: Element<'_, Event> = inner_scrollable.into(); - let column = iced_widget::scrollable(iced_widget::column(vec![inner_scrollable_element])); - let mut elements = Vec::new(); + let mut elements = Vec::new(); let center_text = centered_text("Song list") .size(20) @@ -172,7 +172,7 @@ impl Page for SelectsongPage { left: 0.0, }); elements.push(center_text_container.into()); - + let center_text = centered_text(format!("Selected song: {}", song_file_name)) .size(12) .width(Length::Fill) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index c8755b97..ff6f27da 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -77,7 +77,7 @@ impl Page for StatsPage { .image(trophy_image) .date(datetime.format("%d/%m/%y %H:%M:%S").to_string()) .place(&(index + 1).to_string()) // Index starts from 1 - .score(scores) + .score(scores) .notes_hits(stats.notes_hit) .notes_missed(stats.notes_missed) .wrong_notes(stats.wrong_notes) @@ -96,10 +96,9 @@ impl Page for StatsPage { let scrollable = iced_widget::Scrollable::new( iced_widget::Column::with_children(all_elements) .spacing(10) - .align_items(Alignment::Start), + .align_items(Alignment::Start), ) - .height(ctx.window_state.logical_size.height as u16 - 400); - + .height(ctx.window_state.logical_size.height as u16 - 400); let mut elements = Vec::new(); let scrollable_element: Element<'_, Event> = scrollable.into(); @@ -119,12 +118,12 @@ impl Page for StatsPage { songhistory_header.push(Vec::>::from( first_place_card, )); - + for children in songhistory_header { elements.extend(children); } elements.push(scrollable_element.into()); - + let column = iced_widget::scrollable(iced_widget::column(elements)); let mut elements = Vec::new(); diff --git a/neothesia/src/scene/menu_scene/iced_menu/theme.rs b/neothesia/src/scene/menu_scene/iced_menu/theme.rs index 7c75117f..ec0bd44e 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/theme.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/theme.rs @@ -247,11 +247,11 @@ impl iced_style::button::StyleSheet for FilelistButton { text_color: Color::WHITE, border: Border { width: 0.0, // - + radius: Radius::from(0.0), - color: Color::TRANSPARENT, + color: Color::TRANSPARENT, }, - + background: Some(iced_core::Background::Color(self.color)), ..Default::default() } From 767333798e9b739fa72ae1790ce7c1b1322e0e24 Mon Sep 17 00:00:00 2001 From: captainerd Date: Wed, 22 May 2024 08:14:14 +0300 Subject: [PATCH 12/29] Scenes Refinements, track icons --- Cargo.lock | 4 +- neothesia-iced-widgets/Cargo.toml | 2 +- .../src/stats_container/mod.rs | 18 +- .../src/stats_container/theme.rs | 6 - .../src/track_card/img/bells.png | Bin 0 -> 2292 bytes .../src/track_card/img/brasses.png | Bin 12598 -> 2371 bytes .../src/track_card/img/choirs.png | Bin 0 -> 8108 bytes .../src/track_card/img/flutes.png | Bin 0 -> 6967 bytes .../src/track_card/img/guitars.png | Bin 24088 -> 3459 bytes .../src/track_card/img/percussions.png | Bin 0 -> 6492 bytes .../src/track_card/img/piano-left.png | Bin 4265 -> 739 bytes .../src/track_card/img/piano-right.png | Bin 4633 -> 718 bytes .../src/track_card/img/sercussions.png | Bin 36452 -> 0 bytes .../src/track_card/img/toggle_off.png | Bin 0 -> 7070 bytes .../src/track_card/img/toggle_on.png | Bin 0 -> 6798 bytes .../src/track_card/img/violins.png | Bin 43330 -> 5214 bytes .../src/track_card/img/xylophones.png | Bin 0 -> 2855 bytes neothesia-iced-widgets/src/track_card/mod.rs | 209 ++++++++++++++++-- .../src/track_card/theme.rs | 33 +++ neothesia/Cargo.toml | 2 +- .../src/scene/menu_scene/iced_menu/stats.rs | 1 + .../src/scene/menu_scene/iced_menu/tracks.rs | 15 +- .../src/scene/playing_scene/midi_player.rs | 9 +- 23 files changed, 246 insertions(+), 53 deletions(-) create mode 100644 neothesia-iced-widgets/src/track_card/img/bells.png create mode 100644 neothesia-iced-widgets/src/track_card/img/choirs.png create mode 100644 neothesia-iced-widgets/src/track_card/img/flutes.png create mode 100755 neothesia-iced-widgets/src/track_card/img/percussions.png delete mode 100755 neothesia-iced-widgets/src/track_card/img/sercussions.png create mode 100644 neothesia-iced-widgets/src/track_card/img/toggle_off.png create mode 100644 neothesia-iced-widgets/src/track_card/img/toggle_on.png mode change 100755 => 100644 neothesia-iced-widgets/src/track_card/img/violins.png create mode 100644 neothesia-iced-widgets/src/track_card/img/xylophones.png diff --git a/Cargo.lock b/Cargo.lock index 712577ee..bd3956c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2353,7 +2353,7 @@ dependencies = [ [[package]] name = "neothesia" -version = "0.1.0" +version = "0.1.8" dependencies = [ "async-thread", "chrono", @@ -2415,7 +2415,7 @@ dependencies = [ [[package]] name = "neothesia-iced-widgets" -version = "0.1.0" +version = "0.1.1" dependencies = [ "iced_core", "iced_graphics", diff --git a/neothesia-iced-widgets/Cargo.toml b/neothesia-iced-widgets/Cargo.toml index 835f5890..92ecb9b0 100644 --- a/neothesia-iced-widgets/Cargo.toml +++ b/neothesia-iced-widgets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "neothesia-iced-widgets" -version = "0.1.0" +version = "0.1.1" edition = "2021" [dependencies] diff --git a/neothesia-iced-widgets/src/stats_container/mod.rs b/neothesia-iced-widgets/src/stats_container/mod.rs index 8ab4f941..5954e0fa 100644 --- a/neothesia-iced-widgets/src/stats_container/mod.rs +++ b/neothesia-iced-widgets/src/stats_container/mod.rs @@ -123,13 +123,13 @@ impl<'a, MSG: 'a + Clone> StatsContainer<'a, MSG> { impl<'a, M: Clone + 'a> From> for Vec> { fn from(card: StatsContainer<'a, M>) -> Self { let columns = vec![ - (card.place, 40), - (card.date, 80), - (card.score, 40), - (card.notes_hits, 30), - (card.notes_missed, 45), - (card.wrong_notes, 60), - (card.correct_notes_duration, 55), + (card.place, 90), + (card.date, 90), + (card.score, 90), + (card.notes_hits, 90), + (card.notes_missed, 90), + (card.wrong_notes, 90), + (card.correct_notes_duration, 90), ]; let header_row = columns @@ -145,7 +145,7 @@ impl<'a, M: Clone + 'a> From> for Vec> { .collect::>(); let header = iced_widget::row(header_row) - .spacing(3) + .spacing(0) .align_items(Alignment::Start); let image_container = if let Some(image) = card.image { @@ -173,7 +173,7 @@ impl<'a, M: Clone + 'a> From> for Vec> { .into(); children.push(centered_with_style); } else { - children.push(centered_container.padding(10).into()); + children.push(centered_container.padding(8).into()); } children diff --git a/neothesia-iced-widgets/src/stats_container/theme.rs b/neothesia-iced-widgets/src/stats_container/theme.rs index efcfeee8..b311f9bf 100644 --- a/neothesia-iced-widgets/src/stats_container/theme.rs +++ b/neothesia-iced-widgets/src/stats_container/theme.rs @@ -1,5 +1,3 @@ -use iced_core::border::{Border, Radius}; - pub fn card() -> iced_style::theme::Container { iced_style::theme::Container::Custom(Box::new(ContainerStyle)) } @@ -14,11 +12,7 @@ impl iced_style::container::StyleSheet for ContainerStyle { background: Some(iced_core::Background::from(iced_core::Color::from_rgba8( 44, 59, 102, 1.0, ))), - border: Border { - radius: Radius::from(0), - ..Default::default() - }, ..Default::default() } } diff --git a/neothesia-iced-widgets/src/track_card/img/bells.png b/neothesia-iced-widgets/src/track_card/img/bells.png new file mode 100644 index 0000000000000000000000000000000000000000..c5d48a7e4117ae75959fd52ca2ebbb84fb06a681 GIT binary patch literal 2292 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 literal 12598 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 diff --git a/neothesia-iced-widgets/src/track_card/img/choirs.png b/neothesia-iced-widgets/src/track_card/img/choirs.png new file mode 100644 index 0000000000000000000000000000000000000000..02e35329731932a5313f4a43372d37fbab15b382 GIT binary patch literal 8108 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 JPDHLkV1m*BTu}f3 literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/track_card/img/guitars.png b/neothesia-iced-widgets/src/track_card/img/guitars.png index e8aa924d7e6719a87c98d9b1868344cf6b745faa..aad15c4b8d204d247806e89515dc8a18f1188add 100755 GIT binary patch literal 3459 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 HhmZRo8)fX~ literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/track_card/img/piano-left.png b/neothesia-iced-widgets/src/track_card/img/piano-left.png index 3bf0315e83151bd2b679cc097372a1b9b1edfd75..be1c0ba01996ad107bc3e311024fd479a57c2e9a 100755 GIT binary patch delta 677 zcmZ3f_?T6(Gr-TCmrII^fq{Y7)59eQNT+}>2Q!d#w@FQ#sHn=iF~BFpbz-1ay#Tv# znMvPTpYxmit^ygo-MyDDUO9W_TyIaWu(0sa@HbcE{`c9hTDg4X-{1cNloJ-XADHa8 zftO9-)r;3a1=;!yhr?b8afp_el`mejc&gK;jT<%{3VZSF>GL-0g}iM1Ks)*Q`RC7D za3bQv7XRy095-%Qx8d5AYwzB?zk21GKs~!~icUqR?GoMPj}`&dT9*X*1v4;ebzFG; z?|-A%+|P#R-d%h19|+!Dd-niDgTRCLK;qG-&!1nuy!!gj>#HCC{Qv*wXJ1^KgOL^98a&wEgkocrYRo>Zar$x>F`naFn#gsWxbFFjtj|eLz zpVBW%ZZ=OZbxhS@*)uiRd5LJ!>Ef@oDNCKUOtF2n%wK#SxA;%9j{MxC3UMDV&T|XU z&Hi$kU4p+=b8*Vr>YKMKPBiW={qU7%qFH_3nY`9-({6tMb@NI7gu~OnK47?RuY76# z%(v23Wd}abQD{C8*O=$@ZH_{wTMLJvl1qnxq7#&nDYH`I4|_^=)C{AUv)_JLl@-wU z=FF%48&`gue6@L%qovaB14oawBrEKdRbH#j_O#I$I~f_a-CFibbHTP-xD zNO@V@Wb>pSl~-6kdoiMz|HoA2`||p|Cloe>?5kZEr;;6i!ZhhhSB**1mo2vTtWCX| zp2?l@G1(t~AGkizl;y0+ag$5WE_)mfGF}^g)?{Mm=dvB;wI>xm)<0ce4~$s`Pgg&e IbxsLQ09Z3jng9R* literal 4265 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 diff --git a/neothesia-iced-widgets/src/track_card/img/piano-right.png b/neothesia-iced-widgets/src/track_card/img/piano-right.png index 1fbdbc8e0e6e97c26c0cbbad292b0e7bf73dd28e..294f23bf3d2481e2eb671a28bc43f716cda758b6 100755 GIT binary patch delta 656 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 S+k*dN1Lr>@othi>p8P+~qD=n) literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/track_card/img/toggle_on.png b/neothesia-iced-widgets/src/track_card/img/toggle_on.png new file mode 100644 index 0000000000000000000000000000000000000000..dbfdfbc015089cad92b7d8fd0352e8957a969206 GIT binary patch literal 6798 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 literal 0 HcmV?d00001 diff --git a/neothesia-iced-widgets/src/track_card/img/violins.png b/neothesia-iced-widgets/src/track_card/img/violins.png old mode 100755 new mode 100644 index ac59f7b1bb66cd8ecd8543766a5484ec2a4c3898..e6284ae7dacf1d7f845e5d20ffa3b8f49f071b0c GIT binary patch literal 5214 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 Y|97W*yxNJ&O8@`>07*qoM6N<$f^}dIYXATM literal 43330 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 diff --git a/neothesia-iced-widgets/src/track_card/img/xylophones.png b/neothesia-iced-widgets/src/track_card/img/xylophones.png new file mode 100644 index 0000000000000000000000000000000000000000..75a40d49a677c0ea1080b003dbf410339eb0bd03 GIT binary patch literal 2855 zcmV+?3)u9DP)<%IM!t$$fj+R%0AVrv2)?-URY7{bc!@ zsY$+bvfuA-8o9!JmzqTTl_Ig}bOZxef`In-0R6i_>pOsMEzq(CXnq@LdJAX_1R7TJSijyts1K%#4dIm25XBDE z29u^v!@_DpNow4!&aYfUK6M{3pPDH4fG$!TbXBPlP67bV} z;LJRrU@nmV8jtm{KOt`cY76{GdwMaY=lM~}sim~@lrL!t-eN(yek2udVY3TE$fxl~ z%VU$h&E0}{XeL8Q?K^~)FH~GkR#6|vP`imx6+)<3L%0|Klr0;Xki1uc({q5_*+9-K zz{y!a_Dmpi2Jqv{K*meJi5G#i7l7mc0ggS-mwbJeFClFX6=nHTPUdpaNRIQTFAyoHo-%L%cLA-b=X zVP*8R$S7SlK8Gw%LJmEPcCQv<`k29#qo8LSIfQh7%FvUgzz|IiAszgAT|X*lji3<; zspjjiWLunM81*u$qS&~NA)bUB{=T?6B+NYvp!@wBQ&JSN5dsXOyC$0~%3Nc*YgGZVyzQ_E! zg?MpeXcbcZnS$;n8Qsm!=^7mVoR)kujy~_rdq~W$U&vSw>XRyj5-Cgw@ggB?FPkld zIQ1cuCq!x=XwEWaMcE@D2if0=ZZM;}Q|Rw1n$(A2(%KmLs8Qzo_Xw0^=Q9ZyTLEzKV>sfp+EZYDK;$RxXv zia<)K+sUL$J9v_qRP%u?)!Ug=m1xV)2|VvJseSQ}`!V*i8L&zcZ)tjl+Zzk<^ zA=;aL-9dYZ=4R?jf=RLqDUVjAo2kuSPFkyw)aP#g{Z1G{h?gORco{;7mm!3B5tc*h zRLd3wJA{1Bg8FhSfAUmks+Xr2K4FjQBdGS8kaeil$CFP_p~d5MRfZhP-8JjzNrw<$ zBwvbWe;vvDtxi^_7QaUkb|L42Sa3tC<-U>Bo{M2mWckr$tB~)XMeT_tAD;rVfst;)nMWZg7e1@xSe4qJO1(Lz358+Gg zT1sz8Ra|b|%0zWa@oI`MnD5+&Oiy)+ZZn4>w;*ftJf?I zVG9c9!!m4R_zIM>q3j<+>$;ldJF=J29(SF3>I^D79j4y%%eU$;fF)9ir*m1xIMNKQ zGv+CO>7#p)~VkDAg z*8}VQs}h8e2}cMKLWB@^2qE4lL~#u2gN1Z)A#pVPwY@^f_`njV;M%m;`uUJu1oMXk znJ@eK-r>0VJ<<8<_rXHCvlaB|`K;`EdM=uUkkO(h(?YkO4~c}a@1Xkd(7M4wdJ1p6 ziI}lL7D7gg^@aiJ$FxO>b|EARM$?CEk*hi(WSmhBu&I{K@ZmyyxDcOy4Udb@XV?)! zybK}4%jn$2974L%_@Le)JJMY|FsNS+awB9VpPe02p!?RAmV*jvw=p4PH1y_K?(GPL zY!%YJo@X0Dzm?DyOVF(+hYQI;;29&lABgp4D`O7j%MF7}vy6Fu1$ zK~J`Z^JOeO-gR>LJ2?m;UPeRobs+)ng|ub}ArnGc)!Kz<`SjS- zDZ@A@gO$DSW%2qB|pEQC~k zt)RPAc0_-{EQE}fu@F*w_{MW@R~uy^WVD=l-6o_goS|1Qqqp6bZk>$0B{m^Bk`OXs zl&q$7dmnOU8K3U*6!;SI77g?v`70@AXq^x;PLzeRX@wGu!!?E{=RhuwU=I(i6GFxj zZ7iF4W)Yh5=c6lcK6*~iLr?B&=*;t_`jT)q-BnFN5c9GBQ84XZh4(G}j_8U92KCH0 zS=a>sIKK_5cdPf51k;11;q0OF8`(oeYw0hS4k%8Yy`7S6>b>c+&}0>I>?I)Mb;5}S zgmj7U!%VXMb%bePC;aK@iTpWkX|fhmyt~Hm$ZRSq`Dl2lf-$BrlugO ImageHandle { + match index { + 797979 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/percussions.png" + )) + .to_vec(), + ), // Percussions + 696969 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/piano-right.png" + )) + .to_vec(), + ), // Pianos Right hand mark + 0..=7 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/piano-left.png" + )) + .to_vec(), + ), // Pianos, default will be left hand + 8..=15 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/xylophones.png" + )) + .to_vec(), + ), // Chromatic Percussion + 16..=23 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/brasses.png" + )) + .to_vec(), + ), // Organs + 24..=31 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/guitars.png" + )) + .to_vec(), + ), // Guitars + 32..=39 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/guitars.png" + )) + .to_vec(), + ), // Basses + 40..=47 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/violins.png" + )) + .to_vec(), + ), // Strings + 48..=51 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/uncategorized.png" + )) + .to_vec(), + ), // Ensemble + 52..=55 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/choirs.png" + )) + .to_vec(), + ), // choirs + 56..=63 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/brasses.png" + )) + .to_vec(), + ), // Brass + 64..=71 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/flutes.png" + )) + .to_vec(), + ), // Reeds + 72..=79 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/flutes.png" + )) + .to_vec(), + ), // Pipes + 80..=87 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/uncategorized.png" + )) + .to_vec(), + ), // Synth Leads + 88..=95 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/uncategorized.png" + )) + .to_vec(), + ), // Synth Pads + 96..=103 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/uncategorized.png" + )) + .to_vec(), + ), // Synth Effects + 104..=111 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/percussions.png" + )) + .to_vec(), + ), // Ethnic + 112..=119 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/percussions.png" + )) + .to_vec(), + ), // Percussive + 120..=127 => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/uncategorized.png" + )) + .to_vec(), + ), // Sound effects + _ => ImageHandle::from_memory( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/uncategorized.png" + )) + .to_vec(), + ), // Default to Uncategorized + } +} + pub struct TrackCard<'a, MSG> { title: String, subtitle: String, - hand_info: String, body: Option>, track_color: Color, on_icon_press: Option, + instrument_id: usize, } impl<'a, MSG: 'a + Clone> Default for TrackCard<'a, MSG> { @@ -23,8 +170,9 @@ impl<'a, MSG: 'a + Clone> TrackCard<'a, MSG> { Self { title: String::new(), subtitle: String::new(), - hand_info: String::new(), body: None, + instrument_id: 0, + track_color: Color::from_rgba8(210, 89, 222, 1.0), on_icon_press: None, } @@ -35,13 +183,13 @@ impl<'a, MSG: 'a + Clone> TrackCard<'a, MSG> { self } - pub fn hand_info(mut self, text: impl ToString) -> Self { - self.hand_info = text.to_string(); + pub fn subtitle(mut self, text: impl ToString) -> Self { + self.subtitle = text.to_string(); self } - pub fn subtitle(mut self, text: impl ToString) -> Self { - self.subtitle = text.to_string(); + pub fn instrument_id(mut self, instrument_id: usize) -> Self { + self.instrument_id = instrument_id; self } @@ -62,27 +210,48 @@ impl<'a, MSG: 'a + Clone> TrackCard<'a, MSG> { } impl<'a, M: Clone + 'a> From> for Element<'a, M> { fn from(card: TrackCard<'a, M>) -> Self { - let mut header_content = vec![ - iced_widget::text(card.title).size(16).into(), + let header_content = vec![ + iced_widget::text(card.title).size(16).width(187).into(), iced_widget::text(card.subtitle).size(14).into(), ]; - // Only add hand_info if it's not empty - if !card.hand_info.is_empty() { - header_content.insert(1, iced_widget::text(card.hand_info).size(16).into()); - } + let img = get_instrument_icon(card.instrument_id); + + let img_toggle = if card.track_color == iced_core::Color::from_rgb8(102, 102, 102) { + ImageHandle::from_memory(include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/toggle_off.png" + ))) + } else { + ImageHandle::from_memory(include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/track_card/img/toggle_on.png" + ))) + }; + + let on_press_clone = card.on_icon_press.clone(); + + let button1 = iced_widget::button(iced_widget::image(img).width(55)) + .width(55) + .height(55) + .style(theme::track_icon_button(iced_core::Color::TRANSPARENT)) + .on_press_maybe(card.on_icon_press); + + let button2 = iced_widget::button(iced_widget::image(img_toggle).width(40).height(15)) + .width(55) + .height(15) + .padding(0) + .style(theme::toggle_button(iced_core::Color::TRANSPARENT)) + .on_press_maybe(on_press_clone); let header = iced_widget::row![ - iced_widget::button(iced_widget::text("")) - .width(40) - .height(40) - .style(theme::track_icon_button(card.track_color)) - .on_press_maybe(card.on_icon_press), + button1, iced_widget::column(header_content) - .spacing(4) + .spacing(0) .align_items(Alignment::Start), + button2, ] - .spacing(16); + .spacing(8); let mut children = vec![header.into()]; if let Some(body) = card.body { diff --git a/neothesia-iced-widgets/src/track_card/theme.rs b/neothesia-iced-widgets/src/track_card/theme.rs index ac2ba3a7..58111439 100644 --- a/neothesia-iced-widgets/src/track_card/theme.rs +++ b/neothesia-iced-widgets/src/track_card/theme.rs @@ -56,3 +56,36 @@ impl iced_style::button::StyleSheet for TrackIconButtonStyle { active } } +pub fn toggle_button(color: iced_core::Color) -> iced_style::theme::Button { + iced_style::theme::Button::Custom(Box::new(ToggleButtonStyle(color))) +} + +struct ToggleButtonStyle(iced_core::Color); + +impl iced_style::button::StyleSheet for ToggleButtonStyle { + type Style = iced_style::Theme; + + fn active(&self, _style: &Self::Style) -> iced_style::button::Appearance { + iced_style::button::Appearance { + background: Some(iced_core::Background::Color(self.0)), + border: Border { + radius: Radius::from(255.0), + ..Default::default() + }, + ..Default::default() + } + } + + /// Produces the hovered [`Appearance`] of a button. + fn hovered(&self, style: &Self::Style) -> iced_style::button::Appearance { + let mut active = self.active(style); + + if let Some(iced_core::Background::Color(ref mut color)) = active.background { + color.r = (color.r + 0.05).min(1.0); + color.g = (color.g + 0.05).min(1.0); + color.b = (color.b + 0.05).min(1.0); + } + + active + } +} diff --git a/neothesia/Cargo.toml b/neothesia/Cargo.toml index 4e18f30d..05750a31 100644 --- a/neothesia/Cargo.toml +++ b/neothesia/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "neothesia" -version = "0.1.0" +version = "0.1.8" authors = ["Poly "] edition = "2021" default-run = "neothesia" diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index ff6f27da..77bb556f 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -88,6 +88,7 @@ impl Page for StatsPage { // Collect all elements from songhistory into a single Vec let mut all_elements = Vec::new(); + for children in songhistory { all_elements.extend(children); } diff --git a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs index 0c8836a6..b2f6473f 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs @@ -59,6 +59,7 @@ impl Page for TracksPage { fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut tracks = Vec::new(); + if let Some(song) = ctx.song.as_ref() { let mut piano_count = 0; for track in song @@ -90,23 +91,25 @@ impl Page for TracksPage { .last() .map(|p| p.program as usize) .unwrap_or(0); - + let mut instrument_card_id = instrument_id; let name = if track.has_drums && !track.has_other_than_drums { + instrument_card_id = 797979; "Percussion" } else { midi_file::INSTRUMENT_NAMES[instrument_id] }; // Check if the instrument is a Piano (id 0, 1, or 2) - let hand_info = if instrument_id <= 2 && name != "Percussion" { + let hand_info = if instrument_id <= 7 && name != "Percussion" { // Increment the piano counter piano_count += 1; // Determine if it's the first or second occurrence of Piano if piano_count % 2 == 0 { - "Right Hand" + instrument_card_id = 696969; + "/ Right Hand" } else { - "Left Hand" + "/ Left Hand" } } else { // For other instruments, no hand information @@ -131,9 +134,9 @@ impl Page for TracksPage { let card = neothesia_iced_widgets::TrackCard::new() .title(name) - .subtitle(format!("{} Notes", track.notes.len())) + .subtitle(format!("{} Notes {}", track.notes.len(), hand_info)) .track_color(color) - .hand_info(hand_info) // Use hand_info field + .instrument_id(instrument_card_id) .body(body); let card = if track.has_drums && !track.has_other_than_drums { diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index fd1d66fc..cabbf8e8 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -312,7 +312,6 @@ impl PlayAlong { let count_deleted = count_before - self.user_pressed_recently.len(); if count_deleted > 0 { self.user_stats.wrong_notes += count_deleted as i32; - // println!("Update() Sum mistakes: {}", count_deleted); } } @@ -332,7 +331,6 @@ impl PlayAlong { .iter_mut() .find(|item| item.note_id == note_id) { - // println!("{}", "One wrong note, turned out to be correct note"); // Remove/take back. -1 a count_deleted (WRONG NOTE) added by update() if reached file_press_key(); /// self.user_stats.wrong_notes -= 1; } @@ -344,10 +342,8 @@ impl PlayAlong { { //160 to forgive touching the bottom - // println!("{}", "Note miss detected"); self.user_stats.notes_missed += 1; } else { - // println!("{}", "Note hit detected"); self.user_stats.notes_hit += 1; } self.required_notes.remove(index); @@ -367,7 +363,6 @@ impl PlayAlong { { // already exists, update timestamp item.timestamp = timestamp; - // println!("{}", " 'EXTRA NOTE', 'NOTE MISS' or 'WRONG NOTE'"); self.user_stats.wrong_notes += 1; } else { // Not found, push a new UserPress @@ -406,7 +401,6 @@ impl PlayAlong { .find(|(_, item)| item.note_id == note_id) { // Note was pressed earlier, remove it from user_pressed_recently - // println!("{}", "Note hit detected"); self.user_stats.notes_hit += 1; // log user_note by user_pressed_recently.timestamp as keydown value, update occurence @@ -420,7 +414,6 @@ impl PlayAlong { .retain(|item| item.note_id != note_id); } else { // Player never pressed that note, let it reach required_notes, check if note_id already exists in required_notes, update timestamp else push. - // Catch possible clone-note velocity overlay, update the new occurence and exit the function if let Some((_id, item)) = self.file_notes.iter_mut().enumerate().find(|(_, item)| { @@ -560,9 +553,9 @@ impl PlayAlong { // Save the modified SavedStats object saved_stats.save(); + // better save right here keeping things simple, since stats could be loaded from song list when select folder for a file list is implemented - // Maybe cook everything together for a total score if let Some(callback) = &self.on_finish { callback(); // Call on finish callback } From 1e9fddd3bd0c48a45994f1de33bae45dcb067e25 Mon Sep 17 00:00:00 2001 From: captainerd Date: Wed, 22 May 2024 08:20:01 +0300 Subject: [PATCH 13/29] Refinements --- neothesia-iced-widgets/src/stats_container/mod.rs | 6 +++--- neothesia/src/scene/menu_scene/iced_menu/stats.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/neothesia-iced-widgets/src/stats_container/mod.rs b/neothesia-iced-widgets/src/stats_container/mod.rs index 5954e0fa..ee6ffdc5 100644 --- a/neothesia-iced-widgets/src/stats_container/mod.rs +++ b/neothesia-iced-widgets/src/stats_container/mod.rs @@ -124,12 +124,12 @@ impl<'a, M: Clone + 'a> From> for Vec> { fn from(card: StatsContainer<'a, M>) -> Self { let columns = vec![ (card.place, 90), - (card.date, 90), + (card.date, 190), (card.score, 90), (card.notes_hits, 90), - (card.notes_missed, 90), + (card.notes_missed, 100), (card.wrong_notes, 90), - (card.correct_notes_duration, 90), + (card.correct_notes_duration, 120), ]; let header_row = columns diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index 77bb556f..b208a965 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -112,9 +112,9 @@ impl Page for StatsPage { .place("Place") .score("Score") .notes_hits("Hits") - .notes_missed("Misses") - .wrong_notes("Mistakes") - .correct_notes_duration("Durations") + .notes_missed("Missed notes") + .wrong_notes("Wrong notes") + .correct_notes_duration("Good Durations") .header(true); songhistory_header.push(Vec::>::from( first_place_card, From 2fe60a73ff5307fa63724380cb34407ab391e372 Mon Sep 17 00:00:00 2001 From: captainerd Date: Thu, 23 May 2024 08:15:37 +0300 Subject: [PATCH 14/29] minor corrections --- Cargo.lock | 61 ++++++++++++++++++ Cargo.toml | 2 +- .../src/stats_container/mod.rs | 10 +-- .../src/track_card/img/toggle_off.png | Bin 7070 -> 1704 bytes .../src/track_card/img/toggle_on.png | Bin 6798 -> 1746 bytes .../src/track_card/img/uncategorized.png | Bin 23234 -> 4671 bytes .../src/scene/menu_scene/iced_menu/tracks.rs | 15 +++-- 7 files changed, 76 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd3956c8..6d6f2473 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,6 +1250,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float_next_after" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" + [[package]] name = "fluidlite" version = "0.2.1" @@ -1749,6 +1755,7 @@ dependencies = [ "image", "kamadak-exif", "log", + "lyon_path", "once_cell", "raw-window-handle 0.6.0", "rustc-hash", @@ -1824,6 +1831,7 @@ dependencies = [ "guillotiere", "iced_graphics", "log", + "lyon", "once_cell", "wgpu", ] @@ -2141,6 +2149,58 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "lyon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7f9cda98b5430809e63ca5197b06c7d191bf7e26dfc467d5a3f0290e2a74f" +dependencies = [ + "lyon_algorithms", + "lyon_tessellation", +] + +[[package]] +name = "lyon_algorithms" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3bca95f9a4955b3e4a821fbbcd5edfbd9be2a9a50bb5758173e5358bfb4c623" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_geom" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edecfb8d234a2b0be031ab02ebcdd9f3b9ee418fb35e265f7a540a48d197bff9" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c08a606c7a59638d6c6aa18ac91a06aa9fb5f765a7efb27e6a4da58700740d7" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "lyon_tessellation" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579d42360a4b09846eff2feef28f538696c7d6c7439bfa65874ff3cbe0951b2c" +dependencies = [ + "float_next_after", + "lyon_path", + "num-traits", +] + [[package]] name = "mach2" version = "0.4.2" @@ -2487,6 +2547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7760dfa3..91181723 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,4 +34,4 @@ iced_graphics = "0.12" iced_core = "0.12" iced_runtime = "0.12" iced_wgpu = { version = "0.12", features = ["image"] } -iced_widget = { version = "0.12", features = ["image"] } +iced_widget = { version = "0.12", features = ["image","canvas"] } diff --git a/neothesia-iced-widgets/src/stats_container/mod.rs b/neothesia-iced-widgets/src/stats_container/mod.rs index ee6ffdc5..3b8be081 100644 --- a/neothesia-iced-widgets/src/stats_container/mod.rs +++ b/neothesia-iced-widgets/src/stats_container/mod.rs @@ -12,8 +12,7 @@ pub struct StatsContainer<'a, MSG> { notes_missed: String, wrong_notes: String, correct_notes_duration: String, - body: Option>, - + _marker: std::marker::PhantomData<&'a MSG>, // PhantomData to indicate usage of Msg header: bool, } @@ -34,7 +33,7 @@ impl<'a, MSG: 'a + Clone> StatsContainer<'a, MSG> { notes_missed: String::new(), wrong_notes: String::new(), correct_notes_duration: String::new(), - body: None, + _marker: std::marker::PhantomData, header: false, } @@ -110,10 +109,7 @@ impl<'a, MSG: 'a + Clone> StatsContainer<'a, MSG> { self } - pub fn body(mut self, body: impl Into>) -> Self { - self.body = Some(body.into()); - self - } + pub fn header(mut self, header: bool) -> Self { self.header = header; self diff --git a/neothesia-iced-widgets/src/track_card/img/toggle_off.png b/neothesia-iced-widgets/src/track_card/img/toggle_off.png index 3687ebb47c34d2bb8f5bac353e4a545875bc6032..852c4b91bf2c0091083d1341de9a1c139250bcdd 100644 GIT binary patch literal 1704 zcmX|=3tUuH9>)h*Q9zIsOHosBL?~jjQZmhaU^4E?PR6$OVRN&{S8AqFl$uJqD1zVs z0|PUoFat90M}Ry=859I$o-nU_89?3xGcflu`JqfW{i$}(=ic-9|9|IqzUSO~uF?~B z1^S2jQz(=`T72AIXp`ZMp63HKKX&{OG+w9o?%M8!wMCzYf#1pa4^LAl0gGl|FG>-6 z35DX_N&kD|PDpBT=bWcuBk|a4kJ~1-l=;`j&>5O%?4GMXc zRPv)lto;8Y7AZtRh2XZd*3mRXj5x`0Vv=w;MztD4Rb}lTV$cX~%M30n2;7qdhIQSk zu7{LZq!bDjur4gB)f(ioD#>h6(J^itCLH7>+0*m5se0wPLd- zA|*D_4XfW(HU7?{a1f&d{eud5wN$Kp3bps zEcB(~A7K}Edyh<734&45SzT2JaR7$8xvBM0n^x1VgN@kj_Uue1hGBAP<+Uq}igJk+ zvz6Q|hoA+sna!4hJWftlK__l~*xY(OGe7S}krp>sRn}x)&1JJnn!7qc&t>zjU&}A& z3(dIIU@&H7I>U|ZLPid&4ex|mx64E@>n59jwnL`JEx^#+ z)RLKz3(kd1uEAh9t&^BAtI^oO%w@wYv)Qb|b!NkTENK9ErtV8;aV+b23r7VR6n@IErY`WJpiaMZ4+kHW9ClG0s_6> zAgGY$F^Y1sn2hW~IJy#UIXJkZ716-dO0 z5t3|hB4?~u3V6?a}6G+h=vvGxV%B zBBFQ{#?D(&i|InkGw4oZlEfDZj!5B7dw)rb+m@Kh<`nLU5BYM*!`|BqY+LDuTS3Kn z$?29KmKxJmg``#TEfHx+VMo&DX04i6`hy{?Vn_O=Ez}*)u55StL|uxU_cS~s$P!k@ z-%K40E7?IeY2J$QkSKNJ+= z@NK`a^+#!Qh*y;Iy@GULiMcaWl6565zYle2?!*BlQ^XGHJX-7Ts)f+RqmM@V^#Vvg6!ZvzK zMbbROcP9gDh=O*56mPh15x=&-% z{NDAg-}W!w`XtsK&uhCDa&%8p1_IK%y`L{%a_pO~N5Nax*^c*HIH%Wqs;>*cvn~S-|yb~vMlKR;VmDn6?f?#zxYzTLm;qPlm6E5 zwVZi&;dk8gH|P<(cajr)>myf{#Hv49{B3YyaFlZE;>*;yPW8UOXuG36>D@Mc#OI}e zWf#|u%|F@MaBjXUXjwcNwraF1=^+{cJhkMn RC*bB$Xgd?)q}xAE`wfRw5TyVB literal 7070 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 S+k*dN1Lr>@othi>p8P+~qD=n) diff --git a/neothesia-iced-widgets/src/track_card/img/toggle_on.png b/neothesia-iced-widgets/src/track_card/img/toggle_on.png index dbfdfbc015089cad92b7d8fd0352e8957a969206..55cf0de2891563f86d7fad1a40d2240712d1cd3b 100644 GIT binary patch literal 1746 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 diff --git a/neothesia-iced-widgets/src/track_card/img/uncategorized.png b/neothesia-iced-widgets/src/track_card/img/uncategorized.png index 087d4873a7dacb1b51c8018eb08e3c574f0e6317..7edd9e7cee983cc479d4086f67e49ea788d36bcc 100755 GIT binary patch literal 4671 zcmV-F62R?=P)CENkWGRTHbFp^kgx{=62hL&0)&Jm5O!2ZAb}(V zNIF~ZOYPm&-}_fLnXyv{NxF(|Am2H^L-=mhckliG>)xt5X=sBXii5q$-wNCXp5Xq? zKLV@-J3s+20T+;f{{qs5oaw?b%CRfJm#FbHxLc_i>3LmM;c4k_14c0|{i&c7xBzK{ z`$A14`WOvbM|!?d7w+H6tz5sAdw_ZF-^hi)59kV^^i}BkjXWRy_XOAH>apJ}-w4_| zekYFuhn&BYIY1GH!&r`h(HL7h`_29vBdwF};rb71Vf%NvBS^rc9e|<~2gbMnJQ8Wm zbP4k<@(t!&eC;i__>913xkaX{17)nfbd0@&`4;aDk=9X@sJYd5TkWmBB=djzctBSv zJm#>x=2rQ(NbA|;sJhM9vikSF{=f$48bO&$e`Riw*0)hndAsi(kXm)S&kyJt!;iTc zO_*b(b-rv=-Y&GL_=9%?**#`~UMB0Zyl-wzGDgC3j=*%CzbX{|&_f+Yf-YyX} zqxf#AOUYf56;Lw)EYRffh?sHePf}070BR-#MUx&^)QppVmbw)ESz-V+qoxqrK%*~i8Sk`+)hm&BrIrK=go?-g6;|5Yq1_^U|GTpmTM{Ch=xp1yu=Bi($gwRjXz zGmYY?qMfE@9BCu8_~~zAJfLQpMEpQj??ItI@b7<6plgbU zaK%0)(($)NIy1#f)@&ciyq|oGpV(rVEL(k4I?+ofHA>Nkv5Kq?v`yS@$SYMIKW=iBbDwAaMli%kj?wm|DXWu= zWhX>E&|9DrF%ngzcmtv zK77Q+ll@%KkRL}2TGw_!^R~ZgNX8RfOy(0DMVf6rV93utI<-WK_*fLOp63FF92p~M zUOVFnHs+#cq(8;BN_&buj6W&TYfGGs${rf_3-hN6MgUM!jMXnP`2yfS_EU}(n>j!v$? zizS}owtvWlv>RV#1BUDy&+F1Zv_BbQ#@gqYHtTvaen8Q{rdNW76f75Ysc(FXrM)qD zuURQl^&v0ucA31KOy+#NU`l?<`HJOoSlW%NykIp9I2>F7 z%8O;dfK-X{rVEtzAxp_Gsn1mm$&KYha_j%W5^GWCH6}G+#;RVPRzLLelmdztQhGB~ zQ{bhaVaVl>@f3fy;@8Bj3af;GJa#r}r%lpZT z6;NB~qhrYeZ5hc@N`IzFee*D6=VU%4x907jAv-5?dd}OWcwt!nnx`9}Xkt|#hN@x6 zkJ$6;x1GtA$S-3BIAp5I_tL>7csCfvQqmjR^v%0u%9+B4@G(|hhu8J4~7 z9+CLEhoXs0KCNQ|EOc$*}lM_YOeOMB+Oz z40)OoGoV91v5xRBhk4}yl&&+9;eA-=E66yMiP(Zu5S-BekK8#WB7-&O@f4sTHB zwL&o@a|RodTQblcFrsq$bq$js;%lYR?bFsUMmzs(r25QgAhu@Co(`fZgkws*S z`M%Q+D4Ll2v5U%auh_eRSGAd7$o^DyUMmzsHqT)~a&d!Q0Yf&=WpwNJ0LRyYo!0@;Fl~_21t^-BHN-{dVMy*K zUe#6sL-Nwpd96?k*$~HssG^BoB2b_kfA306me&nQRV&+gMoyX04_hwGjR#A$r zES=Y_Z^e-H^O=y`_g^T6_*8kVffp5q$saok07VniKX=l((-Q4UgP3Qup`GX;Zw&7K+(jM;Z8aWLvqqMRonS9*vhu>y7jFXlDv=!$$dLAXh{9M z4kQ}B{>(7~P&6^=O9!1TktjQzQ?;ExgO#&Io!1HmhOA!X3CT?v

y3Kd%GB4KZKX zy8((OVj(~o4B4K+soKt!!H})$d}En7+Cj4>;T>bTE5NLYPKq5FG-TBhPsp*8#=sD# zPnFl4&+Shdz8Yq~>#N~*H=tS@w^8i;EwyfBOzZf`YaguN6{v@m|GgU-N^ zZP=RXx1EI{*;(rRuMvZluzLp=5L6IkI($f=lw^kD=ecRdG(7uH2{LoKlNQW(Q}PcC z#g2D`)R+J>oj8BRGLN3~E&;*M_>LTDGXjbh#*MSn8Qd$jZe>+%XU}3Q+s-wp&UfEA zsjA9L77N}X)-!>+O&QPl@%Dfr%a^k0JJ<9g456TT2V{0>Ptj!N78W;@$O0hL% zX0fWaGKjn_hr4WzMYx(7My6Pp5$<@##s&>pn&j4N&i>(JZTE(JzW4KSwn9MBz{m-9 zDuE#x+gVlH85pt^_k_#USZ`#=gzf4J4aPHe5)5(sXb}w2Y0jY^wpLH% zBPQAchNNY)sxSTG{Yv_s2KN(v>aB|RtiHhcd7IB89KpAr^`e#ReNdNOnZ~Z5;MzA)n;#CJUY#n zgZAowu=7c*rPU`BtcL+z5n`?M^*jeH+u$bS4wkm(ag@D}qYQ|hoPq78#!IQl*FUec z99!9Lb^cUOko?mk86ou2O>X*rrIWs0iuaI2ys;;{XjQt0vJY@ngq0;q zGL_?^NZIBIj9W)tMqbnmB?e8hv>i0r;sB&IBj(sBzeFGbZ^fsv?IfnTX~JSVjhJnt zA=5Fisg?lB&%?jRjWpg)gQrL{8tSbIK^_~2U9HxfV5=7QajnO^pBScG&#vZ1H-6Q zg6+e&mknz?O8=kXLWscyF=@GjViWOZzQ9f&&#-Db?*lW9nTHSAjN&N5ROR@=J0OxU#| z$_%qZ(YV2e^qXbAq3?6mKEPCsSO8E9_d6*Exv8L&3~cXV|qO%rwxrFByCL zd-L!6%r@Hqh0E%_9umDW&EM*x{_`4t{@ZiR^vzlaIT$<`oENF@-0;T~L9BhCZKKSn zi#O-g_J4D3tshW0^ogsbq&@C{DJLsLnge6rn%98yVBVC?4mw&U1kT-clA{k7Tf!Pk zgz-bueoZn%iQe;STK0~sO$DR{BU5aY4N+a3k34wxKVB}9PrSxTsI|xl!G41 zDqztjkel}rhX;bZVxA@$9h!_G!ld?|R~z0pyuC5M_MX@0*P36CuO%($olr}If3VWr z92cb>XX)@+fr@J-Dz|&7+=jPy+_Vpt@nk&4(wuA;4NbPvKNe`ycSM1Pik4xSQ5UZ! z)D8d=Aia1EqQAO8zxokI(N3HHYFvre7F$}pys&0|uZ1<#Yf&?eVqt*zm*dUae!bp{ zi)wCqadAx^pk^9H-b>IZ(FO*ExkxL5ql*Q5Rj4t6FzmQ*{K;bxNM1L8N^M ziOy@QZtk2?HUIIoRT7}<1nKdVs(8#hy1u@f8pn*e4tOl3 zDmuU5{+IFShRQ!ZvZ2!W$i_;#2JvHVshHzEk=D6U(Q#vC%ZE2r_6Jr#*9f+bn=1P$ zbBnaTO^yzmD{t$NS~l!(5v7o4#m^hm4gsJZP+Z=)ttg&A_2`07WSdj4=T`5^24zNIZ~ky0Kk`scqX#(>QPtux+=P zD57MVIB*Dz!r0n@OMjy9T8;a*m|B7E_iZ)J11EtW&=o@Is}RIt3_bpLOJ&o)7WG<< zzh#+PgOMN=l(fk*xd64<9wu1<+)B+0wMQv^MS8whRkYq-(F)uJp13!=VmL?wIiLWT zfD?$oe*y7A&UE1z<=Ew51Zs2xcembN9@VSh{{f}7@#<9{7efF5002ovPDHLkV1lXw B@mT-> literal 23234 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 PageMessage { match event { Event::AllTracksPlayer(config) => { @@ -59,7 +62,7 @@ impl Page for TracksPage { fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut tracks = Vec::new(); - + if let Some(song) = ctx.song.as_ref() { let mut piano_count = 0; for track in song @@ -146,8 +149,10 @@ impl Page for TracksPage { }; tracks.push(card.into()); + } } + let column = neothesia_iced_widgets::Wrap::with_elements(tracks) .spacing(14.0) @@ -243,8 +248,10 @@ impl Page for TracksPage { bottom: 10.0, left: 0.0, }); - - Layout::new() + + + + Layout::new() .body(column) .bottom(BarLayout::new().left(left).center(center).right(right)) .into() From 453d3d14b599e5620b87f2aff78930aeeb9dfe34 Mon Sep 17 00:00:00 2001 From: captainerd Date: Thu, 23 May 2024 08:16:38 +0300 Subject: [PATCH 15/29] minor corrections --- Cargo.lock | 61 ------------------------------------------------------ Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d6f2473..bd3956c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,12 +1250,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float_next_after" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" - [[package]] name = "fluidlite" version = "0.2.1" @@ -1755,7 +1749,6 @@ dependencies = [ "image", "kamadak-exif", "log", - "lyon_path", "once_cell", "raw-window-handle 0.6.0", "rustc-hash", @@ -1831,7 +1824,6 @@ dependencies = [ "guillotiere", "iced_graphics", "log", - "lyon", "once_cell", "wgpu", ] @@ -2149,58 +2141,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "lyon" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7f9cda98b5430809e63ca5197b06c7d191bf7e26dfc467d5a3f0290e2a74f" -dependencies = [ - "lyon_algorithms", - "lyon_tessellation", -] - -[[package]] -name = "lyon_algorithms" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3bca95f9a4955b3e4a821fbbcd5edfbd9be2a9a50bb5758173e5358bfb4c623" -dependencies = [ - "lyon_path", - "num-traits", -] - -[[package]] -name = "lyon_geom" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edecfb8d234a2b0be031ab02ebcdd9f3b9ee418fb35e265f7a540a48d197bff9" -dependencies = [ - "arrayvec", - "euclid", - "num-traits", -] - -[[package]] -name = "lyon_path" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c08a606c7a59638d6c6aa18ac91a06aa9fb5f765a7efb27e6a4da58700740d7" -dependencies = [ - "lyon_geom", - "num-traits", -] - -[[package]] -name = "lyon_tessellation" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579d42360a4b09846eff2feef28f538696c7d6c7439bfa65874ff3cbe0951b2c" -dependencies = [ - "float_next_after", - "lyon_path", - "num-traits", -] - [[package]] name = "mach2" version = "0.4.2" @@ -2547,7 +2487,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", - "libm", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 91181723..8c4792fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,4 +34,4 @@ iced_graphics = "0.12" iced_core = "0.12" iced_runtime = "0.12" iced_wgpu = { version = "0.12", features = ["image"] } -iced_widget = { version = "0.12", features = ["image","canvas"] } +iced_widget = { version = "0.12", features = ["image"] } From 919837583c1009e314e8a3602a93e8de6092a717 Mon Sep 17 00:00:00 2001 From: captainerd Date: Thu, 23 May 2024 08:17:43 +0300 Subject: [PATCH 16/29] cargo fmt --- neothesia-iced-widgets/src/stats_container/mod.rs | 1 - .../src/scene/menu_scene/iced_menu/tracks.rs | 15 ++++----------- neothesia/src/scene/playing_scene/midi_player.rs | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/neothesia-iced-widgets/src/stats_container/mod.rs b/neothesia-iced-widgets/src/stats_container/mod.rs index 3b8be081..ea79c249 100644 --- a/neothesia-iced-widgets/src/stats_container/mod.rs +++ b/neothesia-iced-widgets/src/stats_container/mod.rs @@ -109,7 +109,6 @@ impl<'a, MSG: 'a + Clone> StatsContainer<'a, MSG> { self } - pub fn header(mut self, header: bool) -> Self { self.header = header; self diff --git a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs index 8a649d27..b2f6473f 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/tracks.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/tracks.rs @@ -24,12 +24,9 @@ pub enum Event { pub struct TracksPage; - - - impl Page for TracksPage { type Event = Event; - + fn update(data: &mut Data, event: Event, ctx: &mut Context) -> PageMessage { match event { Event::AllTracksPlayer(config) => { @@ -62,7 +59,7 @@ impl Page for TracksPage { fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut tracks = Vec::new(); - + if let Some(song) = ctx.song.as_ref() { let mut piano_count = 0; for track in song @@ -149,10 +146,8 @@ impl Page for TracksPage { }; tracks.push(card.into()); - } } - let column = neothesia_iced_widgets::Wrap::with_elements(tracks) .spacing(14.0) @@ -248,10 +243,8 @@ impl Page for TracksPage { bottom: 10.0, left: 0.0, }); - - - - Layout::new() + + Layout::new() .body(column) .bottom(BarLayout::new().left(left).center(center).right(right)) .into() diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index cabbf8e8..63f80f0d 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -553,7 +553,7 @@ impl PlayAlong { // Save the modified SavedStats object saved_stats.save(); - + // better save right here keeping things simple, since stats could be loaded from song list when select folder for a file list is implemented if let Some(callback) = &self.on_finish { From 18ba27c1dba29c868756af328a149219af397ad2 Mon Sep 17 00:00:00 2001 From: captainerd Date: Fri, 24 May 2024 04:32:05 +0300 Subject: [PATCH 17/29] After-test debugging --- .../src/scene/menu_scene/iced_menu/stats.rs | 22 ++++++++++++++----- .../src/scene/playing_scene/midi_player.rs | 21 ++++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index b208a965..f2d156e4 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -68,8 +68,20 @@ impl Page for StatsPage { // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { - let scores = stats.notes_hit + stats.correct_note_times * 10 - - (stats.notes_missed + stats.wrong_note_times + stats.notes_missed); // There are many ways to cook + let mut scores = stats.notes_hit + stats.correct_note_times * 10; // There are many ways to cook + + + // Apply penalties + if stats.notes_missed > 0 { + scores = scores.saturating_sub(stats.notes_missed); + } + if stats.wrong_notes > 0 { + scores = scores.saturating_sub(stats.wrong_notes); + } + + // Final bonus addition + scores += stats.correct_note_times; + let datetime: DateTime = stats.date.into(); let score = (index + 1) as u32; let trophy_image = if score <= 3 { score } else { 0 }; @@ -99,7 +111,7 @@ impl Page for StatsPage { .spacing(10) .align_items(Alignment::Start), ) - .height(ctx.window_state.logical_size.height as u16 - 400); + .height(ctx.window_state.logical_size.height as u16 - 250); let mut elements = Vec::new(); let scrollable_element: Element<'_, Event> = scrollable.into(); @@ -111,8 +123,8 @@ impl Page for StatsPage { .date("Date") .place("Place") .score("Score") - .notes_hits("Hits") - .notes_missed("Missed notes") + .notes_hits("Good Hits") + .notes_missed("Slow Hits") .wrong_notes("Wrong notes") .correct_notes_duration("Good Durations") .header(true); diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 63f80f0d..8a4a182a 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -326,7 +326,7 @@ impl PlayAlong { .iter() .position(|item| item.note_id == note_id) { - if let None = self + /* if let None = self .user_pressed_recently .iter_mut() .find(|item| item.note_id == note_id) @@ -335,6 +335,8 @@ impl PlayAlong { self.user_stats.wrong_notes -= 1; } + */ + if timestamp .duration_since(self.required_notes[index].timestamp) .as_millis() @@ -520,15 +522,16 @@ impl PlayAlong { // Loop through user_stats.note_durations items, compare user_note_dur to file_note_dur let mut correct_note_times = 0; let mut wrong_note_times = 0; + // make it relaxed, Lower Bound: 83% of the file's note duration, Upper Bound: 112% of the file's note duration. for duration in &self.user_stats.note_durations { - // Compare user_note_dur to file_note_dur - let duration_difference = - (duration.user_note_dur as f64 - duration.file_note_dur as f64).abs(); - let percentage_difference = - duration_difference / duration.user_note_dur as f64 * 100.0; - - // Increment correctNoteTimes if it is close to 90%, otherwise increment wrongNoteTimes - if percentage_difference <= 10.0 { + // Calculate the lower and upper bounds for a "correct" duration + let lower_bound = duration.file_note_dur as f64 * 0.83; + let upper_bound = duration.file_note_dur as f64 * 1.12; + + // Increment correctNoteTimes if it is within the bounds, otherwise increment wrongNoteTimes + if (duration.user_note_dur as f64) >= lower_bound + && (duration.user_note_dur as f64) <= upper_bound + { correct_note_times += 1; } else { wrong_note_times += 1; From 2379e399505ded40fbacb39c7038aac64e9b2eec Mon Sep 17 00:00:00 2001 From: captainerd Date: Fri, 24 May 2024 04:32:50 +0300 Subject: [PATCH 18/29] After-tests debugging --- neothesia/src/scene/menu_scene/iced_menu/stats.rs | 7 +++---- neothesia/src/scene/playing_scene/midi_player.rs | 11 ----------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index f2d156e4..3c16decb 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -69,16 +69,15 @@ impl Page for StatsPage { // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { let mut scores = stats.notes_hit + stats.correct_note_times * 10; // There are many ways to cook - - // Apply penalties + // Apply penalties if stats.notes_missed > 0 { scores = scores.saturating_sub(stats.notes_missed); - } + } if stats.wrong_notes > 0 { scores = scores.saturating_sub(stats.wrong_notes); } - + // Final bonus addition scores += stats.correct_note_times; diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 8a4a182a..fd943e52 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -326,17 +326,6 @@ impl PlayAlong { .iter() .position(|item| item.note_id == note_id) { - /* if let None = self - .user_pressed_recently - .iter_mut() - .find(|item| item.note_id == note_id) - { - // Remove/take back. -1 a count_deleted (WRONG NOTE) added by update() if reached file_press_key(); /// - self.user_stats.wrong_notes -= 1; - } - - */ - if timestamp .duration_since(self.required_notes[index].timestamp) .as_millis() From 8205bb488f0c71d43416ec811938057d5b7c2151 Mon Sep 17 00:00:00 2001 From: captainerd <58100748+captainerd@users.noreply.github.com> Date: Sat, 25 May 2024 02:01:50 +0300 Subject: [PATCH 19/29] Update neothesia/src/scene/playing_scene/midi_player.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit leftovers Co-authored-by: Bartłomiej Maryńczak --- neothesia/src/scene/playing_scene/midi_player.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index fd943e52..9d10bdc2 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -385,11 +385,10 @@ impl PlayAlong { *occurrence += 1; // Check if note got pressed earlier 500ms (user_pressed_recently) - if let Some((_id, item)) = self + if let Some(item) = self .user_pressed_recently .iter() - .enumerate() - .find(|(_, item)| item.note_id == note_id) + .find(|item| item.note_id == note_id) { // Note was pressed earlier, remove it from user_pressed_recently self.user_stats.notes_hit += 1; From 09219e089d553cfab8d54381d39b3e3953ed1770 Mon Sep 17 00:00:00 2001 From: captainerd Date: Sat, 25 May 2024 02:54:11 +0300 Subject: [PATCH 20/29] Refracted unessesary double-ended queues, removed unused enumerates --- .../src/scene/playing_scene/midi_player.rs | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 9d10bdc2..8f16f160 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -7,7 +7,6 @@ use neothesia_core::gamesave::{SavedStats, SongStats}; use std::time::SystemTime; use std::{ collections::HashMap, - collections::VecDeque, time::{Duration, Instant}, }; @@ -259,16 +258,16 @@ struct UserPress { pub struct PlayAlong { user_keyboard_range: piano_math::KeyboardRange, - required_notes: VecDeque, + required_notes: Vec, finished: bool, // List of user key press events that happened in last 500ms, // used for play along leeway logic - user_pressed_recently: VecDeque, + user_pressed_recently: Vec, user_stats: NoteStats, // struct to finalize the stats log - user_notes: VecDeque, // log all user notes to get durrations - file_notes: VecDeque, // log all file notes to compare against user - occurrence: HashMap, // Keeping user to file log incremental pointer rewind immune + user_notes: Vec, // log all user notes to get durrations + file_notes: Vec, // log all file notes to compare against user + occurrence: HashMap, // Keeping user to file log incremental pointer rewind immune on_finish: Option>, } @@ -339,8 +338,8 @@ impl PlayAlong { } self.required_notes.remove(index); - self.user_notes.push_back(UserPress { - timestamp: timestamp, + self.user_notes.push(UserPress { + timestamp, note_id, occurrence: *occurrence, time_key_up: timestamp, @@ -357,7 +356,7 @@ impl PlayAlong { self.user_stats.wrong_notes += 1; } else { // Not found, push a new UserPress - self.user_pressed_recently.push_back(UserPress { + self.user_pressed_recently.push(UserPress { timestamp, note_id, occurrence: *occurrence, @@ -394,7 +393,7 @@ impl PlayAlong { self.user_stats.notes_hit += 1; // log user_note by user_pressed_recently.timestamp as keydown value, update occurence - self.user_notes.push_back(UserPress { + self.user_notes.push(UserPress { timestamp: item.timestamp, note_id, occurrence: *occurrence, @@ -405,10 +404,11 @@ impl PlayAlong { } else { // Player never pressed that note, let it reach required_notes, check if note_id already exists in required_notes, update timestamp else push. // Catch possible clone-note velocity overlay, update the new occurence and exit the function - if let Some((_id, item)) = - self.file_notes.iter_mut().enumerate().find(|(_, item)| { - item.note_id == note_id && item.time_key_up == item.timestamp - }) + + if let Some(item) = self + .file_notes + .iter_mut() + .find(|item| item.note_id == note_id && item.time_key_up == item.timestamp) { item.occurrence = *occurrence; return; // Everything bellow already done before by its clone @@ -421,8 +421,8 @@ impl PlayAlong { // Update the timestamp of the existing note user_press.timestamp = timestamp; } else { - self.required_notes.push_back(UserPress { - timestamp: timestamp, + self.required_notes.push(UserPress { + timestamp, note_id, occurrence: *occurrence, time_key_up: timestamp, @@ -431,8 +431,8 @@ impl PlayAlong { } // Log the note - self.file_notes.push_back(UserPress { - timestamp: timestamp, + self.file_notes.push(UserPress { + timestamp, note_id, occurrence: *occurrence, // Set the occurrence count time_key_up: timestamp, @@ -471,6 +471,7 @@ impl PlayAlong { pub fn clear(&mut self) { self.required_notes.clear(); + // Remove from the file log, notes that left pressed down with no key up yet (rewinding a non-played part) self.file_notes .retain(|item| item.time_key_up != item.timestamp); self.user_pressed_recently.clear(); From f9abb7af1e92e779c66a96bf9120b6a4463e06a7 Mon Sep 17 00:00:00 2001 From: captainerd Date: Sat, 25 May 2024 03:21:43 +0300 Subject: [PATCH 21/29] Refract to Some(None) unsetted key up times, inclease a little the note durration difficulty --- .../src/scene/playing_scene/midi_player.rs | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 8f16f160..119f8a77 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -251,7 +251,7 @@ pub enum MidiEventSource { struct UserPress { timestamp: Instant, note_id: u8, - time_key_up: Instant, + time_key_up: Option, occurrence: usize, } @@ -342,7 +342,7 @@ impl PlayAlong { timestamp, note_id, occurrence: *occurrence, - time_key_up: timestamp, + time_key_up: None, }); } else { // Haven't reached required_notes yet, place a possible later validation in 'user_pressed_recently' / file_press_key() @@ -360,7 +360,7 @@ impl PlayAlong { timestamp, note_id, occurrence: *occurrence, - time_key_up: timestamp, + time_key_up: None, }); } } @@ -372,7 +372,7 @@ impl PlayAlong { .rev() .find(|item| item.note_id == note_id && item.occurrence == *occurrence) { - item.time_key_up = Instant::now(); + item.time_key_up = Some(Instant::now()); } } } @@ -408,7 +408,7 @@ impl PlayAlong { if let Some(item) = self .file_notes .iter_mut() - .find(|item| item.note_id == note_id && item.time_key_up == item.timestamp) + .find(|item| item.note_id == note_id && item.time_key_up.is_none()) { item.occurrence = *occurrence; return; // Everything bellow already done before by its clone @@ -425,7 +425,7 @@ impl PlayAlong { timestamp, note_id, occurrence: *occurrence, - time_key_up: timestamp, + time_key_up: None, }); } } @@ -435,7 +435,7 @@ impl PlayAlong { timestamp, note_id, occurrence: *occurrence, // Set the occurrence count - time_key_up: timestamp, + time_key_up: None, }); } else { // update time_key_up @@ -445,7 +445,7 @@ impl PlayAlong { .rev() .find(|item| item.note_id == note_id && item.occurrence == *occurrence) { - item.time_key_up = timestamp; + item.time_key_up = Some(timestamp); } } } @@ -472,8 +472,7 @@ impl PlayAlong { pub fn clear(&mut self) { self.required_notes.clear(); // Remove from the file log, notes that left pressed down with no key up yet (rewinding a non-played part) - self.file_notes - .retain(|item| item.time_key_up != item.timestamp); + self.file_notes.retain(|item| item.time_key_up.is_some()); self.user_pressed_recently.clear(); } @@ -486,14 +485,14 @@ impl PlayAlong { && user_note.note_id == file_note.note_id { // Subtract timestamp from time_key_up to get total seconds - let user_note_dur = user_note - .time_key_up - .duration_since(user_note.timestamp) - .as_secs(); - let file_note_dur = file_note - .time_key_up - .duration_since(file_note.timestamp) - .as_secs(); + let user_note_dur = match (user_note.timestamp, user_note.time_key_up) { + (start, Some(end)) => end.duration_since(start).as_secs(), + _ => 0, + }; + let file_note_dur = match (file_note.timestamp, file_note.time_key_up) { + (start, Some(end)) => end.duration_since(start).as_secs(), + _ => 0, + }; // Add this information to user_stats.note_durations let note_duration = NoteDurations { @@ -511,11 +510,11 @@ impl PlayAlong { // Loop through user_stats.note_durations items, compare user_note_dur to file_note_dur let mut correct_note_times = 0; let mut wrong_note_times = 0; - // make it relaxed, Lower Bound: 83% of the file's note duration, Upper Bound: 112% of the file's note duration. + // make it relaxed, Lower Bound: 87% of the file's note duration, Upper Bound: 108% of the file's note duration. for duration in &self.user_stats.note_durations { // Calculate the lower and upper bounds for a "correct" duration - let lower_bound = duration.file_note_dur as f64 * 0.83; - let upper_bound = duration.file_note_dur as f64 * 1.12; + let lower_bound = duration.file_note_dur as f64 * 0.87; + let upper_bound = duration.file_note_dur as f64 * 1.08; // Increment correctNoteTimes if it is within the bounds, otherwise increment wrongNoteTimes if (duration.user_note_dur as f64) >= lower_bound From bac66080154dce75aeb1c8448632940f19698f9a Mon Sep 17 00:00:00 2001 From: captainerd Date: Sat, 25 May 2024 18:52:30 +0300 Subject: [PATCH 22/29] Clear leftovers from old 'wrong_notes -= x' there is no subtracting --- neothesia/src/scene/playing_scene/midi_player.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 119f8a77..52208873 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -21,7 +21,7 @@ pub struct NoteStats { song_name: String, notes_missed: usize, notes_hit: usize, - wrong_notes: i32, + wrong_notes: usize, note_durations: Vec, } #[derive(Debug)] @@ -307,10 +307,11 @@ impl PlayAlong { elapsed <= threshold }); - // Calculate the count of deleted items + // Calculate the count of deleted items, + // Either pressed extremely too earlier than should have, or a wrong note, both cases is wrong note, we don't sub these. let count_deleted = count_before - self.user_pressed_recently.len(); if count_deleted > 0 { - self.user_stats.wrong_notes += count_deleted as i32; + self.user_stats.wrong_notes += count_deleted; } } @@ -319,7 +320,8 @@ impl PlayAlong { let occurrence = self.occurrence.entry(note_id).or_insert(0); if active { - // Check if note_id has reached required_notes, then remove it now + // Check if note_id has reached required_notes, then remove it now, + if let Some(index) = self .required_notes .iter() @@ -503,10 +505,7 @@ impl PlayAlong { } } } - // Clear negative self.user_stats.wrong_notes - if self.user_stats.wrong_notes < 0 { - self.user_stats.wrong_notes = 0; - } + // Loop through user_stats.note_durations items, compare user_note_dur to file_note_dur let mut correct_note_times = 0; let mut wrong_note_times = 0; From bfe2b2a26646431d53e9bca3298a890f66189798 Mon Sep 17 00:00:00 2001 From: captainerd Date: Sun, 26 May 2024 09:14:50 +0300 Subject: [PATCH 23/29] After-tests debugging: correct the score shorting logic to match, ignore non-played songs --- .../src/scene/menu_scene/iced_menu/stats.rs | 53 ++++++++++++++++--- .../src/scene/playing_scene/midi_player.rs | 8 ++- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index 3c16decb..5a114342 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -58,14 +58,51 @@ impl Page for StatsPage { .filter(|stats| stats.song_name == songname) .collect(); - // Sort stats by fewer wrong_notes, fewer notes_missed, and max note_hits - let mut sorted_stats = filtered_stats.clone(); - sorted_stats.sort_by(|a, b| { - let score_a = a.wrong_notes + a.notes_missed - a.notes_hit; - let score_b = b.wrong_notes + b.notes_missed - b.notes_hit; - score_a.cmp(&score_b) + + // Sort stats as whatever is the cooking logic: hits + correct timing * 10 subtract from sum the missed and wrong notes + let mut sorted_stats = filtered_stats.clone(); + + sorted_stats.sort_by(|a, b| { + let score_a = { + let mut score = a.notes_hit + a.correct_note_times * 10; + + // Apply penalties + if a.notes_missed > 0 { + score = score.saturating_sub(a.notes_missed); + } + if a.wrong_notes > 0 { + score = score.saturating_sub(a.wrong_notes); + } + + // Final bonus addition + score += a.correct_note_times; + + score + }; + + let score_b = { + let mut score = b.notes_hit + b.correct_note_times * 10; + + // Apply penalties + if b.notes_missed > 0 { + score = score.saturating_sub(b.notes_missed); + } + if b.wrong_notes > 0 { + score = score.saturating_sub(b.wrong_notes); + } + + // Final bonus addition + score += b.correct_note_times; + + score + }; + + score_b.cmp(&score_a) }); + + + // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { let mut scores = stats.notes_hit + stats.correct_note_times * 10; // There are many ways to cook @@ -81,6 +118,10 @@ impl Page for StatsPage { // Final bonus addition scores += stats.correct_note_times; + + //Sort by score, higher score first + + let datetime: DateTime = stats.date.into(); let score = (index + 1) as u32; let trophy_image = if score <= 3 { score } else { 0 }; diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 52208873..f7ab9430 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -525,6 +525,10 @@ impl PlayAlong { } } + // Save only if the user pressed something, it wasn't a full rewind OR [AUTO] + + if self.user_stats.notes_hit + self.user_stats.notes_missed + self.user_stats.wrong_notes > 0 { + let mut saved_stats = SavedStats::load().unwrap_or_default(); // Create the new stats object @@ -537,12 +541,14 @@ impl PlayAlong { wrong_notes: self.user_stats.wrong_notes as u32, date: SystemTime::now(), }; - + // // Push the new stats object to the existing SavedStats saved_stats.songs.push(new_stats); + // Save the modified SavedStats object saved_stats.save(); + } // better save right here keeping things simple, since stats could be loaded from song list when select folder for a file list is implemented From ae0d4444ab5cc169d7cb50729d53e0b392867afa Mon Sep 17 00:00:00 2001 From: captainerd Date: Sun, 26 May 2024 09:15:52 +0300 Subject: [PATCH 24/29] After-tests debugging: correct the score shorting logic to match, ignore non-played songs --- .../src/scene/menu_scene/iced_menu/stats.rs | 32 +++++-------- .../src/scene/playing_scene/midi_player.rs | 48 ++++++++++--------- 2 files changed, 38 insertions(+), 42 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index 5a114342..d0ccc78e 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -58,14 +58,13 @@ impl Page for StatsPage { .filter(|stats| stats.song_name == songname) .collect(); - - // Sort stats as whatever is the cooking logic: hits + correct timing * 10 subtract from sum the missed and wrong notes - let mut sorted_stats = filtered_stats.clone(); - - sorted_stats.sort_by(|a, b| { + // Sort stats as whatever is the cooking logic: hits + correct timing * 10 subtract from sum the missed and wrong notes + let mut sorted_stats = filtered_stats.clone(); + + sorted_stats.sort_by(|a, b| { let score_a = { let mut score = a.notes_hit + a.correct_note_times * 10; - + // Apply penalties if a.notes_missed > 0 { score = score.saturating_sub(a.notes_missed); @@ -73,16 +72,16 @@ impl Page for StatsPage { if a.wrong_notes > 0 { score = score.saturating_sub(a.wrong_notes); } - + // Final bonus addition score += a.correct_note_times; - + score }; - + let score_b = { let mut score = b.notes_hit + b.correct_note_times * 10; - + // Apply penalties if b.notes_missed > 0 { score = score.saturating_sub(b.notes_missed); @@ -90,18 +89,15 @@ impl Page for StatsPage { if b.wrong_notes > 0 { score = score.saturating_sub(b.wrong_notes); } - + // Final bonus addition score += b.correct_note_times; - + score }; - - score_b.cmp(&score_a) - }); - - + score_b.cmp(&score_a) + }); // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { @@ -118,9 +114,7 @@ impl Page for StatsPage { // Final bonus addition scores += stats.correct_note_times; - //Sort by score, higher score first - let datetime: DateTime = stats.date.into(); let score = (index + 1) as u32; diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index f7ab9430..45256e60 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -525,29 +525,31 @@ impl PlayAlong { } } - // Save only if the user pressed something, it wasn't a full rewind OR [AUTO] - - if self.user_stats.notes_hit + self.user_stats.notes_missed + self.user_stats.wrong_notes > 0 { - - let mut saved_stats = SavedStats::load().unwrap_or_default(); - - // Create the new stats object - let new_stats = SongStats { - song_name: self.user_stats.song_name.clone(), - correct_note_times, - wrong_note_times, - notes_missed: self.user_stats.notes_missed as u32, - notes_hit: self.user_stats.notes_hit as u32, - wrong_notes: self.user_stats.wrong_notes as u32, - date: SystemTime::now(), - }; - // - // Push the new stats object to the existing SavedStats - saved_stats.songs.push(new_stats); - - - // Save the modified SavedStats object - saved_stats.save(); + // Save only if the user pressed something, it wasn't a full rewind OR [AUTO] + + if self.user_stats.notes_hit + + self.user_stats.notes_missed + + self.user_stats.wrong_notes + > 0 + { + let mut saved_stats = SavedStats::load().unwrap_or_default(); + + // Create the new stats object + let new_stats = SongStats { + song_name: self.user_stats.song_name.clone(), + correct_note_times, + wrong_note_times, + notes_missed: self.user_stats.notes_missed as u32, + notes_hit: self.user_stats.notes_hit as u32, + wrong_notes: self.user_stats.wrong_notes as u32, + date: SystemTime::now(), + }; + // + // Push the new stats object to the existing SavedStats + saved_stats.songs.push(new_stats); + + // Save the modified SavedStats object + saved_stats.save(); } // better save right here keeping things simple, since stats could be loaded from song list when select folder for a file list is implemented From ffd0ce0a91f946a84ac8d0548d2e49690a77af36 Mon Sep 17 00:00:00 2001 From: captainerd Date: Sun, 26 May 2024 09:35:22 +0300 Subject: [PATCH 25/29] Remove unnecessary if's and repeated code --- .../src/scene/menu_scene/iced_menu/stats.rs | 56 ++++++------------- 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index d0ccc78e..84eb02f2 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -23,6 +23,15 @@ pub enum Event { use crate::menu_scene::Step; pub struct StatsPage; + +fn score_cooking(stats: &SongStats) -> u32 { + + let mut score = stats.notes_hit + stats.correct_note_times * 10; + // Apply penalties then give the bonus + score = score.saturating_sub(stats.notes_missed + stats.wrong_notes) + stats.correct_note_times; + + score +} impl Page for StatsPage { type Event = Event; @@ -36,6 +45,7 @@ impl Page for StatsPage { PageMessage::none() } + fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut songhistory = Vec::new(); @@ -63,37 +73,13 @@ impl Page for StatsPage { sorted_stats.sort_by(|a, b| { let score_a = { - let mut score = a.notes_hit + a.correct_note_times * 10; - - // Apply penalties - if a.notes_missed > 0 { - score = score.saturating_sub(a.notes_missed); - } - if a.wrong_notes > 0 { - score = score.saturating_sub(a.wrong_notes); - } - - // Final bonus addition - score += a.correct_note_times; - - score + // initial score + score_cooking(a) }; let score_b = { - let mut score = b.notes_hit + b.correct_note_times * 10; - - // Apply penalties - if b.notes_missed > 0 { - score = score.saturating_sub(b.notes_missed); - } - if b.wrong_notes > 0 { - score = score.saturating_sub(b.wrong_notes); - } - - // Final bonus addition - score += b.correct_note_times; - - score + // initial score + score_cooking(b) }; score_b.cmp(&score_a) @@ -101,18 +87,7 @@ impl Page for StatsPage { // Populate data into tracks for (index, stats) in sorted_stats.iter().enumerate() { - let mut scores = stats.notes_hit + stats.correct_note_times * 10; // There are many ways to cook - - // Apply penalties - if stats.notes_missed > 0 { - scores = scores.saturating_sub(stats.notes_missed); - } - if stats.wrong_notes > 0 { - scores = scores.saturating_sub(stats.wrong_notes); - } - - // Final bonus addition - scores += stats.correct_note_times; + let scores = score_cooking(stats); //Sort by score, higher score first @@ -298,4 +273,5 @@ impl Page for StatsPage { _ => None, } } + } From 307de7085103dcda40fc14ade0903a7892068ebf Mon Sep 17 00:00:00 2001 From: captainerd Date: Sun, 26 May 2024 09:35:38 +0300 Subject: [PATCH 26/29] Remove unnecessary if's and repeated code --- neothesia/src/scene/menu_scene/iced_menu/stats.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index 84eb02f2..bdc6dd5d 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -23,9 +23,7 @@ pub enum Event { use crate::menu_scene::Step; pub struct StatsPage; - fn score_cooking(stats: &SongStats) -> u32 { - let mut score = stats.notes_hit + stats.correct_note_times * 10; // Apply penalties then give the bonus score = score.saturating_sub(stats.notes_missed + stats.wrong_notes) + stats.correct_note_times; @@ -45,7 +43,6 @@ impl Page for StatsPage { PageMessage::none() } - fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> { let mut songhistory = Vec::new(); @@ -273,5 +270,4 @@ impl Page for StatsPage { _ => None, } } - } From 520b0edade723abc6e68006fa0e679f6d7fa3740 Mon Sep 17 00:00:00 2001 From: captainerd Date: Mon, 27 May 2024 02:38:14 +0300 Subject: [PATCH 27/29] mopping the floor --- neothesia-core/src/gamesave.rs | 36 +++++++- .../src/scene/menu_scene/iced_menu/main.rs | 12 +-- .../scene/menu_scene/iced_menu/selectsong.rs | 14 +-- .../src/scene/menu_scene/iced_menu/stats.rs | 85 ++++++------------- .../src/scene/playing_scene/midi_player.rs | 9 +- neothesia/src/song.rs | 9 ++ 6 files changed, 74 insertions(+), 91 deletions(-) diff --git a/neothesia-core/src/gamesave.rs b/neothesia-core/src/gamesave.rs index 609aaff7..d24f9398 100644 --- a/neothesia-core/src/gamesave.rs +++ b/neothesia-core/src/gamesave.rs @@ -1,12 +1,12 @@ use serde::{Deserialize, Serialize}; use std::time::SystemTime; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct SavedStats { pub songs: Vec, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct SongStats { pub song_name: String, pub correct_note_times: u32, @@ -36,6 +36,30 @@ impl SavedStats { } } + pub fn load_for_song(songname: String) -> Vec { + if let Some(saved_stats) = SavedStats::load() { + // Filter stats for the current song + let filtered_stats: Vec = saved_stats + .songs + .iter() + .filter(|stats| stats.song_name == songname) + .cloned() + .collect(); + + // Sort stats using the defined scoring cooking logic + let mut sorted_stats = filtered_stats.clone(); + + sorted_stats.sort_by(|a, b| { + let score_a = SavedStats::score_cooking(a); + let score_b = SavedStats::score_cooking(b); + score_b.cmp(&score_a) + }); + + sorted_stats + } else { + vec![] + } + } pub fn save(&self) { if let Ok(s) = ron::ser::to_string_pretty(self, Default::default()) { if let Some(path) = crate::utils::resources::gamestats_ron() { @@ -44,6 +68,14 @@ impl SavedStats { } } } + pub fn score_cooking(stats: &SongStats) -> u32 { + let mut score = stats.notes_hit + stats.correct_note_times * 10; + // Apply penalties then give the bonus + score = + score.saturating_sub(stats.notes_missed + stats.wrong_notes) + stats.correct_note_times; + + score + } } impl Default for SavedStats { diff --git a/neothesia/src/scene/menu_scene/iced_menu/main.rs b/neothesia/src/scene/menu_scene/iced_menu/main.rs index 78e4a5d4..a7ce25a8 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/main.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/main.rs @@ -105,16 +105,8 @@ impl Page for MainPage { bottom: 10.0, left: 0.0, }); - // - let song_name = if let Some(song_name) = - song.file.name.to_lowercase().strip_suffix(".mid") - { - song_name.to_string() - } else if let Some(song_name) = song.file.name.to_lowercase().strip_suffix(".midi") { - song_name.to_string() - } else { - song.file.name.clone() - }; + + let song_name = Song::get_clean_songname(song.file.name.clone()); layout = layout.bottom( BarLayout::new() diff --git a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs index 4df6cf3b..65296c97 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/selectsong.rs @@ -97,12 +97,7 @@ impl Page for SelectsongPage { if let Some(path_buf) = &ctx.config.last_opened_song { if let Some(file_name) = path_buf.file_name() { if let Some(name) = file_name.to_str() { - if let Some(stripped_name) = name.strip_suffix(".mid") { - song_file_name = stripped_name.to_string(); - } else { - // If the file name doesn't end with ".mid", use the original file name - song_file_name = name.to_string(); - } + song_file_name = Song::get_clean_songname(name.to_string()); } } } @@ -114,12 +109,7 @@ impl Page for SelectsongPage { if let Some(file_name) = entry.file_name().to_str() { if let Some(extension) = Path::new(file_name).extension() { if extension == "mid" || extension == "midi" { - let song_name = - if let Some(stripped_name) = file_name.strip_suffix(".mid") { - stripped_name.to_string() - } else { - file_name.to_string() - }; + let song_name = Song::get_clean_songname(file_name.to_string()); let button_color = if song_file_name == song_name { iced_core::Color::from_rgb8(106, 0, 163) } else { diff --git a/neothesia/src/scene/menu_scene/iced_menu/stats.rs b/neothesia/src/scene/menu_scene/iced_menu/stats.rs index bdc6dd5d..b91b14ed 100644 --- a/neothesia/src/scene/menu_scene/iced_menu/stats.rs +++ b/neothesia/src/scene/menu_scene/iced_menu/stats.rs @@ -1,11 +1,11 @@ -use crate::{context::Context, scene::menu_scene::icons}; +use crate::{context::Context, scene::menu_scene::icons, song::Song}; use chrono::{DateTime, Local}; use iced_core::{ alignment::{Horizontal, Vertical}, Alignment, Length, Padding, }; use iced_widget::{column as col, container, row, vertical_space}; -use neothesia_core::gamesave::{SavedStats, SongStats}; +use neothesia_core::gamesave::SavedStats; use neothesia_iced_widgets::{BarLayout, Element, Layout, NeoBtn}; use super::{ @@ -23,13 +23,6 @@ pub enum Event { use crate::menu_scene::Step; pub struct StatsPage; -fn score_cooking(stats: &SongStats) -> u32 { - let mut score = stats.notes_hit + stats.correct_note_times * 10; - // Apply penalties then give the bonus - score = score.saturating_sub(stats.notes_missed + stats.wrong_notes) + stats.correct_note_times; - - score -} impl Page for StatsPage { type Event = Event; @@ -49,59 +42,31 @@ impl Page for StatsPage { let mut songname = String::new(); if let Some(song) = ctx.song.as_ref() { - songname = song.file.name.clone(); - // Clear out .ext - if let Some(stripped_name) = songname.to_lowercase().strip_suffix(".mid") { - songname = stripped_name.to_string(); - } + songname = Song::get_clean_songname(song.file.name.clone()) } - // Load saved stats and filter stats for the current song - if let Some(saved_stats) = SavedStats::load() { - // Filter stats for the current song - let filtered_stats: Vec<&SongStats> = saved_stats - .songs - .iter() - .filter(|stats| stats.song_name == songname) - .collect(); - - // Sort stats as whatever is the cooking logic: hits + correct timing * 10 subtract from sum the missed and wrong notes - let mut sorted_stats = filtered_stats.clone(); - - sorted_stats.sort_by(|a, b| { - let score_a = { - // initial score - score_cooking(a) - }; - - let score_b = { - // initial score - score_cooking(b) - }; - - score_b.cmp(&score_a) - }); - - // Populate data into tracks - for (index, stats) in sorted_stats.iter().enumerate() { - let scores = score_cooking(stats); - - //Sort by score, higher score first - - let datetime: DateTime = stats.date.into(); - let score = (index + 1) as u32; - let trophy_image = if score <= 3 { score } else { 0 }; - let card = neothesia_iced_widgets::StatsContainer::new() - .image(trophy_image) - .date(datetime.format("%d/%m/%y %H:%M:%S").to_string()) - .place(&(index + 1).to_string()) // Index starts from 1 - .score(scores) - .notes_hits(stats.notes_hit) - .notes_missed(stats.notes_missed) - .wrong_notes(stats.wrong_notes) - .correct_notes_duration(stats.correct_note_times); - songhistory.push(Vec::>::from(card)); - } + // Load saved stats for the current song + let sorted_stats = SavedStats::load_for_song(songname.clone()); + + // Populate data into tracks + for (index, stats) in sorted_stats.iter().enumerate() { + let scores = SavedStats::score_cooking(stats); + + //Sort by score, higher score first + + let datetime: DateTime = stats.date.into(); + let score = (index + 1) as u32; + let trophy_image = if score <= 3 { score } else { 0 }; + let card = neothesia_iced_widgets::StatsContainer::new() + .image(trophy_image) + .date(datetime.format("%d/%m/%y %H:%M:%S").to_string()) + .place(&(index + 1).to_string()) // Index starts from 1 + .score(scores) + .notes_hits(stats.notes_hit) + .notes_missed(stats.notes_missed) + .wrong_notes(stats.wrong_notes) + .correct_notes_duration(stats.correct_note_times); + songhistory.push(Vec::>::from(card)); } // Collect all elements from songhistory into a single Vec diff --git a/neothesia/src/scene/playing_scene/midi_player.rs b/neothesia/src/scene/playing_scene/midi_player.rs index 45256e60..0a25d88e 100644 --- a/neothesia/src/scene/playing_scene/midi_player.rs +++ b/neothesia/src/scene/playing_scene/midi_player.rs @@ -57,13 +57,8 @@ impl MidiPlayer { user_keyboard_range: piano_math::KeyboardRange, ) -> Self { let mut user_stats = NoteStats::default(); - if let Some(song_name) = song.file.name.to_lowercase().strip_suffix(".mid") { - user_stats.song_name = song_name.to_string(); - } else if let Some(song_name) = song.file.name.to_lowercase().strip_suffix(".midi") { - user_stats.song_name = song_name.to_string(); - } else { - user_stats.song_name = song.file.name.clone(); - } + + user_stats.song_name = Song::get_clean_songname(song.file.name.clone()); let mut player = Self { playback: midi_file::PlaybackState::new( diff --git a/neothesia/src/song.rs b/neothesia/src/song.rs index f9a6b173..ec95b8b7 100644 --- a/neothesia/src/song.rs +++ b/neothesia/src/song.rs @@ -49,4 +49,13 @@ impl Song { let config = SongConfig::new(&file.tracks); Self { file, config } } + pub fn get_clean_songname(filename: String) -> String { + if let Some(stripped) = filename.strip_suffix(".midi") { + stripped.to_string() + } else if let Some(stripped) = filename.strip_suffix(".mid") { + stripped.to_string() + } else { + filename.to_string() + } + } } From 5ae11ff95e697386a835168ddf8740f539e145c4 Mon Sep 17 00:00:00 2001 From: captainerd Date: Mon, 27 May 2024 02:46:29 +0300 Subject: [PATCH 28/29] case insensitive clean songname --- neothesia/src/song.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/neothesia/src/song.rs b/neothesia/src/song.rs index ec95b8b7..f463a33f 100644 --- a/neothesia/src/song.rs +++ b/neothesia/src/song.rs @@ -50,10 +50,12 @@ impl Song { Self { file, config } } pub fn get_clean_songname(filename: String) -> String { - if let Some(stripped) = filename.strip_suffix(".midi") { - stripped.to_string() - } else if let Some(stripped) = filename.strip_suffix(".mid") { - stripped.to_string() + let lower_filename = filename.to_lowercase(); + + if lower_filename.ends_with(".midi") { + filename[..filename.len() - 5].to_string() + } else if lower_filename.ends_with(".mid") { + filename[..filename.len() - 4].to_string() } else { filename.to_string() } From 4030a3a0d7a7b4786e6d68b1db23591cc97ba9c5 Mon Sep 17 00:00:00 2001 From: captainerd <58100748+captainerd@users.noreply.github.com> Date: Sun, 3 Nov 2024 08:46:16 +0200 Subject: [PATCH 29/29] Update README.md old project stagnated --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9155643b..199ed8d8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ -![Neothesia Baner](https://github.com/PolyMeilex/Neothesia/assets/20758186/ca9aa8ae-2a69-48de-92d6-97d7ea9e678d) +# MetaThesia + +### Status: Mostly inactive, but feature-complete + +MetaThesia is a fork of [Neothesia by PolyMeilex](https://github.com/PolyMeilex/neothesia), enhanced with a few additional scenes, including game stats and a MIDI folder viewer etc. For more details on what’s changed, check out the commits or changelog. + +### Project Status + +This project is mostly inactive due to limited time, and frankly, it works for my needs. Barring any major bugs that interfere with usability, there likely won’t be new updates. + +If you encounter bugs, you can try the [original project](https://github.com/PolyMeilex/neothesia), or feel free to open an issue here. With a bit of luck, we might be able to address it! # Neothesia