mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-30 21:26:48 -06:00
Docking: files dropped on a floating panel window open or place
craft-ui reports drops on native floating windows in DockOutput::window_files; they go through the main window's drop handling in the same frame.
This commit is contained in:
@@ -1320,12 +1320,7 @@ impl DesignApp {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let (dropped, pointer) = ctx.input(|i| (i.raw.dropped_files.clone(), i.pointer.hover_pos()));
|
||||
for f in dropped {
|
||||
let p = f.path().to_string_lossy().to_string();
|
||||
if !p.is_empty() {
|
||||
let _ = self.open_dropped_at(&p, pointer);
|
||||
}
|
||||
}
|
||||
self.open_dropped_files(&dropped, pointer);
|
||||
}
|
||||
self.handle_quit(ctx);
|
||||
}
|
||||
@@ -1482,6 +1477,18 @@ impl DesignApp {
|
||||
self.open_dropped_at(path, None)
|
||||
}
|
||||
|
||||
/// Open or place each file dropped on the main window or on a floating panel's own window.
|
||||
/// `pointer` is in the main window's coordinates.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) fn open_dropped_files(&mut self, files: &[egui::DroppedFileHandle], pointer: Option<egui::Pos2>) {
|
||||
for f in files {
|
||||
let p = f.path().to_string_lossy().to_string();
|
||||
if !p.is_empty() {
|
||||
let _ = self.open_dropped_at(&p, pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Self::open_dropped`] at the pointer: a graphic's top left lands where the file was
|
||||
/// dropped on the canvas, text goes to a new frame on the document page there.
|
||||
pub fn open_dropped_at(&mut self, path: &str, pointer: Option<egui::Pos2>) -> Result<Value, String> {
|
||||
|
||||
@@ -1086,10 +1086,21 @@ pub(crate) fn show(app: &mut DesignApp, ui: &mut egui::Ui) {
|
||||
if let Some(panel) = focused.filter(|panel| panel == CANVAS || layout_of(app).contains(panel)) {
|
||||
app.ui.docking_focused = Some(panel);
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
open_window_drops(app, &output.window_files);
|
||||
// Keys pressed in a floating panel's own OS window run the main window's shortcuts.
|
||||
crate::menus::forwarded_shortcuts(app, ui.ctx(), output.forwarded_events, output.forwarded_modifiers.unwrap_or_default());
|
||||
}
|
||||
|
||||
/// Files dropped on a floating panel's own OS window open or place as drops on the main window
|
||||
/// do. The pointer there is in that window's coordinates, so a placed file gets no canvas point.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn open_window_drops(app: &mut DesignApp, windows: &[craft_ui::docking::WindowFiles<String>]) {
|
||||
for window in windows {
|
||||
app.open_dropped_files(&window.dropped, None);
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a modal (a dialog, About or Quick Apply) is open. Floating panels in their own OS
|
||||
/// windows take no input then, as the main window behind the modal doesn't.
|
||||
pub(crate) fn modal_open(app: &DesignApp) -> bool {
|
||||
|
||||
@@ -1242,3 +1242,36 @@ fn dialogs_about_and_quick_apply_block_native_floating_windows() {
|
||||
app.ui.palette = None;
|
||||
assert!(!modal_open(&app));
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[test]
|
||||
fn a_document_dropped_on_a_floating_panel_window_opens() {
|
||||
#[derive(Debug)]
|
||||
struct Dropped(std::path::PathBuf);
|
||||
impl egui::DroppedFile for Dropped {
|
||||
fn path(&self) -> &std::path::Path {
|
||||
&self.0
|
||||
}
|
||||
fn bytes(&self) -> Result<Vec<u8>, String> {
|
||||
std::fs::read(&self.0).map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let path = dir.path().join("dropped.designcraft");
|
||||
let mut saved = app();
|
||||
saved.run("file.new", json!({})).unwrap();
|
||||
saved.run("file.save", json!({"path": path})).unwrap();
|
||||
|
||||
let mut app = app();
|
||||
assert!(app.session.documents().is_empty());
|
||||
let files = craft_ui::docking::WindowFiles {
|
||||
window: 1,
|
||||
viewport: egui::ViewportId::from_hash_of("float"),
|
||||
panel: "layers".to_owned(),
|
||||
pos: None,
|
||||
hovered: Vec::new(),
|
||||
dropped: vec![std::sync::Arc::new(Dropped(path.clone())) as egui::DroppedFileHandle],
|
||||
};
|
||||
open_window_drops(&mut app, &[files]);
|
||||
assert_eq!(app.session.documents().len(), 1, "the dropped document opens");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user