diff --git a/src/main.rs b/src/main.rs index 845ae92..ee60a8d 100755 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ use cosmic::{ Application, ApplicationExt, Apply, Element, cosmic_config, executor, theme, }; +use std::time::{Duration, Instant}; // use crisp::types::Value; // use lisp::parse_lisp; use miette::{IntoDiagnostic, Result, miette}; @@ -198,6 +199,7 @@ enum Message { LibraryToggle, Quit, Key(Key, Modifiers), + Tick(Instant), None, EditorToggle(bool), ChangeServiceItem(usize), @@ -666,11 +668,15 @@ impl cosmic::Application for App { } fn subscription(&self) -> Subscription { - event::listen_with(|event, status, id| { - // debug!(?event); - match status { - event::Status::Ignored => { - match event { + let time_subscription = + cosmic::iced::time::every(Duration::from_millis(50)) + .map(Message::Tick); + let event_subscription = event::listen_with( + |event, status, id| { + // debug!(?event); + match status { + event::Status::Ignored => { + match event { iced::Event::Keyboard(event) => match event { iced::keyboard::Event::KeyReleased { key, @@ -720,10 +726,13 @@ impl cosmic::Application for App { } iced::Event::InputMethod(_event) => todo!(), } + } + event::Status::Captured => None, } - event::Status::Captured => None, - } - }) + }, + ); + + Subscription::batch([time_subscription, event_subscription]) } fn context_drawer( @@ -1129,6 +1138,9 @@ impl cosmic::Application for App { } } } + Message::Tick(instant) => self.update(Message::Present( + presenter::Message::Tick(instant), + )), Message::Library(message) => { if let Some(library) = &mut self.library { match library.update(message) { diff --git a/src/ui/presenter.rs b/src/ui/presenter.rs index 1454b68..8aaaeb4 100644 --- a/src/ui/presenter.rs +++ b/src/ui/presenter.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::BufReader; use std::path::PathBuf; use std::sync::{Arc, LazyLock}; -use std::time::Duration; +use std::time::{Duration, Instant}; use cosmic::cosmic_theme::Spacing; use cosmic::iced::alignment::Horizontal; @@ -14,8 +14,8 @@ use cosmic::iced::widget::scrollable::{ }; use cosmic::iced::widget::stack; use cosmic::iced::{ - Background, Border, Color, ContentFit, Font, Length, Point, - Shadow, Vector, + Animation, Background, Border, Color, ContentFit, Font, Length, + Point, Shadow, Vector, animation, }; use cosmic::prelude::*; use cosmic::widget::divider::{self, vertical}; @@ -74,6 +74,8 @@ pub(crate) struct Presenter { obs_scenes: Option>, preview_size: f32, pub image_loader: ImageLoader, + animation: Option>, + now: Instant, } #[allow(dead_code)] @@ -110,42 +112,9 @@ pub(crate) enum Message { PlayPauseVideo, CloseContextMenu, ChangePreviewSize(f64), + Tick(Instant), } -// #[allow(clippy::enum_variant_names)] -// #[derive(Debug, Clone, Copy, PartialEq, Eq)] -// enum MenuAction { -// ObsSceneAssign(usize), -// ObsStartStream, -// ObsStopStream, -// // ObsStartRecord, -// // ObsStopRecord, -// } - -// impl menu::Action for MenuAction { -// type Message = Message; - -// fn message(&self) -> Self::Message { -// match self { -// Self::ObsSceneAssign(scene) => { -// Message::AssignObsScene(*scene) -// } -// Self::ObsStartStream => Message::AssignSlideAction( -// slide_actions::Action::Obs { -// action: ObsAction::StartStream, -// }, -// ), -// Self::ObsStopStream => Message::AssignSlideAction( -// slide_actions::Action::Obs { -// action: ObsAction::StopStream, -// }, -// ), -// // Self::ObsStartRecord => todo!(), -// // Self::ObsStopRecord => todo!(), -// } -// } -// } - impl Presenter { #[allow(clippy::too_many_lines)] pub fn with_items(items: Arc>) -> Self { @@ -262,6 +231,8 @@ impl Presenter { obs_scenes: None, image_loader: ImageLoader::default(), preview_size: 100.0, + animation: None, + now: Instant::now(), } } @@ -323,6 +294,9 @@ impl Presenter { return self.change_slide(slide.clone()); } } + Message::Tick(instant) => { + self.now = instant; + } Message::AddObsClient(client) => { self.obs_client = Some(client); } @@ -1149,6 +1123,23 @@ impl Presenter { self.audio_position = Some(self.sink.1.get_pos()); } } + if self.service.get(self.current_item).is_some_and(|item| { + matches!( + item.kind, + crate::core::kinds::ServiceItemKind::Song(..) + ) + }) { + self.animation = Some( + Animation::new(false) + .slow() + .easing(animation::Easing::EaseInExpo), + ); + if let Some(animation) = &mut self.animation { + animation.go_mut(true, self.now); + }; + } else { + self.animation = None; + }; let task_count = tasks.len(); debug!(?task_count);