aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpml68 <contact@pml68.dev>2025-04-15 01:34:09 +0200
committerpml68 <contact@pml68.dev>2025-04-15 01:34:09 +0200
commite7e5b05ca8c11c2ba329d0b6daffe9a218aee9a1 (patch)
tree2d86d51c1d9ab46258f7f626ace6645c19582bf8
parentfix: example package name (diff)
downloadiced_dialog-e7e5b05ca8c11c2ba329d0b6daffe9a218aee9a1.tar.gz
refactor!: move backdrop_color into `Style` struct
-rw-r--r--.gitignore1
-rw-r--r--README.md2
-rw-r--r--example/src/main.rs13
-rw-r--r--src/dialog.rs104
-rw-r--r--src/lib.rs2
5 files changed, 102 insertions, 20 deletions
diff --git a/.gitignore b/.gitignore
index 2c96eb1..2fd7392 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
target/
Cargo.lock
+rustc-ice-*.txt
diff --git a/README.md b/README.md
index 18d0e0a..0f1c11c 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
Custom dialog for [`iced`](https://iced.rs)
+It's mostly the dialog from @frgp42's [Fluent Iced Gallery](https://github.com/frgp42/fluent_iced_gallery), but made into a "widget"
+
## Example
See the [/example](/example) directory.
diff --git a/example/src/main.rs b/example/src/main.rs
index 6b0a363..8d2fcc3 100644
--- a/example/src/main.rs
+++ b/example/src/main.rs
@@ -1,8 +1,8 @@
use iced::{
- Element, Length, Task,
- widget::{center, column, text},
+ Element, Length, Task, color,
+ widget::{button, center, column, text},
};
-use iced_dialog::{button, dialog};
+use iced_dialog::dialog;
#[derive(Default)]
struct State {
@@ -41,8 +41,7 @@ impl State {
let base = center(
column![
text(&self.action_text),
- iced::widget::button("Open Dialog")
- .on_press(Message::OpenDialog)
+ button("Open Dialog").on_press(Message::OpenDialog)
]
.spacing(14.0),
)
@@ -53,8 +52,8 @@ impl State {
dialog(self.is_open, base, dialog_content)
.title("Save")
- .push_button(button("Save").on_press(Message::Saved))
- .push_button(button("Cancel").on_press(Message::Cancelled))
+ .push_button(iced_dialog::button("Save", Message::Saved))
+ .push_button(iced_dialog::button("Cancel", Message::Cancelled))
.width(350)
.height(234)
.into()
diff --git a/src/dialog.rs b/src/dialog.rs
index dba27f7..5df75ae 100644
--- a/src/dialog.rs
+++ b/src/dialog.rs
@@ -31,7 +31,7 @@ where
spacing: f32,
padding: Padding,
button_alignment: Alignment,
- backdrop_color: Box<dyn Fn(&Theme) -> Color + 'a>,
+ class: <Theme as Catalog>::Class<'a>,
title_class: <Theme as text::Catalog>::Class<'a>,
container_class: <Theme as container::Catalog>::Class<'a>,
}
@@ -41,8 +41,6 @@ where
Renderer: 'a + core::Renderer + core::text::Renderer,
Theme: 'a + Catalog,
Message: 'a + Clone,
- <Theme as container::Catalog>::Class<'a>:
- From<container::StyleFn<'a, Theme>>,
{
/// Creates a new [`Dialog`] with the given base and dialog content.
pub fn new(
@@ -72,7 +70,7 @@ where
spacing: 8.0,
padding: 24.into(),
button_alignment: Alignment::Start,
- backdrop_color: Box::new(|_theme| color!(0x000000, 0.3)),
+ class: <Theme as Catalog>::default(),
title_class: <Theme as Catalog>::default_title(),
container_class: <Theme as Catalog>::default_container(),
}
@@ -151,9 +149,13 @@ where
buttons.into_iter().fold(self, Self::push_button)
}
- /// Sets the coloring method for the [`Dialog`]'s backdrop.
- pub fn backdrop(mut self, color: impl Fn(&Theme) -> Color + 'a) -> Self {
- self.backdrop_color = Box::new(color);
+ /// Sets the style of the [`Dialog`].
+ #[must_use]
+ pub fn style(mut self, style: impl Fn(&Theme) -> Style + 'a) -> Self
+ where
+ <Theme as Catalog>::Class<'a>: From<StyleFn<'a, Theme>>,
+ {
+ self.class = (Box::new(style) as StyleFn<'a, Theme>).into();
self
}
@@ -185,7 +187,42 @@ where
self
}
- fn view(self) -> Element<'a, Message, Theme, Renderer> {
+ /// Sets the style class of the [`Dialog`].
+ #[must_use]
+ pub fn class(
+ mut self,
+ class: impl Into<<Theme as Catalog>::Class<'a>>,
+ ) -> Self {
+ self.class = class.into();
+ self
+ }
+
+ /// Sets the style class of the [`Dialog`]'s title.
+ #[must_use]
+ pub fn title_class(
+ mut self,
+ class: impl Into<<Theme as text::Catalog>::Class<'a>>,
+ ) -> Self {
+ self.title_class = class.into();
+ self
+ }
+
+ /// Sets the style class of the [`Dialog`]'s container.
+ #[must_use]
+ pub fn container_class(
+ mut self,
+ class: impl Into<<Theme as container::Catalog>::Class<'a>>,
+ ) -> Self {
+ self.container_class = class.into();
+ self
+ }
+
+ fn view(self) -> Element<'a, Message, Theme, Renderer>
+ where
+ <Theme as container::Catalog>::Class<'a>:
+ From<container::StyleFn<'a, Theme>>,
+ <Theme as Catalog>::Class<'a>: Into<StyleFn<'a, Theme>>,
+ {
if self.is_open {
let contents = Container::new(
Column::new()
@@ -226,7 +263,7 @@ where
.class(self.container_class)
.clip(true);
- modal(self.base, dialog, self.backdrop_color)
+ modal(self.base, dialog, self.class)
} else {
self.base
}
@@ -241,6 +278,7 @@ where
Message: 'a + Clone,
<Theme as container::Catalog>::Class<'a>:
From<container::StyleFn<'a, Theme>>,
+ <Theme as Catalog>::Class<'a>: Into<StyleFn<'a, Theme>>,
{
fn from(dialog: Dialog<'a, Message, Theme, Renderer>) -> Self {
dialog.view()
@@ -250,17 +288,21 @@ where
fn modal<'a, Message, Theme, Renderer>(
base: impl Into<Element<'a, Message, Theme, Renderer>>,
content: impl Into<Element<'a, Message, Theme, Renderer>>,
- backdrop_color: impl Fn(&Theme) -> Color + 'a,
+ class: <Theme as Catalog>::Class<'a>,
) -> Element<'a, Message, Theme, Renderer>
where
Message: 'a + Clone,
Renderer: 'a + core::Renderer,
- Theme: 'a + container::Catalog,
- Theme::Class<'a>: From<container::StyleFn<'a, Theme>>,
+ Theme: 'a + container::Catalog + Catalog,
+ <Theme as container::Catalog>::Class<'a>:
+ From<container::StyleFn<'a, Theme>>,
+ <Theme as Catalog>::Class<'a>: Into<StyleFn<'a, Theme>>,
{
+ let style = class.into();
+
let area = mouse_area(center(opaque(content)).style(move |theme| {
container::Style {
- background: Some(backdrop_color(theme).into()),
+ background: Some(style(theme).backdrop_color.into()),
..Default::default()
}
}));
@@ -268,8 +310,21 @@ where
stack![base.into(), opaque(area)].into()
}
+/// The style of a [`Dialog`].
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub struct Style {
+ /// The [`Dialog`]'s backdrop.
+ pub backdrop_color: Color,
+}
+
/// The theme catalog of a [`Dialog`].
pub trait Catalog: text::Catalog + container::Catalog {
+ /// The item class of the [`Catalog`].
+ type Class<'a>;
+
+ /// The default class produced by the [`Catalog`].
+ fn default<'a>() -> <Self as Catalog>::Class<'a>;
+
/// The default class for the [`Dialog`]'s title.
fn default_title<'a>() -> <Self as text::Catalog>::Class<'a> {
<Self as text::Catalog>::default()
@@ -279,9 +334,21 @@ pub trait Catalog: text::Catalog + container::Catalog {
fn default_container<'a>() -> <Self as container::Catalog>::Class<'a> {
<Self as container::Catalog>::default()
}
+
+ /// The [`Style`] of a class.
+ fn style(&self, class: <Self as Catalog>::Class<'_>) -> Style;
}
+/// A styling function for a [`Dialog`].
+pub type StyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> Style + 'a>;
+
impl Catalog for Theme {
+ type Class<'a> = StyleFn<'a, Self>;
+
+ fn default<'a>() -> <Self as Catalog>::Class<'a> {
+ Box::new(default)
+ }
+
fn default_container<'a>() -> <Self as container::Catalog>::Class<'a> {
Box::new(|theme| {
container::background(
@@ -289,4 +356,15 @@ impl Catalog for Theme {
)
})
}
+
+ fn style(&self, class: <Self as Catalog>::Class<'_>) -> Style {
+ class(self)
+ }
+}
+
+/// The default style of a [`Dialog`].
+pub fn default(_theme: &Theme) -> Style {
+ Style {
+ backdrop_color: color!(0x000000, 0.3),
+ }
}
diff --git a/src/lib.rs b/src/lib.rs
index 856a45c..718f1ce 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -30,6 +30,7 @@ where
/// [`Button`]: https://docs.iced.rs/iced/widget/struct.Button.html
pub fn button<'a, Message, Theme, Renderer>(
content: &'a str,
+ message: Message,
) -> Button<'a, Message, Theme, Renderer>
where
Theme: 'a + iced_widget::button::Catalog + text::Catalog,
@@ -41,6 +42,7 @@ where
.line_height(text::LineHeight::Absolute(core::Pixels(20.0)))
.align_x(Horizontal::Center),
)
+ .on_press(message)
.height(32)
.width(core::Length::Fill)
}