Compare commits
6 commits
master
...
update-lib
| Author | SHA1 | Date | |
|---|---|---|---|
| 54b681de7c | |||
| 2e5fe439b0 | |||
| 69410e3b6e | |||
| 896eda5b9d | |||
| b05f29d7b5 | |||
| 11cca05de4 |
21 changed files with 2308 additions and 2163 deletions
3693
Cargo.lock
generated
3693
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -54,11 +54,11 @@ serde_json = "1.0.149"
|
||||||
[dependencies.libcosmic]
|
[dependencies.libcosmic]
|
||||||
git = "https://github.com/pop-os/libcosmic"
|
git = "https://github.com/pop-os/libcosmic"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["debug", "winit", "desktop", "winit_wgpu", "winit_tokio", "tokio", "wayland", "rfd", "dbus-config", "a11y", "wgpu", "multi-window", "process"]
|
features = ["debug", "winit", "desktop", "wayland", "tokio", "rfd", "dbus-config", "a11y", "wgpu", "multi-window", "process"]
|
||||||
|
|
||||||
[dependencies.iced_video_player]
|
[dependencies.iced_video_player]
|
||||||
git = "https://github.com/jackpot51/iced_video_player.git"
|
git = "https://github.com/wash2/iced_video_player.git"
|
||||||
branch = "cosmic"
|
branch = "iced-rebase"
|
||||||
features = ["wgpu"]
|
features = ["wgpu"]
|
||||||
|
|
||||||
# [profile.dev]
|
# [profile.dev]
|
||||||
|
|
|
||||||
4
TODO.org
4
TODO.org
|
|
@ -12,6 +12,10 @@ This is working but the right click context menu is all the way on the edge of t
|
||||||
|
|
||||||
Let's build some tests that ensure that these functions are working for the models. Make sure the models are built in such a way as to make sure that they are testable and work fast for the user.
|
Let's build some tests that ensure that these functions are working for the models. Make sure the models are built in such a way as to make sure that they are testable and work fast for the user.
|
||||||
|
|
||||||
|
By making the db functions take the vector of items in the model, we can drain the model, pass an owned version of those items to the async db function(adding, updating, deleting, etc) and then return an updated list of the items back in the Result.
|
||||||
|
|
||||||
|
We should probably return a tuple with the original vector of items in case the db function fails somehow.
|
||||||
|
|
||||||
* TODO [#B] Font in the song editor doesn't always use the original version
|
* TODO [#B] Font in the song editor doesn't always use the original version
|
||||||
There seems to be some issue with fontdb not able to decipher all the versions of some fonts that are OTF and then end up loading the wrong ones in some issues.
|
There seems to be some issue with fontdb not able to decipher all the versions of some fonts that are OTF and then end up loading the wrong ones in some issues.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
libGL
|
libGL
|
||||||
cargo-flamegraph
|
cargo-flamegraph
|
||||||
bacon
|
bacon
|
||||||
|
openssl
|
||||||
|
|
||||||
fontconfig
|
fontconfig
|
||||||
glib
|
glib
|
||||||
|
|
|
||||||
|
|
@ -114,10 +114,10 @@ pub async fn get_genius_lyrics(
|
||||||
root.inner_html()
|
root.inner_html()
|
||||||
})
|
})
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
let lyrics = lyrics.find("[").map_or_else(
|
let lyrics = lyrics.find('[').map_or_else(
|
||||||
|| {
|
|| {
|
||||||
lyrics.find("</div></div></div>").map_or(
|
lyrics.find("</div></div></div>").map_or_else(
|
||||||
lyrics.clone(),
|
|| lyrics.clone(),
|
||||||
|position| {
|
|position| {
|
||||||
lyrics.split_at(position + 18).1.to_string()
|
lyrics.split_at(position + 18).1.to_string()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -789,7 +789,7 @@ pub async fn remove_from_db(
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_song_to_db(
|
pub async fn new_song_from_db(
|
||||||
db: PoolConnection<Sqlite>,
|
db: PoolConnection<Sqlite>,
|
||||||
) -> Result<Song> {
|
) -> Result<Song> {
|
||||||
let mut song = Song::default();
|
let mut song = Song::default();
|
||||||
|
|
@ -1357,7 +1357,7 @@ You saved my soul"
|
||||||
async fn fill_db(db: &SqlitePool) -> Result<()> {
|
async fn fill_db(db: &SqlitePool) -> Result<()> {
|
||||||
for _ in 0..20 {
|
for _ in 0..20 {
|
||||||
let conn = db.acquire().await.into_diagnostic()?;
|
let conn = db.acquire().await.into_diagnostic()?;
|
||||||
let db_song = add_song_to_db(conn).await?;
|
let db_song = new_song_from_db(conn).await?;
|
||||||
let mut song = test_song();
|
let mut song = test_song();
|
||||||
song.id = db_song.id;
|
song.id = db_song.id;
|
||||||
let conn = db.acquire().await.into_diagnostic()?;
|
let conn = db.acquire().await.into_diagnostic()?;
|
||||||
|
|
|
||||||
57
src/main.rs
57
src/main.rs
|
|
@ -10,7 +10,7 @@ use cosmic::cosmic_config::{Config, CosmicConfigEntry};
|
||||||
use cosmic::dialog::file_chooser::{open, save};
|
use cosmic::dialog::file_chooser::{open, save};
|
||||||
use cosmic::iced::alignment::Vertical;
|
use cosmic::iced::alignment::Vertical;
|
||||||
use cosmic::iced::keyboard::{Key, Modifiers};
|
use cosmic::iced::keyboard::{Key, Modifiers};
|
||||||
use cosmic::iced::window::{Mode, Position};
|
use cosmic::iced::window::Position;
|
||||||
use cosmic::iced::{
|
use cosmic::iced::{
|
||||||
self, Background as IcedBackground, Border, Color, Length, event,
|
self, Background as IcedBackground, Border, Color, Length, event,
|
||||||
window,
|
window,
|
||||||
|
|
@ -18,18 +18,19 @@ use cosmic::iced::{
|
||||||
use cosmic::iced_core::text::Wrapping;
|
use cosmic::iced_core::text::Wrapping;
|
||||||
use cosmic::iced_futures::Subscription;
|
use cosmic::iced_futures::Subscription;
|
||||||
use cosmic::iced_widget::{column, row, stack};
|
use cosmic::iced_widget::{column, row, stack};
|
||||||
|
use cosmic::prelude::*;
|
||||||
use cosmic::widget::dnd_destination::dnd_destination;
|
use cosmic::widget::dnd_destination::dnd_destination;
|
||||||
use cosmic::widget::menu::key_bind::Modifier;
|
use cosmic::widget::menu::key_bind::Modifier;
|
||||||
use cosmic::widget::menu::{ItemWidth, KeyBind};
|
use cosmic::widget::menu::{ItemWidth, KeyBind};
|
||||||
use cosmic::widget::nav_bar::nav_bar_style;
|
use cosmic::widget::nav_bar::nav_bar_style;
|
||||||
|
use cosmic::widget::space::horizontal;
|
||||||
use cosmic::widget::tooltip::Position as TPosition;
|
use cosmic::widget::tooltip::Position as TPosition;
|
||||||
use cosmic::widget::{
|
use cosmic::widget::{
|
||||||
Container, divider, menu, settings, text_input,
|
Container, divider, menu, settings, text_input,
|
||||||
};
|
};
|
||||||
use cosmic::widget::{
|
use cosmic::widget::{
|
||||||
Space, button, context_menu, horizontal_space, mouse_area,
|
Space, button, context_menu, mouse_area, nav_bar, nav_bar_toggle,
|
||||||
nav_bar, nav_bar_toggle, responsive, scrollable, search_input,
|
responsive, scrollable, search_input, tooltip,
|
||||||
tooltip,
|
|
||||||
};
|
};
|
||||||
use cosmic::widget::{container, text};
|
use cosmic::widget::{container, text};
|
||||||
use cosmic::widget::{icon, slider};
|
use cosmic::widget::{icon, slider};
|
||||||
|
|
@ -699,6 +700,7 @@ impl cosmic::Application for App {
|
||||||
// debug!(?platform_specific);
|
// debug!(?platform_specific);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
iced::Event::InputMethod(_event) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event::Status::Captured => None,
|
event::Status::Captured => None,
|
||||||
|
|
@ -736,7 +738,7 @@ impl cosmic::Application for App {
|
||||||
row![
|
row![
|
||||||
column![title, subtitle]
|
column![title, subtitle]
|
||||||
.spacing(space_xxs),
|
.spacing(space_xxs),
|
||||||
horizontal_space(),
|
horizontal(),
|
||||||
tooltip(
|
tooltip(
|
||||||
icon::from_name("add")
|
icon::from_name("add")
|
||||||
.symbolic(true).apply(button::icon)
|
.symbolic(true).apply(button::icon)
|
||||||
|
|
@ -785,7 +787,9 @@ impl cosmic::Application for App {
|
||||||
.center_x(Length::Fill)
|
.center_x(Length::Fill)
|
||||||
.align_top(Length::Fill);
|
.align_top(Length::Fill);
|
||||||
let mouse_stack = stack!(
|
let mouse_stack = stack!(
|
||||||
Space::new(Length::Fill, Length::Fill)
|
Space::new()
|
||||||
|
.height(Length::Fill)
|
||||||
|
.width(Length::Fill)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.style(|_| {
|
.style(|_| {
|
||||||
container::background(
|
container::background(
|
||||||
|
|
@ -824,7 +828,7 @@ impl cosmic::Application for App {
|
||||||
.padding(space_s)
|
.padding(space_s)
|
||||||
.align_right(Length::Fill)
|
.align_right(Length::Fill)
|
||||||
.align_top(60),
|
.align_top(60),
|
||||||
horizontal_space().height(space_xxl),
|
horizontal().height(space_xxl),
|
||||||
settings::section()
|
settings::section()
|
||||||
.title("Obs Settings")
|
.title("Obs Settings")
|
||||||
.add(obs_socket)
|
.add(obs_socket)
|
||||||
|
|
@ -845,7 +849,9 @@ impl cosmic::Application for App {
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding([space_xxl, space_xxxl * 2]);
|
.padding([space_xxl, space_xxxl * 2]);
|
||||||
let mouse_stack = stack!(
|
let mouse_stack = stack!(
|
||||||
Space::new(Length::Fill, Length::Fill)
|
Space::new()
|
||||||
|
.height(Length::Fill)
|
||||||
|
.width(Length::Fill)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.style(|_| {
|
.style(|_| {
|
||||||
container::background(
|
container::background(
|
||||||
|
|
@ -1239,7 +1245,7 @@ impl cosmic::Application for App {
|
||||||
if let Some(video) = &mut self.presenter.video {
|
if let Some(video) = &mut self.presenter.video {
|
||||||
video.set_muted(false);
|
video.set_muted(false);
|
||||||
}
|
}
|
||||||
window::change_mode(id, Mode::Fullscreen)
|
window::maximize(id, true)
|
||||||
} else {
|
} else {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -1290,10 +1296,12 @@ impl cosmic::Application for App {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Message::HoveredServiceItem(index) => {
|
Message::HoveredServiceItem(index) => {
|
||||||
|
debug!(index);
|
||||||
self.hovered_item = index;
|
self.hovered_item = index;
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::HoveredServiceDrop(index) => {
|
Message::HoveredServiceDrop(index) => {
|
||||||
|
debug!(index);
|
||||||
self.hovered_dnd = index;
|
self.hovered_dnd = index;
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -1656,7 +1664,7 @@ impl cosmic::Application for App {
|
||||||
);
|
);
|
||||||
|
|
||||||
let slide_preview = column![
|
let slide_preview = column![
|
||||||
Space::with_height(Length::Fill),
|
Space::new().height(Length::Fill),
|
||||||
Container::new(
|
Container::new(
|
||||||
self.presenter.view_preview().map(Message::Present),
|
self.presenter.view_preview().map(Message::Present),
|
||||||
)
|
)
|
||||||
|
|
@ -1685,7 +1693,7 @@ impl cosmic::Application for App {
|
||||||
row![]
|
row![]
|
||||||
})
|
})
|
||||||
.center_x(Length::Fill),
|
.center_x(Length::Fill),
|
||||||
Space::with_height(Length::Fill),
|
Space::new().height(Length::Fill)
|
||||||
]
|
]
|
||||||
.spacing(3);
|
.spacing(3);
|
||||||
|
|
||||||
|
|
@ -1696,7 +1704,7 @@ impl cosmic::Application for App {
|
||||||
let library = if self.library_open {
|
let library = if self.library_open {
|
||||||
Container::new(
|
Container::new(
|
||||||
Container::new(self.library.as_ref().map_or_else(
|
Container::new(self.library.as_ref().map_or_else(
|
||||||
|| Element::from(Space::new(0, 0)),
|
|| Element::from(Space::new()),
|
||||||
|library| library.view().map(Message::Library),
|
|library| library.view().map(Message::Library),
|
||||||
))
|
))
|
||||||
.style(nav_bar_style),
|
.style(nav_bar_style),
|
||||||
|
|
@ -1704,11 +1712,11 @@ impl cosmic::Application for App {
|
||||||
.padding(space_s)
|
.padding(space_s)
|
||||||
.width(Length::FillPortion(2))
|
.width(Length::FillPortion(2))
|
||||||
} else {
|
} else {
|
||||||
Container::new(horizontal_space().width(0))
|
Container::new(horizontal().width(0))
|
||||||
};
|
};
|
||||||
|
|
||||||
let editor = self.editor_mode.as_ref().map_or_else(
|
let editor = self.editor_mode.as_ref().map_or_else(
|
||||||
|| Element::from(Space::new(0, 0)),
|
|| Element::from(Space::new()),
|
||||||
|mode| match mode {
|
|mode| match mode {
|
||||||
EditorMode::Song => {
|
EditorMode::Song => {
|
||||||
self.song_editor.view().map(Message::SongEditor)
|
self.song_editor.view().map(Message::SongEditor)
|
||||||
|
|
@ -1763,7 +1771,7 @@ impl cosmic::Application for App {
|
||||||
|
|
||||||
let preview_bar = if self.editor_mode.is_none() {
|
let preview_bar = if self.editor_mode.is_none() {
|
||||||
if self.service.is_empty() {
|
if self.service.is_empty() {
|
||||||
Container::new(horizontal_space())
|
Container::new(horizontal())
|
||||||
} else {
|
} else {
|
||||||
Container::new(
|
Container::new(
|
||||||
self.presenter
|
self.presenter
|
||||||
|
|
@ -1775,7 +1783,7 @@ impl cosmic::Application for App {
|
||||||
.center_y(180)
|
.center_y(180)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Container::new(horizontal_space())
|
Container::new(horizontal())
|
||||||
};
|
};
|
||||||
|
|
||||||
let main_area = self.editor_mode.as_ref().map_or_else(
|
let main_area = self.editor_mode.as_ref().map_or_else(
|
||||||
|
|
@ -1788,7 +1796,7 @@ impl cosmic::Application for App {
|
||||||
if self.library_open {
|
if self.library_open {
|
||||||
library.width(Length::FillPortion(1))
|
library.width(Length::FillPortion(1))
|
||||||
} else {
|
} else {
|
||||||
container(Space::new(0, 0))
|
container(Space::new())
|
||||||
},
|
},
|
||||||
main_area.width(Length::FillPortion(4))
|
main_area.width(Length::FillPortion(4))
|
||||||
]
|
]
|
||||||
|
|
@ -1850,6 +1858,7 @@ where
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
// if let Some(library) = self.library.clone() {
|
// if let Some(library) = self.library.clone() {
|
||||||
// Task::perform(
|
// Task::perform(
|
||||||
// async move { library.search_items(query).await },
|
// async move { library.search_items(query).await },
|
||||||
|
|
@ -1915,11 +1924,9 @@ where
|
||||||
) => self.update(Message::Present(
|
) => self.update(Message::Present(
|
||||||
presenter::Message::PrevSlide,
|
presenter::Message::PrevSlide,
|
||||||
)),
|
)),
|
||||||
(Key::Named(iced::keyboard::key::Named::Space), _) => {
|
(Key::Character(k), _) if k == *" " => self.update(
|
||||||
self.update(Message::Present(
|
Message::Present(presenter::Message::NextSlide),
|
||||||
presenter::Message::NextSlide,
|
),
|
||||||
))
|
|
||||||
}
|
|
||||||
(Key::Character(k), _) if k == *"j" || k == *"l" => self
|
(Key::Character(k), _) if k == *"j" || k == *"l" => self
|
||||||
.update(Message::Present(
|
.update(Message::Present(
|
||||||
presenter::Message::NextSlide,
|
presenter::Message::NextSlide,
|
||||||
|
|
@ -2001,11 +2008,11 @@ where
|
||||||
let color = t.cosmic().accent_color();
|
let color = t.cosmic().accent_color();
|
||||||
cosmic::iced_widget::rule::Style {
|
cosmic::iced_widget::rule::Style {
|
||||||
color: color.into(),
|
color: color.into(),
|
||||||
width: 2,
|
snap: true,
|
||||||
radius: t.cosmic().corner_radii.radius_xs.into(),
|
radius: t.cosmic().corner_radii.radius_xs.into(),
|
||||||
fill_mode: cosmic::iced_widget::rule::FillMode::Full,
|
fill_mode: cosmic::iced_widget::rule::FillMode::Full,
|
||||||
}
|
}
|
||||||
} ));
|
} )).width(2);
|
||||||
Container::new(column![divider, container].spacing(theme::spacing().space_s))
|
Container::new(column![divider, container].spacing(theme::spacing().space_s))
|
||||||
} else { container };
|
} else { container };
|
||||||
let mouse_area = mouse_area(visual_item)
|
let mouse_area = mouse_area(visual_item)
|
||||||
|
|
@ -2145,7 +2152,7 @@ where
|
||||||
text::heading("Service List")
|
text::heading("Service List")
|
||||||
.center()
|
.center()
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
iced::widget::horizontal_rule(1),
|
divider::horizontal::light(),
|
||||||
scrollable
|
scrollable
|
||||||
]
|
]
|
||||||
.padding(10)
|
.padding(10)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use cosmic::{
|
||||||
iced_widget::{column, row},
|
iced_widget::{column, row},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
self, Space, button, container, horizontal_space, icon, text,
|
self, Space, button, container, icon, space::horizontal,
|
||||||
text_input,
|
text, text_input,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
|
@ -94,7 +94,7 @@ impl ImageEditor {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn view(&self) -> Element<Message> {
|
pub fn view(&self) -> Element<Message> {
|
||||||
let container = self.image.as_ref().map_or_else(
|
let container = self.image.as_ref().map_or_else(
|
||||||
|| Space::new(0, 0).apply(container),
|
|| Space::new().apply(container),
|
||||||
|pic| widget::image(pic.path.clone()).apply(container),
|
|pic| widget::image(pic.path.clone()).apply(container),
|
||||||
);
|
);
|
||||||
let column = column![
|
let column = column![
|
||||||
|
|
@ -120,7 +120,7 @@ impl ImageEditor {
|
||||||
row![
|
row![
|
||||||
text::body("Title:"),
|
text::body("Title:"),
|
||||||
title_box,
|
title_box,
|
||||||
horizontal_space(),
|
horizontal(),
|
||||||
image_selector
|
image_selector
|
||||||
]
|
]
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@ use cosmic::{
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
Container, DndSource, Space, button, container, context_menu,
|
Container, DndSource, Space, button, container, context_menu,
|
||||||
dnd_destination, horizontal_space, icon,
|
divider, dnd_destination, icon,
|
||||||
menu::{self, Action as MenuAction},
|
menu::{self, Action as MenuAction},
|
||||||
mouse_area, responsive, row, scrollable, text, text_input,
|
mouse_area, responsive, row, scrollable,
|
||||||
|
space::{self, horizontal},
|
||||||
|
text, text_input,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
|
|
@ -32,7 +34,7 @@ use crate::core::{
|
||||||
update_presentation_in_db,
|
update_presentation_in_db,
|
||||||
},
|
},
|
||||||
service_items::ServiceItem,
|
service_items::ServiceItem,
|
||||||
songs::{self, Song, add_song_to_db, update_song_in_db},
|
songs::{self, Song, new_song_from_db, update_song_in_db},
|
||||||
videos::{self, Video, add_video_to_db, update_video_in_db},
|
videos::{self, Video, add_video_to_db, update_video_in_db},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -169,17 +171,25 @@ impl<'a> Library {
|
||||||
self.library_open.unwrap_or(LibraryKind::Song);
|
self.library_open.unwrap_or(LibraryKind::Song);
|
||||||
match kind {
|
match kind {
|
||||||
LibraryKind::Song => {
|
LibraryKind::Song => {
|
||||||
let _song = Song::default();
|
let index = (self.song_library.items.len()
|
||||||
let task = Task::future(self.db.acquire()).and_then(move |db| {
|
- 1)
|
||||||
Task::perform(add_song_to_db(db), move |res| {
|
as i32;
|
||||||
match res {
|
|
||||||
Ok(song) => {
|
let task = Task::future(self.db.acquire())
|
||||||
Message::AddSong(song)
|
.map_err(|e| {
|
||||||
},
|
miette::miette!("Database error: {e}")
|
||||||
Err(e) => {error!(?e, "couldn't add song to db"); Message::None}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
.and_then(move |db| {
|
||||||
|
Task::perform(
|
||||||
|
new_song_from_db(db),
|
||||||
|
move |res| {
|
||||||
|
res.map(|song| {
|
||||||
|
Message::AddSong(song)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|r| r.unwrap_or(Message::None));
|
||||||
return Action::Task(task);
|
return Action::Task(task);
|
||||||
}
|
}
|
||||||
LibraryKind::Video => {
|
LibraryKind::Video => {
|
||||||
|
|
@ -208,7 +218,7 @@ impl<'a> Library {
|
||||||
// Check if empty
|
// Check if empty
|
||||||
let mut tasks = Vec::new();
|
let mut tasks = Vec::new();
|
||||||
if let Some(videos) = videos {
|
if let Some(videos) = videos {
|
||||||
let len = videos.len();
|
// let len = videos.len();
|
||||||
for video in videos {
|
for video in videos {
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
self.video_library.add_item(video.clone())
|
self.video_library.add_item(video.clone())
|
||||||
|
|
@ -216,6 +226,9 @@ impl<'a> Library {
|
||||||
error!(?e);
|
error!(?e);
|
||||||
}
|
}
|
||||||
let task = Task::future(self.db.acquire())
|
let task = Task::future(self.db.acquire())
|
||||||
|
.map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
})
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
add_video_to_db(
|
add_video_to_db(
|
||||||
|
|
@ -223,25 +236,16 @@ impl<'a> Library {
|
||||||
db,
|
db,
|
||||||
),
|
),
|
||||||
move |res| {
|
move |res| {
|
||||||
debug!(
|
res.map(|_| {
|
||||||
len,
|
|
||||||
index, "added to db"
|
|
||||||
);
|
|
||||||
if let Err(e) = res {
|
|
||||||
error!(?e);
|
|
||||||
}
|
|
||||||
if len == index {
|
|
||||||
debug!("open the pres");
|
|
||||||
Message::OpenItem(Some((
|
Message::OpenItem(Some((
|
||||||
LibraryKind::Video,
|
LibraryKind::Video,
|
||||||
index as i32,
|
index as i32,
|
||||||
)))
|
)))
|
||||||
} else {
|
})
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
|
.map(|r| r.unwrap_or(Message::None));
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -265,23 +269,22 @@ impl<'a> Library {
|
||||||
error!(?e);
|
error!(?e);
|
||||||
}
|
}
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire())
|
||||||
move |db| {
|
.map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
})
|
||||||
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
add_presentation_to_db(
|
add_presentation_to_db(
|
||||||
presentation.clone(),
|
presentation.clone(),
|
||||||
db,
|
db,
|
||||||
),
|
),
|
||||||
move |res| {
|
move |res| {
|
||||||
debug!("added to db");
|
res.map(|_| Message::None)
|
||||||
if let Err(e) = res {
|
|
||||||
error!(?e);
|
|
||||||
}
|
|
||||||
Message::None
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
),
|
.map(|r| r.unwrap_or(Message::None)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +294,7 @@ impl<'a> Library {
|
||||||
// Check if empty
|
// Check if empty
|
||||||
let mut tasks = Vec::new();
|
let mut tasks = Vec::new();
|
||||||
if let Some(presentations) = presentations {
|
if let Some(presentations) = presentations {
|
||||||
let len = presentations.len();
|
// let len = presentations.len();
|
||||||
for presentation in presentations {
|
for presentation in presentations {
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.presentation_library
|
.presentation_library
|
||||||
|
|
@ -302,32 +305,16 @@ impl<'a> Library {
|
||||||
let task = Task::future(
|
let task = Task::future(
|
||||||
self.db.acquire(),
|
self.db.acquire(),
|
||||||
)
|
)
|
||||||
|
.map_err(|e| miette::miette!("Database error: {e}"))
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
add_presentation_to_db(
|
add_presentation_to_db(
|
||||||
presentation.clone(),
|
presentation.clone(),
|
||||||
db,
|
db,
|
||||||
),
|
),
|
||||||
move |res| {
|
move |res| res.map(|_| Message::OpenItem(Some((LibraryKind::Presentation, index as i32))))
|
||||||
debug!(
|
|
||||||
len,
|
|
||||||
index, "added to db"
|
|
||||||
);
|
|
||||||
if let Err(e) = res {
|
|
||||||
error!(?e);
|
|
||||||
}
|
|
||||||
if len == index {
|
|
||||||
debug!("open the pres");
|
|
||||||
Message::OpenItem(Some((
|
|
||||||
LibraryKind::Presentation,
|
|
||||||
index as i32,
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
});
|
}).map(|r| r.unwrap_or(Message::None));
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -348,7 +335,7 @@ impl<'a> Library {
|
||||||
// Check if empty
|
// Check if empty
|
||||||
let mut tasks = Vec::new();
|
let mut tasks = Vec::new();
|
||||||
if let Some(images) = images {
|
if let Some(images) = images {
|
||||||
let len = images.len();
|
// let len = images.len();
|
||||||
for image in images {
|
for image in images {
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
self.image_library.add_item(image.clone())
|
self.image_library.add_item(image.clone())
|
||||||
|
|
@ -356,6 +343,9 @@ impl<'a> Library {
|
||||||
error!(?e);
|
error!(?e);
|
||||||
}
|
}
|
||||||
let task = Task::future(self.db.acquire())
|
let task = Task::future(self.db.acquire())
|
||||||
|
.map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
})
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
add_image_to_db(
|
add_image_to_db(
|
||||||
|
|
@ -363,25 +353,16 @@ impl<'a> Library {
|
||||||
db,
|
db,
|
||||||
),
|
),
|
||||||
move |res| {
|
move |res| {
|
||||||
debug!(
|
res.map(|_| {
|
||||||
len,
|
|
||||||
index, "added to db"
|
|
||||||
);
|
|
||||||
if let Err(e) = res {
|
|
||||||
error!(?e);
|
|
||||||
}
|
|
||||||
if len == index {
|
|
||||||
debug!("open the pres");
|
|
||||||
Message::OpenItem(Some((
|
Message::OpenItem(Some((
|
||||||
LibraryKind::Image,
|
LibraryKind::Image,
|
||||||
index as i32,
|
index as i32,
|
||||||
)))
|
)))
|
||||||
} else {
|
})
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
|
.map(|r| r.unwrap_or(Message::None));
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -516,20 +497,17 @@ impl<'a> Library {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire())
|
||||||
move |conn| {
|
.map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
})
|
||||||
|
.and_then(move |conn| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
update_song_in_db(song.clone(), conn),
|
update_song_in_db(song.clone(), conn),
|
||||||
|r| match r {
|
|r| r.map(|_| Message::SongChanged),
|
||||||
Ok(()) => Message::SongChanged,
|
|
||||||
Err(e) => {
|
|
||||||
error!(?e);
|
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
),
|
.map(|r| r.unwrap_or(Message::None)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Message::SongChanged => {
|
Message::SongChanged => {
|
||||||
|
|
@ -566,23 +544,20 @@ impl<'a> Library {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire())
|
||||||
move |conn| {
|
.map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
})
|
||||||
|
.and_then(move |conn| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
update_image_in_db(
|
update_image_in_db(
|
||||||
image.clone(),
|
image.clone(),
|
||||||
conn,
|
conn,
|
||||||
),
|
),
|
||||||
|r| match r {
|
|r| r.map(|_| Message::ImageChanged),
|
||||||
Ok(()) => Message::ImageChanged,
|
|
||||||
Err(e) => {
|
|
||||||
error!(?e);
|
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
),
|
.map(|r| r.unwrap_or(Message::None)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Message::ImageChanged => (),
|
Message::ImageChanged => (),
|
||||||
|
|
@ -607,23 +582,20 @@ impl<'a> Library {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire())
|
||||||
move |conn| {
|
.map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
})
|
||||||
|
.and_then(move |conn| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
update_video_in_db(
|
update_video_in_db(
|
||||||
video.clone(),
|
video.clone(),
|
||||||
conn,
|
conn,
|
||||||
),
|
),
|
||||||
|r| match r {
|
|r| r.map(|_| Message::VideoChanged),
|
||||||
Ok(()) => Message::VideoChanged,
|
|
||||||
Err(e) => {
|
|
||||||
error!(?e);
|
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
),
|
.map(|r| r.unwrap_or(Message::None)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Message::VideoChanged => debug!("vid shoulda changed"),
|
Message::VideoChanged => debug!("vid shoulda changed"),
|
||||||
|
|
@ -651,23 +623,19 @@ impl<'a> Library {
|
||||||
.update_item(presentation.clone(), index)
|
.update_item(presentation.clone(), index)
|
||||||
{
|
{
|
||||||
Ok(()) => return Action::Task(
|
Ok(()) => return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire()).map_err(|e| {
|
||||||
|
miette::miette!("Database error: {e}")
|
||||||
|
}).and_then(
|
||||||
move |conn| {
|
move |conn| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
update_presentation_in_db(
|
update_presentation_in_db(
|
||||||
presentation.clone(),
|
presentation.clone(),
|
||||||
conn,
|
conn,
|
||||||
),
|
),
|
||||||
|r| match r {
|
|r| r.map(|_| Message::PresentationChanged)
|
||||||
Ok(()) => Message::PresentationChanged,
|
|
||||||
Err(e) => {
|
|
||||||
error!(?e);
|
|
||||||
Message::None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
).map(|r| r.unwrap_or(Message::None)),
|
||||||
),
|
),
|
||||||
Err(_) => todo!(),
|
Err(_) => todo!(),
|
||||||
}
|
}
|
||||||
|
|
@ -715,26 +683,27 @@ impl<'a> Library {
|
||||||
.add_item(song.clone())
|
.add_item(song.clone())
|
||||||
.err()
|
.err()
|
||||||
else {
|
else {
|
||||||
let task =
|
let task = Task::future(
|
||||||
Task::future(self.db.acquire())
|
self.db.acquire(),
|
||||||
.and_then(move |db| {
|
)
|
||||||
Task::perform(
|
.map_err(|e| {
|
||||||
add_song_to_db(db),
|
miette::miette!(
|
||||||
{
|
"Database error: {e}"
|
||||||
move |res| {
|
)
|
||||||
if let Err(
|
})
|
||||||
e,
|
.and_then(move |db| {
|
||||||
) = res
|
Task::perform(
|
||||||
{
|
new_song_from_db(db),
|
||||||
error!(
|
{
|
||||||
?e
|
move |res| {
|
||||||
);
|
res.map(|_song| {
|
||||||
}
|
Message::None
|
||||||
Message::None
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
|
.map(|r| r.unwrap_or(Message::None));
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
@ -746,30 +715,29 @@ impl<'a> Library {
|
||||||
.add_item(video.clone())
|
.add_item(video.clone())
|
||||||
.err()
|
.err()
|
||||||
else {
|
else {
|
||||||
let task = Task::future(
|
let task =
|
||||||
self.db.acquire(),
|
Task::future(self.db.acquire())
|
||||||
)
|
.map_err(|e| {
|
||||||
.and_then(move |db| {
|
miette::miette!(
|
||||||
Task::perform(
|
"Database error: {e}"
|
||||||
add_video_to_db(
|
)
|
||||||
video.clone(),
|
})
|
||||||
db,
|
.and_then(move |db| {
|
||||||
),
|
Task::perform(
|
||||||
{
|
add_video_to_db(
|
||||||
let video = video.clone();
|
video.clone(),
|
||||||
move |res| {
|
db,
|
||||||
debug!(
|
),
|
||||||
?video,
|
move |res| {
|
||||||
"added to db"
|
res.map(|_| {
|
||||||
);
|
Message::None
|
||||||
if let Err(e) = res {
|
})
|
||||||
error!(?e);
|
},
|
||||||
}
|
)
|
||||||
Message::None
|
})
|
||||||
}
|
.map(|r| {
|
||||||
},
|
r.unwrap_or(Message::None)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
@ -781,30 +749,29 @@ impl<'a> Library {
|
||||||
.add_item(image.clone())
|
.add_item(image.clone())
|
||||||
.err()
|
.err()
|
||||||
else {
|
else {
|
||||||
let task = Task::future(
|
let task =
|
||||||
self.db.acquire(),
|
Task::future(self.db.acquire())
|
||||||
)
|
.map_err(|e| {
|
||||||
.and_then(move |db| {
|
miette::miette!(
|
||||||
Task::perform(
|
"Database error: {e}"
|
||||||
add_image_to_db(
|
)
|
||||||
image.clone(),
|
})
|
||||||
db,
|
.and_then(move |db| {
|
||||||
),
|
Task::perform(
|
||||||
{
|
add_image_to_db(
|
||||||
let image = image.clone();
|
image.clone(),
|
||||||
move |res| {
|
db,
|
||||||
debug!(
|
),
|
||||||
?image,
|
move |res| {
|
||||||
"added to db"
|
res.map(|_| {
|
||||||
);
|
Message::None
|
||||||
if let Err(e) = res {
|
})
|
||||||
error!(?e);
|
},
|
||||||
}
|
)
|
||||||
Message::None
|
})
|
||||||
}
|
.map(|r| {
|
||||||
},
|
r.unwrap_or(Message::None)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
@ -820,6 +787,11 @@ impl<'a> Library {
|
||||||
else {
|
else {
|
||||||
let task =
|
let task =
|
||||||
Task::future(self.db.acquire())
|
Task::future(self.db.acquire())
|
||||||
|
.map_err(|e| {
|
||||||
|
miette::miette!(
|
||||||
|
"Database error: {e}"
|
||||||
|
)
|
||||||
|
})
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
add_presentation_to_db(
|
add_presentation_to_db(
|
||||||
|
|
@ -827,20 +799,16 @@ impl<'a> Library {
|
||||||
db,
|
db,
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
let presentation =
|
|
||||||
presentation.clone();
|
|
||||||
move |res| {
|
move |res| {
|
||||||
debug!(
|
res.map(|_| {
|
||||||
?presentation,
|
Message::None
|
||||||
"added to db"
|
})
|
||||||
);
|
|
||||||
if let Err(e) = res {
|
|
||||||
error!(?e);
|
|
||||||
}
|
|
||||||
Message::None
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
.map(|r| {
|
||||||
|
r.unwrap_or(Message::None)
|
||||||
});
|
});
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
|
|
||||||
|
|
@ -871,7 +839,7 @@ impl<'a> Library {
|
||||||
|
|
||||||
let library_column = column![
|
let library_column = column![
|
||||||
text::heading("Library").center().width(Length::Fill),
|
text::heading("Library").center().width(Length::Fill),
|
||||||
cosmic::iced::widget::horizontal_rule(1),
|
divider::horizontal::light(),
|
||||||
song_library,
|
song_library,
|
||||||
image_library,
|
image_library,
|
||||||
video_library,
|
video_library,
|
||||||
|
|
@ -950,7 +918,7 @@ impl<'a> Library {
|
||||||
where
|
where
|
||||||
T: Content,
|
T: Content,
|
||||||
{
|
{
|
||||||
let mut row = row::<Message>().spacing(5);
|
let mut row = row::with_capacity(5).spacing(5);
|
||||||
match &model.kind {
|
match &model.kind {
|
||||||
LibraryKind::Song => {
|
LibraryKind::Song => {
|
||||||
row = row
|
row = row
|
||||||
|
|
@ -981,7 +949,7 @@ impl<'a> Library {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let item_count = model.items.len();
|
let item_count = model.items.len();
|
||||||
row = row.push(horizontal_space());
|
row = row.push(space::horizontal());
|
||||||
row = row
|
row = row
|
||||||
.push(textm!("{}", item_count).align_y(Vertical::Center));
|
.push(textm!("{}", item_count).align_y(Vertical::Center));
|
||||||
row = row.push(
|
row = row.push(
|
||||||
|
|
@ -1118,7 +1086,7 @@ impl<'a> Library {
|
||||||
column![library_toolbar, context_menu].spacing(3);
|
column![library_toolbar, context_menu].spacing(3);
|
||||||
Container::new(library_column).padding(5)
|
Container::new(library_column).padding(5)
|
||||||
} else {
|
} else {
|
||||||
Container::new(Space::new(0, 0))
|
Container::new(Space::new())
|
||||||
};
|
};
|
||||||
column![library_button, lib_container].into()
|
column![library_button, lib_container].into()
|
||||||
}
|
}
|
||||||
|
|
@ -1133,6 +1101,9 @@ impl<'a> Library {
|
||||||
where
|
where
|
||||||
T: Content,
|
T: Content,
|
||||||
{
|
{
|
||||||
|
let cosmic::cosmic_theme::Spacing {
|
||||||
|
space_xxs, space_s, ..
|
||||||
|
} = theme::spacing();
|
||||||
let text = Container::new(responsive(|size| {
|
let text = Container::new(responsive(|size| {
|
||||||
text::heading(elide_text(item.title(), size.width))
|
text::heading(elide_text(item.title(), size.width))
|
||||||
.center()
|
.center()
|
||||||
|
|
@ -1183,11 +1154,10 @@ impl<'a> Library {
|
||||||
let texts = column([text.into(), subtext.into()]);
|
let texts = column([text.into(), subtext.into()]);
|
||||||
|
|
||||||
Container::new(
|
Container::new(
|
||||||
rowm![horizontal_space().width(0), texts]
|
rowm![horizontal().width(0), texts]
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.align_y(Vertical::Center),
|
.align_y(Vertical::Center),
|
||||||
)
|
)
|
||||||
// .padding(5)
|
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.style(move |t| {
|
.style(move |t| {
|
||||||
container::Style::default()
|
container::Style::default()
|
||||||
|
|
@ -1228,7 +1198,7 @@ impl<'a> Library {
|
||||||
.rounded(t.cosmic().corner_radii.radius_m),
|
.rounded(t.cosmic().corner_radii.radius_m),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.padding([3, 0])
|
.padding([space_xxs, space_s])
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1372,6 +1342,7 @@ impl<'a> Library {
|
||||||
Message::None
|
Message::None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.map(|m| Ok(m))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1403,6 +1374,7 @@ impl<'a> Library {
|
||||||
Message::None
|
Message::None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.map(|m| Ok(m))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1436,6 +1408,7 @@ impl<'a> Library {
|
||||||
Message::None
|
Message::None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.map(|m| Ok(m))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1469,6 +1442,7 @@ impl<'a> Library {
|
||||||
Message::None
|
Message::None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.map(|m| Ok(m))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1477,6 +1451,11 @@ impl<'a> Library {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.map(|t| {
|
||||||
|
t.map(
|
||||||
|
|r| if let Ok(r) = r { r } else { Message::None },
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if !tasks.is_empty() {
|
if !tasks.is_empty() {
|
||||||
self.selected_items = None;
|
self.selected_items = None;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ pub mod image_editor;
|
||||||
pub mod library;
|
pub mod library;
|
||||||
pub mod presentation_editor;
|
pub mod presentation_editor;
|
||||||
pub mod presenter;
|
pub mod presenter;
|
||||||
pub mod service;
|
// pub mod service;
|
||||||
pub mod slide_editor;
|
pub mod slide_editor;
|
||||||
pub mod song_editor;
|
pub mod song_editor;
|
||||||
pub mod text_svg;
|
pub mod text_svg;
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,11 @@ use cosmic::{
|
||||||
iced_widget::{column, row},
|
iced_widget::{column, row},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
self, Space, button, container, context_menu,
|
self, Space, button, container, context_menu, icon,
|
||||||
horizontal_space, icon, image::Handle, menu, mouse_area,
|
image::Handle,
|
||||||
scrollable, text, text_input,
|
menu, mouse_area, scrollable,
|
||||||
|
space::{self, horizontal},
|
||||||
|
text, text_input,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use miette::{IntoDiagnostic, Result, miette};
|
use miette::{IntoDiagnostic, Result, miette};
|
||||||
|
|
@ -335,7 +337,7 @@ impl PresentationEditor {
|
||||||
|
|
||||||
pub fn view(&self) -> Element<Message> {
|
pub fn view(&self) -> Element<Message> {
|
||||||
let presentation = self.current_slide.as_ref().map_or_else(
|
let presentation = self.current_slide.as_ref().map_or_else(
|
||||||
|| container(Space::new(0, 0)),
|
|| container(Space::new()),
|
||||||
|slide| {
|
|slide| {
|
||||||
container(
|
container(
|
||||||
widget::image(slide)
|
widget::image(slide)
|
||||||
|
|
@ -350,7 +352,7 @@ impl PresentationEditor {
|
||||||
);
|
);
|
||||||
let pdf_pages: Vec<Element<Message>> =
|
let pdf_pages: Vec<Element<Message>> =
|
||||||
self.slides.as_ref().map_or_else(
|
self.slides.as_ref().map_or_else(
|
||||||
|| vec![horizontal_space().into()],
|
|| vec![horizontal().into()],
|
||||||
|pages| {
|
|pages| {
|
||||||
pages
|
pages
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -421,7 +423,7 @@ impl PresentationEditor {
|
||||||
let control_buttons = row![
|
let control_buttons = row![
|
||||||
button::standard("Previous Page")
|
button::standard("Previous Page")
|
||||||
.on_press(Message::PrevPage),
|
.on_press(Message::PrevPage),
|
||||||
horizontal_space(),
|
space::horizontal(),
|
||||||
button::standard("Next Page").on_press(Message::NextPage),
|
button::standard("Next Page").on_press(Message::NextPage),
|
||||||
];
|
];
|
||||||
let column =
|
let column =
|
||||||
|
|
@ -450,7 +452,7 @@ impl PresentationEditor {
|
||||||
row![
|
row![
|
||||||
text::body("Title:"),
|
text::body("Title:"),
|
||||||
title_box,
|
title_box,
|
||||||
horizontal_space(),
|
space::horizontal(),
|
||||||
presentation_selector
|
presentation_selector
|
||||||
]
|
]
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,13 @@ use cosmic::{
|
||||||
scrollable::{
|
scrollable::{
|
||||||
AbsoluteOffset, Direction, Scrollbar, scroll_to,
|
AbsoluteOffset, Direction, Scrollbar, scroll_to,
|
||||||
},
|
},
|
||||||
stack, vertical_rule,
|
stack,
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widget::{
|
widget::{
|
||||||
Container, Id, Row, Space, container, context_menu, image,
|
Container, Id, Row, Space, container, context_menu,
|
||||||
menu, mouse_area, responsive, scrollable, text,
|
divider::vertical, image, menu, mouse_area, responsive,
|
||||||
|
scrollable, text,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use derive_more::Debug;
|
use derive_more::Debug;
|
||||||
|
|
@ -454,7 +455,10 @@ impl Presenter {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tasks = vec![];
|
let mut tasks = vec![];
|
||||||
tasks.push(scroll_to(self.scroll_id.clone(), offset));
|
tasks.push(scroll_to(
|
||||||
|
self.scroll_id.clone(),
|
||||||
|
offset.into(),
|
||||||
|
));
|
||||||
|
|
||||||
if self.slide_action_map.is_some() {
|
if self.slide_action_map.is_some() {
|
||||||
debug!("Found slide actions, running them");
|
debug!("Found slide actions, running them");
|
||||||
|
|
@ -723,7 +727,7 @@ impl Presenter {
|
||||||
.align_top(Length::Fill)
|
.align_top(Length::Fill)
|
||||||
.align_left(Length::Fill)
|
.align_left(Length::Fill)
|
||||||
.padding([0, 0, 0, 35]);
|
.padding([0, 0, 0, 35]);
|
||||||
let divider = vertical_rule(2);
|
let divider = vertical::light();
|
||||||
items.push(
|
items.push(
|
||||||
container(stack!(row, label_container))
|
container(stack!(row, label_container))
|
||||||
.padding([5, 2])
|
.padding([5, 2])
|
||||||
|
|
@ -981,7 +985,7 @@ pub(crate) fn slide_view<'a>(
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
responsive(move |size| {
|
responsive(move |size| {
|
||||||
let width = size.height * 16.0 / 9.0;
|
let width = size.height * 16.0 / 9.0;
|
||||||
let black = Container::new(Space::new(0, 0))
|
let black = Container::new(Space::new())
|
||||||
.style(|_| {
|
.style(|_| {
|
||||||
container::background(Background::Color(Color::BLACK))
|
container::background(Background::Color(Color::BLACK))
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -121,10 +121,10 @@ impl<'a> Program<SlideWidget, cosmic::Theme, cosmic::Renderer>
|
||||||
fn update(
|
fn update(
|
||||||
&self,
|
&self,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
event: canvas::Event,
|
event: &canvas::Event,
|
||||||
bounds: cosmic::iced::Rectangle,
|
bounds: cosmic::iced::Rectangle,
|
||||||
_cursor: cosmic::iced_core::mouse::Cursor,
|
_cursor: cosmic::iced_core::mouse::Cursor,
|
||||||
) -> (canvas::event::Status, Option<SlideWidget>) {
|
) -> Option<cosmic::iced_widget::Action<SlideWidget>> {
|
||||||
match event {
|
match event {
|
||||||
canvas::Event::Mouse(event) => match event {
|
canvas::Event::Mouse(event) => match event {
|
||||||
cosmic::iced::mouse::Event::CursorEntered => {
|
cosmic::iced::mouse::Event::CursorEntered => {
|
||||||
|
|
@ -157,8 +157,15 @@ impl<'a> Program<SlideWidget, cosmic::Theme, cosmic::Renderer>
|
||||||
},
|
},
|
||||||
canvas::Event::Touch(_event) => debug!("test"),
|
canvas::Event::Touch(_event) => debug!("test"),
|
||||||
canvas::Event::Keyboard(_event) => debug!("test"),
|
canvas::Event::Keyboard(_event) => debug!("test"),
|
||||||
|
canvas::Event::Window(_event) => todo!(),
|
||||||
|
canvas::Event::InputMethod(_event) => todo!(),
|
||||||
|
canvas::Event::A11y(_id, _action_request) => todo!(),
|
||||||
|
canvas::Event::Dnd(_dnd_event) => todo!(),
|
||||||
|
canvas::Event::PlatformSpecific(_platform_specific) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(canvas::event::Status::Ignored, None)
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@ use cosmic::{
|
||||||
combo_box, container, divider, dnd_destination, dnd_source,
|
combo_box, container, divider, dnd_destination, dnd_source,
|
||||||
dropdown,
|
dropdown,
|
||||||
grid::{self},
|
grid::{self},
|
||||||
horizontal_space, icon, mouse_area, popover, progress_bar,
|
icon, mouse_area, popover, progress_bar, scrollable,
|
||||||
scrollable, text, text_editor, text_input, tooltip,
|
space::{self, horizontal},
|
||||||
|
text, text_editor, text_input, tooltip,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use derive_more::Debug;
|
use derive_more::Debug;
|
||||||
|
|
@ -900,7 +901,7 @@ impl SongEditor {
|
||||||
pub fn view(&self) -> Element<Message> {
|
pub fn view(&self) -> Element<Message> {
|
||||||
let video_elements: Element<Message> =
|
let video_elements: Element<Message> =
|
||||||
self.video.as_ref().map_or_else(
|
self.video.as_ref().map_or_else(
|
||||||
|| horizontal_space().into(),
|
|| horizontal().into(),
|
||||||
|video| {
|
|video| {
|
||||||
let play_button =
|
let play_button =
|
||||||
button::icon(if video.paused() {
|
button::icon(if video.paused() {
|
||||||
|
|
@ -913,8 +914,8 @@ impl SongEditor {
|
||||||
0.0..=video.duration().as_secs_f32(),
|
0.0..=video.duration().as_secs_f32(),
|
||||||
video.position().as_secs_f32(),
|
video.position().as_secs_f32(),
|
||||||
)
|
)
|
||||||
.height(cosmic::theme::spacing().space_s)
|
.girth(cosmic::theme::spacing().space_s)
|
||||||
.width(Length::Fill);
|
.length(Length::Fill);
|
||||||
container(
|
container(
|
||||||
row![play_button, video_track]
|
row![play_button, video_track]
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
|
|
@ -947,7 +948,7 @@ impl SongEditor {
|
||||||
|
|
||||||
fn slide_preview(&self) -> Element<Message> {
|
fn slide_preview(&self) -> Element<Message> {
|
||||||
self.song_slides.as_ref().map_or_else(
|
self.song_slides.as_ref().map_or_else(
|
||||||
|| horizontal_space().into(),
|
|| space::horizontal().into(),
|
||||||
|slides| {
|
|slides| {
|
||||||
let slides: Vec<Element<Message>> = slides
|
let slides: Vec<Element<Message>> = slides
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -1107,7 +1108,7 @@ impl SongEditor {
|
||||||
if let Some(hovered_chip) =
|
if let Some(hovered_chip) =
|
||||||
self.hovered_dnd_verse_chip
|
self.hovered_dnd_verse_chip
|
||||||
&& index == hovered_chip {
|
&& index == hovered_chip {
|
||||||
let phantom_chip = horizontal_space().width(60).height(19)
|
let phantom_chip = space::horizontal().width(60).height(19)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(
|
.padding(
|
||||||
Padding::new(space_xxs.into())
|
Padding::new(space_xxs.into())
|
||||||
|
|
@ -1119,7 +1120,7 @@ impl SongEditor {
|
||||||
.background(ContainerBackground::Color(
|
.background(ContainerBackground::Color(
|
||||||
Color::from(t.cosmic().secondary.base).scale_alpha(0.5)
|
Color::from(t.cosmic().secondary.base).scale_alpha(0.5)
|
||||||
))
|
))
|
||||||
.border(Border::default().rounded(space_m).width(2))
|
.border(Border::default().rounded(space_m as u8).width(2))
|
||||||
})));
|
})));
|
||||||
chip = row![
|
chip = row![
|
||||||
phantom_chip,
|
phantom_chip,
|
||||||
|
|
@ -1166,7 +1167,7 @@ impl SongEditor {
|
||||||
|
|
||||||
let mut verse_order_row = if self.dragging_verse_chip {
|
let mut verse_order_row = if self.dragging_verse_chip {
|
||||||
let ending_dnd_dest = dnd_destination(
|
let ending_dnd_dest = dnd_destination(
|
||||||
horizontal_space().height(19),
|
space::horizontal().height(19),
|
||||||
vec!["application/verse".into()],
|
vec!["application/verse".into()],
|
||||||
)
|
)
|
||||||
.on_enter(|_, _, _| {
|
.on_enter(|_, _, _| {
|
||||||
|
|
@ -1213,7 +1214,7 @@ impl SongEditor {
|
||||||
if self.editing_verse_order {
|
if self.editing_verse_order {
|
||||||
Element::from(verse_options)
|
Element::from(verse_options)
|
||||||
} else {
|
} else {
|
||||||
Element::from(horizontal_space())
|
Element::from(space::horizontal())
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
.spacing(space_s),
|
.spacing(space_s),
|
||||||
|
|
@ -1236,7 +1237,7 @@ impl SongEditor {
|
||||||
.spacing(5);
|
.spacing(5);
|
||||||
|
|
||||||
let verse_list = self.verses.as_ref().map_or_else(
|
let verse_list = self.verses.as_ref().map_or_else(
|
||||||
|| Element::from(horizontal_space()),
|
|| Element::from(space::horizontal()),
|
||||||
|verse_list| {
|
|verse_list| {
|
||||||
Element::from(
|
Element::from(
|
||||||
column(verse_list.iter().enumerate().map(
|
column(verse_list.iter().enumerate().map(
|
||||||
|
|
@ -1347,7 +1348,7 @@ impl SongEditor {
|
||||||
.on_close(Message::FontSelectorOpen(false))
|
.on_close(Message::FontSelectorOpen(false))
|
||||||
.width(300),
|
.width(300),
|
||||||
container(if self.font_selector_open {
|
container(if self.font_selector_open {
|
||||||
Element::from(horizontal_space())
|
Element::from(space::horizontal())
|
||||||
} else {
|
} else {
|
||||||
Element::from(
|
Element::from(
|
||||||
icon::from_name("arrow-down").size(space_m),
|
icon::from_name("arrow-down").size(space_m),
|
||||||
|
|
@ -1383,7 +1384,7 @@ impl SongEditor {
|
||||||
.on_close(Message::FontSizeOpen(false))
|
.on_close(Message::FontSizeOpen(false))
|
||||||
.width(space_xxxl),
|
.width(space_xxxl),
|
||||||
container(if self.font_size_open {
|
container(if self.font_size_open {
|
||||||
Element::from(horizontal_space())
|
Element::from(space::horizontal())
|
||||||
} else {
|
} else {
|
||||||
Element::from(
|
Element::from(
|
||||||
icon::from_name("arrow-down").size(space_m),
|
icon::from_name("arrow-down").size(space_m),
|
||||||
|
|
@ -1797,7 +1798,7 @@ impl SongEditor {
|
||||||
shadow_tools_button,
|
shadow_tools_button,
|
||||||
divider::vertical::default().height(space_l),
|
divider::vertical::default().height(space_l),
|
||||||
text_alignment_popup,
|
text_alignment_popup,
|
||||||
horizontal_space(),
|
space::horizontal(),
|
||||||
background_selector
|
background_selector
|
||||||
]
|
]
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
|
|
@ -1974,7 +1975,9 @@ fn verse_chip(
|
||||||
))
|
))
|
||||||
.color(text_color)
|
.color(text_color)
|
||||||
.border(
|
.border(
|
||||||
Border::default().rounded(space_m).width(2),
|
Border::default()
|
||||||
|
.rounded(space_m as u8)
|
||||||
|
.width(2),
|
||||||
)
|
)
|
||||||
})));
|
})));
|
||||||
let button = button::icon(icon::from_name("view-close"))
|
let button = button::icon(icon::from_name("view-close"))
|
||||||
|
|
@ -2006,7 +2009,9 @@ fn verse_chip(
|
||||||
))
|
))
|
||||||
.color(text_color)
|
.color(text_color)
|
||||||
.border(
|
.border(
|
||||||
Border::default().rounded(space_m).width(2),
|
Border::default()
|
||||||
|
.rounded(space_m as u8)
|
||||||
|
.width(2),
|
||||||
)
|
)
|
||||||
})))
|
})))
|
||||||
.into()
|
.into()
|
||||||
|
|
|
||||||
|
|
@ -518,7 +518,13 @@ impl TextSvg {
|
||||||
|
|
||||||
pub fn view<'a>(&self) -> Element<'a, Message> {
|
pub fn view<'a>(&self) -> Element<'a, Message> {
|
||||||
self.handle.clone().map_or_else(
|
self.handle.clone().map_or_else(
|
||||||
|| Element::from(Space::new(Length::Fill, Length::Fill)),
|
|| {
|
||||||
|
Element::from(
|
||||||
|
Space::new()
|
||||||
|
.height(Length::Fill)
|
||||||
|
.width(Length::Fill),
|
||||||
|
)
|
||||||
|
},
|
||||||
|handle| {
|
|handle| {
|
||||||
Image::new(handle)
|
Image::new(handle)
|
||||||
.content_fit(ContentFit::Cover)
|
.content_fit(ContentFit::Cover)
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ use cosmic::{
|
||||||
iced_widget::{column, row},
|
iced_widget::{column, row},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
Space, button, container, horizontal_space, icon,
|
Space, button, container, icon, progress_bar,
|
||||||
progress_bar, text, text_input,
|
space::{self, horizontal},
|
||||||
|
text, text_input,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use iced_video_player::{Video, VideoPlayer};
|
use iced_video_player::{Video, VideoPlayer};
|
||||||
|
|
@ -110,7 +111,7 @@ impl VideoEditor {
|
||||||
|
|
||||||
pub fn view(&self) -> Element<Message> {
|
pub fn view(&self) -> Element<Message> {
|
||||||
let video_elements = self.video.as_ref().map_or_else(
|
let video_elements = self.video.as_ref().map_or_else(
|
||||||
|| container(horizontal_space()),
|
|| container(horizontal()),
|
||||||
|video| {
|
|video| {
|
||||||
let play_button = button::icon(if video.paused() {
|
let play_button = button::icon(if video.paused() {
|
||||||
icon::from_name("media-playback-start")
|
icon::from_name("media-playback-start")
|
||||||
|
|
@ -122,8 +123,8 @@ impl VideoEditor {
|
||||||
0.0..=video.duration().as_secs_f32(),
|
0.0..=video.duration().as_secs_f32(),
|
||||||
video.position().as_secs_f32(),
|
video.position().as_secs_f32(),
|
||||||
)
|
)
|
||||||
.height(cosmic::theme::spacing().space_s)
|
.girth(cosmic::theme::spacing().space_s)
|
||||||
.width(Length::Fill);
|
.length(Length::Fill);
|
||||||
container(
|
container(
|
||||||
row![play_button, video_track]
|
row![play_button, video_track]
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
|
|
@ -135,7 +136,7 @@ impl VideoEditor {
|
||||||
);
|
);
|
||||||
|
|
||||||
let video_player = self.video.as_ref().map_or_else(
|
let video_player = self.video.as_ref().map_or_else(
|
||||||
|| Element::from(Space::new(0, 0)),
|
|| Element::from(Space::new()),
|
||||||
|video| Element::from(VideoPlayer::new(video)),
|
|video| Element::from(VideoPlayer::new(video)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -164,7 +165,7 @@ impl VideoEditor {
|
||||||
row![
|
row![
|
||||||
text::body("Title:"),
|
text::body("Title:"),
|
||||||
title_box,
|
title_box,
|
||||||
horizontal_space(),
|
space::horizontal(),
|
||||||
video_selector
|
video_selector
|
||||||
]
|
]
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
|
|
@ -177,6 +178,7 @@ impl VideoEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_entire_video(&mut self, video: &videos::Video) {
|
fn update_entire_video(&mut self, video: &videos::Video) {
|
||||||
|
debug!(?video);
|
||||||
let Ok(mut player_video) =
|
let Ok(mut player_video) =
|
||||||
Url::from_file_path(video.path.clone())
|
Url::from_file_path(video.path.clone())
|
||||||
.map(|url| Video::new(&url).expect("Should be here"))
|
.map(|url| Video::new(&url).expect("Should be here"))
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use cosmic::iced::advanced::layout::{self, Layout};
|
||||||
use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
|
use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
|
||||||
use cosmic::iced::advanced::{Clipboard, Shell, overlay, renderer};
|
use cosmic::iced::advanced::{Clipboard, Shell, overlay, renderer};
|
||||||
use cosmic::iced::alignment::{self, Alignment};
|
use cosmic::iced::alignment::{self, Alignment};
|
||||||
use cosmic::iced::event::{self, Event};
|
use cosmic::iced::event::Event;
|
||||||
use cosmic::iced::{self, Transformation, mouse};
|
use cosmic::iced::{self, Transformation, mouse};
|
||||||
use cosmic::iced::{
|
use cosmic::iced::{
|
||||||
Background, Border, Color, Element, Length, Padding, Pixels,
|
Background, Border, Color, Element, Length, Padding, Pixels,
|
||||||
|
|
@ -376,7 +376,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
|
|
@ -392,53 +392,49 @@ where
|
||||||
self.padding,
|
self.padding,
|
||||||
self.spacing,
|
self.spacing,
|
||||||
self.align,
|
self.align,
|
||||||
&self.children,
|
self.children.as_mut(),
|
||||||
&mut tree.children,
|
&mut tree.children,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
operation: &mut dyn Operation,
|
operation: &mut dyn Operation,
|
||||||
) {
|
) {
|
||||||
operation.container(
|
operation.container(None, layout.bounds());
|
||||||
None,
|
|
||||||
layout.bounds(),
|
operation.traverse(&mut |operation| {
|
||||||
&mut |operation| {
|
self.children
|
||||||
self.children
|
.iter_mut()
|
||||||
.iter()
|
.zip(&mut tree.children)
|
||||||
.zip(&mut tree.children)
|
.zip(layout.children())
|
||||||
.zip(layout.children())
|
.for_each(|((child, state), c_layout)| {
|
||||||
.for_each(|((child, state), c_layout)| {
|
child.as_widget_mut().operate(
|
||||||
child.as_widget().operate(
|
state,
|
||||||
state,
|
c_layout.with_virtual_offset(
|
||||||
c_layout.with_virtual_offset(
|
layout.virtual_offset(),
|
||||||
layout.virtual_offset(),
|
),
|
||||||
),
|
renderer,
|
||||||
renderer,
|
operation,
|
||||||
operation,
|
);
|
||||||
);
|
});
|
||||||
});
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
event: Event,
|
event: &Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) {
|
||||||
let mut event_status = event::Status::Ignored;
|
|
||||||
|
|
||||||
let action = tree.state.downcast_mut::<Action>();
|
let action = tree.state.downcast_mut::<Action>();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
|
|
@ -459,7 +455,7 @@ where
|
||||||
index,
|
index,
|
||||||
origin: cursor_position,
|
origin: cursor_position,
|
||||||
};
|
};
|
||||||
event_status = event::Status::Captured;
|
shell.capture_event();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -484,7 +480,7 @@ where
|
||||||
DragEvent::Picked { index },
|
DragEvent::Picked { index },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
event_status = event::Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::Dragging { origin, index, .. } => {
|
Action::Dragging { origin, index, .. } => {
|
||||||
|
|
@ -496,7 +492,7 @@ where
|
||||||
origin,
|
origin,
|
||||||
index,
|
index,
|
||||||
};
|
};
|
||||||
event_status = event::Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -529,8 +525,7 @@ where
|
||||||
drop_position,
|
drop_position,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
event_status =
|
shell.capture_event();
|
||||||
event::Status::Captured;
|
|
||||||
}
|
}
|
||||||
} else if let Some(on_reorder) =
|
} else if let Some(on_reorder) =
|
||||||
&self.on_drag
|
&self.on_drag
|
||||||
|
|
@ -538,8 +533,7 @@ where
|
||||||
shell.publish(on_reorder(
|
shell.publish(on_reorder(
|
||||||
DragEvent::Canceled { index },
|
DragEvent::Canceled { index },
|
||||||
));
|
));
|
||||||
event_status =
|
shell.capture_event();
|
||||||
event::Status::Captured;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*action = Action::Idle;
|
*action = Action::Idle;
|
||||||
|
|
@ -554,15 +548,14 @@ where
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let child_status = self
|
self.children
|
||||||
.children
|
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(&mut tree.children)
|
.zip(&mut tree.children)
|
||||||
.zip(layout.children())
|
.zip(layout.children())
|
||||||
.map(|((child, state), c_layout)| {
|
.for_each(|((child, state), c_layout)| {
|
||||||
child.as_widget_mut().on_event(
|
child.as_widget_mut().update(
|
||||||
state,
|
state,
|
||||||
event.clone(),
|
&event.clone(),
|
||||||
c_layout
|
c_layout
|
||||||
.with_virtual_offset(layout.virtual_offset()),
|
.with_virtual_offset(layout.virtual_offset()),
|
||||||
cursor,
|
cursor,
|
||||||
|
|
@ -571,10 +564,7 @@ where
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
)
|
)
|
||||||
})
|
});
|
||||||
.fold(event::Status::Ignored, event::Status::merge);
|
|
||||||
|
|
||||||
event::Status::merge(event_status, child_status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
|
|
@ -807,8 +797,9 @@ where
|
||||||
fn overlay<'b>(
|
fn overlay<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
tree: &'b mut Tree,
|
tree: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'b>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
viewport: &Rectangle,
|
||||||
translation: Vector,
|
translation: Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||||
overlay::from_children(
|
overlay::from_children(
|
||||||
|
|
@ -816,6 +807,7 @@ where
|
||||||
tree,
|
tree,
|
||||||
layout,
|
layout,
|
||||||
renderer,
|
renderer,
|
||||||
|
viewport,
|
||||||
translation,
|
translation,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use cosmic::iced::advanced::layout::{self, Layout};
|
||||||
use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
|
use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
|
||||||
use cosmic::iced::advanced::{Clipboard, Shell, overlay, renderer};
|
use cosmic::iced::advanced::{Clipboard, Shell, overlay, renderer};
|
||||||
use cosmic::iced::alignment::{self, Alignment};
|
use cosmic::iced::alignment::{self, Alignment};
|
||||||
use cosmic::iced::event::{self, Event};
|
use cosmic::iced::event::Event;
|
||||||
use cosmic::iced::{self, Transformation, mouse};
|
use cosmic::iced::{self, Transformation, mouse};
|
||||||
use cosmic::iced::{
|
use cosmic::iced::{
|
||||||
Background, Border, Color, Element, Length, Padding, Pixels,
|
Background, Border, Color, Element, Length, Padding, Pixels,
|
||||||
|
|
@ -371,7 +371,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
|
|
@ -385,48 +385,43 @@ where
|
||||||
self.padding,
|
self.padding,
|
||||||
self.spacing,
|
self.spacing,
|
||||||
self.align,
|
self.align,
|
||||||
&self.children,
|
&mut self.children,
|
||||||
&mut tree.children,
|
&mut tree.children,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
operation: &mut dyn Operation,
|
operation: &mut dyn Operation,
|
||||||
) {
|
) {
|
||||||
operation.container(
|
operation.container(None, layout.bounds());
|
||||||
None,
|
operation.traverse(&mut |operation| {
|
||||||
layout.bounds(),
|
self.children
|
||||||
&mut |operation| {
|
.iter_mut()
|
||||||
self.children
|
.zip(&mut tree.children)
|
||||||
.iter()
|
.zip(layout.children())
|
||||||
.zip(&mut tree.children)
|
.for_each(|((child, state), layout)| {
|
||||||
.zip(layout.children())
|
child
|
||||||
.for_each(|((child, state), layout)| {
|
.as_widget_mut()
|
||||||
child.as_widget().operate(
|
.operate(state, layout, renderer, operation);
|
||||||
state, layout, renderer, operation,
|
});
|
||||||
);
|
});
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
event: Event,
|
event: &Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) {
|
||||||
let mut event_status = event::Status::Ignored;
|
|
||||||
|
|
||||||
let action = tree.state.downcast_mut::<Action>();
|
let action = tree.state.downcast_mut::<Action>();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
|
|
@ -447,7 +442,7 @@ where
|
||||||
index,
|
index,
|
||||||
origin: cursor_position,
|
origin: cursor_position,
|
||||||
};
|
};
|
||||||
event_status = event::Status::Captured;
|
shell.capture_event();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -472,7 +467,7 @@ where
|
||||||
DragEvent::Picked { index },
|
DragEvent::Picked { index },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
event_status = event::Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::Dragging { origin, index, .. } => {
|
Action::Dragging { origin, index, .. } => {
|
||||||
|
|
@ -484,7 +479,7 @@ where
|
||||||
origin,
|
origin,
|
||||||
index,
|
index,
|
||||||
};
|
};
|
||||||
event_status = event::Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -517,8 +512,7 @@ where
|
||||||
drop_position,
|
drop_position,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
event_status =
|
shell.capture_event();
|
||||||
event::Status::Captured;
|
|
||||||
}
|
}
|
||||||
} else if let Some(on_reorder) =
|
} else if let Some(on_reorder) =
|
||||||
&self.on_drag
|
&self.on_drag
|
||||||
|
|
@ -526,8 +520,7 @@ where
|
||||||
shell.publish(on_reorder(
|
shell.publish(on_reorder(
|
||||||
DragEvent::Canceled { index },
|
DragEvent::Canceled { index },
|
||||||
));
|
));
|
||||||
event_status =
|
shell.capture_event();
|
||||||
event::Status::Captured;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*action = Action::Idle;
|
*action = Action::Idle;
|
||||||
|
|
@ -542,15 +535,14 @@ where
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let child_status = self
|
self.children
|
||||||
.children
|
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(&mut tree.children)
|
.zip(&mut tree.children)
|
||||||
.zip(layout.children())
|
.zip(layout.children())
|
||||||
.map(|((child, state), layout)| {
|
.for_each(|((child, state), layout)| {
|
||||||
child.as_widget_mut().on_event(
|
child.as_widget_mut().update(
|
||||||
state,
|
state,
|
||||||
event.clone(),
|
&event.clone(),
|
||||||
layout,
|
layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -558,10 +550,7 @@ where
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
)
|
)
|
||||||
})
|
});
|
||||||
.fold(event::Status::Ignored, event::Status::merge);
|
|
||||||
|
|
||||||
event::Status::merge(event_status, child_status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
|
|
@ -769,8 +758,9 @@ where
|
||||||
fn overlay<'b>(
|
fn overlay<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
tree: &'b mut Tree,
|
tree: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'b>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
viewport: &Rectangle,
|
||||||
translation: Vector,
|
translation: Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||||
overlay::from_children(
|
overlay::from_children(
|
||||||
|
|
@ -778,6 +768,7 @@ where
|
||||||
tree,
|
tree,
|
||||||
layout,
|
layout,
|
||||||
renderer,
|
renderer,
|
||||||
|
viewport,
|
||||||
translation,
|
translation,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -833,7 +824,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
|
|
@ -875,8 +866,8 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, child) in self.row.children.iter().enumerate() {
|
for (i, child) in self.row.children.iter_mut().enumerate() {
|
||||||
let node = child.as_widget().layout(
|
let node = child.as_widget_mut().layout(
|
||||||
&mut tree.children[i],
|
&mut tree.children[i],
|
||||||
renderer,
|
renderer,
|
||||||
&limits,
|
&limits,
|
||||||
|
|
@ -927,7 +918,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
|
@ -936,18 +927,18 @@ where
|
||||||
self.row.operate(tree, layout, renderer, operation);
|
self.row.operate(tree, layout, renderer, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut Tree,
|
tree: &mut Tree,
|
||||||
event: Event,
|
event: &Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) {
|
||||||
self.row.on_event(
|
self.row.update(
|
||||||
tree, event, layout, cursor, renderer, clipboard, shell,
|
tree, event, layout, cursor, renderer, clipboard, shell,
|
||||||
viewport,
|
viewport,
|
||||||
)
|
)
|
||||||
|
|
@ -984,11 +975,18 @@ where
|
||||||
fn overlay<'b>(
|
fn overlay<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
tree: &'b mut Tree,
|
tree: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'b>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
viewport: &Rectangle,
|
||||||
translation: Vector,
|
translation: Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||||
self.row.overlay(tree, layout, renderer, translation)
|
self.row.overlay(
|
||||||
|
tree,
|
||||||
|
layout,
|
||||||
|
renderer,
|
||||||
|
viewport,
|
||||||
|
translation,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
#[allow(clippy::nursery)]
|
#[allow(clippy::nursery)]
|
||||||
#[allow(clippy::pedantic)]
|
#[allow(clippy::pedantic)]
|
||||||
pub mod draggable;
|
pub mod draggable;
|
||||||
pub mod slide_text;
|
// pub mod slide_text;
|
||||||
pub mod verse_editor;
|
pub mod verse_editor;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&self,
|
&mut self,
|
||||||
_tree: &mut widget::Tree,
|
_tree: &mut widget::Tree,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_limits: &layout::Limits,
|
_limits: &layout::Limits,
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ use cosmic::{
|
||||||
iced_widget::{column, row},
|
iced_widget::{column, row},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
button, combo_box, container, horizontal_space, icon,
|
button, combo_box, container, icon, space, text_editor,
|
||||||
text_editor,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -62,12 +61,12 @@ impl VerseEditor {
|
||||||
let verse = self.verse_name;
|
let verse = self.verse_name;
|
||||||
Action::UpdateVerse((verse, lyrics))
|
Action::UpdateVerse((verse, lyrics))
|
||||||
}
|
}
|
||||||
text_editor::Action::Scroll { pixels } => {
|
text_editor::Action::Scroll { lines } => {
|
||||||
if self.content.line_count() > 6 {
|
if self.content.line_count() > 6 {
|
||||||
self.content.perform(action);
|
self.content.perform(action);
|
||||||
Action::None
|
Action::None
|
||||||
} else {
|
} else {
|
||||||
Action::ScrollVerses(pixels)
|
Action::ScrollVerses(lines as f32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
@ -109,12 +108,12 @@ impl VerseEditor {
|
||||||
);
|
);
|
||||||
|
|
||||||
let verse_title =
|
let verse_title =
|
||||||
row![combo, horizontal_space(), delete_button];
|
row![combo, space::horizontal(), delete_button];
|
||||||
|
|
||||||
let lyric: Element<Message> = if self.verse_name
|
let lyric: Element<Message> = if self.verse_name
|
||||||
== VerseName::Blank
|
== VerseName::Blank
|
||||||
{
|
{
|
||||||
horizontal_space().into()
|
space::horizontal().into()
|
||||||
} else {
|
} else {
|
||||||
text_editor(&self.content)
|
text_editor(&self.content)
|
||||||
.on_action(Message::UpdateLyric)
|
.on_action(Message::UpdateLyric)
|
||||||
|
|
@ -131,15 +130,11 @@ impl VerseEditor {
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
border: Border::default()
|
border: Border::default()
|
||||||
.rounded(space_s)
|
.rounded(space_s as u8)
|
||||||
.width(2)
|
.width(2)
|
||||||
.color(
|
.color(
|
||||||
t.cosmic().bg_component_divider(),
|
t.cosmic().bg_component_divider(),
|
||||||
),
|
),
|
||||||
icon: t
|
|
||||||
.cosmic()
|
|
||||||
.primary_component_color()
|
|
||||||
.into(),
|
|
||||||
placeholder: neutral
|
placeholder: neutral
|
||||||
.with_alpha(0.7)
|
.with_alpha(0.7)
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -147,13 +142,15 @@ impl VerseEditor {
|
||||||
selection: t.cosmic().accent.base.into(),
|
selection: t.cosmic().accent.base.into(),
|
||||||
};
|
};
|
||||||
let hovered_border = Border::default()
|
let hovered_border = Border::default()
|
||||||
.rounded(space_s)
|
.rounded(space_s as u8)
|
||||||
.width(3)
|
.width(3)
|
||||||
.color(t.cosmic().accent.hover);
|
.color(t.cosmic().accent.hover);
|
||||||
match s {
|
match s {
|
||||||
text_editor::Status::Active => base_style,
|
text_editor::Status::Active => base_style,
|
||||||
text_editor::Status::Hovered
|
text_editor::Status::Hovered
|
||||||
| text_editor::Status::Focused => {
|
| text_editor::Status::Focused {
|
||||||
|
..
|
||||||
|
} => {
|
||||||
base_style.border = hovered_border;
|
base_style.border = hovered_border;
|
||||||
base_style
|
base_style
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue