From 991feb18c8af06c5b839634e3791f1728358e5c6 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Tue, 23 Sep 2025 06:25:25 -0500 Subject: [PATCH] lots of cleanup and some ui tweaks --- Cargo.lock | 33 ----- Cargo.toml | 2 - justfile | 3 + src/core/lisp.rs | 157 --------------------- src/core/mod.rs | 1 - src/main.rs | 307 +++++++++++++++++++++++++----------------- src/ui/library.rs | 4 +- src/ui/presenter.rs | 22 ++- src/ui/service.rs | 30 +++-- src/ui/song_editor.rs | 2 +- src/ui/text_svg.rs | 32 ----- 11 files changed, 219 insertions(+), 374 deletions(-) delete mode 100644 src/core/lisp.rs diff --git a/Cargo.lock b/Cargo.lock index d6b747b..d19e19c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3888,27 +3888,6 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" -[[package]] -name = "lexpr" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a84de6a9df442363b08f5dbf0cd5b92edc70097b89c4ce4bfea4679fe48bc67" -dependencies = [ - "itoa", - "lexpr-macros", - "ryu", -] - -[[package]] -name = "lexpr-macros" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b5cb8bb985c81a8ac1a0f8b5c4865214f574ddd64397ef7a99c236e21f35bb" -dependencies = [ - "proc-macro2", - "quote", -] - [[package]] name = "libc" version = "0.2.175" @@ -4105,7 +4084,6 @@ dependencies = [ "gstreamer-app", "iced_video_player", "image", - "lexpr", "libcosmic", "miette", "mupdf", @@ -4117,7 +4095,6 @@ dependencies = [ "rodio", "ron 0.8.1", "serde", - "serde-lexpr", "sqlx", "strum", "strum_macros", @@ -6223,16 +6200,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-lexpr" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4cda13396159f59e7946118cdac0beadeecfb7cf76b197f4147e546f4ead6f" -dependencies = [ - "lexpr", - "serde", -] - [[package]] name = "serde_core" version = "1.0.225" diff --git a/Cargo.toml b/Cargo.toml index 958f31a..1ae39a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,9 @@ description = "A cli presentation system" [dependencies] clap = { version = "4.5.20", features = ["debug", "derive"] } -lexpr = "0.2.7" miette = { version = "7.2.0", features = ["fancy"] } pretty_assertions = "1.4.1" serde = { version = "1.0.213", features = ["derive"] } -serde-lexpr = "0.1.3" tracing = "0.1.40" tracing-log = "0.2.0" tracing-subscriber = { version = "0.3.18", features = ["fmt", "std", "chrono", "time", "local-time", "env-filter"] } diff --git a/justfile b/justfile index 8eb74f5..1da1804 100644 --- a/justfile +++ b/justfile @@ -8,6 +8,8 @@ build: sbuild: RUST_LOG=debug sccache cargo build run: + RUST_LOG=debug cargo run -- {{ui}} +run-file: RUST_LOG=debug cargo run -- {{ui}} {{file}} srun: RUST_LOG=debug sccache cargo run -- {{ui}} {{file}} @@ -20,5 +22,6 @@ profile: alias b := build alias r := run +alias rf := run-file alias sr := srun alias c := clean diff --git a/src/core/lisp.rs b/src/core/lisp.rs deleted file mode 100644 index 2c1a666..0000000 --- a/src/core/lisp.rs +++ /dev/null @@ -1,157 +0,0 @@ -use lexpr::Value; -use strum_macros::EnumString; - -#[derive(Debug, Clone, Default, PartialEq, Eq, EnumString)] -pub(crate) enum Symbol { - #[strum(ascii_case_insensitive)] - Slide, - #[strum(ascii_case_insensitive)] - Image, - #[strum(ascii_case_insensitive)] - Text, - #[strum(ascii_case_insensitive)] - Video, - #[strum(ascii_case_insensitive)] - Song, - #[strum(disabled)] - ImageFit(ImageFit), - #[strum(disabled)] - VerseOrder(VerseOrder), - #[strum(disabled)] - #[default] - None, -} - -#[derive(Debug, Clone, PartialEq, Eq, EnumString)] -pub(crate) enum Keyword { - ImageFit(ImageFit), -} - -#[derive(Debug, Default, Clone, PartialEq, Eq, EnumString)] -pub(crate) enum ImageFit { - #[strum(ascii_case_insensitive)] - #[default] - Cover, - #[strum(ascii_case_insensitive)] - Fill, - #[strum(ascii_case_insensitive)] - Crop, -} - -#[derive(Clone, Debug, Default, PartialEq, Eq, EnumString)] -pub(crate) enum VerseOrder { - #[strum(ascii_case_insensitive)] - #[default] - V1, - #[strum(ascii_case_insensitive)] - V2, - #[strum(ascii_case_insensitive)] - V3, - #[strum(ascii_case_insensitive)] - V4, - #[strum(ascii_case_insensitive)] - V5, - #[strum(ascii_case_insensitive)] - V6, - #[strum(ascii_case_insensitive)] - C1, - #[strum(ascii_case_insensitive)] - C2, - #[strum(ascii_case_insensitive)] - C3, - #[strum(ascii_case_insensitive)] - C4, - #[strum(ascii_case_insensitive)] - B1, - #[strum(ascii_case_insensitive)] - B2, - #[strum(ascii_case_insensitive)] - B3, - #[strum(ascii_case_insensitive)] - B4, - #[strum(ascii_case_insensitive)] - O1, - #[strum(ascii_case_insensitive)] - O2, - #[strum(ascii_case_insensitive)] - O3, - #[strum(ascii_case_insensitive)] - O4, - #[strum(ascii_case_insensitive)] - E1, - #[strum(ascii_case_insensitive)] - E2, - #[strum(ascii_case_insensitive)] - I1, - #[strum(ascii_case_insensitive)] - I2, -} - -#[derive(Clone, Debug, PartialEq, Eq, EnumString)] -pub(crate) enum SongKeyword { - #[strum(ascii_case_insensitive)] - Title, - #[strum(ascii_case_insensitive)] - Author, - #[strum(ascii_case_insensitive)] - Ccli, - #[strum(ascii_case_insensitive)] - Audio, - #[strum(ascii_case_insensitive)] - Font, - #[strum(ascii_case_insensitive)] - FontSize, - #[strum(ascii_case_insensitive)] - Background, - #[strum(ascii_case_insensitive)] - VerseOrder(VerseOrder), -} - -#[derive(Clone, Debug, PartialEq, Eq, EnumString)] -pub(crate) enum ImageKeyword { - #[strum(ascii_case_insensitive)] - Source, - #[strum(ascii_case_insensitive)] - Fit, -} - -#[derive(Clone, Debug, Eq, PartialEq, EnumString)] -pub(crate) enum VideoKeyword { - #[strum(ascii_case_insensitive)] - Source, - #[strum(ascii_case_insensitive)] - Fit, -} - -pub(crate) fn get_lists(exp: &Value) -> Vec { - if exp.is_cons() { - exp.as_cons().unwrap().to_vec().0 - } else { - vec![] - } -} - -#[cfg(test)] -mod test { - - // #[test] - // fn test_list() { - // let lisp = - // read_to_string("./test_presentation.lisp").expect("oops"); - // // println!("{lisp}"); - // let mut parser = - // Parser::from_str_custom(&lisp, Options::elisp()); - // for atom in parser.value_iter() { - // match atom { - // Ok(atom) => { - // // println!("{atom}"); - // let lists = get_lists(&atom); - // assert_eq!(lists, vec![Value::Null]) - // } - // Err(e) => { - // panic!("{e}"); - // } - // } - // } - // } -} diff --git a/src/core/mod.rs b/src/core/mod.rs index e23192e..3cae43a 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,7 +1,6 @@ pub mod content; pub mod images; pub mod kinds; -pub mod lisp; pub mod model; pub mod presentations; pub mod service_items; diff --git a/src/main.rs b/src/main.rs index eaf69d8..91122d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,9 +9,11 @@ use cosmic::app::{Core, Settings, Task}; use cosmic::iced::alignment::Vertical; use cosmic::iced::keyboard::{Key, Modifiers}; use cosmic::iced::window::{Mode, Position}; -use cosmic::iced::{self, event, window, Color, Length, Point}; +use cosmic::iced::{ + self, event, window, Background as IcedBackground, Border, Length, +}; +use cosmic::iced_core::text::Wrapping; use cosmic::iced_futures::Subscription; -use cosmic::iced_runtime::dnd::DndAction; use cosmic::iced_widget::{column, row, stack}; use cosmic::theme; use cosmic::widget::dnd_destination::dnd_destination; @@ -20,8 +22,8 @@ use cosmic::widget::menu::{ItemWidth, KeyBind}; use cosmic::widget::nav_bar::nav_bar_style; use cosmic::widget::tooltip::Position as TPosition; use cosmic::widget::{ - button, dnd_source, horizontal_space, mouse_area, nav_bar, - search_input, tooltip, vertical_space, RcElementWrapper, Space, + button, horizontal_space, mouse_area, nav_bar, responsive, + search_input, tooltip, vertical_space, Space, }; use cosmic::widget::{container, text}; use cosmic::widget::{icon, slider}; @@ -58,7 +60,7 @@ struct Cli { watch: bool, #[arg(short = 'i', long)] ui: bool, - file: PathBuf, + file: Option, } fn main() -> Result<()> { @@ -111,6 +113,7 @@ struct App { windows: Vec, service: Vec, current_item: (usize, usize), + hovered_item: Option, presentation_open: bool, cli_mode: bool, library: Option, @@ -134,7 +137,7 @@ enum Message { File(PathBuf), OpenWindow, CloseWindow(Option), - WindowOpened(window::Id, Option), + WindowOpened(window::Id), WindowClosed(window::Id), AddLibrary(Library), LibraryToggle, @@ -143,10 +146,10 @@ enum Message { None, EditorToggle(bool), ChangeServiceItem(usize), + HoveredServiceItem(Option), AddServiceItem(usize, ServiceItem), AddServiceItemDrop(usize), AppendServiceItem(ServiceItem), - AddService(Vec), SearchFocus, Search(String), CloseSearch, @@ -213,30 +216,36 @@ impl cosmic::Application for App { windows.push(core.main_window_id().unwrap()); } - let items = match read_to_string(input.file) { - Ok(lisp) => { - let mut service_items = vec![]; - let lisp = crisp::reader::read(&lisp); - match lisp { - Value::List(vec) => { - // let items = vec - // .into_par_iter() - // .map(|value| parse_lisp(value)) - // .collect(); - // slide_vector.append(items); - for value in vec { - let mut inner_vector = parse_lisp(value); - service_items.append(&mut inner_vector); + let items = if let Some(file) = input.file { + match read_to_string(file) { + Ok(lisp) => { + let mut service_items = vec![]; + let lisp = crisp::reader::read(&lisp); + match lisp { + Value::List(vec) => { + // let items = vec + // .into_par_iter() + // .map(|value| parse_lisp(value)) + // .collect(); + // slide_vector.append(items); + for value in vec { + let mut inner_vector = + parse_lisp(value); + service_items + .append(&mut inner_vector); + } } + _ => todo!(), } - _ => todo!(), + service_items + } + Err(e) => { + warn!("Missing file or could not read: {e}"); + vec![] } - service_items - } - Err(e) => { - warn!("Missing file or could not read: {e}"); - vec![] } + } else { + vec![] }; let items: Vec = items @@ -308,6 +317,7 @@ impl cosmic::Application for App { library_dragged_item: None, fontdb: Arc::clone(&fontdb), menu_keys, + hovered_item: None, }; let mut batch = vec![]; @@ -530,23 +540,33 @@ impl cosmic::Application for App { debug!("Closing window"); Some(Message::CloseWindow(Some(id))) } - window::Event::Opened { - position, .. - } => { + window::Event::Opened { .. } => { debug!(?window_event, ?id); - Some(Message::WindowOpened(id, position)) + Some(Message::WindowOpened(id)) } window::Event::Closed => { debug!("Closed window"); Some(Message::WindowClosed(id)) } + window::Event::FileHovered(file) => { + debug!(?file); + None + } + window::Event::FileDropped(file) => { + debug!(?file); + None + } _ => None, } } iced::Event::Touch(_touch) => None, iced::Event::A11y(_id, _action_request) => None, - iced::Event::Dnd(_dnd_event) => None, - iced::Event::PlatformSpecific(_platform_specific) => { + iced::Event::Dnd(_dnd_event) => { + // debug!(?dnd_event); + None + } + iced::Event::PlatformSpecific(platform_specific) => { + debug!(?platform_specific); None } } @@ -676,7 +696,7 @@ impl cosmic::Application for App { }) } song_editor::Action::UpdateSong(song) => { - if let Some(library) = &mut self.library { + if let Some(_) = &mut self.library { self.update(Message::Library( library::Message::UpdateSong(song), )) @@ -914,9 +934,7 @@ impl cosmic::Application for App { .set_window_title(format!("window_{count}"), id); spawn_window.map(|id| { - cosmic::Action::App(Message::WindowOpened( - id, None, - )) + cosmic::Action::App(Message::WindowOpened(id)) }) } Message::CloseWindow(id) => { @@ -926,7 +944,7 @@ impl cosmic::Application for App { Task::none() } } - Message::WindowOpened(id, _) => { + Message::WindowOpened(id) => { debug!(?id, "Window opened"); if self.cli_mode || id > self.core.main_window_id().expect("Cosmic core seems to be missing a main window, was this started in cli mode?") @@ -969,10 +987,6 @@ impl cosmic::Application for App { self.library = Some(library); Task::none() } - Message::AddService(service) => { - self.service = service; - Task::none() - } Message::None => Task::none(), Message::EditorToggle(edit) => { if edit { @@ -988,6 +1002,10 @@ impl cosmic::Application for App { self.search_id.clone(), ) } + Message::HoveredServiceItem(index) => { + self.hovered_item = index; + Task::none() + } Message::ChangeServiceItem(index) => { if let Some((index, item)) = self .service @@ -1283,9 +1301,8 @@ where }); self.windows.push(id); _ = self.set_window_title("Lumina Presenter".to_owned(), id); - spawn_window.map(|id| { - cosmic::Action::App(Message::WindowOpened(id, None)) - }) + spawn_window + .map(|id| cosmic::Action::App(Message::WindowOpened(id))) } fn add_library(&self) -> Task { @@ -1309,36 +1326,6 @@ where } } - fn add_service( - &self, - items: Vec, - fontdb: Arc, - ) -> Task { - Task::perform( - async move { - let items: Vec = items - .into_par_iter() - .map(|mut item| { - item.slides = item - .slides - .into_par_iter() - .map(|mut slide| { - text_svg::text_svg_generator( - &mut slide, - Arc::clone(&fontdb), - ); - slide - }) - .collect(); - item - }) - .collect(); - items - }, - |x| cosmic::Action::App(Message::AddService(x)), - ) - } - fn process_key_press( &mut self, key: Key, @@ -1411,56 +1398,123 @@ where } fn service_list(&self) -> Element { - let list = self - .service - .iter() - .enumerate() - .map(|(index, item)| { - let button = button::standard(item.title.clone()) - .leading_icon({ - match item.kind { - core::kinds::ServiceItemKind::Song(_) => { - icon::from_name("folder-music-symbolic") - }, - core::kinds::ServiceItemKind::Video(_) => { - icon::from_name("folder-videos-symbolic") - }, - core::kinds::ServiceItemKind::Image(_) => { - icon::from_name("folder-pictures-symbolic") - }, - core::kinds::ServiceItemKind::Presentation(_) => { - icon::from_name("x-office-presentation-symbolic") - }, - core::kinds::ServiceItemKind::Content(_) => { - icon::from_name("x-office-presentation-symbolic") - }, - } - }) - // .icon_size(cosmic::theme::spacing().space_l) - .class(cosmic::theme::style::Button::HeaderBar) - // .spacing(cosmic::theme::spacing().space_l) - .height(cosmic::theme::spacing().space_xl) - .width(Length::Fill) - .on_press(Message::ChangeServiceItem(index)); - let tooltip = tooltip(button, - text::body(item.kind.to_string()), - TPosition::Right); - dnd_destination(tooltip, vec!["application/service-item".into()]) - .data_received_for::( move |item| { - if let Some(item) = item { - Message::AddServiceItem(index, item) - } else { - Message::None - } - }).on_finish(move |mime, data, action, x, y| { - debug!(mime, ?data, ?action, x, y); - let Ok(item) = ServiceItem::try_from((data, mime)) else { - return Message::None; - }; - debug!(?item); - Message::AddServiceItem(index, item) - }) + let list = + self.service.iter().enumerate().map(|(index, item)| { + let icon = match item.kind { + ServiceItemKind::Song(_) => { + icon::from_name("folder-music-symbolic") + } + ServiceItemKind::Video(_) => { + icon::from_name("folder-videos-symbolic") + } + ServiceItemKind::Image(_) => { + icon::from_name("folder-pictures-symbolic") + } + ServiceItemKind::Presentation(_) => { + icon::from_name( + "x-office-presentation-symbolic", + ) + } + ServiceItemKind::Content(_) => icon::from_name( + "x-office-presentation-symbolic", + ), + }; + let title = responsive(|size| { + text::heading(library::elide_text( + &item.title, + size.width, + )) + .wrapping(Wrapping::None) .into() + }); + let container = container( + row![icon, title] + .align_y(Vertical::Center) + .spacing(cosmic::theme::spacing().space_xs), + ) + .padding(cosmic::theme::spacing().space_s) + .class(cosmic::theme::style::Container::Secondary) + .style(move |t| { + container::Style::default() + .background(IcedBackground::Color( + if self.hovered_item.is_some_and( + |hovered_index| { + index == hovered_index + }, + ) { + t.cosmic().button.hover.into() + } else { + t.cosmic().button.base.into() + }, + )) + .border(Border::default().rounded( + t.cosmic().corner_radii.radius_m, + )) + }) + .width(Length::Fill); + let mouse_area = mouse_area(container) + .on_enter(Message::HoveredServiceItem(Some( + index, + ))) + .on_exit(Message::HoveredServiceItem(None)) + .on_press(Message::ChangeServiceItem(index)); + // let button = button::standard(item.title.clone()) + // .leading_icon({ + // match item.kind { + // core::kinds::ServiceItemKind::Song(_) => { + // icon::from_name("folder-music-symbolic") + // }, + // core::kinds::ServiceItemKind::Video(_) => { + // icon::from_name("folder-videos-symbolic") + // }, + // core::kinds::ServiceItemKind::Image(_) => { + // icon::from_name("folder-pictures-symbolic") + // }, + // core::kinds::ServiceItemKind::Presentation(_) => { + // icon::from_name("x-office-presentation-symbolic") + // }, + // core::kinds::ServiceItemKind::Content(_) => { + // icon::from_name("x-office-presentation-symbolic") + // }, + // } + // }) + // // .icon_size(cosmic::theme::spacing().space_l) + // .class(cosmic::theme::style::Button::HeaderBar) + // // .spacing(cosmic::theme::spacing().space_l) + // .height(cosmic::theme::spacing().space_xl) + // .width(Length::Fill) + // .on_press(Message::ChangeServiceItem(index)); + let tooltip = tooltip( + mouse_area, + text::body(item.kind.to_string()), + TPosition::Right, + ) + .gap(cosmic::theme::spacing().space_xs); + dnd_destination( + tooltip, + vec![ + "application/service-item".into(), + "video/mp4".into(), + ], + ) + .data_received_for::(move |item| { + if let Some(item) = item { + Message::AddServiceItem(index, item) + } else { + Message::None + } + }) + .on_finish(move |mime, data, action, x, y| { + debug!(mime, ?data, ?action, x, y); + let Ok(item) = + ServiceItem::try_from((data, mime)) + else { + return Message::None; + }; + debug!(?item); + Message::AddServiceItem(index, item) + }) + .into() }); let column = column![ @@ -1469,6 +1523,7 @@ where .width(Length::Fill), iced::widget::horizontal_rule(1), column(list).spacing(10), + // service::service(&self.service), dnd_destination( vertical_space().width(Length::Fill), vec!["application/service-item".into()] @@ -1494,9 +1549,7 @@ where ] .padding(10) .spacing(10); - let container = Container::new(column) - // .height(Length::Fill) - .style(nav_bar_style); + let container = Container::new(column).style(nav_bar_style); container.center(Length::FillPortion(2)).into() } diff --git a/src/ui/library.rs b/src/ui/library.rs index 89c3cbb..947ad42 100644 --- a/src/ui/library.rs +++ b/src/ui/library.rs @@ -51,7 +51,6 @@ pub struct Library { enum MenuMessage { Delete((LibraryKind, i32)), Open, - None, } impl MenuAction for MenuMessage { @@ -63,7 +62,6 @@ impl MenuAction for MenuMessage { Message::DeleteItem((*kind, *index)) } MenuMessage::Open => todo!(), - MenuMessage::None => todo!(), } } } @@ -827,7 +825,7 @@ async fn add_db() -> Result { SqlitePool::connect(&db_url).await.into_diagnostic() } -fn elide_text(text: impl AsRef, width: f32) -> String { +pub fn elide_text(text: impl AsRef, width: f32) -> String { const CHAR_SIZE: f32 = 8.0; let text: String = text.as_ref().to_owned(); let text_length = text.len() as f32 * CHAR_SIZE; diff --git a/src/ui/presenter.rs b/src/ui/presenter.rs index 136d8fe..c1c6a5a 100644 --- a/src/ui/presenter.rs +++ b/src/ui/presenter.rs @@ -1,5 +1,10 @@ use miette::{IntoDiagnostic, Result}; -use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc}; +use std::{ + fs::File, + io::BufReader, + path::PathBuf, + sync::{Arc, LazyLock}, +}; use cosmic::{ iced::{ @@ -31,7 +36,8 @@ use crate::{ }; const REFERENCE_WIDTH: f32 = 1920.0; -const REFERENCE_HEIGHT: f32 = 1080.0; +static DEFAULT_SLIDE: LazyLock = + LazyLock::new(|| Slide::default()); // #[derive(Default, Clone, Debug)] pub(crate) struct Presenter { @@ -147,14 +153,22 @@ impl Presenter { let total_slides: usize = items.iter().fold(0, |a, item| a + item.slides.len()); + let slide = + items.get(0).map(|item| item.slides.get(0)).flatten(); + let audio = items + .get(0) + .map(|item| item.slides.get(0).map(|slide| slide.audio())) + .flatten() + .flatten(); + Self { - current_slide: items[0].slides[0].clone(), + current_slide: slide.unwrap_or(&DEFAULT_SLIDE).clone(), current_item: 0, current_slide_index: 0, absolute_slide_index: 0, total_slides, video, - audio: items[0].slides[0].audio(), + audio, service: items, video_position: 0.0, hovered_slide: None, diff --git a/src/ui/service.rs b/src/ui/service.rs index a5a65ab..bebabb5 100644 --- a/src/ui/service.rs +++ b/src/ui/service.rs @@ -1,22 +1,19 @@ -use std::any::Any; - -use cosmic::iced::{self, Size}; -use cosmic::iced_core::window; +use cosmic::iced::Size; +use cosmic::iced_core::widget::tree; use cosmic::{ iced::{ - clipboard::dnd::{DndAction, DndEvent, SourceEvent}, - event, mouse, overlay, Event, Length, Point, Rectangle, - Vector, + clipboard::dnd::{DndEvent, SourceEvent}, + event, mouse, Event, Length, Point, Rectangle, Vector, }, iced_core::{ - self, layout, renderer, - widget::{tree, Tree}, + self, image::Renderer, layout, renderer, widget::Tree, Clipboard, Shell, }, - widget::{container, Id, Widget}, + widget::Widget, Element, }; +use tracing::debug; use crate::core::service_items::ServiceItem; @@ -133,6 +130,10 @@ impl layout::atomic(limits, self.width, self.height) } + fn state(&self) -> iced_core::widget::tree::State { + tree::State::new(State::new()) + } + // fn operate( // &self, // tree: &mut Tree, @@ -231,6 +232,7 @@ impl _ => return event::Status::Ignored, }, Event::Dnd(DndEvent::Source(SourceEvent::Cancelled)) => { + debug!("canceled"); if state.is_dragging { if let Some(m) = self.on_cancelled.as_ref() { shell.publish(m.clone()); @@ -241,6 +243,7 @@ impl return event::Status::Ignored; } Event::Dnd(DndEvent::Source(SourceEvent::Finished)) => { + debug!("dropped"); if state.is_dragging { if let Some(m) = self.on_finish.as_ref() { shell.publish(m.clone()); @@ -250,6 +253,7 @@ impl } return event::Status::Ignored; } + Event::Dnd(event) => debug!(?event), _ => return event::Status::Ignored, } event::Status::Ignored @@ -286,10 +290,8 @@ impl cursor_position: mouse::Cursor, viewport: &Rectangle, ) { - let state = tree.state.downcast_mut::(); - for item in self.service { - todo!() - } + // let state = tree.state.downcast_mut::(); + for item in self.service {} } // fn overlay<'b>( diff --git a/src/ui/song_editor.rs b/src/ui/song_editor.rs index 8996797..05ad850 100644 --- a/src/ui/song_editor.rs +++ b/src/ui/song_editor.rs @@ -2,7 +2,7 @@ use std::{io, path::PathBuf, sync::Arc}; use cosmic::{ dialog::file_chooser::{open::Dialog, FileFilter}, - iced::{alignment::Vertical, Font, Length}, + iced::{alignment::Vertical, Length}, iced_wgpu::graphics::text::cosmic_text::fontdb, iced_widget::{column, row}, theme, diff --git a/src/ui/text_svg.rs b/src/ui/text_svg.rs index f7263b7..7b01846 100644 --- a/src/ui/text_svg.rs +++ b/src/ui/text_svg.rs @@ -354,14 +354,6 @@ impl TextSvg { .height(Length::Fill) .into() } - - fn text_spans(&self) -> Vec { - self.text - .lines() - .enumerate() - .map(|(i, t)| format!("{t}")) - .collect() - } } pub fn shadow( @@ -408,27 +400,3 @@ pub fn text_svg_generator( slide.text_svg = Some(text_svg); } } - -#[cfg(test)] -mod test { - use pretty_assertions::assert_eq; - - use super::TextSvg; - - #[test] - fn test_text_spans() { - let mut text = TextSvg::new("yes"); - text.text = "This is -multiline -text." - .into(); - assert_eq!( - vec![ - String::from("This is"), - String::from("multiline"), - String::from("text."), - ], - text.text_spans() - ) - } -}