Compare commits
No commits in common. "77af1ebaf47783a4e66450cc2b8aeb81ab4f306d" and "00dc33a66117f30b9d430163013ba706c3870f03" have entirely different histories.
77af1ebaf4
...
00dc33a661
7 changed files with 64 additions and 178 deletions
18
src/main.rs
18
src/main.rs
|
@ -157,7 +157,7 @@ impl cosmic::Application for App {
|
||||||
input: Self::Flags,
|
input: Self::Flags,
|
||||||
) -> (Self, Task<Self::Message>) {
|
) -> (Self, Task<Self::Message>) {
|
||||||
debug!("init");
|
debug!("init");
|
||||||
let nav_model = nav_bar::Model::default();
|
let mut nav_model = nav_bar::Model::default();
|
||||||
|
|
||||||
let mut windows = vec![];
|
let mut windows = vec![];
|
||||||
|
|
||||||
|
@ -308,6 +308,7 @@ impl cosmic::Application for App {
|
||||||
let tooltip = tooltip(button,
|
let tooltip = tooltip(button,
|
||||||
text::body(item.kind.to_string()),
|
text::body(item.kind.to_string()),
|
||||||
TPosition::Right);
|
TPosition::Right);
|
||||||
|
let dragged_item = &self.library_dragged_item;
|
||||||
dnd_destination(tooltip, vec!["application/service-item".into()])
|
dnd_destination(tooltip, vec!["application/service-item".into()])
|
||||||
.data_received_for::<ServiceItem>( move |item| {
|
.data_received_for::<ServiceItem>( move |item| {
|
||||||
if let Some(item) = item {
|
if let Some(item) = item {
|
||||||
|
@ -599,11 +600,11 @@ impl cosmic::Application for App {
|
||||||
}
|
}
|
||||||
Message::Present(message) => {
|
Message::Present(message) => {
|
||||||
// debug!(?message);
|
// debug!(?message);
|
||||||
if self.presentation_open
|
if self.presentation_open {
|
||||||
&& let Some(video) = &mut self.presenter.video
|
if let Some(video) = &mut self.presenter.video {
|
||||||
{
|
|
||||||
video.set_muted(false);
|
video.set_muted(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
match self.presenter.update(message) {
|
match self.presenter.update(message) {
|
||||||
presenter::Action::Task(task) => task.map(|m| {
|
presenter::Action::Task(task) => task.map(|m| {
|
||||||
// debug!("Should run future");
|
// debug!("Should run future");
|
||||||
|
@ -887,9 +888,8 @@ impl cosmic::Application for App {
|
||||||
// debug!(?action);
|
// debug!(?action);
|
||||||
// debug!(?service_item);
|
// debug!(?service_item);
|
||||||
|
|
||||||
if let Some(library) = &self.library
|
if let Some(library) = &self.library {
|
||||||
&& let Some((lib, item)) = library.dragged_item
|
if let Some((lib, item)) = library.dragged_item {
|
||||||
{
|
|
||||||
// match lib {
|
// match lib {
|
||||||
// core::model::LibraryKind::Song => ,
|
// core::model::LibraryKind::Song => ,
|
||||||
// core::model::LibraryKind::Video => todo!(),
|
// core::model::LibraryKind::Video => todo!(),
|
||||||
|
@ -903,6 +903,7 @@ impl cosmic::Application for App {
|
||||||
.text(item.title.clone())
|
.text(item.title.clone())
|
||||||
.data(item);
|
.data(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::AddLibrary(library) => {
|
Message::AddLibrary(library) => {
|
||||||
|
@ -932,8 +933,8 @@ impl cosmic::Application for App {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(id, _)| index == *id)
|
.find(|(id, _)| index == *id)
|
||||||
&& let Some(slide) = item.slides.first()
|
|
||||||
{
|
{
|
||||||
|
if let Some(slide) = item.slides.first() {
|
||||||
self.current_item = (index, 0);
|
self.current_item = (index, 0);
|
||||||
self.presenter.update(
|
self.presenter.update(
|
||||||
presenter::Message::SlideChange(
|
presenter::Message::SlideChange(
|
||||||
|
@ -941,6 +942,7 @@ impl cosmic::Application for App {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::AddServiceItem(index, item) => {
|
Message::AddServiceItem(index, item) => {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::{
|
iced::{
|
||||||
alignment::Vertical, clipboard::dnd::DndAction,
|
alignment::Vertical, clipboard::dnd::DndAction,
|
||||||
|
@ -392,7 +394,7 @@ impl<'a> Library {
|
||||||
)
|
)
|
||||||
.action(DndAction::Copy)
|
.action(DndAction::Copy)
|
||||||
.drag_icon({
|
.drag_icon({
|
||||||
let model = model.kind;
|
let model = model.kind.clone();
|
||||||
move |i| {
|
move |i| {
|
||||||
let state = State::None;
|
let state = State::None;
|
||||||
let icon = match model {
|
let icon = match model {
|
||||||
|
|
|
@ -7,7 +7,6 @@ pub mod song_editor;
|
||||||
pub mod text_svg;
|
pub mod text_svg;
|
||||||
pub mod video;
|
pub mod video;
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
pub mod slide_editor;
|
|
||||||
|
|
||||||
pub enum EditorMode {
|
pub enum EditorMode {
|
||||||
Song,
|
Song,
|
||||||
|
|
|
@ -9,17 +9,20 @@ use cosmic::{
|
||||||
Background, Border, Color, ContentFit, Font, Length, Shadow,
|
Background, Border, Color, ContentFit, Font, Length, Shadow,
|
||||||
Vector,
|
Vector,
|
||||||
},
|
},
|
||||||
|
iced_core::text::Span,
|
||||||
iced_widget::{
|
iced_widget::{
|
||||||
rich_text,
|
rich_text,
|
||||||
scrollable::{
|
scrollable::{
|
||||||
scroll_to, AbsoluteOffset, Direction, Scrollbar,
|
scroll_to, AbsoluteOffset, Direction, Scrollbar,
|
||||||
},
|
},
|
||||||
span, stack, vertical_rule,
|
span, stack,
|
||||||
|
text::Rich,
|
||||||
|
vertical_rule,
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widget::{
|
widget::{
|
||||||
container, image, mouse_area, responsive, scrollable, text,
|
container, horizontal_space, image, mouse_area, responsive,
|
||||||
Column, Container, Id, Row, Space,
|
scrollable, text, Column, Container, Id, Row, Space,
|
||||||
},
|
},
|
||||||
Task,
|
Task,
|
||||||
};
|
};
|
||||||
|
@ -29,7 +32,11 @@ use tracing::{debug, error, info, warn};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{service_items::ServiceItem, slide::Slide},
|
core::{
|
||||||
|
service_items::{Service, ServiceItem},
|
||||||
|
slide::Slide,
|
||||||
|
},
|
||||||
|
ui::text_svg::{self, Font as SvgFont},
|
||||||
// ui::widgets::slide_text,
|
// ui::widgets::slide_text,
|
||||||
BackgroundKind,
|
BackgroundKind,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
use std::{io, path::PathBuf};
|
|
||||||
|
|
||||||
use cosmic::{
|
|
||||||
iced::{Color, Font},
|
|
||||||
widget::{
|
|
||||||
self,
|
|
||||||
canvas::{self, Program, Stroke},
|
|
||||||
},
|
|
||||||
Renderer,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct State {
|
|
||||||
cache: canvas::Cache,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct SlideEditor<'a> {
|
|
||||||
state: &'a State,
|
|
||||||
font: &'a Font,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Message {
|
|
||||||
ChangeFont(String),
|
|
||||||
ChangeFontSize(usize),
|
|
||||||
ChangeTitle(String),
|
|
||||||
ChangeBackground(Result<PathBuf, SlideError>),
|
|
||||||
PickBackground,
|
|
||||||
Edit(bool),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Text {
|
|
||||||
text: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum SlideWidget {
|
|
||||||
Text(Text),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum SlideError {
|
|
||||||
DialogClosed,
|
|
||||||
IOError(io::ErrorKind),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
pub fn view<'a>(
|
|
||||||
&'a self,
|
|
||||||
font: &'a Font,
|
|
||||||
) -> cosmic::iced::Element<'a, SlideWidget> {
|
|
||||||
widget::canvas(SlideEditor { state: self, font }).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Program<SlideWidget> for SlideEditor<'a> {
|
|
||||||
type State = ();
|
|
||||||
|
|
||||||
fn draw(
|
|
||||||
&self,
|
|
||||||
state: &Self::State,
|
|
||||||
renderer: &Renderer,
|
|
||||||
theme: &cosmic::iced_runtime::core::Theme,
|
|
||||||
bounds: cosmic::iced::Rectangle,
|
|
||||||
cursor: cosmic::iced_core::mouse::Cursor,
|
|
||||||
) -> Vec<canvas::Geometry<Renderer>> {
|
|
||||||
// We prepare a new `Frame`
|
|
||||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
|
||||||
|
|
||||||
// We create a `Path` representing a simple circle
|
|
||||||
let circle = canvas::Path::circle(frame.center(), 50.0);
|
|
||||||
|
|
||||||
// And fill it with some color
|
|
||||||
frame.fill(&circle, Color::BLACK);
|
|
||||||
frame.stroke(
|
|
||||||
&circle,
|
|
||||||
Stroke::default()
|
|
||||||
.with_width(5.0)
|
|
||||||
.with_color(Color::BLACK),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Then, we produce the geometry
|
|
||||||
vec![frame.into_geometry()]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(
|
|
||||||
&self,
|
|
||||||
_state: &mut Self::State,
|
|
||||||
event: canvas::Event,
|
|
||||||
_bounds: cosmic::iced::Rectangle,
|
|
||||||
_cursor: cosmic::iced_core::mouse::Cursor,
|
|
||||||
) -> (canvas::event::Status, Option<SlideWidget>) {
|
|
||||||
match event {
|
|
||||||
canvas::Event::Mouse(event) => match event {
|
|
||||||
cosmic::iced::mouse::Event::CursorEntered => todo!(),
|
|
||||||
cosmic::iced::mouse::Event::CursorLeft => todo!(),
|
|
||||||
cosmic::iced::mouse::Event::CursorMoved {
|
|
||||||
position,
|
|
||||||
} => todo!(),
|
|
||||||
cosmic::iced::mouse::Event::ButtonPressed(button) => {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
cosmic::iced::mouse::Event::ButtonReleased(
|
|
||||||
button,
|
|
||||||
) => todo!(),
|
|
||||||
cosmic::iced::mouse::Event::WheelScrolled {
|
|
||||||
delta,
|
|
||||||
} => todo!(),
|
|
||||||
},
|
|
||||||
canvas::Event::Touch(event) => todo!(),
|
|
||||||
canvas::Event::Keyboard(event) => todo!(),
|
|
||||||
}
|
|
||||||
(canvas::event::Status::Ignored, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mouse_interaction(
|
|
||||||
&self,
|
|
||||||
_state: &Self::State,
|
|
||||||
_bounds: cosmic::iced::Rectangle,
|
|
||||||
_cursor: cosmic::iced_core::mouse::Cursor,
|
|
||||||
) -> cosmic::iced_core::mouse::Interaction {
|
|
||||||
cosmic::iced_core::mouse::Interaction::default()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,11 +7,12 @@ use cosmic::{
|
||||||
Font, Length,
|
Font, Length,
|
||||||
},
|
},
|
||||||
iced_wgpu::graphics::text::cosmic_text::fontdb,
|
iced_wgpu::graphics::text::cosmic_text::fontdb,
|
||||||
iced_widget::row,
|
iced_widget::{row, stack},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
button, column, combo_box, container, horizontal_space, icon,
|
button, column, combo_box, container, dropdown,
|
||||||
scrollable, text, text_editor, text_input,
|
horizontal_space, icon, scrollable, svg::Handle, text,
|
||||||
|
text_editor, text_input, Svg,
|
||||||
},
|
},
|
||||||
Element, Task,
|
Element, Task,
|
||||||
};
|
};
|
||||||
|
@ -178,12 +179,12 @@ impl SongEditor {
|
||||||
.filter(|f| f.1 == font)
|
.filter(|f| f.1 == font)
|
||||||
.map(|f| f.0)
|
.map(|f| f.0)
|
||||||
.next();
|
.next();
|
||||||
if let Some(id) = font_id
|
if let Some(id) = font_id {
|
||||||
&& let Some(face) = self.font_db.face(id)
|
if let Some(face) = self.font_db.face(id) {
|
||||||
{
|
|
||||||
self.font = face.post_script_name.clone();
|
self.font = face.post_script_name.clone();
|
||||||
// self.current_font = Font::from(face);
|
// self.current_font = Font::from(face);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.font = font.clone();
|
self.font = font.clone();
|
||||||
|
|
||||||
let font_name = font.into_boxed_str();
|
let font_name = font.into_boxed_str();
|
||||||
|
@ -424,9 +425,8 @@ order",
|
||||||
}
|
}
|
||||||
|
|
||||||
fn background_video(&mut self, background: &Option<Background>) {
|
fn background_video(&mut self, background: &Option<Background>) {
|
||||||
if let Some(background) = background
|
if let Some(background) = background {
|
||||||
&& background.kind == BackgroundKind::Video
|
if background.kind == BackgroundKind::Video {
|
||||||
{
|
|
||||||
let video =
|
let video =
|
||||||
Video::try_from(background).ok().map(|mut v| {
|
Video::try_from(background).ok().map(|mut v| {
|
||||||
v.set_looping(true);
|
v.set_looping(true);
|
||||||
|
@ -437,6 +437,7 @@ order",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for SongEditor {
|
impl Default for SongEditor {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use cosmic::{
|
||||||
Length, Size,
|
Length, Size,
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widget::{container, svg::Handle, Svg},
|
widget::{container, lazy, responsive, svg::Handle, Svg},
|
||||||
};
|
};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_text_spans() {
|
fn test_text_spans() {
|
||||||
let mut text = TextSvg::new("yes");
|
let mut text = TextSvg::new();
|
||||||
text.text = "This is
|
text.text = "This is
|
||||||
multiline
|
multiline
|
||||||
text."
|
text."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue