crates/gpui2/src/app.rs 🔗
@@ -1110,6 +1110,10 @@ impl AppContext {
}
}
}
+
+ pub fn has_active_drag(&self) -> bool {
+ self.active_drag.is_some()
+ }
}
impl Context for AppContext {
Kirill Bulatov created
crates/gpui2/src/app.rs | 4 +
crates/gpui2/src/interactive.rs | 6 ++
crates/gpui2/src/window.rs | 18 ++++----
crates/gpui2_macros/src/action.rs | 1
crates/recent_projects2/src/projects.rs | 1
crates/recent_projects2/src/recent_projects.rs | 7 +-
crates/terminal2/src/terminal2.rs | 12 +++++
crates/terminal_view2/src/terminal_element.rs | 41 ++++++++++++++-----
crates/terminal_view2/src/terminal_view.rs | 10 +--
crates/workspace2/src/dock.rs | 19 ++++++--
crates/workspace2/src/workspace2.rs | 6 +-
11 files changed, 87 insertions(+), 38 deletions(-)
@@ -1110,6 +1110,10 @@ impl AppContext {
}
}
}
+
+ pub fn has_active_drag(&self) -> bool {
+ self.active_drag.is_some()
+ }
}
impl Context for AppContext {
@@ -193,6 +193,12 @@ impl Deref for MouseExitEvent {
#[derive(Debug, Clone, Default)]
pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
+impl ExternalPaths {
+ pub fn paths(&self) -> &[PathBuf] {
+ &self.0
+ }
+}
+
impl Render for ExternalPaths {
type Element = Div;
@@ -4,12 +4,12 @@ use crate::{
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model,
- ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
- MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
- PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
- RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
- Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline,
- UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
+ ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, Path,
+ Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
+ PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
+ RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet,
+ Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
+ WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::{anyhow, Context as _, Result};
use collections::HashMap;
@@ -1269,10 +1269,9 @@ impl<'a> WindowContext<'a> {
cursor_offset: position,
});
}
- InputEvent::MouseDown(MouseDownEvent {
+ InputEvent::MouseMove(MouseMoveEvent {
position,
- button: MouseButton::Left,
- click_count: 1,
+ pressed_button: Some(MouseButton::Left),
modifiers: Modifiers::default(),
})
}
@@ -1285,6 +1284,7 @@ impl<'a> WindowContext<'a> {
})
}
FileDropEvent::Submit { position } => {
+ self.activate(true);
self.window.mouse_position = position;
InputEvent::MouseUp(MouseUpEvent {
button: MouseButton::Left,
@@ -38,6 +38,7 @@ pub fn action(input: TokenStream) -> TokenStream {
let build_impl = if is_unit_struct {
quote! {
+ let _ = value;
Ok(std::boxed::Box::new(Self {}))
}
} else {
@@ -0,0 +1 @@
+gpui::actions!(OpenRecent);
@@ -1,9 +1,10 @@
mod highlighted_workspace_location;
+mod projects;
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
- actions, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task,
- View, ViewContext, WeakView,
+ AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task, View,
+ ViewContext, WeakView,
};
use highlighted_workspace_location::HighlightedWorkspaceLocation;
use ordered_float::OrderedFloat;
@@ -16,7 +17,7 @@ use workspace::{
WORKSPACE_DB,
};
-actions!(OpenRecent);
+pub use projects::OpenRecent;
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(RecentProjects::register).detach();
@@ -50,7 +50,7 @@ use std::{
use thiserror::Error;
use gpui::{
- px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
+ actions, px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
Point, ScrollWheelEvent, Size, Task, TouchPhase,
};
@@ -58,6 +58,16 @@ use gpui::{
use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
use lazy_static::lazy_static;
+actions!(
+ Clear,
+ Copy,
+ Paste,
+ ShowCharacterPalette,
+ SearchTest,
+ SendText,
+ SendKeystroke,
+);
+
///Scrolling is unbearably sluggish by default. Alacritty supports a configurable
///Scroll multiplier that is set to 3 by default. This will be removed when I
///Implement scroll bars.
@@ -1,9 +1,9 @@
use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
use gpui::{
black, div, point, px, red, relative, transparent_black, AnyElement, AsyncWindowContext,
- AvailableSpace, Bounds, DispatchPhase, Element, ElementId, FocusHandle, Font, FontStyle,
- FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, IntoElement,
- LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
+ AvailableSpace, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font,
+ FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
+ IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
};
@@ -643,13 +643,11 @@ impl TerminalElement {
let connection = connection.clone();
let focus = focus.clone();
move |e, cx| {
- if e.pressed_button.is_some() {
- if focus.is_focused(cx) {
- connection.update(cx, |terminal, cx| {
- terminal.mouse_drag(e, origin, bounds);
- cx.notify();
- })
- }
+ if e.pressed_button.is_some() && focus.is_focused(cx) && !cx.has_active_drag() {
+ connection.update(cx, |terminal, cx| {
+ terminal.mouse_drag(e, origin, bounds);
+ cx.notify();
+ })
}
}
})
@@ -806,7 +804,28 @@ impl Element for TerminalElement {
.map(|cursor| cursor.bounding_rect(origin)),
};
- let mut this = self.register_mouse_listeners(origin, layout.mode, bounds, cx);
+ let terminal_focus_handle = self.focus.clone();
+ let terminal_handle = self.terminal.clone();
+ let mut this: TerminalElement = self
+ .register_mouse_listeners(origin, layout.mode, bounds, cx)
+ .drag_over::<ExternalPaths>(|style| {
+ // todo!() why does not it work? z-index of elements?
+ style.bg(cx.theme().colors().ghost_element_hover)
+ })
+ .on_drop::<ExternalPaths>(move |external_paths, cx| {
+ cx.focus(&terminal_focus_handle);
+ let mut new_text = external_paths
+ .read(cx)
+ .paths()
+ .iter()
+ .map(|path| format!(" {path:?}"))
+ .join("");
+ new_text.push(' ');
+ terminal_handle.update(cx, |terminal, _| {
+ // todo!() long paths are not displayed properly albeit the text is there
+ terminal.paste(&new_text);
+ });
+ });
let interactivity = mem::take(&mut this.interactivity);
@@ -9,9 +9,9 @@ pub mod terminal_panel;
// use crate::terminal_element::TerminalElement;
use editor::{scroll::autoscroll::Autoscroll, Editor};
use gpui::{
- actions, div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle,
- Focusable, FocusableElement, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model,
- MouseButton, MouseDownEvent, Pixels, Render, Subscription, Task, View, VisualContext, WeakView,
+ div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle, Focusable,
+ FocusableElement, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model, MouseButton,
+ MouseDownEvent, Pixels, Render, Subscription, Task, View, VisualContext, WeakView,
};
use language::Bias;
use persistence::TERMINAL_DB;
@@ -22,7 +22,7 @@ use terminal::{
term::{search::RegexSearch, TermMode},
},
terminal_settings::{TerminalBlink, TerminalSettings, WorkingDirectory},
- Event, MaybeNavigationTarget, Terminal,
+ Clear, Copy, Event, MaybeNavigationTarget, Paste, ShowCharacterPalette, Terminal,
};
use terminal_element::TerminalElement;
use ui::{h_stack, prelude::*, ContextMenu, Icon, IconElement, Label};
@@ -60,8 +60,6 @@ pub struct SendText(String);
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
pub struct SendKeystroke(String);
-actions!(Clear, Copy, Paste, ShowCharacterPalette, SearchTest);
-
pub fn init(cx: &mut AppContext) {
terminal_panel::init(cx);
terminal::init(cx);
@@ -133,13 +133,13 @@ pub struct Dock {
panel_entries: Vec<PanelEntry>,
is_open: bool,
active_panel_index: usize,
+ focus_handle: FocusHandle,
+ focus_subscription: Subscription,
}
impl FocusableView for Dock {
- fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
- self.panel_entries[self.active_panel_index]
- .panel
- .focus_handle(cx)
+ fn focus_handle(&self, _: &AppContext) -> FocusHandle {
+ self.focus_handle.clone()
}
}
@@ -190,12 +190,20 @@ pub struct PanelButtons {
}
impl Dock {
- pub fn new(position: DockPosition) -> Self {
+ pub fn new(position: DockPosition, cx: &mut ViewContext<'_, Self>) -> Self {
+ let focus_handle = cx.focus_handle();
+ let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
+ if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
+ active_entry.panel.focus_handle(cx).focus(cx)
+ }
+ });
Self {
position,
panel_entries: Default::default(),
active_panel_index: 0,
is_open: false,
+ focus_handle,
+ focus_subscription,
}
}
@@ -207,6 +215,7 @@ impl Dock {
self.is_open
}
+ // todo!()
// pub fn has_focus(&self, cx: &WindowContext) -> bool {
// self.visible_panel()
// .map_or(false, |panel| panel.has_focus(cx))
@@ -566,9 +566,9 @@ impl Workspace {
cx.emit(Event::WorkspaceCreated(weak_handle.clone()));
- let left_dock = cx.build_view(|_| Dock::new(DockPosition::Left));
- let bottom_dock = cx.build_view(|_| Dock::new(DockPosition::Bottom));
- let right_dock = cx.build_view(|_| Dock::new(DockPosition::Right));
+ let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx));
+ let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx));
+ let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx));
let left_dock_buttons =
cx.build_view(|cx| PanelButtons::new(left_dock.clone(), weak_handle.clone(), cx));
let bottom_dock_buttons =