Skip to content

Commit

Permalink
Introduce PageMessage type
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyMeilex committed Mar 13, 2024
1 parent 22c4ff5 commit ecd4ca9
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 86 deletions.
1 change: 1 addition & 0 deletions neothesia/src/iced_utils/iced_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ where
}

/// Returns whether the event queue of the [`State`] is empty or not.
#[allow(dead_code)]
pub fn is_queue_empty(&self) -> bool {
self.queued_events.is_empty() && self.queued_messages.is_empty()
}
Expand Down
9 changes: 4 additions & 5 deletions neothesia/src/scene/menu_scene/iced_menu/exit.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use iced_core::{Alignment, Length};
use iced_runtime::Command;
use iced_widget::{column as col, row};
use neothesia_iced_widgets::{Element, NeoBtn};

use crate::{context::Context, NeothesiaEvent};

use super::{center_x, centered_text, Data, Message, Page};
use super::{center_x, centered_text, page::PageMessage, Data, Message, Page};

pub struct ExitPage;

Expand All @@ -18,17 +17,17 @@ pub enum Event {
impl Page for ExitPage {
type Event = Event;

fn update(_data: &mut Data, event: Event, ctx: &mut Context) -> Command<Message> {
fn update(_data: &mut Data, event: Event, ctx: &mut Context) -> PageMessage {
match event {
Event::GoBack => {
return Command::perform(async {}, |_| Message::GoBack);
return PageMessage::go_back();
}
Event::Exit => {
ctx.proxy.send_event(NeothesiaEvent::Exit).ok();
}
}

Command::none()
PageMessage::None
}

fn view<'a>(_data: &'a Data, _ctx: &Context) -> Element<'a, Event> {
Expand Down
92 changes: 48 additions & 44 deletions neothesia/src/scene/menu_scene/iced_menu/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use neothesia_iced_widgets::{BarLayout, Layout, NeoBtn};

use crate::{context::Context, scene::menu_scene::icons, song::Song};

use super::{page::Page, top_padded, Data, Message, Step};
use super::{
page::{Page, PageMessage},
top_padded, Data, Message, Step,
};

#[derive(Debug, Clone)]
pub enum Event {
Expand All @@ -24,20 +27,24 @@ pub struct MainPage;
impl Page for MainPage {
type Event = Event;

fn update(data: &mut Data, msg: Self::Event, ctx: &mut Context) -> Command<Message> {
fn update(data: &mut Data, msg: Self::Event, ctx: &mut Context) -> PageMessage {
match msg {
Event::Play => {
super::play(data, ctx);
}
Event::GoToPage(step) => {
return Command::perform(async {}, move |_| Message::GoToPage(step));
return PageMessage::go_to_page(step);
}
Event::MidiFilePicker(msg) => {
return midi_file_picker_update(data, msg, ctx);
return PageMessage::Command(
midi_file_picker_update(data, msg, ctx)
.map(Event::MidiFilePicker)
.map(Message::MainPage),
);
}
};

Command::none()
PageMessage::None
}

fn view<'a>(data: &'a Data, ctx: &Context) -> neothesia_iced_widgets::Element<'a, Self::Event> {
Expand Down Expand Up @@ -154,19 +161,23 @@ impl MidiFilePickerMessage {

impl From<MidiFilePickerMessage> for Message {
fn from(msg: MidiFilePickerMessage) -> Self {
Message::MainPage(super::main::Event::MidiFilePicker(msg))
Message::MainPage(Event::MidiFilePicker(msg))
}
}

fn midi_file_picker_update(
data: &mut Data,
msg: MidiFilePickerMessage,
ctx: &mut Context,
) -> Command<Message> {
) -> Command<MidiFilePickerMessage> {
match msg {
MidiFilePickerMessage::OpenMidiFilePicker => {
data.is_loading = true;
return open_midi_file_picker(|v| MidiFilePickerMessage::MidiFileLoaded(v).into());

return Command::perform(
open_midi_file_picker(),
MidiFilePickerMessage::MidiFileLoaded,
);
}
MidiFilePickerMessage::MidiFileLoaded(midi) => {
if let Some((midi, path)) = midi {
Expand All @@ -180,41 +191,34 @@ fn midi_file_picker_update(
Command::none()
}

fn open_midi_file_picker(
f: impl FnOnce(Option<(midi_file::MidiFile, PathBuf)>) -> Message + 'static + Send,
) -> Command<Message> {
Command::perform(
async {
let file = rfd::AsyncFileDialog::new()
.add_filter("midi", &["mid", "midi"])
.pick_file()
.await;

if let Some(file) = file {
log::info!("File path = {:?}", file.path());

let thread = async_thread::Builder::new()
.name("midi-loader".into())
.spawn(move || {
let midi = midi_file::MidiFile::new(file.path());

if let Err(e) = &midi {
log::error!("{}", e);
}

midi.map(|midi| (midi, file.path().to_path_buf())).ok()
});

if let Ok(thread) = thread {
thread.join().await.ok().flatten()
} else {
None
async fn open_midi_file_picker() -> Option<(midi_file::MidiFile, PathBuf)> {
let file = rfd::AsyncFileDialog::new()
.add_filter("midi", &["mid", "midi"])
.pick_file()
.await;

if let Some(file) = file {
log::info!("File path = {:?}", file.path());

let thread = async_thread::Builder::new()
.name("midi-loader".into())
.spawn(move || {
let midi = midi_file::MidiFile::new(file.path());

if let Err(e) = &midi {
log::error!("{}", e);
}
} else {
log::info!("User canceled dialog");
None
}
},
f,
)

midi.map(|midi| (midi, file.path().to_path_buf())).ok()
});

if let Ok(thread) = thread {
thread.join().await.ok().flatten()
} else {
None
}
} else {
log::info!("User canceled dialog");
None
}
}
22 changes: 18 additions & 4 deletions neothesia/src/scene/menu_scene/iced_menu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::collections::VecDeque;

use self::page::PageMessage;

use super::Renderer;
use iced_core::{
alignment::{Horizontal, Vertical},
Expand Down Expand Up @@ -100,6 +102,14 @@ impl AppUi {
}
}
}

fn handle_page_msg(&mut self, ctx: &mut Context, msg: PageMessage) -> Command<Message> {
match msg {
PageMessage::Message(msg) => self.update(ctx, msg),
PageMessage::Command(cmd) => cmd,
PageMessage::None => Command::none(),
}
}
}

impl Program for AppUi {
Expand All @@ -114,16 +124,20 @@ impl Program for AppUi {
self.go_back();
}
Message::MainPage(msg) => {
return MainPage::update(&mut self.data, msg, ctx);
let msg = MainPage::update(&mut self.data, msg, ctx);
return self.handle_page_msg(ctx, msg);
}
Message::SettingsPage(msg) => {
return SettingsPage::update(&mut self.data, msg, ctx);
let msg = SettingsPage::update(&mut self.data, msg, ctx);
return self.handle_page_msg(ctx, msg);
}
Message::TracksPage(msg) => {
return TracksPage::update(&mut self.data, msg, ctx);
let msg = TracksPage::update(&mut self.data, msg, ctx);
return self.handle_page_msg(ctx, msg);
}
Message::ExitPage(msg) => {
return ExitPage::update(&mut self.data, msg, ctx);
let msg = ExitPage::update(&mut self.data, msg, ctx);
return self.handle_page_msg(ctx, msg);
}
}

Expand Down
28 changes: 26 additions & 2 deletions neothesia/src/scene/menu_scene/iced_menu/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,35 @@ use neothesia_iced_widgets::Element;

use crate::context::Context;

use super::{Data, Message};
use super::{Data, Message, Step};

pub enum PageMessage {
Message(Message),
Command(Command<Message>),
None,
}

impl PageMessage {
pub fn go_back() -> Self {
Self::message(Message::GoBack)
}

pub fn go_to_page(step: Step) -> Self {
Self::message(Message::GoToPage(step))
}

pub fn none() -> Self {
Self::None
}

fn message(msg: Message) -> Self {
Self::Message(msg)
}
}

pub trait Page {
type Event;
fn update(data: &mut Data, msg: Self::Event, ctx: &mut Context) -> Command<Message>;
fn update(data: &mut Data, msg: Self::Event, ctx: &mut Context) -> PageMessage;
fn view<'a>(data: &'a Data, ctx: &Context) -> Element<'a, Self::Event>;
fn keyboard_input(event: &iced_runtime::keyboard::Event, ctx: &Context) -> Option<Message>;
}
50 changes: 24 additions & 26 deletions neothesia/src/scene/menu_scene/iced_menu/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ use neothesia_iced_widgets::{ActionRow, BarLayout, Element, Layout, NeoBtn, Pref

use crate::{context::Context, output_manager::OutputDescriptor, scene::menu_scene::icons};

use super::{centered_text, page::Page, theme, Data, InputDescriptor, Message};
use super::{
centered_text,
page::{Page, PageMessage},
theme, Data, InputDescriptor, Message,
};

#[derive(Debug, Clone)]
pub enum RangeUpdateKind {
Expand Down Expand Up @@ -44,7 +48,7 @@ impl SettingsPage {
impl Page for SettingsPage {
type Event = Event;

fn update(data: &mut Data, msg: Event, ctx: &mut Context) -> Command<Message> {
fn update(data: &mut Data, msg: Event, ctx: &mut Context) -> PageMessage {
match msg {
Event::SelectOutput(output) => {
ctx.config
Expand All @@ -67,9 +71,10 @@ impl Page for SettingsPage {
}
Event::OpenSoundFontPicker => {
data.is_loading = true;
return open_sound_font_picker(|res| {
Message::SettingsPage(Event::SoundFontFileLoaded(res))
});

let cmd = Command::perform(open_sound_font_picker(), Event::SoundFontFileLoaded)
.map(Message::SettingsPage);
return PageMessage::Command(cmd);
}
Event::SoundFontFileLoaded(font) => {
if let Some(font) = font {
Expand Down Expand Up @@ -100,11 +105,11 @@ impl Page for SettingsPage {
}
},
Event::GoBack => {
return Command::perform(async {}, |_| Message::GoBack);
return PageMessage::go_back();
}
}

Command::none()
PageMessage::none()
}

fn view<'a>(data: &'a Data, ctx: &Context) -> Element<'a, Event> {
Expand Down Expand Up @@ -308,24 +313,17 @@ fn guidelines_group<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> {
.build()
}

fn open_sound_font_picker(
f: impl FnOnce(Option<PathBuf>) -> Message + 'static + Send,
) -> Command<Message> {
Command::perform(
async {
let file = rfd::AsyncFileDialog::new()
.add_filter("SoundFont2", &["sf2"])
.pick_file()
.await;

if let Some(file) = file.as_ref() {
log::info!("Font path = {:?}", file.path());
} else {
log::info!("User canceled dialog");
}
async fn open_sound_font_picker() -> Option<PathBuf> {
let file = rfd::AsyncFileDialog::new()
.add_filter("SoundFont2", &["sf2"])
.pick_file()
.await;

file.map(|f| f.path().to_owned())
},
f,
)
if let Some(file) = file.as_ref() {
log::info!("Font path = {:?}", file.path());
} else {
log::info!("User canceled dialog");
}

file.map(|f| f.path().to_owned())
}
13 changes: 8 additions & 5 deletions neothesia/src/scene/menu_scene/iced_menu/tracks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ use iced_core::{
alignment::{Horizontal, Vertical},
Alignment, Length, Padding,
};
use iced_runtime::Command;
use iced_widget::{button, column as col, container, row, vertical_space};

use crate::{context::Context, scene::menu_scene::icons, song::PlayerConfig};
use neothesia_iced_widgets::{BarLayout, Element, Layout, NeoBtn};

use super::{centered_text, page::Page, theme, Data, Message};
use super::{
centered_text,
page::{Page, PageMessage},
theme, Data, Message,
};

#[derive(Debug, Clone)]
pub enum Event {
Expand All @@ -24,7 +27,7 @@ pub struct TracksPage;
impl Page for TracksPage {
type Event = Event;

fn update(data: &mut Data, event: Event, ctx: &mut Context) -> Command<Message> {
fn update(data: &mut Data, event: Event, ctx: &mut Context) -> PageMessage {
match event {
Event::AllTracksPlayer(config) => {
if let Some(song) = ctx.song.as_mut() {
Expand All @@ -44,14 +47,14 @@ impl Page for TracksPage {
}
}
Event::GoBack => {
return Command::perform(async {}, |_| Message::GoBack);
return PageMessage::go_back();
}
Event::Play => {
super::play(data, ctx);
}
}

Command::none()
PageMessage::none()
}

fn view<'a>(_data: &'a Data, ctx: &Context) -> Element<'a, Event> {
Expand Down

0 comments on commit ecd4ca9

Please sign in to comment.