mirror of
https://github.com/danbulant/cushy
synced 2026-06-24 17:12:11 +00:00
File drop events
This commit is contained in:
parent
e7ccbac18c
commit
01b764de0b
2 changed files with 88 additions and 11 deletions
|
|
@ -159,6 +159,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
initialized.
|
initialized.
|
||||||
- `Window::on_init` is a new callback that is invoked before the winit window is
|
- `Window::on_init` is a new callback that is invoked before the winit window is
|
||||||
initialized.
|
initialized.
|
||||||
|
- `Window::on_file_drop` is a new callback that is invoked when file drop events
|
||||||
|
occur for the window.
|
||||||
|
|
||||||
|
|
||||||
[139]: https://github.com/khonsulabs/cushy/issues/139
|
[139]: https://github.com/khonsulabs/cushy/issues/139
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use std::io;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::num::{NonZeroU32, TryFromIntError};
|
use std::num::{NonZeroU32, TryFromIntError};
|
||||||
use std::ops::{Deref, DerefMut, Not};
|
use std::ops::{Deref, DerefMut, Not};
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use std::sync::{mpsc, Arc, OnceLock};
|
use std::sync::{mpsc, Arc, OnceLock};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
@ -61,8 +61,8 @@ use crate::value::{
|
||||||
Destination, Dynamic, DynamicReader, IntoDynamic, IntoValue, Source, Tracked, Value,
|
Destination, Dynamic, DynamicReader, IntoDynamic, IntoValue, Source, Tracked, Value,
|
||||||
};
|
};
|
||||||
use crate::widget::{
|
use crate::widget::{
|
||||||
EventHandling, MakeWidget, MountedWidget, OnceCallback, RootBehavior, SharedCallback, WidgetId,
|
Callback, EventHandling, MakeWidget, MountedWidget, OnceCallback, RootBehavior, SharedCallback,
|
||||||
WidgetInstance, HANDLED, IGNORED,
|
WidgetId, WidgetInstance, HANDLED, IGNORED,
|
||||||
};
|
};
|
||||||
use crate::widgets::shortcuts::{ShortcutKey, ShortcutMap};
|
use crate::widgets::shortcuts::{ShortcutKey, ShortcutMap};
|
||||||
use crate::window::sealed::WindowCommand;
|
use crate::window::sealed::WindowCommand;
|
||||||
|
|
@ -565,6 +565,7 @@ where
|
||||||
enabled_buttons: Option<Value<WindowButtons>>,
|
enabled_buttons: Option<Value<WindowButtons>>,
|
||||||
fullscreen: Option<Value<Option<Fullscreen>>>,
|
fullscreen: Option<Value<Option<Fullscreen>>>,
|
||||||
shortcuts: Value<ShortcutMap>,
|
shortcuts: Value<ShortcutMap>,
|
||||||
|
on_file_drop: Option<Callback<FileDrop>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Behavior> Default for Window<Behavior>
|
impl<Behavior> Default for Window<Behavior>
|
||||||
|
|
@ -662,6 +663,7 @@ where
|
||||||
fullscreen: None,
|
fullscreen: None,
|
||||||
shortcuts: Value::default(),
|
shortcuts: Value::default(),
|
||||||
on_init: None,
|
on_init: None,
|
||||||
|
on_file_drop: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1015,6 +1017,15 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Invokes `on_file_drop` when a file is hovered or dropped on this window.
|
||||||
|
pub fn on_file_drop<Function>(mut self, on_file_drop: Function) -> Self
|
||||||
|
where
|
||||||
|
Function: FnMut(FileDrop) + Send + 'static,
|
||||||
|
{
|
||||||
|
self.on_file_drop = Some(Callback::new(on_file_drop));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the window's title.
|
/// Sets the window's title.
|
||||||
pub fn titled(mut self, title: impl IntoValue<String>) -> Self {
|
pub fn titled(mut self, title: impl IntoValue<String>) -> Self {
|
||||||
self.title = title.into_value();
|
self.title = title.into_value();
|
||||||
|
|
@ -1159,6 +1170,7 @@ where
|
||||||
.unwrap_or(Value::Constant(WindowButtons::all())),
|
.unwrap_or(Value::Constant(WindowButtons::all())),
|
||||||
fullscreen: this.fullscreen.unwrap_or_default(),
|
fullscreen: this.fullscreen.unwrap_or_default(),
|
||||||
shortcuts: this.shortcuts,
|
shortcuts: this.shortcuts,
|
||||||
|
on_file_drop: this.on_file_drop,
|
||||||
}),
|
}),
|
||||||
pending: this.pending,
|
pending: this.pending,
|
||||||
},
|
},
|
||||||
|
|
@ -1233,6 +1245,35 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A file drop event for a window.
|
||||||
|
pub struct FileDrop {
|
||||||
|
/// The handle to the window the file drop event is for.
|
||||||
|
pub window: WindowHandle,
|
||||||
|
/// The file drop event.
|
||||||
|
pub drop: DropEvent<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A drop event.
|
||||||
|
pub enum DropEvent<T> {
|
||||||
|
/// The payload is being hovered over the container.
|
||||||
|
Hover(T),
|
||||||
|
/// The payload has been dropped on the container.
|
||||||
|
Dropped(T),
|
||||||
|
/// The payload previously hovered has been cancelled.
|
||||||
|
Cancelled,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DropEvent<T> {
|
||||||
|
/// Returns the payload of this event.
|
||||||
|
#[must_use]
|
||||||
|
pub fn payload(&self) -> Option<&T> {
|
||||||
|
match self {
|
||||||
|
Self::Hover(t) | Self::Dropped(t) => Some(t),
|
||||||
|
Self::Cancelled => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The behavior of a Cushy window.
|
/// The behavior of a Cushy window.
|
||||||
pub trait WindowBehavior: Sized + 'static {
|
pub trait WindowBehavior: Sized + 'static {
|
||||||
/// The type that is provided when initializing this window.
|
/// The type that is provided when initializing this window.
|
||||||
|
|
@ -1328,6 +1369,7 @@ struct OpenWindow<T> {
|
||||||
fullscreen: Tracked<Value<Option<Fullscreen>>>,
|
fullscreen: Tracked<Value<Option<Fullscreen>>>,
|
||||||
modifiers: Dynamic<Modifiers>,
|
modifiers: Dynamic<Modifiers>,
|
||||||
shortcuts: Value<ShortcutMap>,
|
shortcuts: Value<ShortcutMap>,
|
||||||
|
on_file_drop: Option<Callback<FileDrop>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> OpenWindow<T>
|
impl<T> OpenWindow<T>
|
||||||
|
|
@ -1768,6 +1810,7 @@ where
|
||||||
enabled_buttons: Tracked::from(settings.enabled_buttons).ignoring_first(),
|
enabled_buttons: Tracked::from(settings.enabled_buttons).ignoring_first(),
|
||||||
fullscreen: Tracked::from(settings.fullscreen).ignoring_first(),
|
fullscreen: Tracked::from(settings.fullscreen).ignoring_first(),
|
||||||
shortcuts: settings.shortcuts,
|
shortcuts: settings.shortcuts,
|
||||||
|
on_file_drop: settings.on_file_drop,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.synchronize_platform_window(&mut window);
|
this.synchronize_platform_window(&mut window);
|
||||||
|
|
@ -2416,6 +2459,19 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_drop(
|
||||||
|
&mut self,
|
||||||
|
drop: DropEvent<PathBuf>,
|
||||||
|
window: &kludgine::app::Window<'_, WindowCommand>,
|
||||||
|
) {
|
||||||
|
if let Some(on_file_drop) = &mut self.on_file_drop {
|
||||||
|
on_file_drop.invoke(FileDrop {
|
||||||
|
window: WindowHandle::new(window.handle(), self.redraw_status.clone()),
|
||||||
|
drop,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
|
|
@ -2634,13 +2690,31 @@ where
|
||||||
self.moved(window.inner_position(), window.outer_position());
|
self.moved(window.inner_position(), window.outer_position());
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn theme_changed(&mut self, window: kludgine::app::Window<'_, ()>) {}
|
fn dropped_file(
|
||||||
|
&mut self,
|
||||||
|
window: kludgine::app::Window<'_, WindowCommand>,
|
||||||
|
_kludgine: &mut Kludgine,
|
||||||
|
path: PathBuf,
|
||||||
|
) {
|
||||||
|
self.handle_drop(DropEvent::Dropped(path), &window);
|
||||||
|
}
|
||||||
|
|
||||||
// fn dropped_file(&mut self, window: kludgine::app::Window<'_, ()>, path: std::path::PathBuf) {}
|
fn hovered_file(
|
||||||
|
&mut self,
|
||||||
|
window: kludgine::app::Window<'_, WindowCommand>,
|
||||||
|
_kludgine: &mut Kludgine,
|
||||||
|
path: PathBuf,
|
||||||
|
) {
|
||||||
|
self.handle_drop(DropEvent::Hover(path), &window);
|
||||||
|
}
|
||||||
|
|
||||||
// fn hovered_file(&mut self, window: kludgine::app::Window<'_, ()>, path: std::path::PathBuf) {}
|
fn hovered_file_cancelled(
|
||||||
|
&mut self,
|
||||||
// fn hovered_file_cancelled(&mut self, window: kludgine::app::Window<'_, ()>) {}
|
window: kludgine::app::Window<'_, WindowCommand>,
|
||||||
|
_kludgine: &mut Kludgine,
|
||||||
|
) {
|
||||||
|
self.handle_drop(DropEvent::Cancelled, &window);
|
||||||
|
}
|
||||||
|
|
||||||
// fn received_character(&mut self, window: kludgine::app::Window<'_, ()>, char: char) {}
|
// fn received_character(&mut self, window: kludgine::app::Window<'_, ()>, char: char) {}
|
||||||
|
|
||||||
|
|
@ -2886,16 +2960,15 @@ pub(crate) mod sealed {
|
||||||
use kludgine::app::winit::window::{Fullscreen, UserAttentionType, WindowButtons, WindowLevel};
|
use kludgine::app::winit::window::{Fullscreen, UserAttentionType, WindowButtons, WindowLevel};
|
||||||
use kludgine::Color;
|
use kludgine::Color;
|
||||||
|
|
||||||
use super::{PendingWindow, WindowHandle};
|
|
||||||
use crate::app::Cushy;
|
use crate::app::Cushy;
|
||||||
use crate::context::sealed::InvalidationStatus;
|
use crate::context::sealed::InvalidationStatus;
|
||||||
use crate::context::EventContext;
|
use crate::context::EventContext;
|
||||||
use crate::fonts::FontCollection;
|
use crate::fonts::FontCollection;
|
||||||
use crate::styles::{FontFamilyList, ThemePair};
|
use crate::styles::{FontFamilyList, ThemePair};
|
||||||
use crate::value::{Dynamic, Value};
|
use crate::value::{Dynamic, Value};
|
||||||
use crate::widget::{OnceCallback, SharedCallback};
|
use crate::widget::{Callback, OnceCallback, SharedCallback};
|
||||||
use crate::widgets::shortcuts::ShortcutMap;
|
use crate::widgets::shortcuts::ShortcutMap;
|
||||||
use crate::window::{ThemeMode, WindowAttributes};
|
use crate::window::{FileDrop, PendingWindow, ThemeMode, WindowAttributes, WindowHandle};
|
||||||
|
|
||||||
pub struct Context<C> {
|
pub struct Context<C> {
|
||||||
pub user: C,
|
pub user: C,
|
||||||
|
|
@ -2947,6 +3020,7 @@ pub(crate) mod sealed {
|
||||||
pub enabled_buttons: Value<WindowButtons>,
|
pub enabled_buttons: Value<WindowButtons>,
|
||||||
pub fullscreen: Value<Option<Fullscreen>>,
|
pub fullscreen: Value<Option<Fullscreen>>,
|
||||||
pub shortcuts: Value<ShortcutMap>,
|
pub shortcuts: Value<ShortcutMap>,
|
||||||
|
pub on_file_drop: Option<Callback<FileDrop>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowExecute(Box<dyn ExecuteFunc>);
|
pub struct WindowExecute(Box<dyn ExecuteFunc>);
|
||||||
|
|
@ -3629,6 +3703,7 @@ impl StandaloneWindowBuilder {
|
||||||
fullscreen: Value::default(),
|
fullscreen: Value::default(),
|
||||||
shortcuts: Value::default(),
|
shortcuts: Value::default(),
|
||||||
on_init: None,
|
on_init: None,
|
||||||
|
on_file_drop: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue