Detailed changes
@@ -821,7 +821,7 @@ impl<G: 'static> DerefMut for GlobalLease<G> {
}
pub(crate) struct AnyDrag {
- pub drag_handle_view: AnyView,
+ pub drag_handle_view: Option<AnyView>,
pub cursor_offset: Point<Pixels>,
pub state: AnyBox,
pub state_type: TypeId,
@@ -374,10 +374,12 @@ pub trait StatefulInteractive: StatelessInteractive {
Some(Arc::new(move |view_state, cursor_offset, cx| {
let drag = listener(view_state, cx);
let view_handle = cx.handle().upgrade().unwrap();
- let drag_handle_view = view(view_handle, move |view_state, cx| {
- (drag.render_drag_handle)(view_state, cx)
- })
- .into_any();
+ let drag_handle_view = Some(
+ view(view_handle, move |view_state, cx| {
+ (drag.render_drag_handle)(view_state, cx)
+ })
+ .into_any(),
+ );
AnyDrag {
drag_handle_view,
cursor_offset,
@@ -780,11 +782,7 @@ impl GroupBounds {
}
pub fn pop(name: &SharedString, cx: &mut AppContext) {
- cx.default_global::<Self>()
- .0
- .get_mut(name)
- .unwrap()
- .pop();
+ cx.default_global::<Self>().0.get_mut(name).unwrap().pop();
}
}
@@ -1035,16 +1033,21 @@ impl Deref for MouseExitEvent {
}
#[derive(Debug, Clone, Default)]
+pub struct DroppedFiles(pub(crate) SmallVec<[PathBuf; 2]>);
+
+#[derive(Debug, Clone)]
pub enum FileDropEvent {
- #[default]
- End,
+ Entered {
+ position: Point<Pixels>,
+ files: DroppedFiles,
+ },
Pending {
position: Point<Pixels>,
},
Submit {
position: Point<Pixels>,
- paths: Vec<PathBuf>,
},
+ Exited,
}
#[derive(Clone, Debug)]
@@ -1054,7 +1057,7 @@ pub enum InputEvent {
ModifiersChanged(ModifiersChangedEvent),
MouseDown(MouseDownEvent),
MouseUp(MouseUpEvent),
- MouseMoved(MouseMoveEvent),
+ MouseMove(MouseMoveEvent),
MouseExited(MouseExitEvent),
ScrollWheel(ScrollWheelEvent),
FileDrop(FileDropEvent),
@@ -1068,12 +1071,14 @@ impl InputEvent {
InputEvent::ModifiersChanged { .. } => None,
InputEvent::MouseDown(event) => Some(event.position),
InputEvent::MouseUp(event) => Some(event.position),
- InputEvent::MouseMoved(event) => Some(event.position),
+ InputEvent::MouseMove(event) => Some(event.position),
InputEvent::MouseExited(event) => Some(event.position),
InputEvent::ScrollWheel(event) => Some(event.position),
- InputEvent::FileDrop(FileDropEvent::End) => None,
+ InputEvent::FileDrop(FileDropEvent::Exited) => None,
InputEvent::FileDrop(
- FileDropEvent::Pending { position } | FileDropEvent::Submit { position, .. },
+ FileDropEvent::Entered { position, .. }
+ | FileDropEvent::Pending { position, .. }
+ | FileDropEvent::Submit { position, .. },
) => Some(*position),
}
}
@@ -1085,7 +1090,7 @@ impl InputEvent {
InputEvent::ModifiersChanged { .. } => None,
InputEvent::MouseDown(event) => Some(event),
InputEvent::MouseUp(event) => Some(event),
- InputEvent::MouseMoved(event) => Some(event),
+ InputEvent::MouseMove(event) => Some(event),
InputEvent::MouseExited(event) => Some(event),
InputEvent::ScrollWheel(event) => Some(event),
InputEvent::FileDrop(event) => Some(event),
@@ -1099,7 +1104,7 @@ impl InputEvent {
InputEvent::ModifiersChanged(event) => Some(event),
InputEvent::MouseDown(_) => None,
InputEvent::MouseUp(_) => None,
- InputEvent::MouseMoved(_) => None,
+ InputEvent::MouseMove(_) => None,
InputEvent::MouseExited(_) => None,
InputEvent::ScrollWheel(_) => None,
InputEvent::FileDrop(_) => None,
@@ -202,7 +202,7 @@ impl InputEvent {
};
window_height.map(|window_height| {
- Self::MouseMoved(MouseMoveEvent {
+ Self::MouseMove(MouseMoveEvent {
pressed_button: Some(pressed_button),
position: point(
px(native_event.locationInWindow().x as f32),
@@ -213,7 +213,7 @@ impl InputEvent {
})
}
NSEventType::NSMouseMoved => window_height.map(|window_height| {
- Self::MouseMoved(MouseMoveEvent {
+ Self::MouseMove(MouseMoveEvent {
position: point(
px(native_event.locationInWindow().x as f32),
window_height - px(native_event.locationInWindow().y as f32),
@@ -1,10 +1,10 @@
use super::{display_bounds_from_native, ns_string, MacDisplay, MetalRenderer, NSRange};
use crate::{
- display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, Executor, FileDropEvent,
- GlobalPixels, InputEvent, KeyDownEvent, Keystroke, Modifiers, ModifiersChangedEvent,
- MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, PlatformAtlas,
- PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, Scene, Size, Timer,
- WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
+ display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, DroppedFiles, Executor,
+ FileDropEvent, GlobalPixels, InputEvent, KeyDownEvent, Keystroke, Modifiers,
+ ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
+ PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, Scene, Size,
+ Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
};
use block::ConcreteBlock;
use cocoa::{
@@ -31,6 +31,7 @@ use objc::{
sel, sel_impl,
};
use parking_lot::Mutex;
+use smallvec::SmallVec;
use std::{
any::Any,
cell::{Cell, RefCell},
@@ -1177,7 +1178,7 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
};
match &event {
- InputEvent::MouseMoved(
+ InputEvent::MouseMove(
event @ MouseMoveEvent {
pressed_button: Some(_),
..
@@ -1194,7 +1195,7 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
.detach();
}
- InputEvent::MouseMoved(_) if !(is_active || lock.kind == WindowKind::PopUp) => return,
+ InputEvent::MouseMove(_) if !(is_active || lock.kind == WindowKind::PopUp) => return,
InputEvent::MouseUp(MouseUpEvent {
button: MouseButton::Left,
@@ -1633,11 +1634,14 @@ extern "C" fn accepts_first_mouse(this: &Object, _: Sel, _: id) -> BOOL {
extern "C" fn dragging_entered(this: &Object, _: Sel, dragging_info: id) -> NSDragOperation {
let window_state = unsafe { get_window_state(this) };
- let position = drag_event_position(&window_state, dragging_info);
- if send_new_event(
- &window_state,
- InputEvent::FileDrop(FileDropEvent::Pending { position }),
- ) {
+ if send_new_event(&window_state, {
+ let position = drag_event_position(&window_state, dragging_info);
+ let paths = external_paths_from_event(dragging_info);
+ InputEvent::FileDrop(FileDropEvent::Entered {
+ position,
+ files: paths,
+ })
+ }) {
NSDragOperationCopy
} else {
NSDragOperationNone
@@ -1659,26 +1663,17 @@ extern "C" fn dragging_updated(this: &Object, _: Sel, dragging_info: id) -> NSDr
extern "C" fn dragging_exited(this: &Object, _: Sel, _: id) {
let window_state = unsafe { get_window_state(this) };
- send_new_event(&window_state, InputEvent::FileDrop(FileDropEvent::End));
+ send_new_event(&window_state, InputEvent::FileDrop(FileDropEvent::Exited));
}
extern "C" fn perform_drag_operation(this: &Object, _: Sel, dragging_info: id) -> BOOL {
- let mut paths = Vec::new();
- let pb: id = unsafe { msg_send![dragging_info, draggingPasteboard] };
- let filenames = unsafe { NSPasteboard::propertyListForType(pb, NSFilenamesPboardType) };
- for file in unsafe { filenames.iter() } {
- let path = unsafe {
- let f = NSString::UTF8String(file);
- CStr::from_ptr(f).to_string_lossy().into_owned()
- };
- paths.push(PathBuf::from(path))
- }
+ let files = external_paths_from_event(dragging_info);
let window_state = unsafe { get_window_state(this) };
let position = drag_event_position(&window_state, dragging_info);
if send_new_event(
&window_state,
- InputEvent::FileDrop(FileDropEvent::Submit { position, paths }),
+ InputEvent::FileDrop(FileDropEvent::Submit { position }),
) {
YES
} else {
@@ -1686,9 +1681,23 @@ extern "C" fn perform_drag_operation(this: &Object, _: Sel, dragging_info: id) -
}
}
+fn external_paths_from_event(dragging_info: *mut Object) -> DroppedFiles {
+ let mut paths = SmallVec::new();
+ let pasteboard: id = unsafe { msg_send![dragging_info, draggingPasteboard] };
+ let filenames = unsafe { NSPasteboard::propertyListForType(pasteboard, NSFilenamesPboardType) };
+ for file in unsafe { filenames.iter() } {
+ let path = unsafe {
+ let f = NSString::UTF8String(file);
+ CStr::from_ptr(f).to_string_lossy().into_owned()
+ };
+ paths.push(PathBuf::from(path))
+ }
+ DroppedFiles(paths)
+}
+
extern "C" fn conclude_drag_operation(this: &Object, _: Sel, _: id) {
let window_state = unsafe { get_window_state(this) };
- send_new_event(&window_state, InputEvent::FileDrop(FileDropEvent::End));
+ send_new_event(&window_state, InputEvent::FileDrop(FileDropEvent::Exited));
}
async fn synthetic_drag(
@@ -1703,7 +1712,7 @@ async fn synthetic_drag(
if lock.synthetic_drag_counter == drag_id {
if let Some(mut callback) = lock.event_callback.take() {
drop(lock);
- callback(InputEvent::MouseMoved(event.clone()));
+ callback(InputEvent::MouseMove(event.clone()));
window_state.lock().event_callback = Some(callback);
}
} else {
@@ -1,13 +1,14 @@
use crate::{
- px, size, Action, AnyBox, AnyView, AppContext, AsyncWindowContext, AvailableSpace, Bounds,
- BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect, Element,
- EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Handle,
- Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
- MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, MouseUpEvent, Path, Pixels,
- PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
- RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
- Style, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle,
- WindowOptions, SUBPIXEL_VARIANTS,
+ px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
+ Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, DroppedFiles,
+ Edges, Effect, Element, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId,
+ GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
+ KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Modifiers, MonochromeSprite,
+ MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas,
+ PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
+ RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription,
+ TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
+ SUBPIXEL_VARIANTS,
};
use anyhow::Result;
use collections::HashMap;
@@ -816,7 +817,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
cx.with_element_offset(Some(offset), |cx| {
let available_space =
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
- draw_any_view(&mut active_drag.drag_handle_view, available_space, cx);
+ if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
+ draw_any_view(drag_handle_view, available_space, cx);
+ }
cx.active_drag = Some(active_drag);
});
});
@@ -889,27 +892,48 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
fn dispatch_event(&mut self, event: InputEvent) -> bool {
- if let Some(any_mouse_event) = event.mouse_event() {
- if let Some(MouseMoveEvent { position, .. }) = any_mouse_event.downcast_ref() {
- self.window.mouse_position = *position;
+ let event = match event {
+ InputEvent::MouseMove(mouse_move) => {
+ self.window.mouse_position = mouse_move.position;
+ InputEvent::MouseMove(mouse_move)
}
-
- match any_mouse_event.downcast_ref() {
- Some(FileDropEvent::Pending { position }) => {
- dbg!("FileDropEvent::Pending", position);
- return true;
- }
- Some(FileDropEvent::Submit { position, paths }) => {
- dbg!("FileDropEvent::Submit", position, paths);
- return true;
- }
- Some(FileDropEvent::End) => {
- self.active_drag = None;
- return true;
+ InputEvent::FileDrop(file_drop) => match file_drop {
+ FileDropEvent::Entered { position, files } => {
+ self.active_drag.get_or_insert_with(|| AnyDrag {
+ drag_handle_view: None,
+ cursor_offset: position,
+ state: Box::new(files),
+ state_type: TypeId::of::<DroppedFiles>(),
+ });
+ InputEvent::MouseDown(MouseDownEvent {
+ position,
+ button: MouseButton::Left,
+ click_count: 1,
+ modifiers: Modifiers::default(),
+ })
}
- _ => {}
- }
+ FileDropEvent::Pending { position } => InputEvent::MouseMove(MouseMoveEvent {
+ position,
+ pressed_button: Some(MouseButton::Left),
+ modifiers: Modifiers::default(),
+ }),
+ FileDropEvent::Submit { position } => InputEvent::MouseUp(MouseUpEvent {
+ button: MouseButton::Left,
+ position,
+ modifiers: Modifiers::default(),
+ click_count: 1,
+ }),
+ FileDropEvent::Exited => InputEvent::MouseUp(MouseUpEvent {
+ button: MouseButton::Left,
+ position: Point::default(),
+ modifiers: Modifiers::default(),
+ click_count: 1,
+ }),
+ },
+ _ => event,
+ };
+ if let Some(any_mouse_event) = event.mouse_event() {
// Handlers may set this to false by calling `stop_propagation`
self.app.propagate_event = true;
self.window.default_prevented = false;
@@ -305,7 +305,18 @@ fn box_prefixes() -> Vec<(&'static str, bool, Vec<TokenStream2>, &'static str)>
vec![quote! { padding.right }],
"Sets the right padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)"
),
- ("top", true, vec![quote! { inset.top }], "Sets the top value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",),
+ (
+ "inset",
+ true,
+ vec![quote! { inset.top }, quote! { inset.right }, quote! { inset.bottom }, quote! { inset.left }],
+ "Sets the top, right, bottom, and left values of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
+ ),
+ (
+ "top",
+ true,
+ vec![quote! { inset.top }],
+ "Sets the top value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
+ ),
(
"bottom",
true,
@@ -159,8 +159,6 @@ pub struct ThemeColor {
impl std::fmt::Debug for ThemeColor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- dbg!("ThemeColor debug");
-
f.debug_struct("ThemeColor")
.field("transparent", &self.transparent.to_rgb().to_hex())
.field(
@@ -1,6 +1,6 @@
use std::marker::PhantomData;
-use gpui2::{hsla, AnyElement, ElementId, Hsla, Length, Size};
+use gpui2::{hsla, red, AnyElement, DroppedFiles, ElementId, Hsla, Length, Size};
use smallvec::SmallVec;
use crate::prelude::*;
@@ -50,8 +50,19 @@ impl<S: 'static + Send + Sync> Pane<S> {
.bg(self.fill)
.w(self.size.width)
.h(self.size.height)
- .overflow_y_scroll()
- .children(self.children.drain(..))
+ .relative()
+ .children(cx.stack(0, |_| self.children.drain(..)))
+ .child(cx.stack(1, |_| {
+ // TODO kb! Figure out why we can't we see the red background when we drag a file over this div.
+ div()
+ .id("drag-target")
+ .drag_over::<DroppedFiles>(|d| d.bg(red()))
+ .on_drop(|_, files: DroppedFiles, _| {
+ dbg!("dropped files!", files);
+ })
+ .absolute()
+ .inset_0()
+ }))
}
}
@@ -179,8 +179,6 @@ impl Workspace {
let color = ThemeColor::new(cx);
- dbg!(color);
-
// HACK: This should happen inside of `debug_toggle_user_settings`, but
// we don't have `cx.global::<FakeSettings>()` in event handlers at the moment.
// Need to talk with Nathan/Antonio about this.