From 2193ac85bfdb52d054fc2381ffa3c6e29984f0d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 31 Oct 2023 10:37:21 +0100 Subject: [PATCH 1/2] Add `disabled`, `active`, `focus` and `focus_visible` style selectors --- examples/widget-gallery/src/buttons.rs | 4 +- examples/widget-gallery/src/inputs.rs | 14 ++-- src/context.rs | 29 +++++---- src/style.rs | 89 ++++++++++++++++++++++++-- src/views/text_input.rs | 2 +- src/window_handle.rs | 3 +- 6 files changed, 113 insertions(+), 28 deletions(-) diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index 953f04fb..ee703236 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -36,9 +36,9 @@ pub fn button_view() -> impl View { .background(Color::YELLOW_GREEN) .color(Color::DARK_GREEN) .cursor(CursorStyle::Pointer) + .active(|s| s.color(Color::WHITE).background(Color::RED)) + .hover(|s| s.background(Color::rgb8(244, 67, 54))) }) - .hover_style(|s| s.background(Color::rgb8(244, 67, 54))) - .active_style(|s| s.color(Color::WHITE).background(Color::RED)) }), form_item("Distabled Button:".to_string(), 120.0, || { label(|| "Click me") diff --git a/examples/widget-gallery/src/inputs.rs b/examples/widget-gallery/src/inputs.rs index f12beaec..bba2d705 100644 --- a/examples/widget-gallery/src/inputs.rs +++ b/examples/widget-gallery/src/inputs.rs @@ -22,25 +22,31 @@ pub fn text_input_view() -> impl View { text_input(text) .style(|s| { s.border(1.5) - .background(Color::rgb8(224, 224, 224)) + .background(Color::rgb8(224, 224, 224).with_alpha_factor(0.1)) .border_radius(15.0) .border_color(Color::rgb8(189, 189, 189)) .padding(10.0) .cursor(CursorStyle::Text) + .hover(|s| { + s.background(Color::rgb8(224, 224, 224).with_alpha_factor(0.2)) + .border_color(Color::rgb8(66, 66, 66)) + }) + .focus(|s| { + s.border_color(Color::LIGHT_SKY_BLUE.with_alpha_factor(0.8)) + .hover(|s| s.border_color(Color::LIGHT_SKY_BLUE)) + }) }) - .hover_style(|s| s.border_color(Color::rgb8(66, 66, 66))) - .focus_style(|s| s.border_color(Color::LIGHT_SKY_BLUE)) .keyboard_navigatable() }), form_item("Disabled Input:".to_string(), 120.0, move || { text_input(text) .style(|s| { s.border(1.5) - .background(Color::rgb8(224, 224, 224)) .border_radius(15.0) .border_color(Color::rgb8(189, 189, 189)) .padding(10.0) .cursor(CursorStyle::Text) + .disabled(|s| s.background(Color::rgb8(224, 224, 224))) }) .hover_style(|s| s.border_color(Color::rgb8(66, 66, 66))) .focus_style(|s| s.border_color(Color::LIGHT_SKY_BLUE)) diff --git a/src/context.rs b/src/context.rs index 9771c9d3..5a60021c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -26,7 +26,7 @@ use crate::{ responsive::{GridBreakpoints, ScreenSize, ScreenSizeBp}, style::{ BuiltinStyleReader, ComputedStyle, CursorStyle, DisplayProp, Style, StyleMap, StyleProp, - StyleSelector, + StyleSelector, StyleSelectors, }, }; @@ -49,7 +49,7 @@ pub struct ViewState { pub(crate) node: Node, pub(crate) children_nodes: Vec, pub(crate) request_layout: bool, - pub(crate) hover_sensitive: bool, + pub(crate) has_style_selectors: StyleSelectors, pub(crate) viewport: Option, pub(crate) layout_rect: Rect, pub(crate) animation: Option, @@ -80,7 +80,7 @@ impl ViewState { viewport: None, layout_rect: Rect::ZERO, request_layout: true, - hover_sensitive: false, + has_style_selectors: StyleSelectors::default(), animation: None, base_style: None, style: Style::BASE, @@ -197,14 +197,14 @@ impl ViewState { } } - self.hover_sensitive = computed_style + self.has_style_selectors = computed_style .other .as_ref() - .map(|map| map.hover_sensitive()) + .map(|map| map.selectors()) .unwrap_or_default(); if let Some(map) = computed_style.other.as_mut() { - map.apply_interact_state(interact_state); + map.apply_interact_state(&interact_state); } self.combined_style = computed_style.clone(); @@ -486,14 +486,15 @@ impl AppState { pub(crate) fn has_style_for_sel(&mut self, id: Id, selector_kind: StyleSelector) -> bool { let view_state = self.view_state(id); - match selector_kind { - StyleSelector::Hover => view_state.hover_style.is_some(), - StyleSelector::Focus => view_state.focus_style.is_some(), - StyleSelector::FocusVisible => view_state.focus_visible_style.is_some(), - StyleSelector::Disabled => view_state.disabled_style.is_some(), - StyleSelector::Active => view_state.active_style.is_some(), - StyleSelector::Dragging => view_state.dragging_style.is_some(), - } + view_state.has_style_selectors.has(selector_kind) + || match selector_kind { + StyleSelector::Hover => view_state.hover_style.is_some(), + StyleSelector::Focus => view_state.focus_style.is_some(), + StyleSelector::FocusVisible => view_state.focus_visible_style.is_some(), + StyleSelector::Disabled => view_state.disabled_style.is_some(), + StyleSelector::Active => view_state.active_style.is_some(), + StyleSelector::Dragging => view_state.dragging_style.is_some(), + } } // TODO: animated should be a HashMap diff --git a/src/style.rs b/src/style.rs index 3db5c8d9..f7ac1ed7 100644 --- a/src/style.rs +++ b/src/style.rs @@ -289,19 +289,52 @@ impl StyleMap { .unwrap_or(StyleValue::Base) } - pub(crate) fn hover_sensitive(&self) -> bool { + pub(crate) fn selectors(&self) -> StyleSelectors { self.selectors .iter() - .any(|(selector, map)| *selector == StyleSelector::Hover || map.hover_sensitive()) + .fold(StyleSelectors::default(), |mut s, (selector, map)| { + s.selectors |= map.selectors().selectors; + s.set(*selector, true) + }) } - pub(crate) fn apply_interact_state(&mut self, interact_state: InteractionState) { + pub(crate) fn apply_interact_state(&mut self, interact_state: &InteractionState) { if interact_state.is_hovered && !interact_state.is_disabled { if let Some(mut map) = self.selectors.remove(&StyleSelector::Hover) { map.apply_interact_state(interact_state); self.apply(map); } } + if interact_state.is_focused { + if let Some(mut map) = self.selectors.remove(&StyleSelector::Focus) { + map.apply_interact_state(interact_state); + self.apply(map); + } + } + if interact_state.is_disabled { + if let Some(mut map) = self.selectors.remove(&StyleSelector::Disabled) { + map.apply_interact_state(interact_state); + self.apply(map); + } + } + + let focused_keyboard = + interact_state.using_keyboard_navigation && interact_state.is_focused; + + if focused_keyboard { + if let Some(mut map) = self.selectors.remove(&StyleSelector::FocusVisible) { + map.apply_interact_state(interact_state); + self.apply(map); + } + } + + let active_mouse = interact_state.is_hovered && !interact_state.using_keyboard_navigation; + if interact_state.is_clicking && (active_mouse || focused_keyboard) { + if let Some(mut map) = self.selectors.remove(&StyleSelector::Active) { + map.apply_interact_state(interact_state); + self.apply(map); + } + } } pub(crate) fn apply_only_inherited(map: &mut Rc, over: &StyleMap) { @@ -359,7 +392,7 @@ impl Debug for StyleMap { } } -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum StyleSelector { Hover, Focus, @@ -369,6 +402,26 @@ pub enum StyleSelector { Dragging, } +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)] +pub(crate) struct StyleSelectors { + selectors: u8, +} + +impl StyleSelectors { + pub(crate) fn set(self, selector: StyleSelector, value: bool) -> Self { + let v = (selector as isize).try_into().unwrap(); + let bit = 1_u8.checked_shl(v).unwrap(); + StyleSelectors { + selectors: (self.selectors & !bit) | ((value as u8) << v), + } + } + pub(crate) fn has(self, selector: StyleSelector) -> bool { + let v = (selector as isize).try_into().unwrap(); + let bit = 1_u8.checked_shl(v).unwrap(); + self.selectors & bit != 0 + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TextOverflow { Wrap, @@ -669,14 +722,38 @@ impl Style { self } - pub fn hover(mut self, style: impl Fn(Style) -> Style + 'static) -> Self { + fn selector( + mut self, + selector: StyleSelector, + style: impl Fn(Style) -> Style + 'static, + ) -> Self { let over = style(Style::BASE).other.unwrap_or_default(); let mut other = self.other.unwrap_or_default(); - other.set_selector(StyleSelector::Hover, over); + other.set_selector(selector, over); self.other = Some(other); self } + pub fn hover(self, style: impl Fn(Style) -> Style + 'static) -> Self { + self.selector(StyleSelector::Hover, style) + } + + pub fn focus(self, style: impl Fn(Style) -> Style + 'static) -> Self { + self.selector(StyleSelector::Focus, style) + } + + pub fn focus_visible(self, style: impl Fn(Style) -> Style + 'static) -> Self { + self.selector(StyleSelector::FocusVisible, style) + } + + pub fn disabled(self, style: impl Fn(Style) -> Style + 'static) -> Self { + self.selector(StyleSelector::Disabled, style) + } + + pub fn active(self, style: impl Fn(Style) -> Style + 'static) -> Self { + self.selector(StyleSelector::Active, style) + } + pub fn width_full(self) -> Self { self.width_pct(100.0) } diff --git a/src/views/text_input.rs b/src/views/text_input.rs index c34be8dd..7d1b0e52 100644 --- a/src/views/text_input.rs +++ b/src/views/text_input.rs @@ -779,7 +779,7 @@ impl View for TextInput { Event::PointerMove(_) => { if !matches!(cx.app_state.cursor, Some(CursorStyle::Text)) { cx.app_state.cursor = Some(CursorStyle::Text); - return true; + return false; } false } diff --git a/src/window_handle.rs b/src/window_handle.rs index 65c5bfcf..da2eefb2 100644 --- a/src/window_handle.rs +++ b/src/window_handle.rs @@ -234,7 +234,8 @@ impl WindowHandle { if view_state.hover_style.is_some() || view_state.active_style.is_some() || view_state.animation.is_some() - || view_state.hover_sensitive + || view_state.has_style_selectors.has(StyleSelector::Hover) + || view_state.has_style_selectors.has(StyleSelector::Active) { cx.app_state.request_layout(*id); } From bd8f868fa1d6344942816544d6ab26965aff07de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 31 Oct 2023 12:59:44 +0100 Subject: [PATCH 2/2] Update examples --- examples/animations/src/main.rs | 2 +- examples/counter/src/main.rs | 26 +++++++------- examples/draggable/src/main.rs | 20 +++++------ examples/widget-gallery/src/buttons.rs | 22 ++++++++---- examples/widget-gallery/src/checkbox.rs | 6 ++-- examples/widget-gallery/src/inputs.rs | 4 +-- examples/widget-gallery/src/lists.rs | 6 ++-- examples/widget-gallery/src/main.rs | 2 +- examples/window-scale/src/main.rs | 46 ++++++++++++++----------- 9 files changed, 73 insertions(+), 61 deletions(-) diff --git a/examples/animations/src/main.rs b/examples/animations/src/main.rs index 07eb64c0..3a4a7083 100644 --- a/examples/animations/src/main.rs +++ b/examples/animations/src/main.rs @@ -34,8 +34,8 @@ fn app_view() -> impl View { .padding(10.0) .margin(20.0) .size(120.0, 120.0) + .active(|s| s.color(Color::BLACK)) }) - .active_style(|s| s.color(Color::BLACK)) .animation( animation() .border_radius(move || if is_hovered.get() { 1.0 } else { 40.0 }) diff --git a/examples/counter/src/main.rs b/examples/counter/src/main.rs index cf1dcf9d..5aad0987 100644 --- a/examples/counter/src/main.rs +++ b/examples/counter/src/main.rs @@ -17,6 +17,9 @@ fn app_view() -> impl View { .padding(10.0) .background(Color::WHITE) .box_shadow_blur(5.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| s.background(Color::LIGHT_GREEN)) + .active(|s| s.color(Color::WHITE).background(Color::DARK_GREEN)) }) .on_click({ move |_| { @@ -24,10 +27,7 @@ fn app_view() -> impl View { true } }) - .hover_style(|s| s.background(Color::LIGHT_GREEN)) - .active_style(|s| s.color(Color::WHITE).background(Color::DARK_GREEN)) - .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .keyboard_navigatable(), text("Decrement") .on_click({ move |_| { @@ -41,11 +41,11 @@ fn app_view() -> impl View { .border_radius(10.0) .padding(10.0) .margin_left(10.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| s.background(Color::rgb8(244, 67, 54))) + .active(|s| s.color(Color::WHITE).background(Color::RED)) }) - .hover_style(|s| s.background(Color::rgb8(244, 67, 54))) - .active_style(|s| s.color(Color::WHITE).background(Color::RED)) - .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .keyboard_navigatable(), text("Reset to 0") .on_click(move |_| { println!("Reset counter pressed"); // will not fire if button is disabled @@ -59,12 +59,12 @@ fn app_view() -> impl View { .padding(10.0) .margin_left(10.0) .background(Color::LIGHT_BLUE) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .disabled(|s| s.background(Color::LIGHT_GRAY)) + .hover(|s| s.background(Color::LIGHT_YELLOW)) + .active(|s| s.color(Color::WHITE).background(Color::YELLOW_GREEN)) }) - .disabled_style(|s| s.background(Color::LIGHT_GRAY)) - .hover_style(|s| s.background(Color::LIGHT_YELLOW)) - .active_style(|s| s.color(Color::WHITE).background(Color::YELLOW_GREEN)) - .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .keyboard_navigatable(), )), )) .style(|s| { diff --git a/examples/draggable/src/main.rs b/examples/draggable/src/main.rs index edd7c9e0..8580866c 100644 --- a/examples/draggable/src/main.rs +++ b/examples/draggable/src/main.rs @@ -11,18 +11,18 @@ fn app_view() -> impl View { .border_radius(2.0) .padding(10.0) .margin_left(10.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| { + s.background(Color::rgb8(244, 67, 54)) + .border_radius(0.) + .border(2.) + .border_color(Color::BLUE) + .outline(2.) + .outline_color(Color::PALE_GREEN) + }) + .active(|s| s.color(Color::WHITE).background(Color::RED)) }) - .hover_style(|s| { - s.background(Color::rgb8(244, 67, 54)) - .border_radius(0.) - .border(2.) - .border_color(Color::BLUE) - .outline(2.) - .outline_color(Color::PALE_GREEN) - }) - .active_style(|s| s.color(Color::WHITE).background(Color::RED)) .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)) .draggable() .dragging_style(|s| { s.border(2.) diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index ee703236..c54073c3 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -17,8 +17,12 @@ pub fn button_view() -> impl View { true }) .keyboard_navigatable() - .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) - .style(|s| s.border(1.0).border_radius(10.0).padding(10.0)) + .style(|s| { + s.border(1.0) + .border_radius(10.0) + .padding(10.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + }) }), form_item("Styled Button:".to_string(), 120.0, || { label(|| "Click me") @@ -27,7 +31,6 @@ pub fn button_view() -> impl View { true }) .keyboard_navigatable() - .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) .style(|s| { s.border(1.0) .border_radius(10.0) @@ -38,6 +41,7 @@ pub fn button_view() -> impl View { .cursor(CursorStyle::Pointer) .active(|s| s.color(Color::WHITE).background(Color::RED)) .hover(|s| s.background(Color::rgb8(244, 67, 54))) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) }) }), form_item("Distabled Button:".to_string(), 120.0, || { @@ -48,14 +52,14 @@ pub fn button_view() -> impl View { true }) .keyboard_navigatable() - .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) .style(|s| { s.border(1.0) .border_radius(10.0) .padding(10.0) .color(Color::GRAY) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| s.background(Color::rgb8(224, 224, 224))) }) - .hover_style(|s| s.background(Color::rgb8(224, 224, 224))) }), form_item("Secondary click button:".to_string(), 120.0, || { label(|| "Right click me") @@ -64,8 +68,12 @@ pub fn button_view() -> impl View { true }) .keyboard_navigatable() - .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) - .style(|s| s.border(1.0).border_radius(10.0).padding(10.0)) + .style(|s| { + s.border(1.0) + .border_radius(10.0) + .padding(10.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + }) }), ) }) diff --git a/examples/widget-gallery/src/checkbox.rs b/examples/widget-gallery/src/checkbox.rs index 131e8e35..d7f4dc72 100644 --- a/examples/widget-gallery/src/checkbox.rs +++ b/examples/widget-gallery/src/checkbox.rs @@ -13,7 +13,7 @@ pub fn checkbox_view() -> impl View { ( form_item("Basic Checkbox:".to_string(), 120.0, move || { checkbox(is_checked) - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)) + .style(|s| s.focus_visible(|s| s.border(2.).border_color(Color::BLUE))) .on_click(move |_| { set_is_checked.update(|checked| *checked = !*checked); true @@ -23,7 +23,7 @@ pub fn checkbox_view() -> impl View { stack({ ( checkbox(is_checked) - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .style(|s| s.focus_visible(|s| s.border(2.).border_color(Color::BLUE))), label(|| "Check me!"), ) }) @@ -36,7 +36,7 @@ pub fn checkbox_view() -> impl View { stack({ ( checkbox(is_checked) - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .style(|s| s.focus_visible(|s| s.border(2.).border_color(Color::BLUE))), label(|| "Check me!"), ) }) diff --git a/examples/widget-gallery/src/inputs.rs b/examples/widget-gallery/src/inputs.rs index bba2d705..2d4e3fc1 100644 --- a/examples/widget-gallery/src/inputs.rs +++ b/examples/widget-gallery/src/inputs.rs @@ -47,9 +47,9 @@ pub fn text_input_view() -> impl View { .padding(10.0) .cursor(CursorStyle::Text) .disabled(|s| s.background(Color::rgb8(224, 224, 224))) + .hover(|s| s.border_color(Color::rgb8(66, 66, 66))) + .focus(|s| s.border_color(Color::LIGHT_SKY_BLUE)) }) - .hover_style(|s| s.border_color(Color::rgb8(66, 66, 66))) - .focus_style(|s| s.border_color(Color::LIGHT_SKY_BLUE)) .keyboard_navigatable() .disabled(|| true) }), diff --git a/examples/widget-gallery/src/lists.rs b/examples/widget-gallery/src/lists.rs index 3acda210..548643b8 100644 --- a/examples/widget-gallery/src/lists.rs +++ b/examples/widget-gallery/src/lists.rs @@ -86,8 +86,8 @@ fn enhanced_list() -> impl View { .border_color(Color::RED) .border_radius(16.0) .margin_right(5.0) + .hover(|s| s.color(Color::WHITE).background(Color::RED)) }) - .hover_style(|s| s.color(Color::WHITE).background(Color::RED)) }) .style(|s| { s.flex_basis(0) @@ -127,7 +127,6 @@ fn enhanced_list() -> impl View { } }) .keyboard_navigatable() - .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) .style(move |s| { s.flex_row() .width(list_width.pct()) @@ -136,8 +135,9 @@ fn enhanced_list() -> impl View { .apply_if(index != 0, |s| { s.border_top(1.0).border_color(Color::LIGHT_GRAY) }) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| s.background(Color::LIGHT_GRAY).cursor(CursorStyle::Pointer)) }) - .hover_style(|s| s.background(Color::LIGHT_GRAY).cursor(CursorStyle::Pointer)) }, ) .style(move |s| s.flex_col().width(list_width)), diff --git a/examples/widget-gallery/src/main.rs b/examples/widget-gallery/src/main.rs index 2859720c..27800c47 100644 --- a/examples/widget-gallery/src/main.rs +++ b/examples/widget-gallery/src/main.rs @@ -81,7 +81,6 @@ fn app_view() -> impl View { }) .keyboard_navigatable() .draggable() - .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) .style(move |s| { s.flex_row() .width(100.pct()) @@ -91,6 +90,7 @@ fn app_view() -> impl View { .apply_if(index == active_tab.get(), |s| { s.background(Color::GRAY) }) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) }) .hover_style(|s| { s.background(Color::LIGHT_GRAY).cursor(CursorStyle::Pointer) diff --git a/examples/window-scale/src/main.rs b/examples/window-scale/src/main.rs index 33344154..453fe88d 100644 --- a/examples/window-scale/src/main.rs +++ b/examples/window-scale/src/main.rs @@ -14,15 +14,19 @@ fn app_view() -> impl View { stack({ ( label(|| "Increment") - .style(|s| s.border(1.0).border_radius(10.0).padding(10.0)) + .style(|s| { + s.border(1.0) + .border_radius(10.0) + .padding(10.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| s.background(Color::LIGHT_GREEN)) + .active(|s| s.color(Color::WHITE).background(Color::DARK_GREEN)) + }) .on_click(move |_| { set_counter.update(|value| *value += 1); true }) - .hover_style(|s| s.background(Color::LIGHT_GREEN)) - .active_style(|s| s.color(Color::WHITE).background(Color::DARK_GREEN)) - .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .keyboard_navigatable(), label(|| "Decrement") .on_click(move |_| { set_counter.update(|value| *value -= 1); @@ -33,11 +37,11 @@ fn app_view() -> impl View { .border_radius(10.0) .padding(10.0) .margin_left(10.0) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .hover(|s| s.background(Color::rgb8(244, 67, 54))) + .active(|s| s.color(Color::WHITE).background(Color::RED)) }) - .hover_style(|s| s.background(Color::rgb8(244, 67, 54))) - .active_style(|s| s.color(Color::WHITE).background(Color::RED)) - .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .keyboard_navigatable(), label(|| "Reset to 0") .on_click(move |_| { println!("Reset counter pressed"); // will not fire if button is disabled @@ -51,12 +55,12 @@ fn app_view() -> impl View { .padding(10.0) .margin_left(10.0) .background(Color::LIGHT_BLUE) + .focus_visible(|s| s.border(2.).border_color(Color::BLUE)) + .disabled(|s| s.background(Color::LIGHT_GRAY)) + .hover(|s| s.background(Color::LIGHT_YELLOW)) + .active(|s| s.color(Color::WHITE).background(Color::YELLOW_GREEN)) }) - .disabled_style(|s| s.background(Color::LIGHT_GRAY)) - .hover_style(|s| s.background(Color::LIGHT_YELLOW)) - .active_style(|s| s.color(Color::WHITE).background(Color::YELLOW_GREEN)) - .keyboard_navigatable() - .focus_visible_style(|s| s.border_color(Color::BLUE).border(2.)), + .keyboard_navigatable(), ) }), stack({ @@ -72,8 +76,8 @@ fn app_view() -> impl View { .margin_top(10.0) .margin_right(10.0) .padding(10.0) - }) - .hover_style(|s| s.background(Color::LIGHT_GREEN)), + .hover(|s| s.background(Color::LIGHT_GREEN)) + }), label(|| "Zoom Out") .on_click(move |_| { window_scale.update(|scale| *scale /= 1.2); @@ -85,8 +89,8 @@ fn app_view() -> impl View { .margin_top(10.0) .margin_right(10.0) .padding(10.0) - }) - .hover_style(|s| s.background(Color::LIGHT_GREEN)), + .hover(|s| s.background(Color::LIGHT_GREEN)) + }), label(|| "Zoom Reset") .disabled(move || window_scale.get() == 1.0) .on_click(move |_| { @@ -99,9 +103,9 @@ fn app_view() -> impl View { .margin_top(10.0) .margin_right(10.0) .padding(10.0) - }) - .hover_style(|s| s.background(Color::LIGHT_GREEN)) - .disabled_style(|s| s.background(Color::LIGHT_GRAY)), + .hover(|s| s.background(Color::LIGHT_GREEN)) + .disabled(|s| s.background(Color::LIGHT_GRAY)) + }), ) }) .style(|s| {