Detailed changes
@@ -472,13 +472,27 @@ pub enum PromptLevel {
Critical,
}
+/// Change the style of the cursor (pointer)
#[derive(Copy, Clone, Debug)]
pub enum CursorStyle {
Arrow,
+ IBeam,
+ Crosshair,
+ ClosedHand,
+ OpenHand,
+ PointingHand,
+ ResizeLeft,
+ ResizeRight,
ResizeLeftRight,
+ ResizeUp,
+ ResizeDown,
ResizeUpDown,
- PointingHand,
- IBeam,
+ DisappearingItem,
+ IBeamCursorForVerticalLayout,
+ OperationNotAllowed,
+ DragLink,
+ DragCopy,
+ ContextualMenu,
}
impl Default for CursorStyle {
@@ -724,16 +724,35 @@ impl Platform for MacPlatform {
}
}
+ /// Match cusor style to to one of the styles available
+ /// in macOS's [NSCursor](https://developer.apple.com/documentation/appkit/nscursor).
fn set_cursor_style(&self, style: CursorStyle) {
unsafe {
let new_cursor: id = match style {
CursorStyle::Arrow => msg_send![class!(NSCursor), arrowCursor],
- CursorStyle::ResizeLeftRight => {
- msg_send![class!(NSCursor), resizeLeftRightCursor]
- }
- CursorStyle::ResizeUpDown => msg_send![class!(NSCursor), resizeUpDownCursor],
- CursorStyle::PointingHand => msg_send![class!(NSCursor), pointingHandCursor],
CursorStyle::IBeam => msg_send![class!(NSCursor), IBeamCursor],
+ CursorStyle::Crosshair => msg_send![class!(NSCursor), crosshairCursor],
+ CursorStyle::ClosedHand => msg_send![class!(NSCursor), closedHandCursor],
+ CursorStyle::OpenHand => msg_send![class!(NSCursor), openHandCursor],
+ CursorStyle::PointingHand => msg_send![class!(NSCursor), pointingHandCursor],
+ CursorStyle::ResizeLeft => msg_send![class!(NSCursor), resizeLeftCursor],
+ CursorStyle::ResizeRight => msg_send![class!(NSCursor), resizeRightCursor],
+ CursorStyle::ResizeLeftRight => msg_send![class!(NSCursor), resizeLeftRightCursor],
+ CursorStyle::ResizeUp => msg_send![class!(NSCursor), resizeUpCursor],
+ CursorStyle::ResizeDown => msg_send![class!(NSCursor), resizeDownCursor],
+ CursorStyle::ResizeUpDown => msg_send![class!(NSCursor), resizeUpDownCursor],
+ CursorStyle::DisappearingItem => {
+ msg_send![class!(NSCursor), disappearingItemCursor]
+ }
+ CursorStyle::IBeamCursorForVerticalLayout => {
+ msg_send![class!(NSCursor), IBeamCursorForVerticalLayout]
+ }
+ CursorStyle::OperationNotAllowed => {
+ msg_send![class!(NSCursor), operationNotAllowedCursor]
+ }
+ CursorStyle::DragLink => msg_send![class!(NSCursor), dragLinkCursor],
+ CursorStyle::DragCopy => msg_send![class!(NSCursor), dragCopyCursor],
+ CursorStyle::ContextualMenu => msg_send![class!(NSCursor), contextualMenuCursor],
};
let old_cursor: id = msg_send![class!(NSCursor), currentCursor];
@@ -101,6 +101,125 @@ pub trait Styled: Sized {
self
}
+ /// Sets cursor style when hovering over an element to `text`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_text(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::IBeam);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `move`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_move(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ClosedHand);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `not-allowed`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_not_allowed(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::OperationNotAllowed);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `context-menu`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_context_menu(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ContextualMenu);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `crosshair`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_crosshair(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::Crosshair);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `vertical-text`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_vertical_text(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::IBeamCursorForVerticalLayout);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `alias`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_alias(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::DragLink);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `copy`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_copy(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::DragCopy);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `no-drop`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_no_drop(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::OperationNotAllowed);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `grab`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_grab(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::OpenHand);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `grabbing`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_grabbing(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ClosedHand);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `col-resize`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_col_resize(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ResizeLeftRight);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `row-resize`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_row_resize(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ResizeUpDown);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `n-resize`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_n_resize(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ResizeUp);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `e-resize`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_e_resize(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ResizeRight);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `s-resize`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_s_resize(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ResizeDown);
+ self
+ }
+
+ /// Sets cursor style when hovering over an element to `w-resize`.
+ /// [Docs](https://tailwindcss.com/docs/cursor)
+ fn cursor_w_resize(mut self) -> Self {
+ self.style().mouse_cursor = Some(CursorStyle::ResizeLeft);
+ self
+ }
+
/// Sets the whitespace of the element to `normal`.
/// [Docs](https://tailwindcss.com/docs/whitespace#normal)
fn whitespace_normal(mut self) -> Self {
@@ -1,4 +1,5 @@
mod auto_height_editor;
+mod cursor;
mod focus;
mod kitchen_sink;
mod picker;
@@ -7,6 +8,7 @@ mod text;
mod z_index;
pub use auto_height_editor::*;
+pub use cursor::*;
pub use focus::*;
pub use kitchen_sink::*;
pub use picker::*;
@@ -0,0 +1,112 @@
+use gpui::{Div, Render, Stateful};
+use story::Story;
+use ui::prelude::*;
+
+pub struct CursorStory;
+
+impl Render for CursorStory {
+ type Element = Div;
+
+ fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
+ let all_cursors: [(&str, Box<dyn Fn(Stateful<Div>) -> Stateful<Div>>); 19] = [
+ (
+ "cursor_default",
+ Box::new(|el: Stateful<Div>| el.cursor_default()),
+ ),
+ (
+ "cursor_pointer",
+ Box::new(|el: Stateful<Div>| el.cursor_pointer()),
+ ),
+ (
+ "cursor_text",
+ Box::new(|el: Stateful<Div>| el.cursor_text()),
+ ),
+ (
+ "cursor_move",
+ Box::new(|el: Stateful<Div>| el.cursor_move()),
+ ),
+ (
+ "cursor_not_allowed",
+ Box::new(|el: Stateful<Div>| el.cursor_not_allowed()),
+ ),
+ (
+ "cursor_context_menu",
+ Box::new(|el: Stateful<Div>| el.cursor_context_menu()),
+ ),
+ (
+ "cursor_crosshair",
+ Box::new(|el: Stateful<Div>| el.cursor_crosshair()),
+ ),
+ (
+ "cursor_vertical_text",
+ Box::new(|el: Stateful<Div>| el.cursor_vertical_text()),
+ ),
+ (
+ "cursor_alias",
+ Box::new(|el: Stateful<Div>| el.cursor_alias()),
+ ),
+ (
+ "cursor_copy",
+ Box::new(|el: Stateful<Div>| el.cursor_copy()),
+ ),
+ (
+ "cursor_no_drop",
+ Box::new(|el: Stateful<Div>| el.cursor_no_drop()),
+ ),
+ (
+ "cursor_grab",
+ Box::new(|el: Stateful<Div>| el.cursor_grab()),
+ ),
+ (
+ "cursor_grabbing",
+ Box::new(|el: Stateful<Div>| el.cursor_grabbing()),
+ ),
+ (
+ "cursor_col_resize",
+ Box::new(|el: Stateful<Div>| el.cursor_col_resize()),
+ ),
+ (
+ "cursor_row_resize",
+ Box::new(|el: Stateful<Div>| el.cursor_row_resize()),
+ ),
+ (
+ "cursor_n_resize",
+ Box::new(|el: Stateful<Div>| el.cursor_n_resize()),
+ ),
+ (
+ "cursor_e_resize",
+ Box::new(|el: Stateful<Div>| el.cursor_e_resize()),
+ ),
+ (
+ "cursor_s_resize",
+ Box::new(|el: Stateful<Div>| el.cursor_s_resize()),
+ ),
+ (
+ "cursor_w_resize",
+ Box::new(|el: Stateful<Div>| el.cursor_w_resize()),
+ ),
+ ];
+
+ Story::container()
+ .flex()
+ .gap_1()
+ .child(Story::title("cursor"))
+ .children(all_cursors.map(|(name, apply_cursor)| {
+ div().gap_1().flex().text_color(gpui::white()).child(
+ div()
+ .flex()
+ .items_center()
+ .justify_center()
+ .id(name)
+ .map(apply_cursor)
+ .w_64()
+ .h_8()
+ .bg(gpui::red())
+ .hover(|style| style.bg(gpui::blue()))
+ .active(|style| style.bg(gpui::green()))
+ .text_sm()
+ .child(Story::label(name)),
+ )
+ }))
+ }
+}
@@ -17,6 +17,7 @@ pub enum ComponentStory {
Button,
Checkbox,
ContextMenu,
+ Cursor,
Disclosure,
Focus,
Icon,
@@ -40,6 +41,7 @@ impl ComponentStory {
Self::Button => cx.build_view(|_| ui::ButtonStory).into(),
Self::Checkbox => cx.build_view(|_| ui::CheckboxStory).into(),
Self::ContextMenu => cx.build_view(|_| ui::ContextMenuStory).into(),
+ Self::Cursor => cx.build_view(|_| crate::stories::CursorStory).into(),
Self::Disclosure => cx.build_view(|_| ui::DisclosureStory).into(),
Self::Focus => FocusStory::view(cx).into(),
Self::Icon => cx.build_view(|_| ui::IconStory).into(),