From 1a193b18626c5e30df515072edd089c764a5621b Mon Sep 17 00:00:00 2001 From: Jared Moulton Date: Thu, 9 Nov 2023 13:18:43 -0700 Subject: [PATCH 1/4] Add docs and default style for toggle button --- examples/widget-gallery/src/buttons.rs | 44 +++++++++++++++++++++++++- src/widgets/mod.rs | 4 ++- src/widgets/toggle_button.rs | 37 ++++++++++++++++++---- 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index aa41732a..f81ae200 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -1,4 +1,11 @@ -use floem::{peniko::Color, style::CursorStyle, view::View, views::Decorators, widgets::button}; +use floem::{ + peniko::Color, + style::{CursorStyle, Foreground}, + unit::UnitExt, + view::View, + views::Decorators, + widgets::{self, button, toggle_button, ToggleButtonClass}, +}; use crate::form::{form, form_item}; @@ -42,6 +49,41 @@ pub fn button_view() -> impl View { true }) }), + form_item("Toggle button - Switch:".to_string(), 120.0, || { + toggle_button(|| true) + .on_toggle(|_| { + println!("Button Toggled"); + }) + .style(|s| { + s.set( + widgets::ToggleButtonBehavior, + widgets::ToggleButtonSwitch::Switch, + ) + }) + }), + form_item("Toggle button - Follow:".to_string(), 120.0, || { + toggle_button(|| true) + .on_toggle(|_| { + println!("Button Toggled"); + // true + }) + .style(|s| { + s.background(Color::DARK_GRAY).set( + widgets::ToggleButtonBehavior, + widgets::ToggleButtonSwitch::Follow, + ) + }) + }), ) }) + .base_style(|s| { + s.class(ToggleButtonClass, |s| { + s.background(Color::DARK_GRAY) + .set(Foreground, Color::WHITE_SMOKE) + .border(1.) + .height(25) + .set(widgets::ToggleButtonCircleRad, 75.pct()) + .set(widgets::ToggleButtonInset, 10.pct()) + }) + }) } diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index e71e90a2..c8e80177 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -4,7 +4,7 @@ //! use crate::{ - style::{Background, Style, Transition}, + style::{Background, Foreground, Style, Transition}, unit::UnitExt, views::scroll, }; @@ -149,6 +149,8 @@ pub(crate) fn default_theme() -> Theme { s.height(FONT_SIZE * 1.5) .aspect_ratio(2.) .border_radius(100.pct()) + .background(Color::DARK_GRAY) + .set(Foreground, Color::WHITE_SMOKE) }) .font_size(FONT_SIZE) .color(Color::BLACK); diff --git a/src/widgets/toggle_button.rs b/src/widgets/toggle_button.rs index ef918985..54cb5217 100644 --- a/src/widgets/toggle_button.rs +++ b/src/widgets/toggle_button.rs @@ -1,3 +1,5 @@ +//! A toggle button widget. An example can be found in widget-gallery/button in the floem examples. + use floem_reactive::create_effect; use floem_renderer::Renderer; use kurbo::{Point, Size}; @@ -12,24 +14,27 @@ use crate::{ views::Decorators, }; +/// Controls the switching behavior of the switch. The cooresponding style prop is [ToggleButtonBehavior] #[derive(Debug, Clone, PartialEq)] -pub enum ToggleButtonBehavior { +pub enum ToggleButtonSwitch { + /// The switch foreground item will follow the position of the cursor. The toggle event happens when the cursor passes teh 50% threshhold. Follow, + /// The switch foreground item will "jump" from being toggled off/on when the cursor passes the 50% threshhold. Switch, } -impl style::StylePropValue for ToggleButtonBehavior {} +impl style::StylePropValue for ToggleButtonSwitch {} prop!(pub ToggleButtonInset: PxPct {} = PxPct::Px(0.)); prop!(pub ToggleButtonCircleRad: PxPct {} = PxPct::Pct(95.)); -prop!(pub ToggleButtonSwitch: ToggleButtonBehavior {} = ToggleButtonBehavior::Switch); +prop!(pub ToggleButtonBehavior: ToggleButtonSwitch {} = ToggleButtonSwitch::Switch); prop_extracter! { ToggleStyle { foreground: Foreground, inset: ToggleButtonInset, circle_rad: ToggleButtonCircleRad, - switch_behavior: ToggleButtonSwitch + switch_behavior: ToggleButtonBehavior } } style_class!(pub ToggleButtonClass); @@ -41,6 +46,7 @@ enum ToggleState { Drag, } +/// A toggle button pub struct ToggleButton { id: id::Id, state: bool, @@ -51,6 +57,25 @@ pub struct ToggleButton { radius: f32, style: ToggleStyle, } + +/// A reactive toggle button. When the button is toggled by clicking or dragging the widget an update will be sent to the [ToggleButton::on_toggle] handler. +/// See also [ToggleButtonClass], [ToggleButtonSwitch] and the other toggle button styles that can be applied. +/// +/// By default this toggle button has a style class of [ToggleButtonClass] applied with a default style provided. +/// +/// Styles: +/// background color: [style::Background] +/// foreground color: [style::Foreground] +/// inner switch inset: [ToggleButtonInset] +/// inner switch (circle) size/radius: [ToggleButtonCircleRad] +/// toggle button switch behavior: [ToggleButtonBehavior] / [ToggleButtonSwitch] +/// +/// An example using RwSignal +/// ```rust +/// let state = create_new_rw_signal(true); +/// toggle_button(move || state.get()) +/// .on_toggle(move |new_state| state.set(new_state)) +///``` pub fn toggle_button(state: impl Fn() -> bool + 'static) -> ToggleButton { let id = crate::id::Id::next(); create_effect(move |_| { @@ -129,7 +154,7 @@ impl View for ToggleButton { if self.held == ToggleState::Held || self.held == ToggleState::Drag { self.held = ToggleState::Drag; match self.style.switch_behavior() { - ToggleButtonBehavior::Follow => { + ToggleButtonSwitch::Follow => { self.position = event.pos.x as f32; if self.position > self.width / 2. && !self.state { self.state = true; @@ -144,7 +169,7 @@ impl View for ToggleButton { } cx.app_state_mut().request_layout(self.id()); } - ToggleButtonBehavior::Switch => { + ToggleButtonSwitch::Switch => { if event.pos.x as f32 > self.width / 2. && !self.state { self.position = self.width; cx.app_state_mut().request_layout(self.id()); From d3572ede1d0732d6b2c8990892761308f874106c Mon Sep 17 00:00:00 2001 From: Jared Moulton Date: Thu, 9 Nov 2023 13:25:32 -0700 Subject: [PATCH 2/4] Update default style --- examples/widget-gallery/src/buttons.rs | 13 +------------ src/widgets/mod.rs | 6 +++++- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index f81ae200..dac09b15 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -65,10 +65,9 @@ pub fn button_view() -> impl View { toggle_button(|| true) .on_toggle(|_| { println!("Button Toggled"); - // true }) .style(|s| { - s.background(Color::DARK_GRAY).set( + s.set( widgets::ToggleButtonBehavior, widgets::ToggleButtonSwitch::Follow, ) @@ -76,14 +75,4 @@ pub fn button_view() -> impl View { }), ) }) - .base_style(|s| { - s.class(ToggleButtonClass, |s| { - s.background(Color::DARK_GRAY) - .set(Foreground, Color::WHITE_SMOKE) - .border(1.) - .height(25) - .set(widgets::ToggleButtonCircleRad, 75.pct()) - .set(widgets::ToggleButtonInset, 10.pct()) - }) - }) } diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index c8e80177..453ecad6 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -7,6 +7,7 @@ use crate::{ style::{Background, Foreground, Style, Transition}, unit::UnitExt, views::scroll, + widgets, }; use peniko::Color; use std::rc::Rc; @@ -148,9 +149,12 @@ pub(crate) fn default_theme() -> Theme { .class(ToggleButtonClass, |s| { s.height(FONT_SIZE * 1.5) .aspect_ratio(2.) - .border_radius(100.pct()) .background(Color::DARK_GRAY) + .border_radius(50.pct()) .set(Foreground, Color::WHITE_SMOKE) + .border(1.) + .set(widgets::ToggleButtonCircleRad, 75.pct()) + .set(widgets::ToggleButtonInset, 10.pct()) }) .font_size(FONT_SIZE) .color(Color::BLACK); From 99279cd1df0180468960ff91bd80383044daedbe Mon Sep 17 00:00:00 2001 From: Jared Moulton Date: Thu, 9 Nov 2023 13:33:28 -0700 Subject: [PATCH 3/4] remove unused imports --- examples/widget-gallery/src/buttons.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index dac09b15..e1ad281a 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -1,10 +1,9 @@ use floem::{ peniko::Color, - style::{CursorStyle, Foreground}, - unit::UnitExt, + style::CursorStyle, view::View, views::Decorators, - widgets::{self, button, toggle_button, ToggleButtonClass}, + widgets::{self, button, toggle_button}, }; use crate::form::{form, form_item}; From 3fc1542aed48fc3873446d0b1ba0a49892fde0dc Mon Sep 17 00:00:00 2001 From: Jared Moulton Date: Sat, 11 Nov 2023 22:23:02 -0700 Subject: [PATCH 4/4] Update example to make test pass --- src/widgets/toggle_button.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/toggle_button.rs b/src/widgets/toggle_button.rs index 54cb5217..ebb2a9a5 100644 --- a/src/widgets/toggle_button.rs +++ b/src/widgets/toggle_button.rs @@ -72,9 +72,9 @@ pub struct ToggleButton { /// /// An example using RwSignal /// ```rust -/// let state = create_new_rw_signal(true); -/// toggle_button(move || state.get()) -/// .on_toggle(move |new_state| state.set(new_state)) +/// let state = floem::reactive::create_rw_signal(true); +/// floem::widgets::toggle_button(move || state.get()) +/// .on_toggle(move |new_state| state.set(new_state)); ///``` pub fn toggle_button(state: impl Fn() -> bool + 'static) -> ToggleButton { let id = crate::id::Id::next();