Compare commits
2 commits
3b1a0c4207
...
761006f516
| Author | SHA1 | Date | |
|---|---|---|---|
| 761006f516 | |||
| 46abd9dd7a |
20 changed files with 228 additions and 265 deletions
|
|
@ -10,8 +10,8 @@ use crisp::types::{Keyword, Symbol, Value};
|
|||
use miette::{IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
pool::PoolConnection, query, query_as, Sqlite, SqliteConnection,
|
||||
SqlitePool,
|
||||
Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
|
||||
query, query_as,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::{debug, error};
|
||||
|
|
@ -211,7 +211,7 @@ pub async fn update_image_in_db(
|
|||
.map(std::string::ToString::to_string)
|
||||
.unwrap_or_default();
|
||||
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)
|
||||
.fetch_one(&mut db)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::mem::replace;
|
||||
|
||||
use miette::{miette, Result};
|
||||
use miette::{Result, miette};
|
||||
use sqlx::{Connection, SqliteConnection};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use miette::{IntoDiagnostic, Result};
|
|||
use mupdf::{Colorspace, Document, Matrix};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
pool::PoolConnection, prelude::FromRow, query, sqlite::SqliteRow,
|
||||
Row, Sqlite, SqliteConnection, SqlitePool,
|
||||
Row, Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
|
||||
prelude::FromRow, query, sqlite::SqliteRow,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::{debug, error};
|
||||
|
|
@ -318,7 +318,7 @@ pub async fn update_presentation_in_db(
|
|||
.unwrap_or_default();
|
||||
let html = presentation.kind == PresKind::Html;
|
||||
let mut db = db.detach();
|
||||
let id = presentation.id.clone();
|
||||
let id = presentation.id;
|
||||
if let Err(e) =
|
||||
query!("SELECT id FROM presentations where id = $1", id)
|
||||
.fetch_one(&mut db)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::Slide;
|
|||
|
||||
use super::images::Image;
|
||||
use super::presentations::Presentation;
|
||||
use super::songs::{lisp_to_song, Song};
|
||||
use super::songs::{Song, lisp_to_song};
|
||||
use super::videos::Video;
|
||||
|
||||
use super::kinds::ServiceItemKind;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use cosmic::widget::image::Handle;
|
|||
// use cosmic::dialog::ashpd::url::Url;
|
||||
use crisp::types::{Keyword, Symbol, Value};
|
||||
use iced_video_player::Video;
|
||||
use miette::{miette, Result};
|
||||
use miette::{Result, miette};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::Display,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
use std::{collections::HashMap, option::Option, path::PathBuf};
|
||||
|
||||
use crisp::types::{Keyword, Symbol, Value};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use miette::{IntoDiagnostic, Result, miette};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
pool::PoolConnection, query, sqlite::SqliteRow, Acquire, FromRow,
|
||||
Row, Sqlite, SqliteConnection, SqlitePool,
|
||||
Acquire, FromRow, Row, Sqlite, SqliteConnection, SqlitePool,
|
||||
pool::PoolConnection, query, sqlite::SqliteRow,
|
||||
};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{core::slide, Slide, SlideBuilder};
|
||||
use crate::{Slide, SlideBuilder, core::slide};
|
||||
|
||||
use super::{
|
||||
content::Content,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ use crisp::types::{Keyword, Symbol, Value};
|
|||
use miette::{IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
pool::PoolConnection, query, query_as, Sqlite, SqliteConnection,
|
||||
SqlitePool,
|
||||
Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
|
||||
query, query_as,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::{debug, error};
|
||||
|
|
@ -246,7 +246,7 @@ pub async fn update_video_in_db(
|
|||
.map(std::string::ToString::to_string)
|
||||
.unwrap_or_default();
|
||||
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)
|
||||
.fetch_one(&mut db)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ mod test {
|
|||
use std::{fs::read_to_string, path::PathBuf};
|
||||
|
||||
use crate::{
|
||||
Background, TextAlignment,
|
||||
core::{
|
||||
images::Image, kinds::ServiceItemKind,
|
||||
service_items::ServiceTrait, songs::Song, videos::Video,
|
||||
},
|
||||
Background, TextAlignment,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
|
|
|||
29
src/main.rs
29
src/main.rs
|
|
@ -1,4 +1,4 @@
|
|||
use clap::{command, Parser};
|
||||
use clap::{Parser, command};
|
||||
use core::service_items::ServiceItem;
|
||||
use core::slide::{
|
||||
Background, BackgroundKind, Slide, SlideBuilder, TextAlignment,
|
||||
|
|
@ -9,8 +9,8 @@ use cosmic::iced::alignment::Vertical;
|
|||
use cosmic::iced::keyboard::{Key, Modifiers};
|
||||
use cosmic::iced::window::{Mode, Position};
|
||||
use cosmic::iced::{
|
||||
self, event, window, Background as IcedBackground, Border, Color,
|
||||
Length,
|
||||
self, Background as IcedBackground, Border, Color, Length, event,
|
||||
window,
|
||||
};
|
||||
use cosmic::iced_core::text::Wrapping;
|
||||
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::nav_bar::nav_bar_style;
|
||||
use cosmic::widget::tooltip::Position as TPosition;
|
||||
use cosmic::widget::{Container, menu};
|
||||
use cosmic::widget::{
|
||||
button, context_menu, horizontal_space, mouse_area, nav_bar,
|
||||
nav_bar_toggle, responsive, scrollable, search_input, tooltip,
|
||||
vertical_space, Space,
|
||||
Space, button, context_menu, horizontal_space, mouse_area,
|
||||
nav_bar, nav_bar_toggle, responsive, scrollable, search_input,
|
||||
tooltip, vertical_space,
|
||||
};
|
||||
use cosmic::widget::{container, text};
|
||||
use cosmic::widget::{icon, slider};
|
||||
use cosmic::widget::{menu, Container};
|
||||
use cosmic::{executor, Application, ApplicationExt, Element};
|
||||
use cosmic::{Application, ApplicationExt, Element, executor};
|
||||
use crisp::types::Value;
|
||||
use lisp::parse_lisp;
|
||||
use miette::{miette, Result};
|
||||
use miette::{Result, miette};
|
||||
use rayon::prelude::*;
|
||||
use resvg::usvg::fontdb;
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -42,10 +42,10 @@ use std::sync::Arc;
|
|||
use tracing::{debug, level_filters::LevelFilter};
|
||||
use tracing::{error, warn};
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use ui::EditorMode;
|
||||
use ui::library::{self, Library};
|
||||
use ui::presenter::{self, Presenter};
|
||||
use ui::song_editor::{self, SongEditor};
|
||||
use ui::EditorMode;
|
||||
|
||||
use crate::core::kinds::ServiceItemKind;
|
||||
use crate::ui::image_editor::{self, ImageEditor};
|
||||
|
|
@ -765,7 +765,7 @@ impl cosmic::Application for App {
|
|||
})
|
||||
}
|
||||
song_editor::Action::UpdateSong(song) => {
|
||||
if let Some(_) = &mut self.library {
|
||||
if self.library.is_some() {
|
||||
self.update(Message::Library(
|
||||
library::Message::UpdateSong(song),
|
||||
))
|
||||
|
|
@ -786,7 +786,7 @@ impl cosmic::Application for App {
|
|||
})
|
||||
}
|
||||
image_editor::Action::UpdateImage(image) => {
|
||||
if let Some(_) = &mut self.library {
|
||||
if self.library.is_some() {
|
||||
self.update(Message::Library(
|
||||
library::Message::UpdateImage(image),
|
||||
))
|
||||
|
|
@ -807,7 +807,7 @@ impl cosmic::Application for App {
|
|||
})
|
||||
}
|
||||
video_editor::Action::UpdateVideo(video) => {
|
||||
if let Some(_) = &mut self.library {
|
||||
if self.library.is_some() {
|
||||
self.update(Message::Library(
|
||||
library::Message::UpdateVideo(video),
|
||||
))
|
||||
|
|
@ -1732,8 +1732,7 @@ where
|
|||
moved_item_overlay: Color::from(
|
||||
t.cosmic().primary.base,
|
||||
)
|
||||
.scale_alpha(0.2)
|
||||
.into(),
|
||||
.scale_alpha(0.2),
|
||||
ghost_border: Border {
|
||||
width: 1.0,
|
||||
color: t.cosmic().secondary.base.into(),
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ use std::{io, path::PathBuf};
|
|||
|
||||
use crate::core::images::Image;
|
||||
use cosmic::{
|
||||
dialog::file_chooser::{open::Dialog, FileFilter},
|
||||
iced::{alignment::Vertical, Length},
|
||||
Element, Task,
|
||||
dialog::file_chooser::{FileFilter, open::Dialog},
|
||||
iced::{Length, alignment::Vertical},
|
||||
iced_widget::{column, row},
|
||||
theme,
|
||||
widget::{
|
||||
self, button, container, horizontal_space, icon, text,
|
||||
text_input, Space,
|
||||
self, Space, button, container, horizontal_space, icon, text,
|
||||
text_input,
|
||||
},
|
||||
Element, Task,
|
||||
};
|
||||
use tracing::{debug, error, warn};
|
||||
|
||||
|
|
@ -73,8 +73,7 @@ impl ImageEditor {
|
|||
.image
|
||||
.as_ref()
|
||||
.map(|v| v.id)
|
||||
.unwrap_or_default()
|
||||
.clone();
|
||||
.unwrap_or_default();
|
||||
let task = Task::perform(
|
||||
pick_image(),
|
||||
move |image_result| {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ use cosmic::{
|
|||
dialog::file_chooser::open::Dialog,
|
||||
iced::{
|
||||
alignment::Vertical, clipboard::dnd::DndAction,
|
||||
futures::FutureExt, keyboard::Modifiers, Background, Border,
|
||||
Color, Length,
|
||||
keyboard::Modifiers, Background, Border, Color, Length,
|
||||
},
|
||||
iced_core::widget::tree::State,
|
||||
iced_widget::{column, row as rowm, text as textm},
|
||||
|
|
@ -19,7 +18,7 @@ use cosmic::{
|
|||
},
|
||||
Element, Task,
|
||||
};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use miette::{IntoDiagnostic, Result};
|
||||
use rapidfuzz::distance::levenshtein;
|
||||
use sqlx::{migrate, SqlitePool};
|
||||
use tracing::{debug, error, warn};
|
||||
|
|
@ -53,8 +52,8 @@ pub struct Library {
|
|||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Copy)]
|
||||
enum MenuMessage {
|
||||
Delete((LibraryKind, i32)),
|
||||
Open,
|
||||
Delete,
|
||||
Open((LibraryKind, i32)),
|
||||
}
|
||||
|
||||
impl MenuAction for MenuMessage {
|
||||
|
|
@ -62,10 +61,10 @@ impl MenuAction for MenuMessage {
|
|||
|
||||
fn message(&self) -> Self::Message {
|
||||
match self {
|
||||
MenuMessage::Delete((kind, index)) => {
|
||||
Message::DeleteItem((*kind, *index))
|
||||
MenuMessage::Delete => Message::DeleteItem,
|
||||
MenuMessage::Open((kind, index)) => {
|
||||
Message::OpenItem(Some((*kind, *index)))
|
||||
}
|
||||
MenuMessage::Open => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +79,7 @@ pub enum Action {
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum Message {
|
||||
AddItem,
|
||||
DeleteItem((LibraryKind, i32)),
|
||||
DeleteItem,
|
||||
OpenItem(Option<(LibraryKind, i32)>),
|
||||
HoverLibrary(Option<LibraryKind>),
|
||||
OpenLibrary(Option<LibraryKind>),
|
||||
|
|
@ -135,7 +134,7 @@ impl<'a> Library {
|
|||
pub fn update(&'a mut self, message: Message) -> Action {
|
||||
match message {
|
||||
Message::None => (),
|
||||
Message::DeleteItem((kind, index)) => {
|
||||
Message::DeleteItem => {
|
||||
return self.delete_items();
|
||||
}
|
||||
Message::AddItem => {
|
||||
|
|
@ -156,13 +155,13 @@ impl<'a> Library {
|
|||
LibraryKind::Video => {
|
||||
return Action::Task(Task::perform(
|
||||
add_videos(),
|
||||
|videos| Message::AddVideos(videos),
|
||||
Message::AddVideos,
|
||||
));
|
||||
}
|
||||
LibraryKind::Image => {
|
||||
return Action::Task(Task::perform(
|
||||
add_images(),
|
||||
|images| Message::AddImages(images),
|
||||
Message::AddImages,
|
||||
));
|
||||
}
|
||||
LibraryKind::Presentation => {
|
||||
|
|
@ -185,6 +184,7 @@ impl<'a> Library {
|
|||
return self.update(Message::OpenItem(item));
|
||||
}
|
||||
Message::AddVideos(videos) => {
|
||||
debug!(?videos);
|
||||
if let Some(videos) = videos {
|
||||
for video in videos {
|
||||
if let Err(e) =
|
||||
|
|
@ -248,13 +248,12 @@ impl<'a> Library {
|
|||
let Some(first_item) = self
|
||||
.selected_items
|
||||
.as_ref()
|
||||
.map(|items| {
|
||||
.and_then(|items| {
|
||||
items
|
||||
.iter()
|
||||
.next()
|
||||
.map(|(_, index)| index)
|
||||
})
|
||||
.flatten()
|
||||
else {
|
||||
let Some(item) = item else {
|
||||
return Action::None;
|
||||
|
|
@ -270,9 +269,9 @@ impl<'a> Library {
|
|||
self.selected_items = self
|
||||
.selected_items
|
||||
.clone()
|
||||
.and_then(|mut items| {
|
||||
.map(|mut items| {
|
||||
items.push((kind, id));
|
||||
Some(items)
|
||||
items
|
||||
});
|
||||
}
|
||||
} else if first_item > &index {
|
||||
|
|
@ -280,9 +279,9 @@ impl<'a> Library {
|
|||
self.selected_items = self
|
||||
.selected_items
|
||||
.clone()
|
||||
.and_then(|mut items| {
|
||||
.map(|mut items| {
|
||||
items.push((kind, id));
|
||||
Some(items)
|
||||
items
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -605,7 +604,10 @@ impl<'a> Library {
|
|||
|
||||
if let Some(context_id) = self.context_menu {
|
||||
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(
|
||||
mouse_area,
|
||||
self.context_menu.map_or_else(|| None, |_| {
|
||||
|
|
@ -685,11 +687,11 @@ impl<'a> Library {
|
|||
"text/org".into(),
|
||||
],
|
||||
)
|
||||
.on_enter(|x, y, mimes| {
|
||||
.on_enter(|_, _, mimes| {
|
||||
warn!(?mimes);
|
||||
Message::None
|
||||
})
|
||||
.on_finish(|mime, data, action, x, y| {
|
||||
.on_finish(|mime, data, action, _, _| {
|
||||
warn!(?mime, ?data, ?action);
|
||||
Message::None
|
||||
});
|
||||
|
|
@ -893,7 +895,8 @@ impl<'a> Library {
|
|||
return Action::None;
|
||||
};
|
||||
items.sort_by(|(_, index), (_, other)| index.cmp(other));
|
||||
let tasks: Vec<Task<Message>> = items
|
||||
let tasks: Vec<Task<Message>> =
|
||||
items
|
||||
.iter()
|
||||
.rev()
|
||||
.map(|(kind, index)| match kind {
|
||||
|
|
@ -908,7 +911,6 @@ impl<'a> Library {
|
|||
error!(?e);
|
||||
Task::none()
|
||||
} else {
|
||||
let task =
|
||||
Task::future(self.db.acquire())
|
||||
.and_then(move |db| {
|
||||
Task::perform(
|
||||
|
|
@ -916,17 +918,13 @@ impl<'a> Library {
|
|||
db, song.id,
|
||||
),
|
||||
|r| {
|
||||
match r {
|
||||
Err(e) => {
|
||||
if let Err(e) = r {
|
||||
error!(?e)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Message::None
|
||||
},
|
||||
)
|
||||
});
|
||||
task
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Task::none()
|
||||
|
|
@ -943,7 +941,6 @@ impl<'a> Library {
|
|||
error!(?e);
|
||||
Task::none()
|
||||
} else {
|
||||
let task =
|
||||
Task::future(self.db.acquire())
|
||||
.and_then(move |db| {
|
||||
Task::perform(
|
||||
|
|
@ -951,17 +948,13 @@ impl<'a> Library {
|
|||
db, video.id,
|
||||
),
|
||||
|r| {
|
||||
match r {
|
||||
Err(e) => {
|
||||
if let Err(e) = r {
|
||||
error!(?e)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Message::None
|
||||
},
|
||||
)
|
||||
});
|
||||
task
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Task::none()
|
||||
|
|
@ -978,7 +971,6 @@ impl<'a> Library {
|
|||
error!(?e);
|
||||
Task::none()
|
||||
} else {
|
||||
let task =
|
||||
Task::future(self.db.acquire())
|
||||
.and_then(move |db| {
|
||||
Task::perform(
|
||||
|
|
@ -986,17 +978,13 @@ impl<'a> Library {
|
|||
db, image.id,
|
||||
),
|
||||
|r| {
|
||||
match r {
|
||||
Err(e) => {
|
||||
if let Err(e) = r {
|
||||
error!(?e)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Message::None
|
||||
},
|
||||
)
|
||||
});
|
||||
task
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Task::none()
|
||||
|
|
@ -1014,7 +1002,6 @@ impl<'a> Library {
|
|||
error!(?e);
|
||||
Task::none()
|
||||
} else {
|
||||
let task =
|
||||
Task::future(self.db.acquire())
|
||||
.and_then(move |db| {
|
||||
Task::perform(
|
||||
|
|
@ -1023,17 +1010,13 @@ impl<'a> Library {
|
|||
presentation.id,
|
||||
),
|
||||
|r| {
|
||||
match r {
|
||||
Err(e) => {
|
||||
if let Err(e) = r {
|
||||
error!(?e)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Message::None
|
||||
},
|
||||
)
|
||||
});
|
||||
task
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Task::none()
|
||||
|
|
@ -1041,7 +1024,7 @@ impl<'a> Library {
|
|||
}
|
||||
})
|
||||
.collect();
|
||||
if tasks.len() > 0 {
|
||||
if !tasks.is_empty() {
|
||||
self.selected_items = None;
|
||||
}
|
||||
Action::Task(Task::batch(tasks))
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@ use crate::core::{
|
|||
slide::Slide,
|
||||
};
|
||||
use cosmic::{
|
||||
dialog::file_chooser::{open::Dialog, FileFilter},
|
||||
iced::{alignment::Vertical, Length},
|
||||
Element, Task,
|
||||
dialog::file_chooser::{FileFilter, open::Dialog},
|
||||
iced::{Length, alignment::Vertical},
|
||||
iced_widget::{column, row},
|
||||
theme,
|
||||
widget::{
|
||||
self, button, container, horizontal_space, icon, text,
|
||||
text_input, Space,
|
||||
Space, button, container, horizontal_space, icon, text,
|
||||
text_input,
|
||||
},
|
||||
Element, Task,
|
||||
};
|
||||
use tracing::{debug, error, warn};
|
||||
|
||||
|
|
@ -83,8 +83,7 @@ impl PresentationEditor {
|
|||
.presentation
|
||||
.as_ref()
|
||||
.map(|v| v.id)
|
||||
.unwrap_or_default()
|
||||
.clone();
|
||||
.unwrap_or_default();
|
||||
let task = Task::perform(
|
||||
pick_presentation(),
|
||||
move |presentation_result| {
|
||||
|
|
|
|||
|
|
@ -7,37 +7,36 @@ use std::{
|
|||
};
|
||||
|
||||
use cosmic::{
|
||||
Task,
|
||||
iced::{
|
||||
font::{Family, Stretch, Style, Weight},
|
||||
Background, Border, Color, ContentFit, Font, Length, Shadow,
|
||||
Vector,
|
||||
font::{Family, Stretch, Style, Weight},
|
||||
},
|
||||
iced_widget::{
|
||||
scrollable::{
|
||||
scroll_to, AbsoluteOffset, Direction, Scrollbar,
|
||||
AbsoluteOffset, Direction, Scrollbar, scroll_to,
|
||||
},
|
||||
stack, vertical_rule,
|
||||
},
|
||||
prelude::*,
|
||||
widget::{
|
||||
container, image, mouse_area, responsive, scrollable, text,
|
||||
Container, Id, Row, Space,
|
||||
Container, Id, Row, Space, container, image, mouse_area,
|
||||
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 tracing::{debug, error, info, warn};
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
core::{service_items::ServiceItem, slide::Slide},
|
||||
BackgroundKind,
|
||||
core::{service_items::ServiceItem, slide::Slide},
|
||||
};
|
||||
|
||||
const REFERENCE_WIDTH: f32 = 1920.0;
|
||||
static DEFAULT_SLIDE: LazyLock<Slide> =
|
||||
LazyLock::new(|| Slide::default());
|
||||
static DEFAULT_SLIDE: LazyLock<Slide> = LazyLock::new(Slide::default);
|
||||
|
||||
// #[derive(Default, Clone, Debug)]
|
||||
pub(crate) struct Presenter {
|
||||
|
|
@ -155,11 +154,12 @@ impl Presenter {
|
|||
items.iter().fold(0, |a, item| a + item.slides.len());
|
||||
|
||||
let slide =
|
||||
items.get(0).map(|item| item.slides.get(0)).flatten();
|
||||
items.first().and_then(|item| item.slides.first());
|
||||
let audio = items
|
||||
.get(0)
|
||||
.map(|item| item.slides.get(0).map(|slide| slide.audio()))
|
||||
.flatten()
|
||||
.first()
|
||||
.and_then(|item| {
|
||||
item.slides.first().map(|slide| slide.audio())
|
||||
})
|
||||
.flatten();
|
||||
|
||||
Self {
|
||||
|
|
@ -179,7 +179,7 @@ impl Presenter {
|
|||
.expect("Can't open default rodio stream");
|
||||
(
|
||||
Arc::new(Sink::connect_new(
|
||||
&stream_handle.mixer(),
|
||||
stream_handle.mixer(),
|
||||
)),
|
||||
stream_handle,
|
||||
)
|
||||
|
|
@ -219,8 +219,7 @@ impl Presenter {
|
|||
if let Some(slide) = self
|
||||
.service
|
||||
.get(item_index)
|
||||
.map(|item| item.slides.get(slide_index))
|
||||
.flatten()
|
||||
.and_then(|item| item.slides.get(slide_index))
|
||||
{
|
||||
self.current_item = item_index;
|
||||
self.current_slide_index = slide_index;
|
||||
|
|
@ -473,7 +472,7 @@ impl Presenter {
|
|||
);
|
||||
|
||||
let container = slide_view(
|
||||
&slide,
|
||||
slide,
|
||||
&self.video,
|
||||
true,
|
||||
false,
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ use cosmic::iced::Size;
|
|||
|
||||
use cosmic::iced_core::widget::tree;
|
||||
use cosmic::{
|
||||
Element,
|
||||
iced::{
|
||||
Event, Length, Point, Rectangle, Vector,
|
||||
clipboard::dnd::{DndEvent, SourceEvent},
|
||||
event, mouse, Event, Length, Point, Rectangle, Vector,
|
||||
event, mouse,
|
||||
},
|
||||
iced_core::{
|
||||
self, image::Renderer, layout, renderer, widget::Tree,
|
||||
Clipboard, Shell,
|
||||
self, Clipboard, Shell, layout, renderer, widget::Tree,
|
||||
},
|
||||
widget::Widget,
|
||||
Element,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
|
|
@ -196,16 +196,14 @@ impl<Message: Clone + 'static>
|
|||
// We ignore motion if we do not possess drag content by now.
|
||||
if let Some(left_pressed_position) =
|
||||
state.left_pressed_position
|
||||
{
|
||||
if position
|
||||
&& position
|
||||
.distance(left_pressed_position)
|
||||
> self.drag_threshold
|
||||
{
|
||||
if let Some(on_start) =
|
||||
self.on_start.as_ref()
|
||||
{
|
||||
shell
|
||||
.publish(on_start.clone())
|
||||
shell.publish(on_start.clone())
|
||||
}
|
||||
let offset = Vector::new(
|
||||
left_pressed_position.x
|
||||
|
|
@ -214,9 +212,7 @@ impl<Message: Clone + 'static>
|
|||
- layout.bounds().y,
|
||||
);
|
||||
state.is_dragging = true;
|
||||
state.left_pressed_position =
|
||||
None;
|
||||
}
|
||||
state.left_pressed_position = None;
|
||||
}
|
||||
if !cursor.is_over(layout.bounds()) {
|
||||
state.hovered = false;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use std::{io, path::PathBuf};
|
||||
|
||||
use cosmic::{
|
||||
Renderer,
|
||||
iced::{Color, Font, Length, Size},
|
||||
widget::{
|
||||
self,
|
||||
canvas::{self, Program, Stroke},
|
||||
container,
|
||||
},
|
||||
Renderer,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use std::{io, path::PathBuf, sync::Arc};
|
||||
|
||||
use cosmic::{
|
||||
dialog::file_chooser::{open::Dialog, FileFilter},
|
||||
iced::{alignment::Vertical, Length},
|
||||
Element, Task,
|
||||
dialog::file_chooser::{FileFilter, open::Dialog},
|
||||
iced::{Length, alignment::Vertical},
|
||||
iced_wgpu::graphics::text::cosmic_text::fontdb,
|
||||
iced_widget::{column, row},
|
||||
theme,
|
||||
|
|
@ -10,7 +11,6 @@ use cosmic::{
|
|||
button, combo_box, container, horizontal_space, icon,
|
||||
progress_bar, scrollable, text, text_editor, text_input,
|
||||
},
|
||||
Element, Task,
|
||||
};
|
||||
use dirs::font_dir;
|
||||
use iced_video_player::Video;
|
||||
|
|
@ -18,11 +18,11 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
|||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
Background, BackgroundKind,
|
||||
core::{service_items::ServiceTrait, slide::Slide, songs::Song},
|
||||
ui::{
|
||||
presenter::slide_view, slide_editor::SlideEditor, text_svg,
|
||||
},
|
||||
Background, BackgroundKind,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -308,12 +308,12 @@ impl SongEditor {
|
|||
fn slide_preview(&self) -> Element<Message> {
|
||||
if let Some(slides) = &self.song_slides {
|
||||
let slides: Vec<Element<Message>> = slides
|
||||
.into_iter()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, slide)| {
|
||||
container(
|
||||
slide_view(
|
||||
&slide,
|
||||
slide,
|
||||
if index == 0 {
|
||||
&self.video
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,16 +8,16 @@ use std::{
|
|||
use colors_transform::Rgb;
|
||||
use cosmic::{
|
||||
iced::{
|
||||
font::{Style, Weight},
|
||||
ContentFit, Length, Size,
|
||||
font::{Style, Weight},
|
||||
},
|
||||
prelude::*,
|
||||
widget::{image::Handle, Image},
|
||||
widget::{Image, image::Handle},
|
||||
};
|
||||
use rapidhash::v3::rapidhash_v3;
|
||||
use resvg::{
|
||||
tiny_skia::{self, Pixmap},
|
||||
usvg::{fontdb, Tree},
|
||||
usvg::{Tree, fontdb},
|
||||
};
|
||||
use tracing::{debug, error};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
use std::{io, path::PathBuf};
|
||||
|
||||
use cosmic::{
|
||||
dialog::file_chooser::{open::Dialog, FileFilter},
|
||||
iced::{alignment::Vertical, Length},
|
||||
Element, Task,
|
||||
dialog::file_chooser::{FileFilter, open::Dialog},
|
||||
iced::{Length, alignment::Vertical},
|
||||
iced_widget::{column, row},
|
||||
theme,
|
||||
widget::{
|
||||
button, container, horizontal_space, icon, progress_bar,
|
||||
text, text_input, Space,
|
||||
Space, button, container, horizontal_space, icon,
|
||||
progress_bar, text, text_input,
|
||||
},
|
||||
Element, Task,
|
||||
};
|
||||
use iced_video_player::{Video, VideoPlayer};
|
||||
use tracing::{debug, error, warn};
|
||||
|
|
@ -94,8 +94,7 @@ impl VideoEditor {
|
|||
.core_video
|
||||
.as_ref()
|
||||
.map(|v| v.id)
|
||||
.unwrap_or_default()
|
||||
.clone();
|
||||
.unwrap_or_default();
|
||||
let task = Task::perform(
|
||||
pick_video(),
|
||||
move |video_result| {
|
||||
|
|
|
|||
|
|
@ -22,17 +22,17 @@
|
|||
// 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.
|
||||
|
||||
use cosmic::Theme;
|
||||
use cosmic::iced::advanced::layout::{self, Layout};
|
||||
use cosmic::iced::advanced::widget::{tree, Operation, Tree, Widget};
|
||||
use cosmic::iced::advanced::{overlay, renderer, Clipboard, Shell};
|
||||
use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
|
||||
use cosmic::iced::advanced::{Clipboard, Shell, overlay, renderer};
|
||||
use cosmic::iced::alignment::{self, Alignment};
|
||||
use cosmic::iced::event::{self, Event};
|
||||
use cosmic::iced::{self, mouse, Transformation};
|
||||
use cosmic::iced::{self, Transformation, mouse};
|
||||
use cosmic::iced::{
|
||||
Background, Border, Color, Element, Length, Padding, Pixels,
|
||||
Point, Rectangle, Size, Vector,
|
||||
};
|
||||
use cosmic::Theme;
|
||||
|
||||
use super::{Action, DragEvent, DropPosition};
|
||||
|
||||
|
|
@ -468,8 +468,7 @@ where
|
|||
Action::Picking { index, origin } => {
|
||||
if let Some(cursor_position) =
|
||||
cursor.position()
|
||||
{
|
||||
if cursor_position.distance(origin)
|
||||
&& cursor_position.distance(origin)
|
||||
> self.deadband_zone
|
||||
{
|
||||
// Start dragging
|
||||
|
|
@ -478,16 +477,12 @@ where
|
|||
origin,
|
||||
last_cursor: cursor_position,
|
||||
};
|
||||
if let Some(on_reorder) =
|
||||
&self.on_drag
|
||||
{
|
||||
if let Some(on_reorder) = &self.on_drag {
|
||||
shell.publish(on_reorder(
|
||||
DragEvent::Picked { index },
|
||||
));
|
||||
}
|
||||
event_status =
|
||||
event::Status::Captured;
|
||||
}
|
||||
event_status = event::Status::Captured;
|
||||
}
|
||||
}
|
||||
Action::Dragging { origin, index, .. } => {
|
||||
|
|
@ -903,8 +898,7 @@ pub fn default(theme: &Theme) -> Style {
|
|||
Style {
|
||||
scale: 1.05,
|
||||
moved_item_overlay: Color::from(theme.cosmic().primary.base)
|
||||
.scale_alpha(0.2)
|
||||
.into(),
|
||||
.scale_alpha(0.2),
|
||||
ghost_border: Border {
|
||||
width: 1.0,
|
||||
color: theme.cosmic().secondary.base.into(),
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use cosmic::iced::advanced::layout::{self, Layout};
|
||||
use cosmic::iced::advanced::widget::{tree, Operation, Tree, Widget};
|
||||
use cosmic::iced::advanced::{overlay, renderer, Clipboard, Shell};
|
||||
use cosmic::iced::advanced::widget::{Operation, Tree, Widget, tree};
|
||||
use cosmic::iced::advanced::{Clipboard, Shell, overlay, renderer};
|
||||
use cosmic::iced::alignment::{self, Alignment};
|
||||
use cosmic::iced::event::{self, Event};
|
||||
use cosmic::iced::{self, mouse, Transformation};
|
||||
use cosmic::iced::{self, Transformation, mouse};
|
||||
use cosmic::iced::{
|
||||
Background, Border, Color, Element, Length, Padding, Pixels,
|
||||
Point, Rectangle, Size, Theme, Vector,
|
||||
|
|
@ -454,8 +454,7 @@ where
|
|||
Action::Picking { index, origin } => {
|
||||
if let Some(cursor_position) =
|
||||
cursor.position()
|
||||
{
|
||||
if cursor_position.distance(origin)
|
||||
&& cursor_position.distance(origin)
|
||||
> self.deadband_zone
|
||||
{
|
||||
// Start dragging
|
||||
|
|
@ -464,16 +463,12 @@ where
|
|||
origin,
|
||||
last_cursor: cursor_position,
|
||||
};
|
||||
if let Some(on_reorder) =
|
||||
&self.on_drag
|
||||
{
|
||||
if let Some(on_reorder) = &self.on_drag {
|
||||
shell.publish(on_reorder(
|
||||
DragEvent::Picked { index },
|
||||
));
|
||||
}
|
||||
event_status =
|
||||
event::Status::Captured;
|
||||
}
|
||||
event_status = event::Status::Captured;
|
||||
}
|
||||
}
|
||||
Action::Dragging { origin, index, .. } => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue