Skip to content

Commit

Permalink
feat: Show the Hand cursor when hovering the Button, Slider and Switc…
Browse files Browse the repository at this point in the history
…h components (#373)
  • Loading branch information
marc2332 authored Nov 11, 2023
1 parent 6d41744 commit f2306ca
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 23 deletions.
22 changes: 19 additions & 3 deletions crates/components/src/button.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use dioxus::prelude::*;
use freya_elements::elements as dioxus_elements;
use freya_elements::events::MouseEvent;
use freya_hooks::{use_focus, use_get_theme};
use freya_hooks::{use_focus, use_get_theme, use_platform};
use winit::window::CursorIcon;

/// [`Button`] component properties.
#[derive(Props)]
Expand Down Expand Up @@ -67,6 +68,7 @@ pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element {
let focus = use_focus(cx);
let theme = use_get_theme(cx);
let status = use_state(cx, ButtonStatus::default);
let platform = use_platform(cx);

let focus_id = focus.attribute(cx);

Expand All @@ -77,11 +79,25 @@ pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element {
}
};

let onmouseenter = move |_| {
status.set(ButtonStatus::Hovering);
use_on_unmount(cx, {
to_owned![status, platform];
move || {
if *status.get() == ButtonStatus::Hovering {
platform.set_cursor(CursorIcon::default());
}
}
});

let onmouseenter = {
to_owned![status, platform];
move |_| {
platform.set_cursor(CursorIcon::Hand);
status.set(ButtonStatus::Hovering);
}
};

let onmouseleave = move |_| {
platform.set_cursor(CursorIcon::default());
status.set(ButtonStatus::default());
};

Expand Down
41 changes: 35 additions & 6 deletions crates/components/src/slider.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use dioxus::prelude::*;
use freya_elements::elements as dioxus_elements;
use freya_elements::events::{MouseEvent, WheelEvent};
use freya_hooks::{use_get_theme, use_node_ref};
use freya_hooks::{use_get_theme, use_node_ref, use_platform};
use tracing::info;
use winit::window::CursorIcon;

/// [`Slider`] component properties.
#[derive(Props)]
Expand All @@ -28,6 +29,16 @@ fn ensure_correct_slider_range(value: f64) -> f64 {
}
}

/// Describes the current status of the Slider.
#[derive(Debug, Default, PartialEq, Clone, Copy)]
pub enum SliderStatus {
/// Default state.
#[default]
Idle,
/// Mouse is hovering the slider.
Hovering,
}

/// Controlled `Slider` component.
///
/// You must pass a percentage from 0.0 to 100.0 and listen for value changes with `onmoved` and then decide if this changes are applicable,
Expand Down Expand Up @@ -63,22 +74,39 @@ fn ensure_correct_slider_range(value: f64) -> f64 {
pub fn Slider<'a>(cx: Scope<'a, SliderProps>) -> Element<'a> {
let theme = use_get_theme(cx);
let theme = &theme.slider;
let hovering = use_state(cx, || false);
let status = use_ref(cx, SliderStatus::default);
let clicking = use_state(cx, || false);
let platform = use_platform(cx);

let value = ensure_correct_slider_range(cx.props.value);
let (node_reference, size) = use_node_ref(cx);
let width = cx.props.width + 14.0;

let progress = (value / 100.0) * cx.props.width + 0.5;

let onmouseleave = |_: MouseEvent| {
if !(*clicking.get()) {
hovering.set(false);
use_on_unmount(cx, {
to_owned![status, platform];
move || {
if *status.read() == SliderStatus::Hovering {
platform.set_cursor(CursorIcon::default());
}
}
});

let onmouseleave = {
to_owned![platform, status];
move |_: MouseEvent| {
*status.write_silent() = SliderStatus::Idle;
platform.set_cursor(CursorIcon::default());
}
};

let onmouseenter = move |_: MouseEvent| {
*status.write_silent() = SliderStatus::Hovering;
platform.set_cursor(CursorIcon::Hand);
};

let onmouseover = move |e: MouseEvent| {
hovering.set(true);
if *clicking.get() {
let coordinates = e.get_element_coordinates();
let mut x = coordinates.x - 7.5 - size.read().area.min_x() as f64;
Expand Down Expand Up @@ -119,6 +147,7 @@ pub fn Slider<'a>(cx: Scope<'a, SliderProps>) -> Element<'a> {
height: "20",
onmousedown: onmousedown,
onglobalclick: onclick,
onmouseenter: onmouseenter,
onglobalmouseover: onmouseover,
onmouseleave: onmouseleave,
onwheel: onwheel,
Expand Down
46 changes: 32 additions & 14 deletions crates/components/src/switch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use dioxus::prelude::*;
use freya_elements::elements as dioxus_elements;
use freya_elements::events::MouseEvent;
use freya_hooks::{use_animation, use_get_theme, Animation};
use freya_hooks::{use_animation, use_get_theme, use_platform, Animation};
use winit::window::CursorIcon;

/// [`Switch`] component properties.
#[derive(Props)]
Expand All @@ -12,6 +13,16 @@ pub struct SwitchProps<'a> {
pub ontoggled: EventHandler<'a, ()>,
}

/// Describes the current status of the Switch.
#[derive(Debug, Default, PartialEq, Clone, Copy)]
pub enum SwitchStatus {
/// Default state.
#[default]
Idle,
/// Mouse is hovering the switch.
Hovering,
}

/// Controlled `Switch` component.
///
/// # Props
Expand Down Expand Up @@ -42,25 +53,32 @@ pub struct SwitchProps<'a> {
pub fn Switch<'a>(cx: Scope<'a, SwitchProps<'a>>) -> Element<'a> {
let animation = use_animation(cx, || 0.0);
let theme = use_get_theme(cx);
let hovering = use_state(cx, || false);
let clicking = use_state(cx, || false);
let platform = use_platform(cx);
let status = use_ref(cx, SwitchStatus::default);

let onmouseleave = |_: MouseEvent| {
if !(*clicking.get()) {
hovering.set(false);
use_on_unmount(cx, {
to_owned![status, platform];
move || {
if *status.read() == SwitchStatus::Hovering {
platform.set_cursor(CursorIcon::default());
}
}
};
});

let onmouseover = |_: MouseEvent| {
hovering.set(true);
let onmouseleave = {
to_owned![platform];
move |_: MouseEvent| {
*status.write_silent() = SwitchStatus::Idle;
platform.set_cursor(CursorIcon::default());
}
};

let onmousedown = |_: MouseEvent| {
clicking.set(true);
let onmouseenter = move |_: MouseEvent| {
*status.write_silent() = SwitchStatus::Hovering;
platform.set_cursor(CursorIcon::Hand);
};

let onclick = |_: MouseEvent| {
clicking.set(false);
cx.props.ontoggled.call(());
};

Expand Down Expand Up @@ -96,8 +114,8 @@ pub fn Switch<'a>(cx: Scope<'a, SwitchProps<'a>>) -> Element<'a> {
padding: "1",
corner_radius: "50",
background: "{border}",
onmousedown: onmousedown,
onmouseover: onmouseover,
onmousedown: |_| {},
onmouseenter: onmouseenter,
onmouseleave: onmouseleave,
onclick: onclick,
rect {
Expand Down

0 comments on commit f2306ca

Please sign in to comment.