diff options
Diffstat (limited to 'widget')
-rw-r--r-- | widget/Cargo.toml | 1 | ||||
-rw-r--r-- | widget/assets/iced-logo.svg | 2 | ||||
-rw-r--r-- | widget/src/combo_box.rs | 9 | ||||
-rw-r--r-- | widget/src/container.rs | 4 | ||||
-rw-r--r-- | widget/src/helpers.rs | 42 | ||||
-rw-r--r-- | widget/src/scrollable.rs | 33 | ||||
-rw-r--r-- | widget/src/slider.rs | 2 | ||||
-rw-r--r-- | widget/src/text_editor.rs | 5 | ||||
-rw-r--r-- | widget/src/text_input.rs | 13 | ||||
-rw-r--r-- | widget/src/vertical_slider.rs | 2 |
10 files changed, 97 insertions, 16 deletions
diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 3c9f6a54..498a768b 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -31,6 +31,7 @@ iced_renderer.workspace = true iced_runtime.workspace = true num-traits.workspace = true +once_cell.workspace = true rustc-hash.workspace = true thiserror.workspace = true unicode-segmentation.workspace = true diff --git a/widget/assets/iced-logo.svg b/widget/assets/iced-logo.svg new file mode 100644 index 00000000..459b7fbb --- /dev/null +++ b/widget/assets/iced-logo.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" fill="none" version="1.1" viewBox="35 31 179 171"><rect x="42" y="31.001" width="169.9" height="169.9" rx="49.815" fill="url(#paint1_linear)"/><path d="m182.62 65.747-28.136 28.606-6.13-6.0291 28.136-28.606 6.13 6.0291zm-26.344 0.218-42.204 42.909-6.13-6.029 42.204-42.909 6.13 6.0291zm-61.648 23.913c5.3254-5.3831 10.65-10.765 21.569-21.867l6.13 6.0291c-10.927 11.11-16.258 16.498-21.587 21.885-4.4007 4.4488-8.8009 8.8968-16.359 16.573l31.977 8.358 25.968-26.402 6.13 6.0292-25.968 26.402 8.907 31.908 42.138-42.087 6.076 6.083-49.109 49.05-45.837-12.628-13.394-45.646 1.7714-1.801c10.928-11.111 16.258-16.499 21.588-21.886zm28.419 70.99-8.846-31.689-31.831-8.32 9.1945 31.335 31.482 8.674zm47.734-56.517 7.122-7.1221-6.08-6.0797-7.147 7.1474-30.171 30.674 6.13 6.029 30.146-30.649z" clip-rule="evenodd" fill="url(#paint2_linear)" fill-rule="evenodd"/><defs><filter id="filter0_f" x="55" y="47.001" width="144" height="168" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur" stdDeviation="2"/></filter><linearGradient id="paint0_linear" x1="127" x2="127" y1="51.001" y2="211" gradientUnits="userSpaceOnUse"><stop offset=".052083"/><stop stop-opacity=".08" offset="1"/></linearGradient><linearGradient id="paint1_linear" x1="212" x2="57.5" y1="31.001" y2="189" gradientUnits="userSpaceOnUse"><stop stop-color="#00A3FF" offset="0"/><stop stop-color="#30f" offset="1"/></linearGradient><linearGradient id="paint2_linear" x1="86.098" x2="206.01" y1="158.28" y2="35.327" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient></defs></svg> diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 253850df..0a4624cb 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -280,6 +280,15 @@ where } } +impl<T> Default for State<T> +where + T: Display + Clone, +{ + fn default() -> Self { + Self::new(Vec::new()) + } +} + impl<T> Filtered<T> where T: Clone, diff --git a/widget/src/container.rs b/widget/src/container.rs index e917471f..08d5cb17 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -13,7 +13,7 @@ use crate::core::{ Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::Task; +use crate::runtime::task::{self, Task}; /// An element decorating some content. /// @@ -538,7 +538,7 @@ pub fn visible_bounds(id: Id) -> Task<Option<Rectangle>> { } } - Task::widget(VisibleBounds { + task::widget(VisibleBounds { target: id.into(), depth: 0, scrollables: Vec::new(), diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 62343a55..d7631959 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -12,7 +12,8 @@ use crate::pick_list::{self, PickList}; use crate::progress_bar::{self, ProgressBar}; use crate::radio::{self, Radio}; use crate::rule::{self, Rule}; -use crate::runtime::{Action, Task}; +use crate::runtime::task::{self, Task}; +use crate::runtime::Action; use crate::scrollable::{self, Scrollable}; use crate::slider::{self, Slider}; use crate::text::{self, Text}; @@ -889,6 +890,41 @@ where crate::Svg::new(handle) } +/// Creates an [`Element`] that displays the iced logo with the given `text_size`. +/// +/// Useful for showing some love to your favorite GUI library in your "About" screen, +/// for instance. +#[cfg(feature = "svg")] +pub fn iced<'a, Message, Theme, Renderer>( + text_size: impl Into<Pixels>, +) -> Element<'a, Message, Theme, Renderer> +where + Message: 'a, + Renderer: core::Renderer + + core::text::Renderer<Font = core::Font> + + core::svg::Renderer + + 'a, + Theme: text::Catalog + crate::svg::Catalog + 'a, +{ + use crate::core::{Alignment, Font}; + use crate::svg; + use once_cell::sync::Lazy; + + static LOGO: Lazy<svg::Handle> = Lazy::new(|| { + svg::Handle::from_memory(include_bytes!("../assets/iced-logo.svg")) + }); + + let text_size = text_size.into(); + + row![ + svg(LOGO.clone()).width(text_size * 1.3), + text("iced").size(text_size).font(Font::MONOSPACE) + ] + .spacing(text_size.0 / 3.0) + .align_items(Alignment::Center) + .into() +} + /// Creates a new [`Canvas`]. /// /// [`Canvas`]: crate::Canvas @@ -930,12 +966,12 @@ where /// Focuses the previous focusable widget. pub fn focus_previous<T>() -> Task<T> { - Task::effect(Action::widget(operation::focusable::focus_previous())) + task::effect(Action::widget(operation::focusable::focus_previous())) } /// Focuses the next focusable widget. pub fn focus_next<T>() -> Task<T> { - Task::effect(Action::widget(operation::focusable::focus_next())) + task::effect(Action::widget(operation::focusable::focus_next())) } /// A container intercepting mouse events. diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index bd612fa6..e0875bbf 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -14,7 +14,8 @@ use crate::core::{ self, Background, Border, Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::{Action, Task}; +use crate::runtime::task::{self, Task}; +use crate::runtime::Action; pub use operation::scrollable::{AbsoluteOffset, RelativeOffset}; @@ -107,6 +108,32 @@ where self } + /// Inverts the alignment of the horizontal direction of the [`Scrollable`], if applicable. + pub fn align_x(mut self, alignment: Alignment) -> Self { + match &mut self.direction { + Direction::Horizontal(horizontal) + | Direction::Both { horizontal, .. } => { + horizontal.alignment = alignment; + } + Direction::Vertical(_) => {} + } + + self + } + + /// Sets the alignment of the vertical direction of the [`Scrollable`], if applicable. + pub fn align_y(mut self, alignment: Alignment) -> Self { + match &mut self.direction { + Direction::Vertical(vertical) + | Direction::Both { vertical, .. } => { + vertical.alignment = alignment; + } + Direction::Horizontal(_) => {} + } + + self + } + /// Sets the style of this [`Scrollable`]. #[must_use] pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self @@ -954,13 +981,13 @@ impl From<Id> for widget::Id { /// Produces a [`Task`] that snaps the [`Scrollable`] with the given [`Id`] /// to the provided `percentage` along the x & y axis. pub fn snap_to<T>(id: Id, offset: RelativeOffset) -> Task<T> { - Task::effect(Action::widget(operation::scrollable::snap_to(id.0, offset))) + task::effect(Action::widget(operation::scrollable::snap_to(id.0, offset))) } /// Produces a [`Task`] that scrolls the [`Scrollable`] with the given [`Id`] /// to the provided [`AbsoluteOffset`] along the x & y axis. pub fn scroll_to<T>(id: Id, offset: AbsoluteOffset) -> Task<T> { - Task::effect(Action::widget(operation::scrollable::scroll_to( + task::effect(Action::widget(operation::scrollable::scroll_to( id.0, offset, ))) } diff --git a/widget/src/slider.rs b/widget/src/slider.rs index a8f1d192..74e6f8d3 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -237,7 +237,7 @@ where let steps = (percent * (end - start) / step).round(); let value = steps * step + start; - T::from_f64(value) + T::from_f64(value.min(end)) }; new_value diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index fc2ade43..0156b960 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -762,6 +762,11 @@ impl Update { { return Some(Self::Paste); } + keyboard::Key::Character("a") + if modifiers.command() => + { + return Some(Self::Action(Action::SelectAll)); + } _ => {} } diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 4e89236b..ba2fbc13 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -30,7 +30,8 @@ use crate::core::{ Background, Border, Color, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::{Action, Task}; +use crate::runtime::task::{self, Task}; +use crate::runtime::Action; /// A field that can be filled with text. /// @@ -1142,13 +1143,13 @@ impl From<Id> for widget::Id { /// Produces a [`Task`] that focuses the [`TextInput`] with the given [`Id`]. pub fn focus<T>(id: Id) -> Task<T> { - Task::effect(Action::widget(operation::focusable::focus(id.0))) + task::effect(Action::widget(operation::focusable::focus(id.0))) } /// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// end. pub fn move_cursor_to_end<T>(id: Id) -> Task<T> { - Task::effect(Action::widget(operation::text_input::move_cursor_to_end( + task::effect(Action::widget(operation::text_input::move_cursor_to_end( id.0, ))) } @@ -1156,7 +1157,7 @@ pub fn move_cursor_to_end<T>(id: Id) -> Task<T> { /// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// front. pub fn move_cursor_to_front<T>(id: Id) -> Task<T> { - Task::effect(Action::widget(operation::text_input::move_cursor_to_front( + task::effect(Action::widget(operation::text_input::move_cursor_to_front( id.0, ))) } @@ -1164,14 +1165,14 @@ pub fn move_cursor_to_front<T>(id: Id) -> Task<T> { /// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// provided position. pub fn move_cursor_to<T>(id: Id, position: usize) -> Task<T> { - Task::effect(Action::widget(operation::text_input::move_cursor_to( + task::effect(Action::widget(operation::text_input::move_cursor_to( id.0, position, ))) } /// Produces a [`Task`] that selects all the content of the [`TextInput`] with the given [`Id`]. pub fn select_all<T>(id: Id) -> Task<T> { - Task::effect(Action::widget(operation::text_input::select_all(id.0))) + task::effect(Action::widget(operation::text_input::select_all(id.0))) } /// The state of a [`TextInput`]. diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index defb442f..33c591f5 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -239,7 +239,7 @@ where let steps = (percent * (end - start) / step).round(); let value = steps * step + start; - T::from_f64(value) + T::from_f64(value.min(end)) }; new_value |