adding base for drag n drop
This commit is contained in:
parent
f79e61f2ed
commit
1ce365fc04
8 changed files with 139 additions and 49 deletions
|
@ -1,6 +1,7 @@
|
|||
use super::kinds::ServiceItemKind;
|
||||
use super::{kinds::ServiceItemKind, service_items::ServiceItem};
|
||||
|
||||
pub trait Content {
|
||||
fn title(&self) -> String;
|
||||
fn kind(&self) -> ServiceItemKind;
|
||||
fn to_service_item(&self) -> ServiceItem;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ impl Content for Image {
|
|||
fn kind(&self) -> ServiceItemKind {
|
||||
ServiceItemKind::Image(self.clone())
|
||||
}
|
||||
|
||||
fn to_service_item(&self) -> super::service_items::ServiceItem {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for Image {
|
||||
|
|
|
@ -44,6 +44,10 @@ impl Content for Presentation {
|
|||
fn kind(&self) -> ServiceItemKind {
|
||||
ServiceItemKind::Presentation(self.clone())
|
||||
}
|
||||
|
||||
fn to_service_item(&self) -> super::service_items::ServiceItem {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for Presentation {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use std::borrow::Cow;
|
||||
use std::ops::Deref;
|
||||
|
||||
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
||||
use crisp::types::{Keyword, Symbol, Value};
|
||||
use miette::Result;
|
||||
use miette::{miette, Result};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::Slide;
|
||||
|
@ -22,6 +24,48 @@ pub struct ServiceItem {
|
|||
// pub item: Box<dyn ServiceTrait>,
|
||||
}
|
||||
|
||||
impl TryFrom<(Vec<u8>, String)> for ServiceItem {
|
||||
type Error = miette::Error;
|
||||
|
||||
fn try_from(
|
||||
value: (Vec<u8>, String),
|
||||
) -> std::result::Result<Self, Self::Error> {
|
||||
let sto = value.0.to_owned();
|
||||
let song = Song {
|
||||
title: "Death Was Arrested".to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
debug!(?value);
|
||||
Ok(Self::from(&song))
|
||||
}
|
||||
}
|
||||
|
||||
impl AllowedMimeTypes for ServiceItem {
|
||||
fn allowed() -> Cow<'static, [String]> {
|
||||
Cow::from(vec!["application/service-item".to_string()])
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMimeTypes for ServiceItem {
|
||||
fn available(&self) -> std::borrow::Cow<'static, [String]> {
|
||||
debug!(?self);
|
||||
Cow::from(vec!["application/service-item".to_string()])
|
||||
}
|
||||
|
||||
fn as_bytes(
|
||||
&self,
|
||||
mime_type: &str,
|
||||
) -> Option<std::borrow::Cow<'static, [u8]>> {
|
||||
todo!();
|
||||
debug!(?self);
|
||||
debug!(mime_type);
|
||||
Some(Cow::from(
|
||||
r#"(slide :background (image :source "~/pics/frodo.jpg" :fit fill)
|
||||
(text "This is frodo" :font-size 70))"#.to_string().into_bytes()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ServiceItem {
|
||||
pub fn title(&self) -> String {
|
||||
self.title.clone()
|
||||
|
|
|
@ -44,6 +44,10 @@ impl Content for Song {
|
|||
fn kind(&self) -> ServiceItemKind {
|
||||
ServiceItemKind::Song(self.clone())
|
||||
}
|
||||
|
||||
fn to_service_item(&self) -> super::service_items::ServiceItem {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ServiceTrait for Song {
|
||||
|
|
|
@ -35,6 +35,10 @@ impl Content for Video {
|
|||
fn kind(&self) -> ServiceItemKind {
|
||||
ServiceItemKind::Video(self.clone())
|
||||
}
|
||||
|
||||
fn to_service_item(&self) -> super::service_items::ServiceItem {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for Video {
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -2,6 +2,7 @@ use clap::{command, Parser};
|
|||
use core::service_items::{ServiceItem, ServiceItemModel};
|
||||
use cosmic::app::context_drawer::ContextDrawer;
|
||||
use cosmic::app::{Core, Settings, Task};
|
||||
use cosmic::iced::clipboard::dnd::DndAction;
|
||||
use cosmic::iced::keyboard::{Key, Modifiers};
|
||||
use cosmic::iced::window::{Mode, Position};
|
||||
use cosmic::iced::{self, event, window, Length, Padding, Point};
|
||||
|
@ -9,7 +10,9 @@ use cosmic::iced_futures::Subscription;
|
|||
use cosmic::iced_widget::{column, row};
|
||||
use cosmic::prelude::ElementExt;
|
||||
use cosmic::prelude::*;
|
||||
use cosmic::widget::dnd_destination::DragId;
|
||||
use cosmic::widget::nav_bar::nav_bar_style;
|
||||
use cosmic::widget::segmented_button::Entity;
|
||||
use cosmic::widget::tooltip::Position as TPosition;
|
||||
use cosmic::widget::{
|
||||
button, nav_bar, text, tooltip, DndSource, Id, Space,
|
||||
|
@ -100,8 +103,8 @@ enum Message {
|
|||
Present(presenter::Message),
|
||||
Library(library::Message),
|
||||
File(PathBuf),
|
||||
DndEnter(ServiceItem),
|
||||
DndDrop(ServiceItem),
|
||||
DndEnter(Entity, Vec<String>),
|
||||
DndDrop(Entity, Option<ServiceItem>, DndAction),
|
||||
OpenWindow,
|
||||
CloseWindow(Option<window::Id>),
|
||||
WindowOpened(window::Id, Option<Point>),
|
||||
|
@ -110,6 +113,7 @@ enum Message {
|
|||
Quit,
|
||||
Key(Key, Modifiers),
|
||||
None,
|
||||
DndLeave(Entity),
|
||||
}
|
||||
|
||||
impl cosmic::Application for App {
|
||||
|
@ -217,9 +221,21 @@ impl cosmic::Application for App {
|
|||
cosmic::app::cosmic::Message::NavBar(id),
|
||||
)
|
||||
})
|
||||
// .on_dnd_drop(|entity, data, idk| {
|
||||
// cosmic::app::Message::Cosmic(Message::DndDrop(entity))
|
||||
// })
|
||||
.on_dnd_drop(|entity, data, action| {
|
||||
debug!(?entity);
|
||||
debug!(?data);
|
||||
debug!(?action);
|
||||
cosmic::app::Message::App(Message::DndDrop(
|
||||
entity, data, action,
|
||||
))
|
||||
})
|
||||
.on_dnd_enter(|entity, data| {
|
||||
cosmic::app::Message::App(Message::DndEnter(entity, data))
|
||||
})
|
||||
.on_dnd_leave(|entity| {
|
||||
cosmic::app::Message::App(Message::DndLeave(entity))
|
||||
})
|
||||
.drag_id(DragId::new())
|
||||
.on_context(|id| {
|
||||
cosmic::app::Message::Cosmic(
|
||||
cosmic::app::cosmic::Message::NavBarContext(id),
|
||||
|
@ -253,7 +269,7 @@ impl cosmic::Application for App {
|
|||
id: nav_bar::Id,
|
||||
) -> Task<Self::Message> {
|
||||
self.nav_model.activate(id);
|
||||
debug!(?id);
|
||||
// debug!(?id);
|
||||
self.update_title()
|
||||
}
|
||||
|
||||
|
@ -503,13 +519,26 @@ impl cosmic::Application for App {
|
|||
}
|
||||
}
|
||||
Message::Quit => cosmic::iced::exit(),
|
||||
Message::DndEnter(service_item) => todo!(),
|
||||
Message::DndDrop(service_item) => todo!(),
|
||||
Message::DndEnter(entity, data) => {
|
||||
debug!(?entity);
|
||||
debug!(?data);
|
||||
Task::none()
|
||||
}
|
||||
Message::DndDrop(entity, service_item, action) => {
|
||||
debug!(?entity);
|
||||
debug!(?service_item);
|
||||
debug!(?action);
|
||||
Task::none()
|
||||
}
|
||||
Message::AddLibrary(library) => {
|
||||
self.library = Some(library);
|
||||
Task::none()
|
||||
}
|
||||
Message::None => Task::none(),
|
||||
Message::DndLeave(entity) => {
|
||||
// debug!(?entity);
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use cosmic::{
|
|||
iced_widget::{column, row as rowm, text as textm},
|
||||
widget::{
|
||||
container, horizontal_space, icon, mouse_area, responsive,
|
||||
row, scrollable, text, Container, Space,
|
||||
row, scrollable, text, Container, DndSource, Space,
|
||||
},
|
||||
Element, Task,
|
||||
};
|
||||
|
@ -14,6 +14,7 @@ use crate::core::{
|
|||
images::Image,
|
||||
model::{get_db, LibraryKind, Model},
|
||||
presentations::Presentation,
|
||||
service_items::ServiceItem,
|
||||
songs::Song,
|
||||
videos::Video,
|
||||
};
|
||||
|
@ -204,54 +205,53 @@ impl Library {
|
|||
.on_enter(Message::HoverLibrary(Some(model.kind)))
|
||||
.on_exit(Message::HoverLibrary(None));
|
||||
let mut dragged_item = None;
|
||||
let lib_container = if self.library_open == Some(model.kind) {
|
||||
let items = scrollable(
|
||||
column({
|
||||
model.items.iter().enumerate().map(
|
||||
let lib_container =
|
||||
if self.library_open == Some(model.kind) {
|
||||
let items = scrollable(
|
||||
column({
|
||||
model.items.iter().enumerate().map(
|
||||
|(index, item)| {
|
||||
mouse_area(
|
||||
self.single_item(index, item, model),
|
||||
)
|
||||
.on_drag({
|
||||
dragged_item =
|
||||
Some(self.single_item(
|
||||
let service_item = item.to_service_item();
|
||||
DndSource::<Message, ServiceItem>::new(
|
||||
mouse_area(
|
||||
self.single_item(
|
||||
index, item, model,
|
||||
));
|
||||
Message::DragItem(Some((
|
||||
),
|
||||
)
|
||||
.on_enter(Message::HoverItem(Some((
|
||||
model.kind,
|
||||
index as i32,
|
||||
)))
|
||||
))))
|
||||
.on_exit(Message::HoverItem(None))
|
||||
.on_press(Message::SelectItem(Some(
|
||||
(model.kind, index as i32),
|
||||
))),
|
||||
)
|
||||
.drag_content(move || {
|
||||
service_item.to_owned()
|
||||
})
|
||||
.on_enter(Message::HoverItem(Some((
|
||||
model.kind,
|
||||
index as i32,
|
||||
))))
|
||||
.on_exit(Message::HoverItem(None))
|
||||
.on_press(Message::SelectItem(Some((
|
||||
model.kind,
|
||||
index as i32,
|
||||
.on_start(Some(Message::DragItem(Some(
|
||||
(model.kind, index as i32),
|
||||
))))
|
||||
.into()
|
||||
},
|
||||
)
|
||||
})
|
||||
.spacing(2)
|
||||
.width(Length::Fill),
|
||||
);
|
||||
Container::new(items).padding(5).style(|t| {
|
||||
container::Style::default()
|
||||
.background(Background::Color(
|
||||
t.cosmic().primary.base.into(),
|
||||
))
|
||||
.border(
|
||||
Border::default().rounded(
|
||||
})
|
||||
.spacing(2)
|
||||
.width(Length::Fill),
|
||||
);
|
||||
Container::new(items).padding(5).style(|t| {
|
||||
container::Style::default()
|
||||
.background(Background::Color(
|
||||
t.cosmic().primary.base.into(),
|
||||
))
|
||||
.border(Border::default().rounded(
|
||||
t.cosmic().corner_radii.radius_m,
|
||||
),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
Container::new(Space::new(0, 0))
|
||||
};
|
||||
))
|
||||
})
|
||||
} else {
|
||||
Container::new(Space::new(0, 0))
|
||||
};
|
||||
(column![button, lib_container].into(), dragged_item)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue