summaryrefslogtreecommitdiffstats
path: root/widget
diff options
context:
space:
mode:
Diffstat (limited to 'widget')
-rw-r--r--widget/Cargo.toml1
-rw-r--r--widget/assets/iced-logo.svg2
-rw-r--r--widget/src/combo_box.rs9
-rw-r--r--widget/src/container.rs4
-rw-r--r--widget/src/helpers.rs42
-rw-r--r--widget/src/scrollable.rs33
-rw-r--r--widget/src/slider.rs2
-rw-r--r--widget/src/text_editor.rs5
-rw-r--r--widget/src/text_input.rs13
-rw-r--r--widget/src/vertical_slider.rs2
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