From 2352aee11b83bf264a52dca4b1e959881a0f3bef Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Mon, 13 May 2024 21:31:58 -0400 Subject: [PATCH 1/7] changed number input's bounds to an inclusive range --- src/widgets/helpers.rs | 3 +- src/widgets/number_input.rs | 59 +++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/widgets/helpers.rs b/src/widgets/helpers.rs index 18280429..bc2412bf 100644 --- a/src/widgets/helpers.rs +++ b/src/widgets/helpers.rs @@ -337,7 +337,6 @@ where #[must_use] pub fn number_input<'a, T, Message, Theme, Renderer, F>( value: T, - max: T, on_changed: F, ) -> crate::NumberInput<'a, T, Message, Theme, Renderer> where @@ -356,7 +355,7 @@ where + std::str::FromStr + Copy, { - crate::NumberInput::new(value, max, on_changed) + crate::NumberInput::new(value, on_changed) } #[cfg(feature = "selection_list")] diff --git a/src/widgets/number_input.rs b/src/widgets/number_input.rs index 0a922792..193242e8 100644 --- a/src/widgets/number_input.rs +++ b/src/widgets/number_input.rs @@ -24,7 +24,7 @@ use iced::{ Rectangle, Shadow, Size, }; use num_traits::{Num, NumAssignOps}; -use std::{fmt::Display, str::FromStr}; +use std::{fmt::Display, ops::RangeInclusive, str::FromStr}; use crate::style; pub use crate::{ @@ -70,7 +70,7 @@ where /// The step for each modify of the [`NumberInput`]. step: T, /// The min and max value of the [`NumberInput`]. - bounds: (T, T), + bounds: RangeInclusive, /// The content padding of the [`NumberInput`]. padding: f32, /// The text size of the [`NumberInput`]. @@ -106,7 +106,7 @@ where /// - the current value /// - the max value /// - a function that produces a message when the [`NumberInput`] changes - pub fn new(value: T, max: T, on_changed: F) -> Self + pub fn new(value: T, on_changed: F) -> Self where F: 'static + Fn(T) -> Message + Copy, T: 'static, @@ -119,7 +119,7 @@ where Self { value, step: T::one(), - bounds: (T::zero(), max), + bounds: RangeInclusive::new(T::zero(), T::one()), padding, size: None, content: TextInput::new("", format!("{value}").as_str()) @@ -135,11 +135,14 @@ where } /// Sets the minimum & maximum value (bound) of the [`NumberInput`]. + /// # Example + /// ``` + /// // Creates a range from -5 till 5. + /// number_input(my_value, my_message).bounds(-5..=5) + /// ``` #[must_use] - pub fn bounds(mut self, bounds: (T, T)) -> Self { - if bounds.0 <= bounds.1 { - self.bounds = bounds; - } + pub fn bounds(mut self, bounds: RangeInclusive) -> Self { + self.bounds = bounds; self } @@ -165,8 +168,8 @@ where /// Sets the minimum value of the [`NumberInput`]. #[must_use] pub fn min(mut self, min: T) -> Self { - if min <= self.bounds.1 { - self.bounds.0 = min; + if min <= *self.bounds.end() { + self.bounds = RangeInclusive::new(min, *self.bounds.end()) } self } @@ -174,8 +177,8 @@ where /// Sets the maximum value of the [`NumberInput`]. #[must_use] pub fn max(mut self, max: T) -> Self { - if max >= self.bounds.0 { - self.bounds.1 = max; + if max >= *self.bounds.start() { + self.bounds = RangeInclusive::new(*self.bounds.start(), max) } self } @@ -235,8 +238,8 @@ where /// Decrease current value by step of the [`NumberInput`]. fn decrease_val(&mut self, shell: &mut Shell) { - if self.value < self.bounds.0 + self.step { - self.value = self.bounds.0; + if self.value < *self.bounds.start() + self.step { + self.value = *self.bounds.start(); } else { self.value -= self.step; } @@ -246,8 +249,8 @@ where /// Increase current value by step of the [`NumberInput`]. fn increase_val(&mut self, shell: &mut Shell) { - if self.value > self.bounds.1 - self.step { - self.value = self.bounds.1; + if self.value > *self.bounds.end() - self.step { + self.value = *self.bounds.end(); } else { self.value += self.step; } @@ -404,7 +407,7 @@ where .expect("fail to get decreate mod layout") .bounds(); - if self.bounds.0 == self.bounds.1 { + if self.bounds.start() == self.bounds.end() { return event::Status::Ignored; } @@ -472,10 +475,7 @@ where } match T::from_str(&new_val) { - Ok(val) - if (self.bounds.0..=self.bounds.1).contains(&val) - && val != self.value => - { + Ok(val) if self.bounds.contains(&val) && val != self.value => { self.value = val; forward_to_text(event, shell, child, clipboard) } @@ -515,10 +515,7 @@ where } match T::from_str(&new_val) { - Ok(val) - if (self.bounds.0..=self.bounds.1).contains(&val) - && val != self.value => - { + Ok(val) if self.bounds.contains(&val) && val != self.value => { self.value = val; forward_to_text(event, shell, child, clipboard) } @@ -590,8 +587,10 @@ where .expect("fail to get decreate mod layout") .bounds(); let is_mouse_over = bounds.contains(cursor.position().unwrap_or_default()); - let is_decrease_disabled = self.value <= self.bounds.0 || self.bounds.0 == self.bounds.1; - let is_increase_disabled = self.value >= self.bounds.1 || self.bounds.0 == self.bounds.1; + let is_decrease_disabled = + self.value <= *self.bounds.start() || self.bounds.start() == self.bounds.end(); + let is_increase_disabled = + self.value >= *self.bounds.end() || self.bounds.start() == self.bounds.end(); let mouse_over_decrease = dec_bounds.contains(cursor.position().unwrap_or_default()); let mouse_over_increase = inc_bounds.contains(cursor.position().unwrap_or_default()); @@ -639,8 +638,10 @@ where None, viewport, ); - let is_decrease_disabled = self.value <= self.bounds.0 || self.bounds.0 == self.bounds.1; - let is_increase_disabled = self.value >= self.bounds.1 || self.bounds.0 == self.bounds.1; + let is_decrease_disabled = + self.value <= *self.bounds.start() || self.bounds.start() == self.bounds.end(); + let is_increase_disabled = + self.value >= *self.bounds.end() || self.bounds.start() == self.bounds.end(); let decrease_btn_style = if is_decrease_disabled { style::number_input::StyleSheet::disabled(theme, &self.style) From 3bf5682af881dedc37a616cf59b6210249a1e3fe Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Mon, 13 May 2024 21:38:22 -0400 Subject: [PATCH 2/7] clippy --- src/widgets/number_input.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/number_input.rs b/src/widgets/number_input.rs index 193242e8..b8144ff0 100644 --- a/src/widgets/number_input.rs +++ b/src/widgets/number_input.rs @@ -169,7 +169,7 @@ where #[must_use] pub fn min(mut self, min: T) -> Self { if min <= *self.bounds.end() { - self.bounds = RangeInclusive::new(min, *self.bounds.end()) + self.bounds = RangeInclusive::new(min, *self.bounds.end()); } self } @@ -178,7 +178,7 @@ where #[must_use] pub fn max(mut self, max: T) -> Self { if max >= *self.bounds.start() { - self.bounds = RangeInclusive::new(*self.bounds.start(), max) + self.bounds = RangeInclusive::new(*self.bounds.start(), max); } self } From 7ea4ce537775cef65ea8dd0d9103040c3644385c Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Mon, 13 May 2024 21:53:14 -0400 Subject: [PATCH 3/7] example --- examples/number_input/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/number_input/src/main.rs b/examples/number_input/src/main.rs index 0477aa13..c58adb6b 100644 --- a/examples/number_input/src/main.rs +++ b/examples/number_input/src/main.rs @@ -93,7 +93,8 @@ impl Application for NumberInputDemo { .into(), NumberInputDemo::Loaded(State { value }) => { let lb_minute = Text::new("Number Input:"); - let txt_minute = number_input(*value, 255.0, Message::NumInpChanged) + let txt_minute = number_input(*value, Message::NumInpChanged) + .max(255.0) .style(NumberInputStyles::Default) .step(0.5); From b75b8ad270e86329c7c3776027e9e1bff2e23ceb Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Mon, 13 May 2024 23:42:50 -0400 Subject: [PATCH 4/7] fixed other examples that use number input --- examples/WidgetIDReturn/src/numberinput.rs | 4 +-- examples/wrap/src/main.rs | 34 +++++++--------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/examples/WidgetIDReturn/src/numberinput.rs b/examples/WidgetIDReturn/src/numberinput.rs index b257b842..34018350 100644 --- a/examples/WidgetIDReturn/src/numberinput.rs +++ b/examples/WidgetIDReturn/src/numberinput.rs @@ -65,9 +65,9 @@ where V: 'static, M: 'static, { - let mut input = NumberInput::new(self.value, max, NumInputMessage::Change) + let mut input = NumberInput::new(self.value, NumInputMessage::Change) .step(step) - .min(min) + .bounds(min..=max) .width(Length::Shrink); if let Some(style) = style { diff --git a/examples/wrap/src/main.rs b/examples/wrap/src/main.rs index c044d329..ce3f3caf 100644 --- a/examples/wrap/src/main.rs +++ b/examples/wrap/src/main.rs @@ -189,29 +189,17 @@ impl Application for RandStrings { Some(Into::::into(state.align)), Message::ChangeAlign, ); - let spacing_input = - Column::new() - .push(Text::new("spacing")) - .push(NumberInput::new( - state.spacing, - 500.0, - Message::ChangeSpacing, - )); - let line_spacing_input = - Column::new() - .push(Text::new("line spacing")) - .push(NumberInput::new( - state.line_spacing, - 500.0, - Message::ChangeLineSpacing, - )); - let line_minimal_length_input = Column::new() - .push(Text::new("line minimal length")) - .push(NumberInput::new( - state.line_minimal_length, - 999.0, - Message::ChangeMinimalLength, - )); + let spacing_input = Column::new() + .push(Text::new("spacing")) + .push(NumberInput::new(state.spacing, Message::ChangeSpacing).max(500.0)); + let line_spacing_input = Column::new().push(Text::new("line spacing")).push( + NumberInput::new(state.line_spacing, Message::ChangeLineSpacing).max(500.0), + ); + let line_minimal_length_input = + Column::new().push(Text::new("line minimal length")).push( + NumberInput::new(state.line_minimal_length, Message::ChangeMinimalLength) + .max(999.0), + ); let ctrls = Column::new() .push(align_picklist) .push(spacing_input) From 829822daf22402f572a0cee596986e150b3a0f21 Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Tue, 14 May 2024 23:29:39 -0400 Subject: [PATCH 5/7] accepet ranges and remove max and min methods --- Cargo.lock | 17 ++++ Cargo.toml | 7 +- examples/WidgetIDReturn/src/numberinput.rs | 9 +- examples/number_input/src/main.rs | 3 +- examples/wrap/src/main.rs | 34 ++++--- src/widgets/helpers.rs | 11 ++- src/widgets/number_input.rs | 108 +++++++++++---------- 7 files changed, 111 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3795499..74cb44ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1319,6 +1319,7 @@ dependencies = [ "chrono", "iced", "itertools", + "num-format", "num-traits", "once_cell", "time", @@ -1550,6 +1551,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "jni" version = "0.21.1" @@ -1934,6 +1941,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec", + "itoa", +] + [[package]] name = "num-traits" version = "0.2.19" diff --git a/Cargo.toml b/Cargo.toml index c30f55d9..8157720c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ tab_bar = [] tabs = ["tab_bar"] time_picker = ["chrono", "icons", "iced/canvas"] wrap = [] -number_input = ["num-traits"] +number_input = ["num-format", "num-traits"] selection_list = [] split = [] menu = [] @@ -67,11 +67,12 @@ default = [ [dependencies] cfg-if = "1.0" +chrono = { version = "0.4.34", optional = true } +itertools = { version = "0.12.1", optional = true } +num-format = { version = "0.4.4", optional = true } num-traits = { version = "0.2.18", optional = true } time = { version = "0.3.34", features = ["local-offset"], optional = true } -chrono = { version = "0.4.34", optional = true } once_cell = { version = "1.19.0", optional = true } -itertools = { version = "0.12.1", optional = true } [dependencies.iced] #git = "https://github.com/iced-rs/iced.git" diff --git a/examples/WidgetIDReturn/src/numberinput.rs b/examples/WidgetIDReturn/src/numberinput.rs index 34018350..fdf920a9 100644 --- a/examples/WidgetIDReturn/src/numberinput.rs +++ b/examples/WidgetIDReturn/src/numberinput.rs @@ -1,6 +1,6 @@ use iced::{Element, Length}; use iced_aw::{NumberInput, NumberInputStyles}; -use num_traits::{Num, NumAssignOps}; +use num_traits::{bounds::Bounded, Num, NumAssignOps}; use std::fmt::Display; use std::marker::PhantomData; use std::str::FromStr; @@ -18,7 +18,7 @@ pub enum NumInputMessage { impl NumInputMessage where - V: Num + NumAssignOps + PartialOrd + Display + FromStr + Copy, + V: Num + NumAssignOps + PartialOrd + Display + FromStr + Copy + Bounded, { pub fn get_data(&self) -> V { let NumInputMessage::Change(data) = self; @@ -38,7 +38,7 @@ where impl NumInput where - V: Num + NumAssignOps + PartialOrd + Display + FromStr + Copy, + V: Num + NumAssignOps + PartialOrd + Display + FromStr + Copy + Bounded, M: Clone, { pub fn new(value: V) -> NumInput @@ -65,9 +65,8 @@ where V: 'static, M: 'static, { - let mut input = NumberInput::new(self.value, NumInputMessage::Change) + let mut input = NumberInput::new(self.value, min..max, NumInputMessage::Change) .step(step) - .bounds(min..=max) .width(Length::Shrink); if let Some(style) = style { diff --git a/examples/number_input/src/main.rs b/examples/number_input/src/main.rs index c58adb6b..dc768370 100644 --- a/examples/number_input/src/main.rs +++ b/examples/number_input/src/main.rs @@ -93,8 +93,7 @@ impl Application for NumberInputDemo { .into(), NumberInputDemo::Loaded(State { value }) => { let lb_minute = Text::new("Number Input:"); - let txt_minute = number_input(*value, Message::NumInpChanged) - .max(255.0) + let txt_minute = number_input(*value, 0.0..250.0, Message::NumInpChanged) .style(NumberInputStyles::Default) .step(0.5); diff --git a/examples/wrap/src/main.rs b/examples/wrap/src/main.rs index ce3f3caf..8a8d744d 100644 --- a/examples/wrap/src/main.rs +++ b/examples/wrap/src/main.rs @@ -189,17 +189,29 @@ impl Application for RandStrings { Some(Into::::into(state.align)), Message::ChangeAlign, ); - let spacing_input = Column::new() - .push(Text::new("spacing")) - .push(NumberInput::new(state.spacing, Message::ChangeSpacing).max(500.0)); - let line_spacing_input = Column::new().push(Text::new("line spacing")).push( - NumberInput::new(state.line_spacing, Message::ChangeLineSpacing).max(500.0), - ); - let line_minimal_length_input = - Column::new().push(Text::new("line minimal length")).push( - NumberInput::new(state.line_minimal_length, Message::ChangeMinimalLength) - .max(999.0), - ); + let spacing_input = + Column::new() + .push(Text::new("spacing")) + .push(NumberInput::new( + state.spacing, + 0.0..500.0, + Message::ChangeSpacing, + )); + let line_spacing_input = + Column::new() + .push(Text::new("line spacing")) + .push(NumberInput::new( + state.line_spacing, + 0.0..500.0, + Message::ChangeLineSpacing, + )); + let line_minimal_length_input = Column::new() + .push(Text::new("line minimal length")) + .push(NumberInput::new( + state.line_minimal_length, + 0.0..999.9, + Message::ChangeMinimalLength, + )); let ctrls = Column::new() .push(align_picklist) .push(spacing_input) diff --git a/src/widgets/helpers.rs b/src/widgets/helpers.rs index bc2412bf..47202c10 100644 --- a/src/widgets/helpers.rs +++ b/src/widgets/helpers.rs @@ -4,8 +4,9 @@ #[allow(unused_imports)] use iced::{self, advanced::renderer, Color, Element}; +use num_traits::bounds::Bounded; #[allow(unused_imports)] -use std::{borrow::Cow, fmt::Display, hash::Hash}; +use std::{borrow::Cow, fmt::Display, hash::Hash, ops::RangeBounds}; /// Creates a [`Grid`] with the given [`GridRow`]s. /// @@ -337,6 +338,7 @@ where #[must_use] pub fn number_input<'a, T, Message, Theme, Renderer, F>( value: T, + bounds: impl RangeBounds, on_changed: F, ) -> crate::NumberInput<'a, T, Message, Theme, Renderer> where @@ -353,9 +355,10 @@ where + PartialOrd + std::fmt::Display + std::str::FromStr - + Copy, + + Copy + + Bounded, { - crate::NumberInput::new(value, on_changed) + crate::NumberInput::new(value, bounds, on_changed) } #[cfg(feature = "selection_list")] @@ -409,7 +412,7 @@ where + crate::style::selection_list::StyleSheet + iced::widget::container::StyleSheet + iced::widget::scrollable::StyleSheet, - T: Clone + Display + Eq + Hash, + T: Clone + Display + Eq + Hash + Bounded, [T]: ToOwned>, { crate::SelectionList::new(options, on_selected) diff --git a/src/widgets/number_input.rs b/src/widgets/number_input.rs index b8144ff0..49df8197 100644 --- a/src/widgets/number_input.rs +++ b/src/widgets/number_input.rs @@ -23,8 +23,12 @@ use iced::{ Alignment, Background, Border, Color, Element, Event, Length, Padding, Pixels, Point, Rectangle, Shadow, Size, }; -use num_traits::{Num, NumAssignOps}; -use std::{fmt::Display, ops::RangeInclusive, str::FromStr}; +use num_traits::{bounds::Bounded, Num, NumAssignOps}; +use std::{ + fmt::Display, + ops::{Bound, RangeBounds}, + str::FromStr, +}; use crate::style; pub use crate::{ @@ -51,7 +55,7 @@ const DEFAULT_PADDING: f32 = 5.0; /// /// let input = NumberInput::new( /// value, -/// max, +/// 0..=max, /// Message::NumberInputChanged, /// ) /// .step(2); @@ -69,8 +73,10 @@ where value: T, /// The step for each modify of the [`NumberInput`]. step: T, - /// The min and max value of the [`NumberInput`]. - bounds: RangeInclusive, + /// The min value of the [`NumberInput`]. + min: T, + /// The max value of the [`NumberInput`]. + max: T, /// The content padding of the [`NumberInput`]. padding: f32, /// The text size of the [`NumberInput`]. @@ -91,7 +97,7 @@ where impl<'a, T, Message, Theme, Renderer> NumberInput<'a, T, Message, Theme, Renderer> where - T: Num + NumAssignOps + PartialOrd + Display + FromStr + Copy, + T: Num + NumAssignOps + PartialOrd + Display + FromStr + Copy + Bounded, Message: Clone, Renderer: iced::advanced::text::Renderer, Theme: number_input::StyleSheet @@ -106,7 +112,7 @@ where /// - the current value /// - the max value /// - a function that produces a message when the [`NumberInput`] changes - pub fn new(value: T, on_changed: F) -> Self + pub fn new(value: T, bounds: impl RangeBounds, on_changed: F) -> Self where F: 'static + Fn(T) -> Message + Copy, T: 'static, @@ -119,7 +125,8 @@ where Self { value, step: T::one(), - bounds: RangeInclusive::new(T::zero(), T::one()), + min: Self::set_min(bounds.start_bound()), + max: Self::set_max(bounds.end_bound()), padding, size: None, content: TextInput::new("", format!("{value}").as_str()) @@ -141,8 +148,10 @@ where /// number_input(my_value, my_message).bounds(-5..=5) /// ``` #[must_use] - pub fn bounds(mut self, bounds: RangeInclusive) -> Self { - self.bounds = bounds; + pub fn bounds(mut self, bounds: impl RangeBounds) -> Self { + self.min = Self::set_min(bounds.start_bound()); + self.max = Self::set_max(bounds.end_bound()); + self } @@ -165,24 +174,6 @@ where self } - /// Sets the minimum value of the [`NumberInput`]. - #[must_use] - pub fn min(mut self, min: T) -> Self { - if min <= *self.bounds.end() { - self.bounds = RangeInclusive::new(min, *self.bounds.end()); - } - self - } - - /// Sets the maximum value of the [`NumberInput`]. - #[must_use] - pub fn max(mut self, max: T) -> Self { - if max >= *self.bounds.start() { - self.bounds = RangeInclusive::new(*self.bounds.start(), max); - } - self - } - /// Sets the message that should be produced when the [`NumberInput`] is /// focused and the enter key is pressed. #[must_use] @@ -237,9 +228,9 @@ where } /// Decrease current value by step of the [`NumberInput`]. - fn decrease_val(&mut self, shell: &mut Shell) { - if self.value < *self.bounds.start() + self.step { - self.value = *self.bounds.start(); + fn decrease_value(&mut self, shell: &mut Shell) { + if self.value < self.min + self.step { + self.value = self.min; } else { self.value -= self.step; } @@ -248,20 +239,35 @@ where } /// Increase current value by step of the [`NumberInput`]. - fn increase_val(&mut self, shell: &mut Shell) { - if self.value > *self.bounds.end() - self.step { - self.value = *self.bounds.end(); + fn increase_value(&mut self, shell: &mut Shell) { + if self.value > self.max - self.step { + self.value = self.max; } else { self.value += self.step; } shell.publish((self.on_change)(self.value)); } + + fn set_min(min: Bound<&T>) -> T { + match min { + Bound::Included(n) | Bound::Excluded(n) => *n, + Bound::Unbounded => T::min_value(), + } + } + + fn set_max(max: Bound<&T>) -> T { + match max { + Bound::Included(n) => *n, + Bound::Excluded(n) => *n - T::one(), + Bound::Unbounded => T::max_value(), + } + } } impl<'a, T, Message, Theme, Renderer> Widget for NumberInput<'a, T, Message, Theme, Renderer> where - T: Num + NumAssignOps + PartialOrd + Display + FromStr + ToString + Copy, + T: Num + NumAssignOps + PartialOrd + Display + FromStr + ToString + Copy + Bounded, Message: 'a + Clone, Renderer: 'a + iced::advanced::text::Renderer, Theme: number_input::StyleSheet @@ -407,7 +413,7 @@ where .expect("fail to get decreate mod layout") .bounds(); - if self.bounds.start() == self.bounds.end() { + if self.min == self.max { return event::Status::Ignored; } @@ -444,11 +450,11 @@ where match key { keyboard::Key::Named(keyboard::key::Named::ArrowDown) => { - self.decrease_val(shell); + self.decrease_value(shell); event::Status::Captured } keyboard::Key::Named(keyboard::key::Named::ArrowUp) => { - self.increase_val(shell); + self.increase_value(shell); event::Status::Captured } keyboard::Key::Named( @@ -475,7 +481,7 @@ where } match T::from_str(&new_val) { - Ok(val) if self.bounds.contains(&val) && val != self.value => { + Ok(val) if (self.min..self.max).contains(&val) && val != self.value => { self.value = val; forward_to_text(event, shell, child, clipboard) } @@ -515,7 +521,7 @@ where } match T::from_str(&new_val) { - Ok(val) if self.bounds.contains(&val) && val != self.value => { + Ok(val) if (self.min..self.max).contains(&val) && val != self.value => { self.value = val; forward_to_text(event, shell, child, clipboard) } @@ -531,9 +537,9 @@ where match delta { mouse::ScrollDelta::Lines { y, .. } | mouse::ScrollDelta::Pixels { y, .. } => { if y.is_sign_positive() { - self.increase_val(shell); + self.increase_value(shell); } else { - self.decrease_val(shell); + self.decrease_value(shell); } } } @@ -542,10 +548,10 @@ where Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) if mouse_over_button => { if mouse_over_dec { modifiers.decrease_pressed = true; - self.decrease_val(shell); + self.decrease_value(shell); } else { modifiers.increase_pressed = true; - self.increase_val(shell); + self.increase_value(shell); } event::Status::Captured } @@ -587,10 +593,8 @@ where .expect("fail to get decreate mod layout") .bounds(); let is_mouse_over = bounds.contains(cursor.position().unwrap_or_default()); - let is_decrease_disabled = - self.value <= *self.bounds.start() || self.bounds.start() == self.bounds.end(); - let is_increase_disabled = - self.value >= *self.bounds.end() || self.bounds.start() == self.bounds.end(); + let is_decrease_disabled = self.value <= self.min || self.min == self.max; + let is_increase_disabled = self.value >= self.max || self.min == self.max; let mouse_over_decrease = dec_bounds.contains(cursor.position().unwrap_or_default()); let mouse_over_increase = inc_bounds.contains(cursor.position().unwrap_or_default()); @@ -638,10 +642,8 @@ where None, viewport, ); - let is_decrease_disabled = - self.value <= *self.bounds.start() || self.bounds.start() == self.bounds.end(); - let is_increase_disabled = - self.value >= *self.bounds.end() || self.bounds.start() == self.bounds.end(); + let is_decrease_disabled = self.value <= self.min || self.min == self.max; + let is_increase_disabled = self.value >= self.max || self.min == self.max; let decrease_btn_style = if is_decrease_disabled { style::number_input::StyleSheet::disabled(theme, &self.style) @@ -746,7 +748,7 @@ pub struct ModifierState { impl<'a, T, Message, Theme, Renderer> From> for Element<'a, Message, Theme, Renderer> where - T: 'a + Num + NumAssignOps + PartialOrd + Display + FromStr + Copy, + T: 'a + Num + NumAssignOps + PartialOrd + Display + FromStr + Copy + Bounded, Message: 'a + Clone, Renderer: 'a + iced::advanced::text::Renderer, Theme: 'a From dabcc3f2d3fc216ed69d06a24ade482cf4c7e337 Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Wed, 15 May 2024 19:57:57 -0400 Subject: [PATCH 6/7] added option to number input to disable buttons --- src/widgets/number_input.rs | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/widgets/number_input.rs b/src/widgets/number_input.rs index 49df8197..d77b43a1 100644 --- a/src/widgets/number_input.rs +++ b/src/widgets/number_input.rs @@ -93,6 +93,8 @@ where width: Length, /// Ignore mouse scroll events for the [`NumberInput`] Default is ``false``. ignore_scroll_events: bool, + /// Ignore drawing increase and decrease buttons [`NumberInput`] Default is ``false``. + ignore_buttons: bool, } impl<'a, T, Message, Theme, Renderer> NumberInput<'a, T, Message, Theme, Renderer> @@ -138,6 +140,7 @@ where font: Renderer::Font::default(), width: Length::Shrink, ignore_scroll_events: false, + ignore_buttons: false, } } @@ -174,6 +177,22 @@ where self } + /// Enable or disable increase and decrease buttons of the [`NumberInput`], by default this is set to + /// ``false``. + #[must_use] + pub fn ignore_buttons(mut self, ignore: bool) -> Self { + self.ignore_buttons = ignore; + self + } + + /// Enable or disable mouse scrolling events of the [`NumberInput`], by default this is set to + /// ``false``. + #[must_use] + pub fn ignore_scroll(mut self, ignore: bool) -> Self { + self.ignore_scroll_events = ignore; + self + } + /// Sets the message that should be produced when the [`NumberInput`] is /// focused and the enter key is pressed. #[must_use] @@ -219,14 +238,6 @@ where self } - /// Enable or disable mouse scrolling events of the [`NumberInput`], by default this is set to - /// ``false``. - #[must_use] - pub fn ignore_scroll(mut self, ignore: bool) -> Self { - self.ignore_scroll_events = ignore; - self - } - /// Decrease current value by step of the [`NumberInput`]. fn decrease_value(&mut self, shell: &mut Shell) { if self.value < self.min + self.step { @@ -545,7 +556,9 @@ where } event::Status::Captured } - Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) if mouse_over_button => { + Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) + if mouse_over_button && !self.ignore_buttons => + { if mouse_over_dec { modifiers.decrease_pressed = true; self.decrease_value(shell); @@ -599,7 +612,7 @@ where let mouse_over_increase = inc_bounds.contains(cursor.position().unwrap_or_default()); if (mouse_over_decrease && !is_decrease_disabled) - || (mouse_over_increase && !is_increase_disabled) + || (mouse_over_increase && !is_increase_disabled) && !self.ignore_buttons { mouse::Interaction::Pointer } else if is_mouse_over { @@ -666,6 +679,9 @@ where let icon_size = Pixels(txt_size * 2.5 / 4.0); + if self.ignore_buttons { + return; + } // decrease button section if dec_bounds.intersects(viewport) { renderer.fill_quad( From 70c3fe080f5a57b8222980b9975fe775558dbbad Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Wed, 15 May 2024 20:09:52 -0400 Subject: [PATCH 7/7] mistake in boolean logic --- src/widgets/number_input.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widgets/number_input.rs b/src/widgets/number_input.rs index d77b43a1..f226525d 100644 --- a/src/widgets/number_input.rs +++ b/src/widgets/number_input.rs @@ -611,8 +611,9 @@ where let mouse_over_decrease = dec_bounds.contains(cursor.position().unwrap_or_default()); let mouse_over_increase = inc_bounds.contains(cursor.position().unwrap_or_default()); - if (mouse_over_decrease && !is_decrease_disabled) - || (mouse_over_increase && !is_increase_disabled) && !self.ignore_buttons + if ((mouse_over_decrease && !is_decrease_disabled) + || (mouse_over_increase && !is_increase_disabled)) + && !self.ignore_buttons { mouse::Interaction::Pointer } else if is_mouse_over {