Compare commits

..

2 commits

Author SHA1 Message Date
761006f516 more clippy fixes
Some checks are pending
/ test (push) Waiting to run
2025-09-26 15:44:42 -05:00
46abd9dd7a some clippy fixes 2025-09-26 14:05:57 -05:00
20 changed files with 228 additions and 265 deletions

View file

@ -10,8 +10,8 @@ use crisp::types::{Keyword, Symbol, Value};
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{ use sqlx::{
pool::PoolConnection, query, query_as, Sqlite, SqliteConnection, Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
SqlitePool, query, query_as,
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tracing::{debug, error}; use tracing::{debug, error};
@ -211,7 +211,7 @@ pub async fn update_image_in_db(
.map(std::string::ToString::to_string) .map(std::string::ToString::to_string)
.unwrap_or_default(); .unwrap_or_default();
let mut db = db.detach(); let mut db = db.detach();
let id = image.id.clone(); let id = image.id;
if let Err(e) = query!("SELECT id FROM images where id = $1", id) if let Err(e) = query!("SELECT id FROM images where id = $1", id)
.fetch_one(&mut db) .fetch_one(&mut db)
.await .await

View file

@ -1,6 +1,6 @@
use std::mem::replace; use std::mem::replace;
use miette::{miette, Result}; use miette::{Result, miette};
use sqlx::{Connection, SqliteConnection}; use sqlx::{Connection, SqliteConnection};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -4,8 +4,8 @@ use miette::{IntoDiagnostic, Result};
use mupdf::{Colorspace, Document, Matrix}; use mupdf::{Colorspace, Document, Matrix};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{ use sqlx::{
pool::PoolConnection, prelude::FromRow, query, sqlite::SqliteRow, Row, Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
Row, Sqlite, SqliteConnection, SqlitePool, prelude::FromRow, query, sqlite::SqliteRow,
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tracing::{debug, error}; use tracing::{debug, error};
@ -318,7 +318,7 @@ pub async fn update_presentation_in_db(
.unwrap_or_default(); .unwrap_or_default();
let html = presentation.kind == PresKind::Html; let html = presentation.kind == PresKind::Html;
let mut db = db.detach(); let mut db = db.detach();
let id = presentation.id.clone(); let id = presentation.id;
if let Err(e) = if let Err(e) =
query!("SELECT id FROM presentations where id = $1", id) query!("SELECT id FROM presentations where id = $1", id)
.fetch_one(&mut db) .fetch_one(&mut db)

View file

@ -12,7 +12,7 @@ use crate::Slide;
use super::images::Image; use super::images::Image;
use super::presentations::Presentation; use super::presentations::Presentation;
use super::songs::{lisp_to_song, Song}; use super::songs::{Song, lisp_to_song};
use super::videos::Video; use super::videos::Video;
use super::kinds::ServiceItemKind; use super::kinds::ServiceItemKind;

View file

@ -2,7 +2,7 @@ use cosmic::widget::image::Handle;
// use cosmic::dialog::ashpd::url::Url; // use cosmic::dialog::ashpd::url::Url;
use crisp::types::{Keyword, Symbol, Value}; use crisp::types::{Keyword, Symbol, Value};
use iced_video_player::Video; use iced_video_player::Video;
use miette::{miette, Result}; use miette::{Result, miette};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
fmt::Display, fmt::Display,

View file

@ -1,15 +1,15 @@
use std::{collections::HashMap, option::Option, path::PathBuf}; use std::{collections::HashMap, option::Option, path::PathBuf};
use crisp::types::{Keyword, Symbol, Value}; use crisp::types::{Keyword, Symbol, Value};
use miette::{miette, IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result, miette};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{ use sqlx::{
pool::PoolConnection, query, sqlite::SqliteRow, Acquire, FromRow, Acquire, FromRow, Row, Sqlite, SqliteConnection, SqlitePool,
Row, Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection, query, sqlite::SqliteRow,
}; };
use tracing::error; use tracing::error;
use crate::{core::slide, Slide, SlideBuilder}; use crate::{Slide, SlideBuilder, core::slide};
use super::{ use super::{
content::Content, content::Content,

View file

@ -11,8 +11,8 @@ use crisp::types::{Keyword, Symbol, Value};
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{ use sqlx::{
pool::PoolConnection, query, query_as, Sqlite, SqliteConnection, Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
SqlitePool, query, query_as,
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tracing::{debug, error}; use tracing::{debug, error};
@ -246,7 +246,7 @@ pub async fn update_video_in_db(
.map(std::string::ToString::to_string) .map(std::string::ToString::to_string)
.unwrap_or_default(); .unwrap_or_default();
let mut db = db.detach(); let mut db = db.detach();
let id = video.id.clone(); let id = video.id;
if let Err(e) = query!("SELECT id FROM videos where id = $1", id) if let Err(e) = query!("SELECT id FROM videos where id = $1", id)
.fetch_one(&mut db) .fetch_one(&mut db)
.await .await

View file

@ -40,11 +40,11 @@ mod test {
use std::{fs::read_to_string, path::PathBuf}; use std::{fs::read_to_string, path::PathBuf};
use crate::{ use crate::{
Background, TextAlignment,
core::{ core::{
images::Image, kinds::ServiceItemKind, images::Image, kinds::ServiceItemKind,
service_items::ServiceTrait, songs::Song, videos::Video, service_items::ServiceTrait, songs::Song, videos::Video,
}, },
Background, TextAlignment,
}; };
use super::*; use super::*;

View file

@ -1,4 +1,4 @@
use clap::{command, Parser}; use clap::{Parser, command};
use core::service_items::ServiceItem; use core::service_items::ServiceItem;
use core::slide::{ use core::slide::{
Background, BackgroundKind, Slide, SlideBuilder, TextAlignment, Background, BackgroundKind, Slide, SlideBuilder, TextAlignment,
@ -9,8 +9,8 @@ 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::{Mode, Position};
use cosmic::iced::{ use cosmic::iced::{
self, event, window, Background as IcedBackground, Border, Color, self, Background as IcedBackground, Border, Color, Length, event,
Length, window,
}; };
use cosmic::iced_core::text::Wrapping; use cosmic::iced_core::text::Wrapping;
use cosmic::iced_futures::Subscription; use cosmic::iced_futures::Subscription;
@ -21,18 +21,18 @@ 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::tooltip::Position as TPosition; use cosmic::widget::tooltip::Position as TPosition;
use cosmic::widget::{Container, menu};
use cosmic::widget::{ use cosmic::widget::{
button, context_menu, horizontal_space, mouse_area, nav_bar, Space, button, context_menu, horizontal_space, mouse_area,
nav_bar_toggle, responsive, scrollable, search_input, tooltip, nav_bar, nav_bar_toggle, responsive, scrollable, search_input,
vertical_space, Space, tooltip, vertical_space,
}; };
use cosmic::widget::{container, text}; use cosmic::widget::{container, text};
use cosmic::widget::{icon, slider}; use cosmic::widget::{icon, slider};
use cosmic::widget::{menu, Container}; use cosmic::{Application, ApplicationExt, Element, executor};
use cosmic::{executor, Application, ApplicationExt, Element};
use crisp::types::Value; use crisp::types::Value;
use lisp::parse_lisp; use lisp::parse_lisp;
use miette::{miette, Result}; use miette::{Result, miette};
use rayon::prelude::*; use rayon::prelude::*;
use resvg::usvg::fontdb; use resvg::usvg::fontdb;
use std::collections::HashMap; use std::collections::HashMap;
@ -42,10 +42,10 @@ use std::sync::Arc;
use tracing::{debug, level_filters::LevelFilter}; use tracing::{debug, level_filters::LevelFilter};
use tracing::{error, warn}; use tracing::{error, warn};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use ui::EditorMode;
use ui::library::{self, Library}; use ui::library::{self, Library};
use ui::presenter::{self, Presenter}; use ui::presenter::{self, Presenter};
use ui::song_editor::{self, SongEditor}; use ui::song_editor::{self, SongEditor};
use ui::EditorMode;
use crate::core::kinds::ServiceItemKind; use crate::core::kinds::ServiceItemKind;
use crate::ui::image_editor::{self, ImageEditor}; use crate::ui::image_editor::{self, ImageEditor};
@ -765,7 +765,7 @@ impl cosmic::Application for App {
}) })
} }
song_editor::Action::UpdateSong(song) => { song_editor::Action::UpdateSong(song) => {
if let Some(_) = &mut self.library { if self.library.is_some() {
self.update(Message::Library( self.update(Message::Library(
library::Message::UpdateSong(song), library::Message::UpdateSong(song),
)) ))
@ -786,7 +786,7 @@ impl cosmic::Application for App {
}) })
} }
image_editor::Action::UpdateImage(image) => { image_editor::Action::UpdateImage(image) => {
if let Some(_) = &mut self.library { if self.library.is_some() {
self.update(Message::Library( self.update(Message::Library(
library::Message::UpdateImage(image), library::Message::UpdateImage(image),
)) ))
@ -807,7 +807,7 @@ impl cosmic::Application for App {
}) })
} }
video_editor::Action::UpdateVideo(video) => { video_editor::Action::UpdateVideo(video) => {
if let Some(_) = &mut self.library { if self.library.is_some() {
self.update(Message::Library( self.update(Message::Library(
library::Message::UpdateVideo(video), library::Message::UpdateVideo(video),
)) ))
@ -1732,8 +1732,7 @@ where
moved_item_overlay: Color::from( moved_item_overlay: Color::from(
t.cosmic().primary.base, t.cosmic().primary.base,
) )
.scale_alpha(0.2) .scale_alpha(0.2),
.into(),
ghost_border: Border { ghost_border: Border {
width: 1.0, width: 1.0,
color: t.cosmic().secondary.base.into(), color: t.cosmic().secondary.base.into(),

View file

@ -2,15 +2,15 @@ use std::{io, path::PathBuf};
use crate::core::images::Image; use crate::core::images::Image;
use cosmic::{ use cosmic::{
dialog::file_chooser::{open::Dialog, FileFilter}, Element, Task,
iced::{alignment::Vertical, Length}, dialog::file_chooser::{FileFilter, open::Dialog},
iced::{Length, alignment::Vertical},
iced_widget::{column, row}, iced_widget::{column, row},
theme, theme,
widget::{ widget::{
self, button, container, horizontal_space, icon, text, self, Space, button, container, horizontal_space, icon, text,
text_input, Space, text_input,
}, },
Element, Task,
}; };
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
@ -73,8 +73,7 @@ impl ImageEditor {
.image .image
.as_ref() .as_ref()
.map(|v| v.id) .map(|v| v.id)
.unwrap_or_default() .unwrap_or_default();
.clone();
let task = Task::perform( let task = Task::perform(
pick_image(), pick_image(),
move |image_result| { move |image_result| {

View file

@ -4,8 +4,7 @@ use cosmic::{
dialog::file_chooser::open::Dialog, dialog::file_chooser::open::Dialog,
iced::{ iced::{
alignment::Vertical, clipboard::dnd::DndAction, alignment::Vertical, clipboard::dnd::DndAction,
futures::FutureExt, keyboard::Modifiers, Background, Border, keyboard::Modifiers, Background, Border, Color, Length,
Color, Length,
}, },
iced_core::widget::tree::State, iced_core::widget::tree::State,
iced_widget::{column, row as rowm, text as textm}, iced_widget::{column, row as rowm, text as textm},
@ -19,7 +18,7 @@ use cosmic::{
}, },
Element, Task, Element, Task,
}; };
use miette::{miette, IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use rapidfuzz::distance::levenshtein; use rapidfuzz::distance::levenshtein;
use sqlx::{migrate, SqlitePool}; use sqlx::{migrate, SqlitePool};
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
@ -53,8 +52,8 @@ pub struct Library {
#[derive(Debug, Clone, Eq, PartialEq, Copy)] #[derive(Debug, Clone, Eq, PartialEq, Copy)]
enum MenuMessage { enum MenuMessage {
Delete((LibraryKind, i32)), Delete,
Open, Open((LibraryKind, i32)),
} }
impl MenuAction for MenuMessage { impl MenuAction for MenuMessage {
@ -62,10 +61,10 @@ impl MenuAction for MenuMessage {
fn message(&self) -> Self::Message { fn message(&self) -> Self::Message {
match self { match self {
MenuMessage::Delete((kind, index)) => { MenuMessage::Delete => Message::DeleteItem,
Message::DeleteItem((*kind, *index)) MenuMessage::Open((kind, index)) => {
Message::OpenItem(Some((*kind, *index)))
} }
MenuMessage::Open => todo!(),
} }
} }
} }
@ -80,7 +79,7 @@ pub enum Action {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Message { pub enum Message {
AddItem, AddItem,
DeleteItem((LibraryKind, i32)), DeleteItem,
OpenItem(Option<(LibraryKind, i32)>), OpenItem(Option<(LibraryKind, i32)>),
HoverLibrary(Option<LibraryKind>), HoverLibrary(Option<LibraryKind>),
OpenLibrary(Option<LibraryKind>), OpenLibrary(Option<LibraryKind>),
@ -135,7 +134,7 @@ impl<'a> Library {
pub fn update(&'a mut self, message: Message) -> Action { pub fn update(&'a mut self, message: Message) -> Action {
match message { match message {
Message::None => (), Message::None => (),
Message::DeleteItem((kind, index)) => { Message::DeleteItem => {
return self.delete_items(); return self.delete_items();
} }
Message::AddItem => { Message::AddItem => {
@ -156,13 +155,13 @@ impl<'a> Library {
LibraryKind::Video => { LibraryKind::Video => {
return Action::Task(Task::perform( return Action::Task(Task::perform(
add_videos(), add_videos(),
|videos| Message::AddVideos(videos), Message::AddVideos,
)); ));
} }
LibraryKind::Image => { LibraryKind::Image => {
return Action::Task(Task::perform( return Action::Task(Task::perform(
add_images(), add_images(),
|images| Message::AddImages(images), Message::AddImages,
)); ));
} }
LibraryKind::Presentation => { LibraryKind::Presentation => {
@ -185,6 +184,7 @@ impl<'a> Library {
return self.update(Message::OpenItem(item)); return self.update(Message::OpenItem(item));
} }
Message::AddVideos(videos) => { Message::AddVideos(videos) => {
debug!(?videos);
if let Some(videos) = videos { if let Some(videos) = videos {
for video in videos { for video in videos {
if let Err(e) = if let Err(e) =
@ -248,13 +248,12 @@ impl<'a> Library {
let Some(first_item) = self let Some(first_item) = self
.selected_items .selected_items
.as_ref() .as_ref()
.map(|items| { .and_then(|items| {
items items
.iter() .iter()
.next() .next()
.map(|(_, index)| index) .map(|(_, index)| index)
}) })
.flatten()
else { else {
let Some(item) = item else { let Some(item) = item else {
return Action::None; return Action::None;
@ -270,9 +269,9 @@ impl<'a> Library {
self.selected_items = self self.selected_items = self
.selected_items .selected_items
.clone() .clone()
.and_then(|mut items| { .map(|mut items| {
items.push((kind, id)); items.push((kind, id));
Some(items) items
}); });
} }
} else if first_item > &index { } else if first_item > &index {
@ -280,9 +279,9 @@ impl<'a> Library {
self.selected_items = self self.selected_items = self
.selected_items .selected_items
.clone() .clone()
.and_then(|mut items| { .map(|mut items| {
items.push((kind, id)); items.push((kind, id));
Some(items) items
}); });
} }
} }
@ -605,7 +604,10 @@ impl<'a> Library {
if let Some(context_id) = self.context_menu { if let Some(context_id) = self.context_menu {
if index == context_id as usize { if index == context_id as usize {
let menu_items = vec![menu::Item::Button("Delete", None, MenuMessage::Delete((model.kind, index as i32)))]; let menu_items = vec![
menu::Item::Button("Open", None, MenuMessage::Open((model.kind, index as i32))),
menu::Item::Button("Delete", None, MenuMessage::Delete)
];
let context_menu = context_menu( let context_menu = context_menu(
mouse_area, mouse_area,
self.context_menu.map_or_else(|| None, |_| { self.context_menu.map_or_else(|| None, |_| {
@ -685,11 +687,11 @@ impl<'a> Library {
"text/org".into(), "text/org".into(),
], ],
) )
.on_enter(|x, y, mimes| { .on_enter(|_, _, mimes| {
warn!(?mimes); warn!(?mimes);
Message::None Message::None
}) })
.on_finish(|mime, data, action, x, y| { .on_finish(|mime, data, action, _, _| {
warn!(?mime, ?data, ?action); warn!(?mime, ?data, ?action);
Message::None Message::None
}); });
@ -893,22 +895,22 @@ impl<'a> Library {
return Action::None; return Action::None;
}; };
items.sort_by(|(_, index), (_, other)| index.cmp(other)); items.sort_by(|(_, index), (_, other)| index.cmp(other));
let tasks: Vec<Task<Message>> = items let tasks: Vec<Task<Message>> =
.iter() items
.rev() .iter()
.map(|(kind, index)| match kind { .rev()
LibraryKind::Song => { .map(|(kind, index)| match kind {
if let Some(song) = LibraryKind::Song => {
self.song_library.get_item(*index) if let Some(song) =
{ self.song_library.get_item(*index)
let song = song.clone();
if let Err(e) =
self.song_library.remove_item(*index)
{ {
error!(?e); let song = song.clone();
Task::none() if let Err(e) =
} else { self.song_library.remove_item(*index)
let task = {
error!(?e);
Task::none()
} else {
Task::future(self.db.acquire()) Task::future(self.db.acquire())
.and_then(move |db| { .and_then(move |db| {
Task::perform( Task::perform(
@ -916,34 +918,29 @@ impl<'a> Library {
db, song.id, db, song.id,
), ),
|r| { |r| {
match r { if let Err(e) = r {
Err(e) => { error!(?e)
error!(?e)
}
_ => (),
} }
Message::None Message::None
}, },
) )
}); })
task }
}
} else {
Task::none()
}
}
LibraryKind::Video => {
if let Some(video) =
self.video_library.get_item(*index)
{
let video = video.clone();
if let Err(e) =
self.video_library.remove_item(*index)
{
error!(?e);
Task::none()
} else { } else {
let task = Task::none()
}
}
LibraryKind::Video => {
if let Some(video) =
self.video_library.get_item(*index)
{
let video = video.clone();
if let Err(e) =
self.video_library.remove_item(*index)
{
error!(?e);
Task::none()
} else {
Task::future(self.db.acquire()) Task::future(self.db.acquire())
.and_then(move |db| { .and_then(move |db| {
Task::perform( Task::perform(
@ -951,34 +948,29 @@ impl<'a> Library {
db, video.id, db, video.id,
), ),
|r| { |r| {
match r { if let Err(e) = r {
Err(e) => { error!(?e)
error!(?e)
}
_ => (),
} }
Message::None Message::None
}, },
) )
}); })
task }
}
} else {
Task::none()
}
}
LibraryKind::Image => {
if let Some(image) =
self.image_library.get_item(*index)
{
let image = image.clone();
if let Err(e) =
self.image_library.remove_item(*index)
{
error!(?e);
Task::none()
} else { } else {
let task = Task::none()
}
}
LibraryKind::Image => {
if let Some(image) =
self.image_library.get_item(*index)
{
let image = image.clone();
if let Err(e) =
self.image_library.remove_item(*index)
{
error!(?e);
Task::none()
} else {
Task::future(self.db.acquire()) Task::future(self.db.acquire())
.and_then(move |db| { .and_then(move |db| {
Task::perform( Task::perform(
@ -986,35 +978,30 @@ impl<'a> Library {
db, image.id, db, image.id,
), ),
|r| { |r| {
match r { if let Err(e) = r {
Err(e) => { error!(?e)
error!(?e)
}
_ => (),
} }
Message::None Message::None
}, },
) )
}); })
task }
}
} else {
Task::none()
}
}
LibraryKind::Presentation => {
if let Some(presentation) =
self.presentation_library.get_item(*index)
{
let presentation = presentation.clone();
if let Err(e) = self
.presentation_library
.remove_item(*index)
{
error!(?e);
Task::none()
} else { } else {
let task = Task::none()
}
}
LibraryKind::Presentation => {
if let Some(presentation) =
self.presentation_library.get_item(*index)
{
let presentation = presentation.clone();
if let Err(e) = self
.presentation_library
.remove_item(*index)
{
error!(?e);
Task::none()
} else {
Task::future(self.db.acquire()) Task::future(self.db.acquire())
.and_then(move |db| { .and_then(move |db| {
Task::perform( Task::perform(
@ -1023,25 +1010,21 @@ impl<'a> Library {
presentation.id, presentation.id,
), ),
|r| { |r| {
match r { if let Err(e) = r {
Err(e) => { error!(?e)
error!(?e)
}
_ => (),
} }
Message::None Message::None
}, },
) )
}); })
task }
} else {
Task::none()
} }
} else {
Task::none()
} }
} })
}) .collect();
.collect(); if !tasks.is_empty() {
if tasks.len() > 0 {
self.selected_items = None; self.selected_items = None;
} }
Action::Task(Task::batch(tasks)) Action::Task(Task::batch(tasks))

View file

@ -5,15 +5,15 @@ use crate::core::{
slide::Slide, slide::Slide,
}; };
use cosmic::{ use cosmic::{
dialog::file_chooser::{open::Dialog, FileFilter}, Element, Task,
iced::{alignment::Vertical, Length}, dialog::file_chooser::{FileFilter, open::Dialog},
iced::{Length, alignment::Vertical},
iced_widget::{column, row}, iced_widget::{column, row},
theme, theme,
widget::{ widget::{
self, button, container, horizontal_space, icon, text, Space, button, container, horizontal_space, icon, text,
text_input, Space, text_input,
}, },
Element, Task,
}; };
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
@ -83,8 +83,7 @@ impl PresentationEditor {
.presentation .presentation
.as_ref() .as_ref()
.map(|v| v.id) .map(|v| v.id)
.unwrap_or_default() .unwrap_or_default();
.clone();
let task = Task::perform( let task = Task::perform(
pick_presentation(), pick_presentation(),
move |presentation_result| { move |presentation_result| {

View file

@ -7,37 +7,36 @@ use std::{
}; };
use cosmic::{ use cosmic::{
Task,
iced::{ iced::{
font::{Family, Stretch, Style, Weight},
Background, Border, Color, ContentFit, Font, Length, Shadow, Background, Border, Color, ContentFit, Font, Length, Shadow,
Vector, Vector,
font::{Family, Stretch, Style, Weight},
}, },
iced_widget::{ iced_widget::{
scrollable::{ scrollable::{
scroll_to, AbsoluteOffset, Direction, Scrollbar, AbsoluteOffset, Direction, Scrollbar, scroll_to,
}, },
stack, vertical_rule, stack, vertical_rule,
}, },
prelude::*, prelude::*,
widget::{ widget::{
container, image, mouse_area, responsive, scrollable, text, Container, Id, Row, Space, container, image, mouse_area,
Container, Id, Row, Space, responsive, scrollable, text,
}, },
Task,
}; };
use iced_video_player::{gst_pbutils, Position, Video, VideoPlayer}; use iced_video_player::{Position, Video, VideoPlayer, gst_pbutils};
use rodio::{Decoder, OutputStream, OutputStreamBuilder, Sink}; use rodio::{Decoder, OutputStream, OutputStreamBuilder, Sink};
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
use url::Url; use url::Url;
use crate::{ use crate::{
core::{service_items::ServiceItem, slide::Slide},
BackgroundKind, BackgroundKind,
core::{service_items::ServiceItem, slide::Slide},
}; };
const REFERENCE_WIDTH: f32 = 1920.0; const REFERENCE_WIDTH: f32 = 1920.0;
static DEFAULT_SLIDE: LazyLock<Slide> = static DEFAULT_SLIDE: LazyLock<Slide> = LazyLock::new(Slide::default);
LazyLock::new(|| Slide::default());
// #[derive(Default, Clone, Debug)] // #[derive(Default, Clone, Debug)]
pub(crate) struct Presenter { pub(crate) struct Presenter {
@ -155,11 +154,12 @@ impl Presenter {
items.iter().fold(0, |a, item| a + item.slides.len()); items.iter().fold(0, |a, item| a + item.slides.len());
let slide = let slide =
items.get(0).map(|item| item.slides.get(0)).flatten(); items.first().and_then(|item| item.slides.first());
let audio = items let audio = items
.get(0) .first()
.map(|item| item.slides.get(0).map(|slide| slide.audio())) .and_then(|item| {
.flatten() item.slides.first().map(|slide| slide.audio())
})
.flatten(); .flatten();
Self { Self {
@ -179,7 +179,7 @@ impl Presenter {
.expect("Can't open default rodio stream"); .expect("Can't open default rodio stream");
( (
Arc::new(Sink::connect_new( Arc::new(Sink::connect_new(
&stream_handle.mixer(), stream_handle.mixer(),
)), )),
stream_handle, stream_handle,
) )
@ -219,8 +219,7 @@ impl Presenter {
if let Some(slide) = self if let Some(slide) = self
.service .service
.get(item_index) .get(item_index)
.map(|item| item.slides.get(slide_index)) .and_then(|item| item.slides.get(slide_index))
.flatten()
{ {
self.current_item = item_index; self.current_item = item_index;
self.current_slide_index = slide_index; self.current_slide_index = slide_index;
@ -473,7 +472,7 @@ impl Presenter {
); );
let container = slide_view( let container = slide_view(
&slide, slide,
&self.video, &self.video,
true, true,
false, false,

View file

@ -2,16 +2,16 @@ use cosmic::iced::Size;
use cosmic::iced_core::widget::tree; use cosmic::iced_core::widget::tree;
use cosmic::{ use cosmic::{
Element,
iced::{ iced::{
Event, Length, Point, Rectangle, Vector,
clipboard::dnd::{DndEvent, SourceEvent}, clipboard::dnd::{DndEvent, SourceEvent},
event, mouse, Event, Length, Point, Rectangle, Vector, event, mouse,
}, },
iced_core::{ iced_core::{
self, image::Renderer, layout, renderer, widget::Tree, self, Clipboard, Shell, layout, renderer, widget::Tree,
Clipboard, Shell,
}, },
widget::Widget, widget::Widget,
Element,
}; };
use tracing::debug; use tracing::debug;
@ -196,27 +196,23 @@ impl<Message: Clone + 'static>
// We ignore motion if we do not possess drag content by now. // We ignore motion if we do not possess drag content by now.
if let Some(left_pressed_position) = if let Some(left_pressed_position) =
state.left_pressed_position state.left_pressed_position
{ && position
if position
.distance(left_pressed_position) .distance(left_pressed_position)
> self.drag_threshold > self.drag_threshold
{
if let Some(on_start) =
self.on_start.as_ref()
{ {
if let Some(on_start) = shell.publish(on_start.clone())
self.on_start.as_ref()
{
shell
.publish(on_start.clone())
}
let offset = Vector::new(
left_pressed_position.x
- layout.bounds().x,
left_pressed_position.y
- layout.bounds().y,
);
state.is_dragging = true;
state.left_pressed_position =
None;
} }
let offset = Vector::new(
left_pressed_position.x
- layout.bounds().x,
left_pressed_position.y
- layout.bounds().y,
);
state.is_dragging = true;
state.left_pressed_position = None;
} }
if !cursor.is_over(layout.bounds()) { if !cursor.is_over(layout.bounds()) {
state.hovered = false; state.hovered = false;

View file

@ -1,13 +1,13 @@
use std::{io, path::PathBuf}; use std::{io, path::PathBuf};
use cosmic::{ use cosmic::{
Renderer,
iced::{Color, Font, Length, Size}, iced::{Color, Font, Length, Size},
widget::{ widget::{
self, self,
canvas::{self, Program, Stroke}, canvas::{self, Program, Stroke},
container, container,
}, },
Renderer,
}; };
use tracing::debug; use tracing::debug;

View file

@ -1,8 +1,9 @@
use std::{io, path::PathBuf, sync::Arc}; use std::{io, path::PathBuf, sync::Arc};
use cosmic::{ use cosmic::{
dialog::file_chooser::{open::Dialog, FileFilter}, Element, Task,
iced::{alignment::Vertical, Length}, dialog::file_chooser::{FileFilter, open::Dialog},
iced::{Length, alignment::Vertical},
iced_wgpu::graphics::text::cosmic_text::fontdb, iced_wgpu::graphics::text::cosmic_text::fontdb,
iced_widget::{column, row}, iced_widget::{column, row},
theme, theme,
@ -10,7 +11,6 @@ use cosmic::{
button, combo_box, container, horizontal_space, icon, button, combo_box, container, horizontal_space, icon,
progress_bar, scrollable, text, text_editor, text_input, progress_bar, scrollable, text, text_editor, text_input,
}, },
Element, Task,
}; };
use dirs::font_dir; use dirs::font_dir;
use iced_video_player::Video; use iced_video_player::Video;
@ -18,11 +18,11 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
use tracing::{debug, error}; use tracing::{debug, error};
use crate::{ use crate::{
Background, BackgroundKind,
core::{service_items::ServiceTrait, slide::Slide, songs::Song}, core::{service_items::ServiceTrait, slide::Slide, songs::Song},
ui::{ ui::{
presenter::slide_view, slide_editor::SlideEditor, text_svg, presenter::slide_view, slide_editor::SlideEditor, text_svg,
}, },
Background, BackgroundKind,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -308,12 +308,12 @@ impl SongEditor {
fn slide_preview(&self) -> Element<Message> { fn slide_preview(&self) -> Element<Message> {
if let Some(slides) = &self.song_slides { if let Some(slides) = &self.song_slides {
let slides: Vec<Element<Message>> = slides let slides: Vec<Element<Message>> = slides
.into_iter() .iter()
.enumerate() .enumerate()
.map(|(index, slide)| { .map(|(index, slide)| {
container( container(
slide_view( slide_view(
&slide, slide,
if index == 0 { if index == 0 {
&self.video &self.video
} else { } else {

View file

@ -8,16 +8,16 @@ use std::{
use colors_transform::Rgb; use colors_transform::Rgb;
use cosmic::{ use cosmic::{
iced::{ iced::{
font::{Style, Weight},
ContentFit, Length, Size, ContentFit, Length, Size,
font::{Style, Weight},
}, },
prelude::*, prelude::*,
widget::{image::Handle, Image}, widget::{Image, image::Handle},
}; };
use rapidhash::v3::rapidhash_v3; use rapidhash::v3::rapidhash_v3;
use resvg::{ use resvg::{
tiny_skia::{self, Pixmap}, tiny_skia::{self, Pixmap},
usvg::{fontdb, Tree}, usvg::{Tree, fontdb},
}; };
use tracing::{debug, error}; use tracing::{debug, error};

View file

@ -1,15 +1,15 @@
use std::{io, path::PathBuf}; use std::{io, path::PathBuf};
use cosmic::{ use cosmic::{
dialog::file_chooser::{open::Dialog, FileFilter}, Element, Task,
iced::{alignment::Vertical, Length}, dialog::file_chooser::{FileFilter, open::Dialog},
iced::{Length, alignment::Vertical},
iced_widget::{column, row}, iced_widget::{column, row},
theme, theme,
widget::{ widget::{
button, container, horizontal_space, icon, progress_bar, Space, button, container, horizontal_space, icon,
text, text_input, Space, progress_bar, text, text_input,
}, },
Element, Task,
}; };
use iced_video_player::{Video, VideoPlayer}; use iced_video_player::{Video, VideoPlayer};
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
@ -94,8 +94,7 @@ impl VideoEditor {
.core_video .core_video
.as_ref() .as_ref()
.map(|v| v.id) .map(|v| v.id)
.unwrap_or_default() .unwrap_or_default();
.clone();
let task = Task::perform( let task = Task::perform(
pick_video(), pick_video(),
move |video_result| { move |video_result| {

View file

@ -22,17 +22,17 @@
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
use cosmic::Theme;
use cosmic::iced::advanced::layout::{self, Layout}; use cosmic::iced::advanced::layout::{self, Layout};
use cosmic::iced::advanced::widget::{tree, Operation, Tree, Widget}; use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
use cosmic::iced::advanced::{overlay, renderer, Clipboard, Shell}; 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::{self, Event};
use cosmic::iced::{self, mouse, Transformation}; 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,
Point, Rectangle, Size, Vector, Point, Rectangle, Size, Vector,
}; };
use cosmic::Theme;
use super::{Action, DragEvent, DropPosition}; use super::{Action, DragEvent, DropPosition};
@ -468,26 +468,21 @@ where
Action::Picking { index, origin } => { Action::Picking { index, origin } => {
if let Some(cursor_position) = if let Some(cursor_position) =
cursor.position() cursor.position()
{ && cursor_position.distance(origin)
if cursor_position.distance(origin)
> self.deadband_zone > self.deadband_zone
{ {
// Start dragging // Start dragging
*action = Action::Dragging { *action = Action::Dragging {
index, index,
origin, origin,
last_cursor: cursor_position, last_cursor: cursor_position,
}; };
if let Some(on_reorder) = if let Some(on_reorder) = &self.on_drag {
&self.on_drag shell.publish(on_reorder(
{ DragEvent::Picked { index },
shell.publish(on_reorder( ));
DragEvent::Picked { index },
));
}
event_status =
event::Status::Captured;
} }
event_status = event::Status::Captured;
} }
} }
Action::Dragging { origin, index, .. } => { Action::Dragging { origin, index, .. } => {
@ -903,8 +898,7 @@ pub fn default(theme: &Theme) -> Style {
Style { Style {
scale: 1.05, scale: 1.05,
moved_item_overlay: Color::from(theme.cosmic().primary.base) moved_item_overlay: Color::from(theme.cosmic().primary.base)
.scale_alpha(0.2) .scale_alpha(0.2),
.into(),
ghost_border: Border { ghost_border: Border {
width: 1.0, width: 1.0,
color: theme.cosmic().secondary.base.into(), color: theme.cosmic().secondary.base.into(),

View file

@ -23,11 +23,11 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
use cosmic::iced::advanced::layout::{self, Layout}; use cosmic::iced::advanced::layout::{self, Layout};
use cosmic::iced::advanced::widget::{tree, Operation, Tree, Widget}; use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
use cosmic::iced::advanced::{overlay, renderer, Clipboard, Shell}; 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::{self, Event};
use cosmic::iced::{self, mouse, Transformation}; 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,
Point, Rectangle, Size, Theme, Vector, Point, Rectangle, Size, Theme, Vector,
@ -454,26 +454,21 @@ where
Action::Picking { index, origin } => { Action::Picking { index, origin } => {
if let Some(cursor_position) = if let Some(cursor_position) =
cursor.position() cursor.position()
{ && cursor_position.distance(origin)
if cursor_position.distance(origin)
> self.deadband_zone > self.deadband_zone
{ {
// Start dragging // Start dragging
*action = Action::Dragging { *action = Action::Dragging {
index, index,
origin, origin,
last_cursor: cursor_position, last_cursor: cursor_position,
}; };
if let Some(on_reorder) = if let Some(on_reorder) = &self.on_drag {
&self.on_drag shell.publish(on_reorder(
{ DragEvent::Picked { index },
shell.publish(on_reorder( ));
DragEvent::Picked { index },
));
}
event_status =
event::Status::Captured;
} }
event_status = event::Status::Captured;
} }
} }
Action::Dragging { origin, index, .. } => { Action::Dragging { origin, index, .. } => {