parent
01ad8bcc83
commit
28d09120e0
7 changed files with 77 additions and 101 deletions
|
|
@ -80,6 +80,7 @@ pub enum VerseName {
|
|||
}
|
||||
|
||||
impl VerseName {
|
||||
#[must_use]
|
||||
pub fn from_string(name: String) -> Self {
|
||||
match name.as_str() {
|
||||
"Verse" => Self::Verse { number: 1 },
|
||||
|
|
@ -96,6 +97,7 @@ impl VerseName {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn all_names() -> Vec<String> {
|
||||
vec![
|
||||
"Verse".into(),
|
||||
|
|
@ -111,6 +113,7 @@ impl VerseName {
|
|||
]
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn next(&self) -> Self {
|
||||
match self {
|
||||
Self::Verse { number } => {
|
||||
|
|
@ -274,13 +277,12 @@ impl ServiceTrait for Song {
|
|||
.ok_or(miette!("There are no verses assigned yet."))?
|
||||
.iter()
|
||||
.filter_map(|verse| self.get_lyric(verse))
|
||||
.map(|lyric| {
|
||||
.flat_map(|lyric| {
|
||||
lyric
|
||||
.split("\n\n")
|
||||
.map(|s| s.to_string())
|
||||
.map(std::string::ToString::to_string)
|
||||
.collect::<Vec<String>>()
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
debug!(?lyrics);
|
||||
|
|
@ -294,14 +296,14 @@ impl ServiceTrait for Song {
|
|||
.clone()
|
||||
.unwrap_or_else(|| "Calibri".into()),
|
||||
)
|
||||
.size(self.font_size.unwrap_or_else(|| 100)
|
||||
.size(self.font_size.unwrap_or(100)
|
||||
as u8);
|
||||
let stroke_size =
|
||||
self.stroke_size.unwrap_or_default();
|
||||
let stroke: Stroke = stroke(
|
||||
stroke_size,
|
||||
self.stroke_color
|
||||
.map(|color| Color::from(color))
|
||||
.map(Color::from)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let shadow_size =
|
||||
|
|
@ -311,7 +313,7 @@ impl ServiceTrait for Song {
|
|||
self.shadow_offset.unwrap_or_default().1,
|
||||
shadow_size,
|
||||
self.shadow_color
|
||||
.map(|color| Color::from(color))
|
||||
.map(Color::from)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let builder = SlideBuilder::new();
|
||||
|
|
@ -422,19 +424,17 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
let stroke_color = row
|
||||
.try_get("stroke_color")
|
||||
.ok()
|
||||
.map(|color: String| {
|
||||
.and_then(|color: String| {
|
||||
ron::de::from_str::<Option<Srgb>>(&color).ok()
|
||||
})
|
||||
.flatten()
|
||||
.flatten();
|
||||
let shadow_size = row.try_get("shadow_size").ok();
|
||||
let shadow_color = row
|
||||
.try_get("shadow_color")
|
||||
.ok()
|
||||
.map(|color: String| {
|
||||
.and_then(|color: String| {
|
||||
ron::de::from_str::<Option<Srgb>>(&color).ok()
|
||||
})
|
||||
.flatten()
|
||||
.flatten();
|
||||
let shadow_offset = match (
|
||||
row.try_get("shadow_offset_x").ok(),
|
||||
|
|
@ -789,7 +789,7 @@ impl Model<Song> {
|
|||
pub async fn load_from_db(&mut self, db: &mut SqlitePool) {
|
||||
// static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
||||
let db1 = db.acquire().await.unwrap();
|
||||
let result = query(r#"SELECT verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, stroke_size, shadow_size, stroke_color, shadow_color, shadow_offset_x, shadow_offset_y, id from songs"#).fetch_all(&mut db1.detach()).await;
|
||||
let result = query(r"SELECT verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, stroke_size, shadow_size, stroke_color, shadow_color, shadow_offset_x, shadow_offset_y, id from songs").fetch_all(&mut db1.detach()).await;
|
||||
match result {
|
||||
Ok(s) => {
|
||||
for song in s {
|
||||
|
|
@ -894,7 +894,7 @@ pub async fn update_song_in_db(
|
|||
let lyrics = item.verse_map.map(|map| {
|
||||
map.iter()
|
||||
.map(|(name, lyric)| {
|
||||
let lyric = lyric.trim_end_matches("\n").to_string();
|
||||
let lyric = lyric.trim_end_matches('\n').to_string();
|
||||
(name.to_owned(), lyric)
|
||||
})
|
||||
.collect::<HashMap<VerseName, String>>()
|
||||
|
|
@ -902,8 +902,7 @@ pub async fn update_song_in_db(
|
|||
let lyrics = ron::ser::to_string(&lyrics).into_diagnostic()?;
|
||||
|
||||
let (vertical_alignment, horizontal_alignment) = item
|
||||
.text_alignment
|
||||
.map(|ta| match ta {
|
||||
.text_alignment.map_or_else(|| ("center", "center"), |ta| match ta {
|
||||
TextAlignment::TopLeft => ("top", "left"),
|
||||
TextAlignment::TopCenter => ("top", "center"),
|
||||
TextAlignment::TopRight => ("top", "right"),
|
||||
|
|
@ -913,8 +912,7 @@ pub async fn update_song_in_db(
|
|||
TextAlignment::BottomLeft => ("bottom", "left"),
|
||||
TextAlignment::BottomCenter => ("bottom", "center"),
|
||||
TextAlignment::BottomRight => ("bottom", "right"),
|
||||
})
|
||||
.unwrap_or_else(|| ("center", "center"));
|
||||
});
|
||||
|
||||
let stroke_size = item.stroke_size.unwrap_or_default();
|
||||
let shadow_size = item.shadow_size.unwrap_or_default();
|
||||
|
|
@ -968,12 +966,12 @@ pub async fn update_song_in_db(
|
|||
impl Song {
|
||||
#[must_use]
|
||||
pub fn get_lyric(&self, verse: &VerseName) -> Option<String> {
|
||||
let lyric = self.verse_map.as_ref().and_then(|verse_map| {
|
||||
|
||||
self.verse_map.as_ref().and_then(|verse_map| {
|
||||
verse_map.get(verse).cloned().map(|lyric| {
|
||||
lyric.trim().trim_end_matches("\n").to_string()
|
||||
lyric.trim().trim_end_matches('\n').to_string()
|
||||
})
|
||||
});
|
||||
lyric
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_lyrics<T: Into<String>>(
|
||||
|
|
@ -987,7 +985,7 @@ impl Song {
|
|||
verse_map
|
||||
.entry(*verse)
|
||||
.and_modify(|old_lyrics| {
|
||||
*old_lyrics = lyric_copy.clone()
|
||||
*old_lyrics = lyric_copy.clone();
|
||||
})
|
||||
.or_insert(lyric_copy);
|
||||
// debug!(?verse_map, "should be updated");
|
||||
|
|
@ -1009,17 +1007,16 @@ impl Song {
|
|||
let mut lyrics = vec![];
|
||||
for verse in verses {
|
||||
if verse == &VerseName::Blank {
|
||||
lyrics.push("".into());
|
||||
lyrics.push(String::new());
|
||||
continue;
|
||||
}
|
||||
if let Some(lyric) = self.get_lyric(verse) {
|
||||
lyrics.push(lyric)
|
||||
lyrics.push(lyric);
|
||||
}
|
||||
}
|
||||
return Ok(lyrics);
|
||||
} else {
|
||||
return Err(miette!("No verses in this song yet"));
|
||||
}
|
||||
return Err(miette!("No verses in this song yet"));
|
||||
|
||||
// ---------------------------------
|
||||
// old implementation
|
||||
|
|
@ -1097,7 +1094,7 @@ impl Song {
|
|||
&& let Some(lyric) = verse_map.remove(old_verse)
|
||||
{
|
||||
if verse == VerseName::Blank {
|
||||
verse_map.insert(verse, "".into());
|
||||
verse_map.insert(verse, String::new());
|
||||
} else {
|
||||
verse_map.insert(verse, lyric);
|
||||
}
|
||||
|
|
@ -1110,7 +1107,7 @@ impl Song {
|
|||
.filter(|verse| verse != old_verse)
|
||||
.collect();
|
||||
new_verses.push(verse);
|
||||
self.verses = Some(new_verses)
|
||||
self.verses = Some(new_verses);
|
||||
}
|
||||
|
||||
// TODO update_verse needs to also change the lyrics for the song such that
|
||||
|
|
@ -1187,6 +1184,7 @@ impl Song {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_next_verse_name(&self) -> VerseName {
|
||||
if let Some(verse_names) = &self.verses {
|
||||
let verses: Vec<&VerseName> = verse_names
|
||||
|
|
@ -1255,7 +1253,7 @@ impl Song {
|
|||
verses.push(verse);
|
||||
} else {
|
||||
self.verses = Some(vec![verse]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn verse_name_from_str(
|
||||
|
|
@ -1265,7 +1263,7 @@ impl Song {
|
|||
) -> VerseName {
|
||||
if old_verse_name.get_name() == verse_name {
|
||||
return old_verse_name;
|
||||
};
|
||||
}
|
||||
if let Some(verses) =
|
||||
self.verse_map.clone().map(|verse_map| {
|
||||
verse_map.into_keys().collect::<Vec<VerseName>>()
|
||||
|
|
@ -1279,7 +1277,7 @@ impl Song {
|
|||
.split_whitespace()
|
||||
.next()
|
||||
.unwrap()
|
||||
== &verse_name
|
||||
== verse_name
|
||||
})
|
||||
.sorted()
|
||||
.last()
|
||||
|
|
|
|||
|
|
@ -862,7 +862,7 @@ impl cosmic::Application for App {
|
|||
Some(
|
||||
self.song_editor
|
||||
.import_view()
|
||||
.map(|message| Message::SongEditor(message)),
|
||||
.map(Message::SongEditor),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -1259,7 +1259,7 @@ impl<'a> Library {
|
|||
})
|
||||
.collect();
|
||||
|
||||
items.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
items.sort_by_key(|a| a.0);
|
||||
items.into_iter().map(|item| item.1).collect()
|
||||
}
|
||||
|
||||
|
|
@ -1294,7 +1294,7 @@ impl<'a> Library {
|
|||
let Some(items) = self.selected_items.as_mut() else {
|
||||
return Action::None;
|
||||
};
|
||||
items.sort_by(|(_, index), (_, other)| index.cmp(other));
|
||||
items.sort_by_key(|(_, index)| *index);
|
||||
let tasks: Vec<Task<Message>> = items
|
||||
.iter()
|
||||
.rev()
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ use cosmic::{
|
|||
},
|
||||
prelude::*,
|
||||
widget::{
|
||||
Container, Id, Row, Space,
|
||||
aspect_ratio::aspect_ratio_container, container,
|
||||
Container, Id, Row, Space, container,
|
||||
context_menu, image, menu, mouse_area, responsive,
|
||||
scrollable, text,
|
||||
},
|
||||
|
|
@ -461,7 +460,7 @@ impl Presenter {
|
|||
let font = if let Some(font) = slide.font() {
|
||||
font.get_name()
|
||||
} else {
|
||||
"".into()
|
||||
String::new()
|
||||
};
|
||||
let _ = self.update(Message::ChangeFont(font));
|
||||
debug!("changing video now...");
|
||||
|
|
@ -1122,7 +1121,7 @@ pub(crate) fn slide_view<'a>(
|
|||
}
|
||||
}
|
||||
BackgroundKind::Html => todo!(),
|
||||
};
|
||||
}
|
||||
if let Some(text) = &slide.text_svg
|
||||
&& let Some(handle) = &text.handle
|
||||
{
|
||||
|
|
@ -1132,7 +1131,7 @@ pub(crate) fn slide_view<'a>(
|
|||
.width(Length::Fill)
|
||||
.height(Length::Fill),
|
||||
);
|
||||
};
|
||||
}
|
||||
Container::new(stack).center(Length::Fill).into()
|
||||
})
|
||||
.into()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use cosmic::{
|
|||
color_picker::{self, ColorPickerUpdate},
|
||||
combo_box, container, divider, dnd_destination, dnd_source,
|
||||
dropdown,
|
||||
grid::{self, widget::Assignment},
|
||||
grid::{self},
|
||||
horizontal_space, icon, mouse_area, popover, progress_bar,
|
||||
scrollable, spin_button, text, text_editor, text_input,
|
||||
tooltip,
|
||||
|
|
@ -479,7 +479,7 @@ impl SongEditor {
|
|||
if let Some(mut song) = self.song.clone()
|
||||
{
|
||||
let old_verse_name =
|
||||
verse.verse_name.clone();
|
||||
verse.verse_name;
|
||||
|
||||
let verse_name = song
|
||||
.verse_name_from_str(
|
||||
|
|
@ -490,7 +490,7 @@ impl SongEditor {
|
|||
verse.verse_name = verse_name;
|
||||
|
||||
if verse_name == VerseName::Blank {
|
||||
verse.lyric = "".into();
|
||||
verse.lyric = String::new();
|
||||
}
|
||||
|
||||
song.update_verse_name(
|
||||
|
|
@ -524,8 +524,7 @@ impl SongEditor {
|
|||
song.delete_verse(verse);
|
||||
if let Some(verses) =
|
||||
self.verses.as_mut()
|
||||
{
|
||||
if let Some(verse) = verses
|
||||
&& let Some(verse) = verses
|
||||
.iter()
|
||||
.position(|inner_verse| {
|
||||
inner_verse.verse_name
|
||||
|
|
@ -534,11 +533,10 @@ impl SongEditor {
|
|||
{
|
||||
verses.remove(verse);
|
||||
}
|
||||
}
|
||||
return Action::Task(
|
||||
self.update_song(song),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
verse_editor::Action::None => (),
|
||||
}
|
||||
|
|
@ -616,11 +614,10 @@ impl SongEditor {
|
|||
return Action::Task(
|
||||
self.update_song(song),
|
||||
);
|
||||
} else {
|
||||
error!(
|
||||
"No verses in this song or no song here"
|
||||
);
|
||||
}
|
||||
error!(
|
||||
"No verses in this song or no song here"
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
error!(?e, "Couldn't convert verse back");
|
||||
|
|
@ -628,11 +625,11 @@ impl SongEditor {
|
|||
}
|
||||
}
|
||||
Message::ChipReorder(event) => match event {
|
||||
draggable::DragEvent::Picked { index } => (),
|
||||
draggable::DragEvent::Picked { index: _ } => (),
|
||||
draggable::DragEvent::Dropped {
|
||||
index,
|
||||
target_index,
|
||||
drop_position,
|
||||
drop_position: _,
|
||||
} => {
|
||||
if let Some(mut song) = self.song.clone()
|
||||
&& let Some(verses) = song.verses.as_mut()
|
||||
|
|
@ -643,7 +640,7 @@ impl SongEditor {
|
|||
return Action::Task(self.update_song(song));
|
||||
}
|
||||
}
|
||||
draggable::DragEvent::Canceled { index } => (),
|
||||
draggable::DragEvent::Canceled { index: _ } => (),
|
||||
},
|
||||
Message::DraggingChipStart => {
|
||||
self.dragging_verse_chip = !self.dragging_verse_chip;
|
||||
|
|
@ -1090,7 +1087,7 @@ impl SongEditor {
|
|||
|song| {
|
||||
Message::AddVerse((
|
||||
song.get_next_verse_name(),
|
||||
"".to_string(),
|
||||
String::new(),
|
||||
))
|
||||
},
|
||||
);
|
||||
|
|
@ -1154,8 +1151,7 @@ impl SongEditor {
|
|||
let selected_font = self
|
||||
.song
|
||||
.as_ref()
|
||||
.map(|song| song.font.as_ref())
|
||||
.flatten();
|
||||
.and_then(|song| song.font.as_ref());
|
||||
|
||||
let font_selector = tooltip(
|
||||
stack![
|
||||
|
|
@ -1190,8 +1186,7 @@ impl SongEditor {
|
|||
let selected_font_size = self
|
||||
.song
|
||||
.as_ref()
|
||||
.map(|song| song.font_size.map(|size| size.to_string()))
|
||||
.flatten();
|
||||
.and_then(|song| song.font_size.map(|size| size.to_string()));
|
||||
|
||||
let font_size = tooltip(
|
||||
stack![
|
||||
|
|
@ -1321,14 +1316,13 @@ impl SongEditor {
|
|||
.width(Length::Fixed(400.0))
|
||||
.build("Recent Colors", "Copy", "Copied");
|
||||
|
||||
let shadow_size_spinner = spin_button::vertical(
|
||||
let _shadow_size_spinner = spin_button::vertical(
|
||||
"Shadow Size",
|
||||
self.song
|
||||
.as_ref()
|
||||
.map(|song| {
|
||||
.and_then(|song| {
|
||||
song.shadow_size.map(|size| size as usize)
|
||||
})
|
||||
.flatten()
|
||||
.unwrap_or_default(),
|
||||
1,
|
||||
0,
|
||||
|
|
@ -1336,32 +1330,30 @@ impl SongEditor {
|
|||
|i| Message::UpdateShadowSize(i as u16),
|
||||
);
|
||||
|
||||
let shadow_offset_x_spinner = spin_button::vertical(
|
||||
let _shadow_offset_x_spinner = spin_button::vertical(
|
||||
"Offset X",
|
||||
self.song
|
||||
.as_ref()
|
||||
.map(|song| song.shadow_offset)
|
||||
.flatten()
|
||||
.and_then(|song| song.shadow_offset)
|
||||
.map(|offset| offset.0)
|
||||
.unwrap_or_default(),
|
||||
1,
|
||||
0,
|
||||
50,
|
||||
|i| Message::UpdateShadowOffsetX(i as i16),
|
||||
Message::UpdateShadowOffsetX,
|
||||
);
|
||||
|
||||
let shadow_offset_y_spinner = spin_button::vertical(
|
||||
let _shadow_offset_y_spinner = spin_button::vertical(
|
||||
"Offset Y",
|
||||
self.song
|
||||
.as_ref()
|
||||
.map(|song| song.shadow_offset)
|
||||
.flatten()
|
||||
.and_then(|song| song.shadow_offset)
|
||||
.map(|offset| offset.1)
|
||||
.unwrap_or_default(),
|
||||
1,
|
||||
0,
|
||||
50,
|
||||
|i| Message::UpdateShadowOffsetY(i as i16),
|
||||
Message::UpdateShadowOffsetY,
|
||||
);
|
||||
|
||||
let shadow_size_dropdown = dropdown(
|
||||
|
|
@ -1371,10 +1363,9 @@ impl SongEditor {
|
|||
],
|
||||
self.song
|
||||
.as_ref()
|
||||
.map(|song| {
|
||||
.and_then(|song| {
|
||||
song.shadow_size.map(|size| size as usize)
|
||||
})
|
||||
.flatten(),
|
||||
}),
|
||||
|i| Message::UpdateShadowSize(i as u16),
|
||||
)
|
||||
.gap(5.0);
|
||||
|
|
@ -1387,10 +1378,9 @@ impl SongEditor {
|
|||
],
|
||||
self.song
|
||||
.as_ref()
|
||||
.map(|song| {
|
||||
.and_then(|song| {
|
||||
song.shadow_offset.map(|offset| offset.0 as usize)
|
||||
})
|
||||
.flatten(),
|
||||
}),
|
||||
|i| Message::UpdateShadowOffsetX(i as i16),
|
||||
)
|
||||
.gap(5.0);
|
||||
|
|
@ -1403,10 +1393,9 @@ impl SongEditor {
|
|||
],
|
||||
self.song
|
||||
.as_ref()
|
||||
.map(|song| {
|
||||
.and_then(|song| {
|
||||
song.shadow_offset.map(|offset| offset.1 as usize)
|
||||
})
|
||||
.flatten(),
|
||||
}),
|
||||
|i| Message::UpdateShadowOffsetY(i as i16),
|
||||
)
|
||||
.gap(5.0);
|
||||
|
|
@ -1696,8 +1685,8 @@ impl SongEditor {
|
|||
if let Ok(slides) = song.to_slides() {
|
||||
if let Some(handle) = &self.update_slide_handle {
|
||||
handle.abort();
|
||||
};
|
||||
let size = slides.len();
|
||||
}
|
||||
let _size = slides.len();
|
||||
|
||||
// let (task, handle) = stream(stream::iter(
|
||||
// slides.into_iter().enumerate().map(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use resvg::{
|
|||
usvg::{Tree, fontdb},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, error};
|
||||
use tracing::error;
|
||||
|
||||
use crate::TextAlignment;
|
||||
|
||||
|
|
@ -175,6 +175,7 @@ impl Hash for Color {
|
|||
}
|
||||
|
||||
impl Color {
|
||||
#[must_use]
|
||||
pub fn to_css_hex_string(&self) -> String {
|
||||
format!("#{:x}", self.0.into_format::<u8>())
|
||||
}
|
||||
|
|
@ -333,21 +334,15 @@ impl TextSvg {
|
|||
("end", position, x_width_padded.as_str())
|
||||
}
|
||||
TextAlignment::BottomLeft => {
|
||||
let position = size.height
|
||||
- (total_lines as f32
|
||||
* text_and_line_spacing);
|
||||
let position = (total_lines as f32).mul_add(-text_and_line_spacing, size.height);
|
||||
("start", position, "10")
|
||||
}
|
||||
TextAlignment::BottomCenter => {
|
||||
let position = size.height
|
||||
- (total_lines as f32
|
||||
* text_and_line_spacing);
|
||||
let position = (total_lines as f32).mul_add(-text_and_line_spacing, size.height);
|
||||
("middle", position, center_y.as_str())
|
||||
}
|
||||
TextAlignment::BottomRight => {
|
||||
let position = size.height
|
||||
- (total_lines as f32
|
||||
* text_and_line_spacing);
|
||||
let position = (total_lines as f32).mul_add(-text_and_line_spacing, size.height);
|
||||
("end", position, x_width_padded.as_str())
|
||||
}
|
||||
};
|
||||
|
|
@ -382,7 +377,7 @@ impl TextSvg {
|
|||
if self.shadow.is_some() {
|
||||
final_svg.push_str(" style=\"filter:url(#shadow);\"");
|
||||
}
|
||||
final_svg.push_str(">");
|
||||
final_svg.push('>');
|
||||
|
||||
let text: String = self
|
||||
.text
|
||||
|
|
@ -444,11 +439,10 @@ impl TextSvg {
|
|||
resvg::render(&resvg_tree, transform, &mut pixmap.as_mut());
|
||||
// debug!("rendered");
|
||||
|
||||
if cache {
|
||||
if let Err(e) = pixmap.save_png(&path) {
|
||||
if cache
|
||||
&& let Err(e) = pixmap.save_png(&path) {
|
||||
error!(?e, "Couldn't save a copy of the text");
|
||||
}
|
||||
}
|
||||
|
||||
// debug!("saved");
|
||||
// let handle = Handle::from_path(path);
|
||||
|
|
@ -509,11 +503,7 @@ pub fn text_svg_generator_with_cache(
|
|||
cache: bool,
|
||||
) {
|
||||
if !slide.text().is_empty() {
|
||||
let font = if let Some(font) = slide.font() {
|
||||
font
|
||||
} else {
|
||||
Font::default()
|
||||
};
|
||||
let font = slide.font().unwrap_or_default();
|
||||
let text_svg = TextSvg::new(slide.text())
|
||||
.alignment(slide.text_alignment())
|
||||
.fill(
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use cosmic::{
|
|||
iced_widget::{column, row},
|
||||
theme,
|
||||
widget::{
|
||||
button, combo_box, container, horizontal_space, icon, text,
|
||||
text_editor, text_input,
|
||||
button, combo_box, container, horizontal_space, icon,
|
||||
text_editor,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ impl VerseEditor {
|
|||
|
||||
pub fn view(&self) -> Element<Message> {
|
||||
let cosmic::cosmic_theme::Spacing {
|
||||
space_xxs,
|
||||
space_xxs: _,
|
||||
space_s,
|
||||
space_m,
|
||||
..
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue