diff --git a/src/main.rs b/src/main.rs index 9b771c2..597d202 100644 --- a/src/main.rs +++ b/src/main.rs @@ -417,49 +417,7 @@ impl cosmic::Application for App { fn update(&mut self, message: Message) -> Task { match message { Message::Key(key, modifiers) => { - debug!(?key, ?modifiers); - match (key, modifiers) { - ( - Key::Named( - iced::keyboard::key::Named::ArrowRight, - ), - _, - ) => self.update(Message::Present( - presenter::Message::NextSlide, - )), - ( - Key::Named( - iced::keyboard::key::Named::ArrowLeft, - ), - _, - ) => self.update(Message::Present( - presenter::Message::PrevSlide, - )), - ( - Key::Named(iced::keyboard::key::Named::Space), - _, - ) => self.update(Message::Present( - presenter::Message::NextSlide, - )), - (Key::Character(k), _) - if k == *"j" || k == *"l" => - { - self.update(Message::Present( - presenter::Message::NextSlide, - )) - } - (Key::Character(k), _) - if k == *"k" || k == *"h" => - { - self.update(Message::Present( - presenter::Message::PrevSlide, - )) - } - (Key::Character(k), _) if k == *"q" => { - self.update(Message::Quit) - } - _ => Task::none(), - } + self.process_key_press(key, modifiers) } Message::SongEditor(message) => { self.song_editor.update(message).map(|m| { @@ -654,13 +612,9 @@ impl cosmic::Application for App { ] .spacing(3); - let mut drag_item = None; - let library = Container::new(if let Some(library) = &self.library { - let (view, item) = library.view(); - drag_item = item; - view.map(|m| Message::Library(m)) + library.view().map(|m| Message::Library(m)) } else { Space::new(0, 0).into() }) @@ -714,7 +668,7 @@ impl cosmic::Application for App { .center_y(130) ]; - if let Some(editor) = &self.editor_mode { + if let Some(_editor) = &self.editor_mode { Element::from(song_editor) } else { Element::from(column) @@ -767,6 +721,45 @@ where cosmic::app::Message::App(Message::AddLibrary(x)) }) } + + fn process_key_press( + &mut self, + key: Key, + modifiers: Modifiers, + ) -> Task { + debug!(?key, ?modifiers); + match (key, modifiers) { + ( + Key::Named(iced::keyboard::key::Named::ArrowRight), + _, + ) => self.update(Message::Present( + presenter::Message::NextSlide, + )), + ( + Key::Named(iced::keyboard::key::Named::ArrowLeft), + _, + ) => self.update(Message::Present( + presenter::Message::PrevSlide, + )), + (Key::Named(iced::keyboard::key::Named::Space), _) => { + self.update(Message::Present( + presenter::Message::NextSlide, + )) + } + (Key::Character(k), _) if k == *"j" || k == *"l" => self + .update(Message::Present( + presenter::Message::NextSlide, + )), + (Key::Character(k), _) if k == *"k" || k == *"h" => self + .update(Message::Present( + presenter::Message::PrevSlide, + )), + (Key::Character(k), _) if k == *"q" => { + self.update(Message::Quit) + } + _ => Task::none(), + } + } } #[cfg(test)] diff --git a/src/ui/library.rs b/src/ui/library.rs index fd14bf8..22340a2 100644 --- a/src/ui/library.rs +++ b/src/ui/library.rs @@ -1,10 +1,10 @@ use cosmic::{ iced::{alignment::Vertical, Background, Border, Length}, - iced_core::widget::tree::State, + iced_core::widget::tree, iced_widget::{column, row as rowm, text as textm}, widget::{ container, horizontal_space, icon, mouse_area, responsive, - row, scrollable, text, Container, DndSource, Space, + row, scrollable, text, Container, DndSource, Space, Widget, }, Element, Task, }; @@ -31,7 +31,6 @@ pub(crate) struct Library { selected_item: Option<(LibraryKind, i32)>, hovered_item: Option<(LibraryKind, i32)>, dragged_item: Option<(LibraryKind, i32)>, - dragged_item_pos: Option<(usize, usize)>, } #[derive(Clone, Debug)] @@ -43,7 +42,6 @@ pub(crate) enum Message { OpenLibrary(Option), HoverItem(Option<(LibraryKind, i32)>), SelectItem(Option<(LibraryKind, i32)>), - DragItem(Option<(LibraryKind, i32)>), None, } @@ -63,7 +61,6 @@ impl Library { selected_item: None, hovered_item: None, dragged_item: None, - dragged_item_pos: None, } } @@ -89,24 +86,14 @@ impl Library { self.selected_item = item; Task::none() } - Message::DragItem(item) => { - self.dragged_item = item; - debug!(?self.dragged_item); - Task::none() - } } } - pub fn view( - &self, - ) -> (Element, Option>) { - let (song_library, song_dragged) = - self.library_item(&self.song_library); - let (image_library, image_dragged) = - self.library_item(&self.image_library); - let (video_library, video_dragged) = - self.library_item(&self.video_library); - let (presentation_library, presentation_dragged) = + pub fn view(&self) -> Element { + let song_library = self.library_item(&self.song_library); + let image_library = self.library_item(&self.image_library); + let video_library = self.library_item(&self.video_library); + let presentation_library = self.library_item(&self.presentation_library); let column = column![ song_library, @@ -114,25 +101,13 @@ impl Library { video_library, presentation_library, ]; - let dragged_vector = vec![ - song_dragged, - image_dragged, - video_dragged, - presentation_dragged, - ]; - let dragged = dragged_vector - .into_iter() - .filter(|x| x.is_some()) - .next() - .unwrap_or(None); - - (column.height(Length::Fill).spacing(5).into(), dragged) + column.height(Length::Fill).spacing(5).into() } pub fn library_item<'a, T>( &'a self, model: &'a Model, - ) -> (Element<'a, Message>, Option>) + ) -> Element<'a, Message> where T: Content, { @@ -205,7 +180,6 @@ impl Library { }) .on_enter(Message::HoverLibrary(Some(model.kind))) .on_exit(Message::HoverLibrary(None)); - let mut dragged_item = None; let lib_container = if self.library_open == Some(model.kind) { let items = scrollable( @@ -213,33 +187,35 @@ impl Library { model.items.iter().enumerate().map( |(index, item)| { let service_item = item.to_service_item(); + let visual_item = self + .single_item(index, item, model) + .map(|_| Message::None); DndSource::::new( - mouse_area( - self.single_item( - index, item, model, - ), - ) - .on_enter(Message::HoverItem(Some(( - model.kind, - index as i32, - )))) - .on_exit(Message::HoverItem(None)) - .on_press(Message::SelectItem(Some( - (model.kind, index as i32), - ))), + mouse_area(visual_item) + .on_enter(Message::HoverItem( + Some(( + model.kind, + index as i32, + )), + )) + .on_exit(Message::HoverItem(None)) + .on_press(Message::SelectItem( + Some(( + model.kind, + index as i32, + )), + )), ) + // .drag_icon(move |i| { + // let drag_item = + // self.single_item(index, item, model); + // let state = + // drag_item.as_widget().state(); + // (drag_item, state, i) + // }) .drag_content(move || { service_item.to_owned() }) - .on_start(Some(Message::DragItem(Some( - (model.kind, index as i32), - )))) - .on_finish(Some(Message::DragItem(Some( - (model.kind, index as i32), - )))) - .on_cancel(Some(Message::DragItem(Some( - (model.kind, index as i32), - )))) .into() }, ) @@ -259,7 +235,7 @@ impl Library { } else { Container::new(Space::new(0, 0)) }; - (column![button, lib_container].into(), dragged_item) + column![button, lib_container].into() } fn single_item<'a, T>( @@ -267,7 +243,7 @@ impl Library { index: usize, item: &'a T, model: &'a Model, - ) -> Element<'a, Message> + ) -> Element<'a, ()> where T: Content, { diff --git a/src/ui/song_editor.rs b/src/ui/song_editor.rs index bf2b004..6546eb1 100644 --- a/src/ui/song_editor.rs +++ b/src/ui/song_editor.rs @@ -1,29 +1,38 @@ use cosmic::{ - iced_widget::{column, row}, - widget::{dropdown, text, text_input}, + iced::Length, + iced_widget::row, + widget::{ + column, combo_box, container, dropdown, text_editor, + text_input, vertical_space, + }, Element, Task, }; use tracing::debug; use crate::core::songs::Song; -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct SongEditor { song: Option, title: String, - fonts: Vec, + fonts: combo_box::State, font_sizes: Vec, font: String, font_size: usize, + verse_order: String, + lyrics: text_editor::Content, + editing: bool, } #[derive(Debug, Clone)] pub enum Message { ChangeSong(Song), UpdateSong(Song), - ChangeFont(usize), + ChangeFont(String), ChangeFontSize(usize), ChangeTitle(String), + ChangeVerseOrder(String), + ChangeLyrics(text_editor::Action), } impl SongEditor { @@ -41,22 +50,28 @@ impl SongEditor { ]; Self { song: None, - fonts, + fonts: combo_box::State::new(fonts), title: String::from("Death was Arrested"), font: String::from("Quicksand"), font_size: 16, font_sizes, + verse_order: String::from("Death was Arrested"), + lyrics: text_editor::Content::new(), + editing: false, } } pub fn update(&mut self, message: Message) -> Task { match message { - Message::ChangeSong(song) => todo!(), - Message::UpdateSong(song) => todo!(), + Message::ChangeSong(song) => { + self.song = Some(song); + Task::none() + } + Message::UpdateSong(song) => { + self.song = Some(song); + Task::none() + } Message::ChangeFont(font) => { - if let Some(font) = self.fonts.get(font) { - debug!(font); - self.font = font.to_owned(); - } + self.font = font; Task::none() } Message::ChangeFontSize(size) => { @@ -72,19 +87,30 @@ impl SongEditor { self.title = title; Task::none() } + Message::ChangeVerseOrder(verse_order) => { + self.verse_order = verse_order; + Task::none() + } + Message::ChangeLyrics(action) => { + self.lyrics.perform(action); + Task::none() + } } } pub fn view(&self) -> Element { - let selected_font = - self.fonts.iter().position(|f| *f == self.font); + let selected_font = &self.font; let selected_font_size = self .font_sizes .iter() .position(|s| *s == self.font_size.to_string()); - let font_selector = - dropdown(&self.fonts, selected_font, Message::ChangeFont) - .width(200); + let font_selector = combo_box( + &self.fonts, + "Font", + Some(selected_font), + Message::ChangeFont, + ) + .width(200); let font_size = dropdown( &self.font_sizes, selected_font_size, @@ -93,8 +119,32 @@ impl SongEditor { let title_input = text_input("song", &self.title) .on_input(Message::ChangeTitle) .label("Song Title"); + let verse_input = text_input( + "Verse +order", + &self.verse_order, + ) + .label("Verse Order") + .on_input(Message::ChangeVerseOrder); + + let lyric_input = text_editor(&self.lyrics) + .on_action(Message::ChangeLyrics); + + let slide_preview = + container(vertical_space()).width(Length::FillPortion(2)); + let toolbar = row![font_selector, font_size]; - let column = column![toolbar, title_input]; + let left_column = column::with_children(vec![ + title_input.into(), + verse_input.into(), + lyric_input.into(), + ]) + .spacing(25) + .width(Length::FillPortion(2)); + let column = column::with_children(vec![ + toolbar.into(), + row![left_column, slide_preview].into(), + ]); column.into() } }