175 lines
5.8 KiB
Rust
175 lines
5.8 KiB
Rust
use cosmic::{
|
|
Element, Task,
|
|
cosmic_theme::palette::WithAlpha,
|
|
iced::{Background, Border},
|
|
iced_widget::{column, row},
|
|
theme,
|
|
widget::{
|
|
button, combo_box, container, horizontal_space, icon,
|
|
text_editor,
|
|
},
|
|
};
|
|
|
|
use crate::core::songs::VerseName;
|
|
|
|
#[derive(Debug)]
|
|
pub struct VerseEditor {
|
|
pub verse_name: VerseName,
|
|
pub lyric: String,
|
|
content: text_editor::Content,
|
|
editing_verse_name: bool,
|
|
verse_name_combo: combo_box::State<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Message {
|
|
UpdateLyric(text_editor::Action),
|
|
UpdateVerseName(String),
|
|
EditVerseName,
|
|
DeleteVerse(VerseName),
|
|
None,
|
|
}
|
|
|
|
pub enum Action {
|
|
Task(Task<Message>),
|
|
UpdateVerse((VerseName, String)),
|
|
UpdateVerseName(String),
|
|
DeleteVerse(VerseName),
|
|
ScrollVerses(f32),
|
|
None,
|
|
}
|
|
|
|
impl VerseEditor {
|
|
#[must_use]
|
|
pub fn new(verse: VerseName, lyric: &str) -> Self {
|
|
Self {
|
|
verse_name: verse,
|
|
lyric: lyric.to_string(),
|
|
content: text_editor::Content::with_text(lyric),
|
|
editing_verse_name: false,
|
|
verse_name_combo: combo_box::State::new(
|
|
VerseName::all_names(),
|
|
),
|
|
}
|
|
}
|
|
pub fn update(&mut self, message: Message) -> Action {
|
|
match message {
|
|
Message::UpdateLyric(action) => match action {
|
|
text_editor::Action::Edit(ref _edit) => {
|
|
self.content.perform(action);
|
|
let lyrics = self.content.text();
|
|
self.lyric.clone_from(&lyrics);
|
|
let verse = self.verse_name;
|
|
Action::UpdateVerse((verse, lyrics))
|
|
}
|
|
text_editor::Action::Scroll { pixels } => {
|
|
if self.content.line_count() > 6 {
|
|
self.content.perform(action);
|
|
Action::None
|
|
} else {
|
|
Action::ScrollVerses(pixels)
|
|
}
|
|
}
|
|
_ => {
|
|
self.content.perform(action);
|
|
Action::None
|
|
}
|
|
},
|
|
Message::UpdateVerseName(verse_name) => {
|
|
Action::UpdateVerseName(verse_name)
|
|
}
|
|
Message::EditVerseName => {
|
|
self.editing_verse_name = !self.editing_verse_name;
|
|
Action::None
|
|
}
|
|
Message::DeleteVerse(verse) => Action::DeleteVerse(verse),
|
|
Message::None => Action::None,
|
|
}
|
|
}
|
|
|
|
pub fn view(&self) -> Element<Message> {
|
|
let cosmic::cosmic_theme::Spacing {
|
|
space_xxs: _,
|
|
space_s,
|
|
space_m,
|
|
..
|
|
} = theme::spacing();
|
|
|
|
let delete_button = button::text("Delete")
|
|
.trailing_icon(
|
|
icon::from_name("view-close").symbolic(true),
|
|
)
|
|
.class(theme::Button::Destructive)
|
|
.on_press(Message::DeleteVerse(self.verse_name));
|
|
let combo = combo_box(
|
|
&self.verse_name_combo,
|
|
"Verse 1",
|
|
Some(&self.verse_name.get_name()),
|
|
Message::UpdateVerseName,
|
|
);
|
|
|
|
let verse_title =
|
|
row![combo, horizontal_space(), delete_button];
|
|
|
|
let lyric: Element<Message> = if self.verse_name
|
|
== VerseName::Blank
|
|
{
|
|
horizontal_space().into()
|
|
} else {
|
|
text_editor(&self.content)
|
|
.on_action(Message::UpdateLyric)
|
|
.padding(space_m)
|
|
.class(theme::iced::TextEditor::Custom(Box::new(
|
|
move |t, s| {
|
|
let neutral = t.cosmic().palette.neutral_9;
|
|
let mut base_style = text_editor::Style {
|
|
background: Background::Color(
|
|
t.cosmic()
|
|
.background
|
|
.small_widget
|
|
.with_alpha(0.25)
|
|
.into(),
|
|
),
|
|
border: Border::default()
|
|
.rounded(space_s)
|
|
.width(2)
|
|
.color(
|
|
t.cosmic().bg_component_divider(),
|
|
),
|
|
icon: t
|
|
.cosmic()
|
|
.primary_component_color()
|
|
.into(),
|
|
placeholder: neutral
|
|
.with_alpha(0.7)
|
|
.into(),
|
|
value: neutral.into(),
|
|
selection: t.cosmic().accent.base.into(),
|
|
};
|
|
let hovered_border = Border::default()
|
|
.rounded(space_s)
|
|
.width(3)
|
|
.color(t.cosmic().accent.hover);
|
|
match s {
|
|
text_editor::Status::Active => base_style,
|
|
text_editor::Status::Hovered
|
|
| text_editor::Status::Focused => {
|
|
base_style.border = hovered_border;
|
|
base_style
|
|
}
|
|
text_editor::Status::Disabled => {
|
|
base_style
|
|
}
|
|
}
|
|
},
|
|
)))
|
|
.height(150)
|
|
.into()
|
|
};
|
|
|
|
container(column![verse_title, lyric].spacing(space_s))
|
|
.padding(space_s)
|
|
.class(theme::Container::Card)
|
|
.into()
|
|
}
|
|
}
|