Add PointingHand on tabs

This commit is contained in:
Conrad Irwin 2023-11-03 11:30:15 -06:00
parent c604a2e34e
commit d73c54f604
6 changed files with 71 additions and 18 deletions

View file

@ -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);
}

View file

@ -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,
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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| {

View file

@ -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)
}