parent
46abd9dd7a
commit
761006f516
20 changed files with 195 additions and 201 deletions
|
|
@ -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};
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
|
||||||
|
|
@ -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::*;
|
||||||
|
|
|
||||||
20
src/main.rs
20
src/main.rs
|
|
@ -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};
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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},
|
||||||
|
|
@ -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 => {
|
||||||
|
|
@ -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) =
|
||||||
|
|
@ -604,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, |_| {
|
||||||
|
|
@ -684,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
|
||||||
});
|
});
|
||||||
|
|
@ -892,23 +895,23 @@ 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)
|
||||||
|
{
|
||||||
Task::future(self.db.acquire())
|
error!(?e);
|
||||||
|
Task::none()
|
||||||
|
} else {
|
||||||
|
Task::future(self.db.acquire())
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
songs::remove_from_db(
|
songs::remove_from_db(
|
||||||
|
|
@ -922,24 +925,23 @@ impl<'a> Library {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} 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 {
|
||||||
|
Task::none()
|
||||||
Task::future(self.db.acquire())
|
}
|
||||||
|
}
|
||||||
|
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())
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
videos::remove_from_db(
|
videos::remove_from_db(
|
||||||
|
|
@ -953,24 +955,23 @@ impl<'a> Library {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} 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 {
|
||||||
|
Task::none()
|
||||||
Task::future(self.db.acquire())
|
}
|
||||||
|
}
|
||||||
|
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())
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
images::remove_from_db(
|
images::remove_from_db(
|
||||||
|
|
@ -984,25 +985,24 @@ impl<'a> Library {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} 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 {
|
||||||
|
Task::none()
|
||||||
Task::future(self.db.acquire())
|
}
|
||||||
|
}
|
||||||
|
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())
|
||||||
.and_then(move |db| {
|
.and_then(move |db| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
presentations::remove_from_db(
|
presentations::remove_from_db(
|
||||||
|
|
@ -1017,13 +1017,13 @@ impl<'a> Library {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Task::none()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
.collect();
|
||||||
.collect();
|
|
||||||
if !tasks.is_empty() {
|
if !tasks.is_empty() {
|
||||||
self.selected_items = None;
|
self.selected_items = None;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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::{
|
||||||
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};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -156,8 +155,11 @@ impl Presenter {
|
||||||
|
|
||||||
let slide =
|
let slide =
|
||||||
items.first().and_then(|item| item.slides.first());
|
items.first().and_then(|item| item.slides.first());
|
||||||
let audio = items.first()
|
let audio = items
|
||||||
.and_then(|item| item.slides.first().map(|slide| slide.audio()))
|
.first()
|
||||||
|
.and_then(|item| {
|
||||||
|
item.slides.first().map(|slide| slide.audio())
|
||||||
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
|
|
@ -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, layout, renderer, widget::Tree,
|
self, Clipboard, Shell, layout, renderer, widget::Tree,
|
||||||
Clipboard, Shell,
|
|
||||||
},
|
},
|
||||||
widget::Widget,
|
widget::Widget,
|
||||||
Element,
|
|
||||||
};
|
};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
|
@ -199,23 +199,21 @@ impl<Message: Clone + 'static>
|
||||||
&& position
|
&& 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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
||||||
|
|
@ -470,23 +470,20 @@ where
|
||||||
cursor.position()
|
cursor.position()
|
||||||
&& cursor_position.distance(origin)
|
&& 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, .. } => {
|
||||||
if let Some(cursor_position) =
|
if let Some(cursor_position) =
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
@ -456,23 +456,20 @@ where
|
||||||
cursor.position()
|
cursor.position()
|
||||||
&& cursor_position.distance(origin)
|
&& 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, .. } => {
|
||||||
if let Some(cursor_position) =
|
if let Some(cursor_position) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue