feat(open): drag & drop files onto the window (#344)
Dropping a supported file (dwg / dxf / bak / sv$, case-insensitive) opens it through the existing open flow: an already-open drawing switches to its tab, a load in progress queues the drop behind it (multi-file drops arrive one event each), anything unsupported reports on the command line instead of failing silently in the parser. Platform support follows winit 0.30: Windows, macOS and Linux/X11 (incl. XWayland) deliver FileDropped; the Wayland backend does not implement file drag & drop yet, so drops are inert there until winit gains it. Closes #344 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
4c99a5c70d
commit
95fcabaacb
3 changed files with 33 additions and 0 deletions
|
|
@ -1260,6 +1260,8 @@ pub enum Message {
|
|||
/// File picker returned. `Some((path, size_in_bytes))` → start loading;
|
||||
/// `None` → user cancelled the dialog (no overlay shown).
|
||||
OpenPathPicked(Option<(PathBuf, u64)>),
|
||||
/// A file was dragged from the desktop and dropped on the window (#344).
|
||||
FileDropped(PathBuf),
|
||||
/// Open a path from the Start tab's recent-documents list (skips the
|
||||
/// file picker; the path is already known).
|
||||
OpenRecent(PathBuf),
|
||||
|
|
|
|||
|
|
@ -292,6 +292,34 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
|
||||
Message::FileDropped(path) => {
|
||||
// Desktop drag & drop (#344): accept the formats the Open
|
||||
// dialog accepts — a drop has no picker filter, so anything
|
||||
// else reports instead of failing silently in the parser.
|
||||
let ext = path
|
||||
.extension()
|
||||
.map(|e| e.to_string_lossy().to_lowercase())
|
||||
.unwrap_or_default();
|
||||
if !matches!(ext.as_str(), "dwg" | "dxf" | "bak" | "sv$") {
|
||||
self.command_line.push_error(&format!(
|
||||
"Unsupported file type: {}",
|
||||
path.display()
|
||||
));
|
||||
return Task::none();
|
||||
}
|
||||
// Already open → switch to its tab; a load in progress →
|
||||
// queue behind it (multi-file drops arrive one event each).
|
||||
if let Some(idx) = self.tab_showing(&path) {
|
||||
return self.update(Message::TabSwitch(idx));
|
||||
}
|
||||
if self.opening.is_some() {
|
||||
self.pending_opens.push_back(path);
|
||||
Task::none()
|
||||
} else {
|
||||
self.update(Message::OpenRecent(path))
|
||||
}
|
||||
}
|
||||
|
||||
Message::RecentRemove(path) => {
|
||||
self.remove_recent(&path);
|
||||
Task::none()
|
||||
|
|
|
|||
|
|
@ -1732,6 +1732,9 @@ impl OpenCADStudio {
|
|||
iced::Event::Window(window::Event::Resized(sz)) => {
|
||||
Some(Message::WindowResized(sz.width as f32, sz.height as f32))
|
||||
}
|
||||
iced::Event::Window(window::Event::FileDropped(path)) => {
|
||||
Some(Message::FileDropped(path))
|
||||
}
|
||||
iced::Event::Keyboard(keyboard::Event::ModifiersChanged(m)) => {
|
||||
// `command()` is Cmd on macOS, Ctrl elsewhere — the
|
||||
// platform multi-select modifier for the layer list.
|
||||
|
|
|
|||
Loading…
Reference in a new issue