Detailed changes
@@ -254,6 +254,13 @@ where
return;
}
+ if let Some(mouse_cursor) = style.mouse_cursor {
+ let hovered = bounds.contains_point(&cx.mouse_position());
+ if hovered {
+ cx.set_cursor_style(mouse_cursor);
+ }
+ }
+
if let Some(group) = this.group.clone() {
GroupBounds::push(group, bounds, cx);
}
@@ -1,8 +1,8 @@
use crate::{
black, phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask,
- Corners, CornersRefinement, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures,
- FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, Rgba,
- SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext, WindowContext,
+ Corners, CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font,
+ FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems,
+ Result, Rgba, SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext, WindowContext,
};
use refineable::{Cascade, Refineable};
use smallvec::SmallVec;
@@ -101,6 +101,9 @@ pub struct Style {
/// TEXT
pub text: TextStyleRefinement,
+ /// The mouse cursor style shown when the mouse pointer is over an element.
+ pub mouse_cursor: Option<CursorStyle>,
+
pub z_index: Option<u32>,
}
@@ -339,6 +342,7 @@ impl Default for Style {
corner_radii: Corners::default(),
box_shadow: Default::default(),
text: TextStyleRefinement::default(),
+ mouse_cursor: None,
z_index: None,
}
}
@@ -1,7 +1,7 @@
use crate::{
- self as gpui2, hsla, point, px, relative, rems, AlignItems, DefiniteLength, Display, Fill,
- FlexDirection, Hsla, JustifyContent, Length, Position, Rems, SharedString, StyleRefinement,
- Visibility,
+ self as gpui2, hsla, point, px, relative, rems, AlignItems, CursorStyle, DefiniteLength,
+ Display, Fill, FlexDirection, Hsla, JustifyContent, Length, Position, Rems, SharedString,
+ StyleRefinement, Visibility,
};
use crate::{BoxShadow, TextStyleRefinement};
use smallvec::smallvec;
@@ -81,6 +81,34 @@ pub trait Styled {
self
}
+ fn cursor(mut self, cursor: CursorStyle) -> Self
+ where
+ Self: Sized,
+ {
+ self.style().mouse_cursor = Some(cursor);
+ self
+ }
+
+ /// Sets the cursor style when hovering an element to `default`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_default(mut self) -> Self
+ where
+ Self: Sized,
+ {
+ self.style().mouse_cursor = Some(CursorStyle::Arrow);
+ self
+ }
+
+ /// Sets the cursor style when hovering an element to `pointer`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_pointer(mut self) -> Self
+ where
+ Self: Sized,
+ {
+ self.style().mouse_cursor = Some(CursorStyle::PointingHand);
+ self
+ }
+
/// Sets the flex direction of the element to `column`.
/// [Docs](https://tailwindcss.com/docs/flex-direction#column)
fn flex_col(mut self) -> Self
@@ -1,14 +1,14 @@
use crate::{
px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
- Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
- Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId,
- Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
- Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
- MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformWindow, Point,
- PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
- RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet,
- Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
- WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
+ Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DispatchContext, DisplayId,
+ Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId,
+ GlobalElementId, GlyphId, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
+ KeyMatcher, Keystroke, LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton,
+ MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay,
+ PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
+ RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
+ Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View,
+ VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::{anyhow, Result};
use collections::HashMap;
@@ -190,6 +190,7 @@ pub struct Window {
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
default_prevented: bool,
mouse_position: Point<Pixels>,
+ requested_cursor_style: Option<CursorStyle>,
scale_factor: f32,
bounds: WindowBounds,
bounds_observers: SubscriberSet<(), AnyObserver>,
@@ -283,6 +284,7 @@ impl Window {
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
default_prevented: true,
mouse_position,
+ requested_cursor_style: None,
scale_factor,
bounds,
bounds_observers: SubscriberSet::new(),
@@ -669,6 +671,10 @@ impl<'a> WindowContext<'a> {
self.window.mouse_position
}
+ pub fn set_cursor_style(&mut self, style: CursorStyle) {
+ self.window.requested_cursor_style = Some(style)
+ }
+
/// Called during painting to invoke the given closure in a new stacking context. The given
/// z-index is interpreted relative to the previous call to `stack`.
pub fn stack<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
@@ -987,6 +993,13 @@ impl<'a> WindowContext<'a> {
let scene = self.window.scene_builder.build();
self.window.platform_window.draw(scene);
+ let cursor_style = self
+ .window
+ .requested_cursor_style
+ .take()
+ .unwrap_or(CursorStyle::Arrow);
+ self.platform.set_cursor_style(cursor_style);
+
self.window.dirty = false;
}
@@ -9,8 +9,9 @@ use crate::{
use anyhow::Result;
use collections::{HashMap, HashSet, VecDeque};
use gpui::{
- AppContext, AsyncWindowContext, Component, Div, EntityId, EventEmitter, FocusHandle, Model,
- PromptLevel, Render, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
+ AppContext, AsyncWindowContext, Component, CursorStyle, Div, EntityId, EventEmitter,
+ FocusHandle, Model, PromptLevel, Render, Task, View, ViewContext, VisualContext, WeakView,
+ WindowContext,
};
use parking_lot::Mutex;
use project2::{Project, ProjectEntryId, ProjectPath};
@@ -1397,6 +1398,7 @@ impl Pane {
div()
.group("")
.id(item.id())
+ .cursor_pointer()
// .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
// .on_drop(|_view, state: View<DraggedTab>, cx| {
@@ -208,7 +208,6 @@ fn main() {
if stdout_is_a_pty() {
cx.activate(true);
let urls = collect_url_args();
- dbg!(&urls);
if !urls.is_empty() {
listener.open_urls(urls)
}