adding more song_editor pieces

This commit is contained in:
Chris Cochrun 2025-02-21 23:17:51 -06:00
parent f13d021b22
commit ab88791d80
3 changed files with 145 additions and 126 deletions

View file

@ -417,49 +417,7 @@ impl cosmic::Application for App {
fn update(&mut self, message: Message) -> Task<Message> {
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<Message> {
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)]

View file

@ -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<LibraryKind>),
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<Message>, Option<Element<Message>>) {
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<Message> {
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<T>,
) -> (Element<'a, Message>, Option<Element<'a, Message>>)
) -> 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::<Message, ServiceItem>::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<T>,
) -> Element<'a, Message>
) -> Element<'a, ()>
where
T: Content,
{

View file

@ -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<Song>,
title: String,
fonts: Vec<String>,
fonts: combo_box::State<String>,
font_sizes: Vec<String>,
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<Message> {
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<Message> {
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()
}
}