From a2f4b4cd9b5333dbd4dbcace84a72054f085f6d3 Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Thu, 8 Sep 2022 08:28:44 -0700 Subject: [PATCH] Add ctrl-shift-alt-S to print matched style rules for hovered element --- crates/vizia_core/src/events/event_manager.rs | 27 ++- crates/vizia_core/src/style/color.rs | 25 +-- crates/vizia_core/src/style/display.rs | 59 ++++++ crates/vizia_core/src/style/mod.rs | 2 +- crates/vizia_core/src/style/property.rs | 193 +++++++++++------- crates/vizia_core/src/style/shadow.rs | 15 ++ crates/vizia_core/src/style/style_rule.rs | 26 +-- crates/vizia_core/src/systems/style.rs | 29 ++- crates/vizia_window/src/cursor.rs | 49 +++++ 9 files changed, 308 insertions(+), 117 deletions(-) diff --git a/crates/vizia_core/src/events/event_manager.rs b/crates/vizia_core/src/events/event_manager.rs index 94b98b9c1..2b2c300df 100644 --- a/crates/vizia_core/src/events/event_manager.rs +++ b/crates/vizia_core/src/events/event_manager.rs @@ -1,7 +1,7 @@ use crate::context::InternalEvent; use crate::events::EventMeta; use crate::prelude::*; -use crate::systems::hover_system; +use crate::systems::{compute_matched_rules, hover_system}; use crate::tree::{focus_backward, focus_forward, is_navigatable}; use instant::{Duration, Instant}; use std::any::Any; @@ -367,6 +367,31 @@ fn internal_state_updates(context: &mut Context, window_event: &WindowEvent, met } } + #[cfg(debug_assertions)] + if *code == Code::KeyS + && context.modifiers == Modifiers::CTRL | Modifiers::SHIFT | Modifiers::ALT + { + let mut result = vec![]; + compute_matched_rules(context, &context.tree, context.hovered, &mut result); + + let entity = context.hovered; + println!("/* Matched rules for Entity: {} Parent: {:?} View: {} posx: {} posy: {} width: {} height: {}", + entity, + entity.parent(&context.tree), + context + .views + .get(&entity) + .map_or("", |view| view.element().unwrap_or("")), + context.cache.get_posx(entity), + context.cache.get_posy(entity), + context.cache.get_width(entity), + context.cache.get_height(entity) + ); + for rule in result.into_iter() { + println!("{}", rule); + } + } + if *code == Code::F5 { context.reload_styles().unwrap(); } diff --git a/crates/vizia_core/src/style/color.rs b/crates/vizia_core/src/style/color.rs index 14eaf9d9a..f5a313950 100644 --- a/crates/vizia_core/src/style/color.rs +++ b/crates/vizia_core/src/style/color.rs @@ -1,5 +1,6 @@ use crate::animation::Interpolator; use std::fmt; +use std::fmt::Formatter; /// Describes a color. /// @@ -10,6 +11,18 @@ pub struct Color { pub data: u32, } +impl std::fmt::Display for Color { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if self.a() == 0 { + write!(f, "transparent") + } else if self.a() == 255 { + write!(f, "#{:02x}{:02x}{:02x}", self.r(), self.g(), self.b()) + } else { + write!(f, "#{:02x}{:02x}{:02x}{:02x}", self.r(), self.g(), self.b(), self.a()) + } + } +} + impl Color { // Create a new color from RGB pub const fn rgb(r: u8, g: u8, b: u8) -> Self { @@ -84,18 +97,6 @@ impl Color { } } -impl ToString for Color { - fn to_string(&self) -> String { - if self.a() == 0 { - return String::from("transparent"); - } - - let data = self.data; - - format!("#{:x}", data) - } -} - impl From<&str> for Color { fn from(s: &str) -> Color { let clean_hex = s.trim_start_matches('#'); diff --git a/crates/vizia_core/src/style/display.rs b/crates/vizia_core/src/style/display.rs index 10e7693b4..3fe4f819a 100644 --- a/crates/vizia_core/src/style/display.rs +++ b/crates/vizia_core/src/style/display.rs @@ -1,5 +1,6 @@ use crate::animation::Interpolator; use crate::entity::Entity; +use std::fmt::Formatter; use vizia_id::GenerationalId; /// Display determines whether an entity will be rendered and acted on by the layout system. @@ -12,6 +13,19 @@ pub enum Display { Flex, } +impl std::fmt::Display for Display { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Display::None => "none", + Display::Flex => "flex", + } + ) + } +} + impl Default for Display { fn default() -> Self { Display::Flex @@ -45,6 +59,19 @@ pub enum Visibility { Invisible, } +impl std::fmt::Display for Visibility { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Visibility::Visible => "visible", + Visibility::Invisible => "invisible", + } + ) + } +} + impl From for Visibility { fn from(val: bool) -> Self { if val { @@ -73,6 +100,12 @@ impl Interpolator for Visibility { #[derive(Debug, Copy, Clone, PartialEq)] pub struct Opacity(pub f32); +impl std::fmt::Display for Opacity { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + impl Default for Opacity { fn default() -> Self { Opacity(1.0) @@ -94,6 +127,19 @@ pub enum Overflow { Hidden, } +impl std::fmt::Display for Overflow { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Overflow::Visible => "visible", + Overflow::Hidden => "hidden", + } + ) + } +} + impl Default for Overflow { fn default() -> Self { Overflow::Visible @@ -123,6 +169,19 @@ pub enum BorderCornerShape { Bevel, } +impl std::fmt::Display for BorderCornerShape { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + BorderCornerShape::Round => "round", + BorderCornerShape::Bevel => "bevel", + } + ) + } +} + impl Default for BorderCornerShape { fn default() -> Self { BorderCornerShape::Round diff --git a/crates/vizia_core/src/style/mod.rs b/crates/vizia_core/src/style/mod.rs index e7307e75b..4f19116e1 100644 --- a/crates/vizia_core/src/style/mod.rs +++ b/crates/vizia_core/src/style/mod.rs @@ -25,7 +25,7 @@ mod parser; pub use parser::*; mod style_rule; -use style_rule::StyleRule; +pub(crate) use style_rule::StyleRule; mod selector; pub use selector::*; diff --git a/crates/vizia_core/src/style/property.rs b/crates/vizia_core/src/style/property.rs index a71657690..c52125c9e 100644 --- a/crates/vizia_core/src/style/property.rs +++ b/crates/vizia_core/src/style/property.rs @@ -120,113 +120,158 @@ pub(crate) enum Property { Cursor(CursorIcon), } -/* +pub(crate) fn fmt_units(val: &Units) -> String { + match val { + Units::Pixels(px) => format!("{}px", px), + Units::Percentage(p) => format!("{}%", p), + Units::Stretch(s) => format!("{}s", s), + Units::Auto => format!("auto"), + } +} + +fn fmt_layout_type(val: &LayoutType) -> String { + match val { + LayoutType::Row => "row", + LayoutType::Column => "column", + LayoutType::Grid => "grid", + } + .to_owned() +} + +fn fmt_position_type(val: &PositionType) -> String { + match val { + PositionType::SelfDirected => "self-directed", + PositionType::ParentDirected => "parent-directed", + } + .to_owned() +} + impl std::fmt::Display for Property { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - - Property::None => write!(f, ""), - Property::Unknown(ident, prop) => { - write!(f, "display: {};", match prop { - PropType::Units(val) => { - match val { - Units::Pixels(px) => { - format!("{}px", px) - } - - Units::Percentage(p) => { - format!("{}%", p) - } - - Units::Stretch(s) => { - format!("{}s", s) - } - - Units::Auto => { - format!("auto") - } - + write!( + f, + "/* unknown: {}: {}; /*", + ident, + match prop { + PropType::Units(val) => fmt_units(val), + + PropType::String(string) => { + string.clone() } } - - PropType::String(string) => { - string.clone() - } - }) + ) } // General - Property::Display(val) => write!(f, "display: {};", 1), - Property::Visibility(val) => write!(f, "visibility: {};", 2), - Property::Overflow(val) => write!(f, "overflow: {};", 3), + Property::Display(val) => write!(f, "display: {};", val), + Property::Visibility(val) => write!(f, "visibility: {};", val), + Property::Overflow(val) => write!(f, "overflow: {};", val), Property::Opacity(val) => write!(f, "opacity: {};", val), // Positioning - Property::LayoutType(val) => write!(f, "layout-type: {};", val), - Property::PositionType(val) => write!(f, "position-type: {};", val), + Property::LayoutType(val) => write!(f, "layout-type: {};", fmt_layout_type(val)), + Property::PositionType(val) => write!(f, "position-type: {};", fmt_position_type(val)), // Position and Size - Property::Space(val) => write!(f, "space: {};", val), - Property::Left(val) => write!(f, "left: {};", val), - Property::Width(val) => write!(f, "width: {};", val), - Property::Right(val) => write!(f, "right: {};", val), - Property::Top(val) => write!(f, "top: {};", val), - Property::Height(val) => write!(f, "height: {};", val), - Property::Bottom(val) => write!(f, "bottom: {};", val), + Property::Space(val) => write!(f, "space: {};", fmt_units(val)), + Property::Left(val) => write!(f, "left: {};", fmt_units(val)), + Property::Width(val) => write!(f, "width: {};", fmt_units(val)), + Property::Right(val) => write!(f, "right: {};", fmt_units(val)), + Property::Top(val) => write!(f, "top: {};", fmt_units(val)), + Property::Height(val) => write!(f, "height: {};", fmt_units(val)), + Property::Bottom(val) => write!(f, "bottom: {};", fmt_units(val)), // Constraints - Property::MinLeft(val) => write!(f, "min-left: {};", val), - Property::MaxLeft(val) => write!(f, "max-left: {};", val), - Property::MinWidth(val) => write!(f, "min-width: {};", val), - Property::MaxWidth(val) => write!(f, "max-width: {};", val), - Property::MinRight(val) => write!(f, "min-right: {};", val), - Property::MaxRight(val) => write!(f, "max-right: {};", val), - - Property::MinTop(val) => write!(f, "min-top: {};", val), - Property::MaxTop(val) => write!(f, "max-top: {};", val), - Property::MinHeight(val) => write!(f, "min-height: {};", val), - Property::MaxHeight(val) => write!(f, "max-height: {};", val), - Property::MinBottom(val) => write!(f, "min-bottom: {};", val), - Property::MaxBottom(val) => write!(f, "max-bottom: {};", val), + Property::MinLeft(val) => write!(f, "min-left: {};", fmt_units(val)), + Property::MaxLeft(val) => write!(f, "max-left: {};", fmt_units(val)), + Property::MinWidth(val) => write!(f, "min-width: {};", fmt_units(val)), + Property::MaxWidth(val) => write!(f, "max-width: {};", fmt_units(val)), + Property::MinRight(val) => write!(f, "min-right: {};", fmt_units(val)), + Property::MaxRight(val) => write!(f, "max-right: {};", fmt_units(val)), + + Property::MinTop(val) => write!(f, "min-top: {};", fmt_units(val)), + Property::MaxTop(val) => write!(f, "max-top: {};", fmt_units(val)), + Property::MinHeight(val) => write!(f, "min-height: {};", fmt_units(val)), + Property::MaxHeight(val) => write!(f, "max-height: {};", fmt_units(val)), + Property::MinBottom(val) => write!(f, "min-bottom: {};", fmt_units(val)), + Property::MaxBottom(val) => write!(f, "max-bottom: {};", fmt_units(val)), // Child Spacing - Property::ChildSpace(val) => write!(f, "child-space: {};", val), - Property::ChildLeft(val) => write!(f, "child-left: {};", val), - Property::ChildRight(val) => write!(f, "child-right: {};", val), - Property::ChildTop(val) => write!(f, "child-top: {};", val), - Property::ChildBottom(val) => write!(f, "child-bottom: {};", val), - Property::ChildBetween(val) => write!(f, "child-between: {};", val), + Property::ChildSpace(val) => write!(f, "child-space: {};", fmt_units(val)), + Property::ChildLeft(val) => write!(f, "child-left: {};", fmt_units(val)), + Property::ChildRight(val) => write!(f, "child-right: {};", fmt_units(val)), + Property::ChildTop(val) => write!(f, "child-top: {};", fmt_units(val)), + Property::ChildBottom(val) => write!(f, "child-bottom: {};", fmt_units(val)), + Property::RowBetween(val) => write!(f, "row-between: {};", fmt_units(val)), + Property::ColBetween(val) => write!(f, "col-between: {};", fmt_units(val)), // Border - Property::BorderRadius(val) => write!(f, "border-radius: {};", val), - Property::BorderTopLeftRadius(val) => write!(f, "border-top-left-radius: {};", val), - Property::BorderTopRightRadius(val) => write!(f, "border-top-right-radius: {};", val), + Property::BorderRadius(val) => write!(f, "border-radius: {};", fmt_units(val)), + Property::BorderTopLeftRadius(val) => { + write!(f, "border-top-left-radius: {};", fmt_units(val)) + } + Property::BorderTopRightRadius(val) => { + write!(f, "border-top-right-radius: {};", fmt_units(val)) + } Property::BorderBottomLeftRadius(val) => { - write!(f, "border-bottom-left-radius: {};", val) + write!(f, "border-bottom-left-radius: {};", fmt_units(val)) } Property::BorderBottomRightRadius(val) => { - write!(f, "border-bottom-right-radius: {};", val) + write!(f, "border-bottom-right-radius: {};", fmt_units(val)) + } + Property::BorderWidth(val) => write!(f, "border-width: {};", fmt_units(val)), + Property::BorderColor(val) => write!(f, "border-color: {};", val), + Property::BorderCornerShape(val) => write!(f, "border-corner-shape: {};", val), + Property::BorderTopLeftShape(val) => write!(f, "border-top-left-shape: {};", val), + Property::BorderTopRightShape(val) => write!(f, "border-top-right-shape: {};", val), + Property::BorderBottomLeftShape(val) => write!(f, "border-bottom-left-shape: {};", val), + Property::BorderBottomRightShape(val) => { + write!(f, "border-bottom-right-shape: {};", val) } - Property::BorderWidth(val) => write!(f, "border-width: {};", val), - Property::BorderColor(val) => write!(f, "border-color: {:?};", val), // Background - Property::BackgroundColor(val) => write!(f, "background-color: {:?};", val), + Property::BackgroundColor(val) => write!(f, "background-color: {};", val), Property::BackgroundImage(val) => write!(f, "background-image: {};", val), - Property::BackgroundGradient(val) => write!(f, "background-gradient: {};", 4), - Property::FontSize(val) => write!(f, "font-size: {};", val), - Property::FontColor(val) => write!(f, "color: {:?};", val), + // Outline + Property::OutlineWidth(val) => write!(f, "outline-width: {}", fmt_units(val)), + Property::OutlineColor(val) => write!(f, "outline-color: {}", val), + Property::OutlineOffset(val) => write!(f, "outline-offset: {}", fmt_units(val)), - Property::OuterShadow(val) => write!(f, "outer-shadow: {};", 5), - Property::InnerShadow(val) => write!(f, "inner-shadow: {};", 6), + // Text + Property::FontSize(val) => write!(f, "font-size: {};", val), + Property::FontColor(val) => write!(f, "color: {};", val), + Property::Font(val) => write!(f, "font: {}", val), + Property::SelectionColor(val) => write!(f, "selection-color: {}", val), + Property::CaretColor(val) => write!(f, "caret-color: {}", val), + Property::TextWrap(val) => write!(f, "text-wrap: {}", val), + + // Shadow + Property::OuterShadow(val) => write!(f, "outer-shadow: {};", val), + Property::InnerShadow(val) => write!(f, "inner-shadow: {};", val), + Property::OuterShadowHOffset(val) => { + write!(f, "outer-shadow-h-offset: {}", fmt_units(val)) + } + Property::OuterShadowVOffset(val) => { + write!(f, "outer-shadow-v-offset: {}", fmt_units(val)) + } + Property::OuterShadowBlur(val) => write!(f, "inner-shadow-blur: {}", fmt_units(val)), + Property::OuterShadowColor(val) => write!(f, "inner-shadow-color: {}", val), + Property::InnerShadowHOffset(val) => { + write!(f, "inner-shadow-h-offset: {}", fmt_units(val)) + } + Property::InnerShadowVOffset(val) => { + write!(f, "inner-shadow-v-offset: {}", fmt_units(val)) + } + Property::InnerShadowBlur(val) => write!(f, "inner-shadow-blur: {}", fmt_units(val)), + Property::InnerShadowColor(val) => write!(f, "inner-shadow-color: {}", val), Property::Transition(val) => write!(f, "transition: {:?};", val), Property::ZIndex(val) => write!(f, "z-index: {};", val), - _=> write!(f, ""), + Property::Cursor(val) => write!(f, "cursor: {};", val), } } } -*/ diff --git a/crates/vizia_core/src/style/shadow.rs b/crates/vizia_core/src/style/shadow.rs index c0d7be7e9..373aa4ad6 100644 --- a/crates/vizia_core/src/style/shadow.rs +++ b/crates/vizia_core/src/style/shadow.rs @@ -1,4 +1,6 @@ use crate::prelude::*; +use crate::style::fmt_units; +use std::fmt::Formatter; #[derive(Debug, Copy, Clone, PartialEq)] pub(crate) struct BoxShadow { @@ -18,3 +20,16 @@ impl Default for BoxShadow { } } } + +impl std::fmt::Display for BoxShadow { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{} {} {} {}", + fmt_units(&self.horizontal_offset), + fmt_units(&self.vertical_offset), + fmt_units(&self.blur_radius), + &self.color + ) + } +} diff --git a/crates/vizia_core/src/style/style_rule.rs b/crates/vizia_core/src/style/style_rule.rs index 5b5e96b2c..b81ab41f6 100644 --- a/crates/vizia_core/src/style/style_rule.rs +++ b/crates/vizia_core/src/style/style_rule.rs @@ -9,23 +9,23 @@ pub(crate) struct StyleRule { pub(crate) properties: Vec, } -// impl std::fmt::Display for StyleRule { -// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -// for selector in self.selectors.iter() { -// write!(f, "{}", selector)?; -// } +impl std::fmt::Display for StyleRule { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for selector in self.selectors.iter() { + write!(f, "{}", selector)?; + } -// write!(f, " {{\n")?; + write!(f, " {{\n")?; -// for property in self.properties.iter() { -// write!(f, " {}\n", property)?; -// } + for property in self.properties.iter() { + write!(f, " {}\n", property)?; + } -// write!(f, "}}\n\n")?; + write!(f, "}}\n")?; -// Ok(()) -// } -// } + Ok(()) + } +} impl StyleRule { pub(crate) fn specificity(&self) -> Specificity { diff --git a/crates/vizia_core/src/systems/style.rs b/crates/vizia_core/src/systems/style.rs index 9200cb90d..2c205c0d7 100644 --- a/crates/vizia_core/src/systems/style.rs +++ b/crates/vizia_core/src/systems/style.rs @@ -1,5 +1,5 @@ use crate::prelude::*; -use crate::style::{Rule, Selector, SelectorRelation}; +use crate::style::{Rule, Selector, SelectorRelation, StyleRule}; use vizia_id::GenerationalId; use vizia_storage::{LayoutTreeIterator, TreeExt}; @@ -142,11 +142,11 @@ fn check_match(cx: &Context, entity: Entity, selector: &Selector) -> bool { return true; } -fn compute_matched_rules( - cx: &Context, +pub(crate) fn compute_matched_rules<'a>( + cx: &'a Context, tree: &Tree, entity: Entity, - matched_rules: &mut Vec, + matched_rules: &mut Vec<&'a StyleRule>, ) { // Loop through all of the style rules 'rule_loop: for rule in cx.style.rules.iter() { @@ -203,7 +203,7 @@ fn compute_matched_rules( } // If all the selectors match then add the rule to the matched rules list - matched_rules.push(rule.id); + matched_rules.push(rule); } } @@ -504,9 +504,8 @@ pub fn style_system(cx: &mut Context, tree: &Tree) { if cx.style.needs_restyle { let mut prev_entity = None; - let mut prev_matched_rules = Vec::with_capacity(100); - - let mut matched_rules = Vec::with_capacity(100); + let mut matched_rule_ids = Vec::with_capacity(100); + let mut prev_matched_rule_ids = Vec::with_capacity(100); let iterator = LayoutTreeIterator::full(tree); @@ -517,19 +516,14 @@ pub fn style_system(cx: &mut Context, tree: &Tree) { continue; } - // Create a list of style rules that match this entity - //let mut matched_rules: Vec = Vec::new(); - matched_rules.clear(); - // If the entity and the previous entity have the same parent and selectors then they share the same rules if let Some(prev) = prev_entity { if let Some(parent) = tree.get_layout_parent(entity) { if let Some(prev_parent) = tree.get_layout_parent(prev) { if parent == prev_parent { if entity_selector(cx, entity).same(&entity_selector(cx, prev)) { - matched_rules = prev_matched_rules.clone(); prev_entity = Some(entity); - link_style_data(cx, entity, &matched_rules); + link_style_data(cx, entity, &prev_matched_rule_ids); continue 'ent; } } @@ -537,11 +531,14 @@ pub fn style_system(cx: &mut Context, tree: &Tree) { } } + let mut matched_rules = Vec::with_capacity(100); compute_matched_rules(cx, tree, entity, &mut matched_rules); - link_style_data(cx, entity, &matched_rules); + matched_rule_ids.extend(matched_rules.into_iter().map(|r| r.id)); + link_style_data(cx, entity, &matched_rule_ids); prev_entity = Some(entity); - prev_matched_rules = matched_rules.clone(); + prev_matched_rule_ids.clear(); + prev_matched_rule_ids.append(&mut matched_rule_ids); } cx.style.needs_restyle = false; diff --git a/crates/vizia_window/src/cursor.rs b/crates/vizia_window/src/cursor.rs index c5eb4ef03..5a71d31d7 100644 --- a/crates/vizia_window/src/cursor.rs +++ b/crates/vizia_window/src/cursor.rs @@ -1,3 +1,5 @@ +use std::fmt::Formatter; + /// Describes the icon the mouse cursor should use. /// /// See the cursor_icon example for a gallery of icons and sample usage. @@ -48,3 +50,50 @@ impl Default for CursorIcon { CursorIcon::Default } } + +impl std::fmt::Display for CursorIcon { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + CursorIcon::Default => "default", + CursorIcon::Crosshair => "crosshair", + CursorIcon::Hand => "hand", + CursorIcon::Arrow => "arrow", + CursorIcon::Move => "move", + CursorIcon::Text => "text", + CursorIcon::Wait => "wait", + CursorIcon::Help => "help", + CursorIcon::Progress => "progress", + CursorIcon::NotAllowed => "not-allowed", + CursorIcon::ContextMenu => "context-menu", + CursorIcon::Cell => "cell", + CursorIcon::VerticalText => "vertical-text", + CursorIcon::Alias => "alias", + CursorIcon::Copy => "copy", + CursorIcon::NoDrop => "no-drop", + CursorIcon::Grab => "grab", + CursorIcon::Grabbing => "grabbing", + CursorIcon::AllScroll => "all-scroll", + CursorIcon::ZoomIn => "zoom-in", + CursorIcon::ZoomOut => "zoom-out", + CursorIcon::EResize => "e-resize", + CursorIcon::NResize => "n-resize", + CursorIcon::NeResize => "ne-resize", + CursorIcon::NwResize => "nw-resize", + CursorIcon::SResize => "s-resize", + CursorIcon::SeResize => "se-resize", + CursorIcon::SwResize => "sw-resize", + CursorIcon::WResize => "w-resize", + CursorIcon::EwResize => "ew-resize", + CursorIcon::NsResize => "ns-resize", + CursorIcon::NeswResize => "nesw-resize", + CursorIcon::NwseResize => "nwse-resize", + CursorIcon::ColResize => "col-resize", + CursorIcon::RowResize => "row-resize", + CursorIcon::None => "none", + } + ) + } +}