From 3cf473c26bcbb519f71936d6e048beb87e20ca7c Mon Sep 17 00:00:00 2001 From: Bryan Hyland Date: Fri, 15 Nov 2024 19:43:22 -0800 Subject: [PATCH] Moved the vertical spin button widget into spin button's mod.rs --- examples/vertical-spin-button/src/main.rs | 8 +- src/widget/mod.rs | 4 - src/widget/spin_button/mod.rs | 114 ++++++++++++++++++++- src/widget/vertical_spin_button.rs | 116 ---------------------- 4 files changed, 117 insertions(+), 125 deletions(-) delete mode 100644 src/widget/vertical_spin_button.rs diff --git a/examples/vertical-spin-button/src/main.rs b/examples/vertical-spin-button/src/main.rs index b3b09349..5b0e02ff 100644 --- a/examples/vertical-spin-button/src/main.rs +++ b/examples/vertical-spin-button/src/main.rs @@ -1,4 +1,4 @@ -use cosmic::widget::{button, container, text, vertical_spinner}; +use cosmic::widget::{button, container, text, spin_button::vertical_spin_button}; use cosmic::{ app::{Core, Task}, iced::{ @@ -83,7 +83,7 @@ impl Application for VertSpinnerApp { fn view(&self) -> Element { let spinner_row = row![ - vertical_spinner( + vertical_spin_button( "Hours", 1, self.hours, @@ -91,7 +91,7 @@ impl Application for VertSpinnerApp { 12, VertSpinnerMessages::UpdateHours ), - vertical_spinner( + vertical_spin_button( "Minutes", 1, self.mins, @@ -99,7 +99,7 @@ impl Application for VertSpinnerApp { 59, VertSpinnerMessages::UpdateMins ), - vertical_spinner( + vertical_spin_button( "Seconds", 1, self.secs, diff --git a/src/widget/mod.rs b/src/widget/mod.rs index 703f88e1..52acf06d 100644 --- a/src/widget/mod.rs +++ b/src/widget/mod.rs @@ -358,10 +358,6 @@ pub mod tooltip { } } -pub mod vertical_spin_button; -#[doc(inline)] -pub use vertical_spin_button::*; - pub mod warning; #[doc(inline)] pub use warning::*; diff --git a/src/widget/spin_button/mod.rs b/src/widget/spin_button/mod.rs index 9da29394..eb3005f8 100644 --- a/src/widget/spin_button/mod.rs +++ b/src/widget/spin_button/mod.rs @@ -8,10 +8,14 @@ use std::borrow::Cow; pub use self::model::{Message, Model}; -use crate::widget::{button, container, icon, row, text}; +use crate::widget::{button, column, container, icon, row, text}; use crate::{theme, Element}; +use std::fmt::Display; +use std::marker::PhantomData; +use std::ops::{Add, Sub}; use apply::Apply; use iced::{Alignment, Length}; +use iced::alignment::Horizontal; use iced_core::{Border, Shadow}; pub struct SpinButton<'a, Message> { @@ -106,3 +110,111 @@ fn container_style(theme: &crate::Theme) -> iced_widget::container::Style { shadow: Shadow::default(), } } + + + +/// VerticalSpinButton is the state/model of the vertical spin button widget. +/// Restricts T to Add, Sub, Eq, Ord, Display, and Copy so that +/// T can only be numerical values. +pub struct VerticalSpinButton<'a, T, M> +where + T: Add + Sub + Eq + Ord + Display + Copy, +{ + label: String, + step: T, + value: T, + min: T, + max: T, + on_select: Box M>, + phantom_data: PhantomData<&'a M>, +} + +impl<'a, T, M> VerticalSpinButton<'a, T, M> +where + T: Add + Sub + Eq + Ord + Display + Copy, +{ + /// Creates a new vertical spin button widget + pub fn new( + label: impl Into, + step: T, + value: T, + min: T, + max: T, + on_select: impl Fn(T) -> M + 'static, + ) -> Self { + VerticalSpinButton { + label: label.into(), + step, + value, + min, + max, + on_select: Box::new(on_select), + phantom_data: PhantomData, + } + } +} + +pub fn vertical_spin_button( + label: impl Into, + step: T, + value: T, + min: T, + max: T, + on_select: impl Fn(T) -> M + 'static, +) -> VerticalSpinButton<'static, T, M> +where + T: Add + Sub + Eq + Ord + Display + Copy, +{ + VerticalSpinButton::new(label, step, value, min, max, on_select) +} + +fn increment(step: T, val: T, min: T, max: T) -> T +where + T: Add + Sub + Eq + Ord + Display + Copy, +{ + std::cmp::min(std::cmp::max(val + step, min), max) +} + +fn decrement(step: T, val: T, min: T, max: T) -> T +where + T: Add + Sub + Eq + Ord + Display + Copy, +{ + std::cmp::max(std::cmp::min(val - step, max), min) +} + +impl<'a, T, Message> From> for Element<'a, Message> +where + Message: Clone + 'static, + T: Add + Sub + Eq + Ord + Display + Copy, +{ + fn from(this: VerticalSpinButton) -> Self { + let val_text = text(format!("{}", this.value)).size(14); + let spinner_container = column::with_capacity(3) + .push( + button::icon(icon::from_name("list-add-symbolic")) + .padding([0, 12]) + .on_press((this.on_select)(increment::( + this.step, this.value, this.min, this.max, + ))), + ) + .push(val_text) + .push( + button::icon(icon::from_name("list-remove-symbolic")) + .padding([0, 12]) + .on_press((this.on_select)(decrement::( + this.step, this.value, this.min, this.max, + ))), + ) + .align_x(Horizontal::Center); + + let content_list = column::with_children(vec![ + row::with_capacity(1).push(text(this.label)).into(), + row::with_children(vec![Element::from(spinner_container)]).into(), + ]) + .width(75) + .padding([8, 0]) + .align_x(Alignment::Center); + + Self::new(content_list) + } +} diff --git a/src/widget/vertical_spin_button.rs b/src/widget/vertical_spin_button.rs deleted file mode 100644 index 768da2c3..00000000 --- a/src/widget/vertical_spin_button.rs +++ /dev/null @@ -1,116 +0,0 @@ -// Spinner for integer selection -// Author: Bryan Hyland - -use crate::iced::alignment::Horizontal; -use crate::iced::Alignment; -use crate::widget::{button, column, icon, row, text}; -use crate::Element; -use std::fmt::Display; -use std::marker::PhantomData; -use std::ops::{Add, Sub}; - -/// Spinner is the state/model of the vertical spinner widget. -/// Restricts T to Add, Sub, Eq, Ord, Display, and Copy so that -/// T can only be numerical values. -pub struct VerticalSpinner<'a, T, M> -where - T: Add + Sub + Eq + Ord + Display + Copy, -{ - label: String, - step: T, - value: T, - min: T, - max: T, - on_select: Box M>, - phantom_data: PhantomData<&'a M>, -} - -impl<'a, T, M> VerticalSpinner<'a, T, M> -where - T: Add + Sub + Eq + Ord + Display + Copy, -{ - /// Creates a new vertical spinner widget - pub fn new( - label: impl Into, - step: T, - value: T, - min: T, - max: T, - on_select: impl Fn(T) -> M + 'static, - ) -> Self { - VerticalSpinner { - label: label.into(), - step, - value, - min, - max, - on_select: Box::new(on_select), - phantom_data: PhantomData, - } - } -} - -pub fn vertical_spinner( - label: impl Into, - step: T, - value: T, - min: T, - max: T, - on_select: impl Fn(T) -> M + 'static, -) -> VerticalSpinner<'static, T, M> -where - T: Add + Sub + Eq + Ord + Display + Copy, -{ - VerticalSpinner::new(label, step, value, min, max, on_select) -} - -fn increment(step: T, val: T, min: T, max: T) -> T -where - T: Add + Sub + Eq + Ord + Display + Copy, -{ - std::cmp::min(std::cmp::max(val + step, min), max) -} - -fn decrement(step: T, val: T, min: T, max: T) -> T -where - T: Add + Sub + Eq + Ord + Display + Copy, -{ - std::cmp::max(std::cmp::min(val - step, max), min) -} - -impl<'a, T, Message> From> for Element<'a, Message> -where - Message: Clone + 'static, - T: Add + Sub + Eq + Ord + Display + Copy, -{ - fn from(this: VerticalSpinner) -> Self { - let val_text = text(format!("{}", this.value)).size(14); - let spinner_container = column::with_capacity(3) - .push( - button::icon(icon::from_name("list-add-symbolic")) - .padding([0, 12]) - .on_press((this.on_select)(increment::( - this.step, this.value, this.min, this.max, - ))), - ) - .push(val_text) - .push( - button::icon(icon::from_name("list-remove-symbolic")) - .padding([0, 12]) - .on_press((this.on_select)(decrement::( - this.step, this.value, this.min, this.max, - ))), - ) - .align_x(Horizontal::Center); - - let content_list = column::with_children(vec![ - row::with_capacity(1).push(text(this.label)).into(), - row::with_children(vec![Element::from(spinner_container)]).into(), - ]) - .width(75) - .padding([8, 0]) - .align_x(Alignment::Center); - - Self::new(content_list) - } -}