Skip to content

Commit

Permalink
Support conversion from Fn trait to custom theme
Browse files Browse the repository at this point in the history
...instead of just from function pointers.

I'm making this change not because I actually want to pass a closure,
but to make passing a single fixed function work. This commit also
simplifies the scrollable example slightly, and without the other half
of this change that simplified example fails to compile with:

```
error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied
   --> examples/scrollable/src/main.rs:292:28
    |
292 |                     .style(progress_bar_custom_style)
    |                      ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar`
    |                      |
    |                      required by a bound introduced by this call
    |
    = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar`
    = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>`
note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style`
   --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21
    |
77  |         style: impl Into<<Renderer::Theme as StyleSheet>::Style>,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style`
```

This happens because `progress_bar_custom_style` by itself is a function
item, which is typically coerced to a function pointer when one is
needed, but not in this case. It is possible to work around this on the
caller's side, but especially since the compiler diagnostic for this is
a bit rough (see rust-lang/rust#100116) let's
try to make it work out of the box.
  • Loading branch information
marienz committed May 21, 2023
1 parent 640e139 commit d20493c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 31 deletions.
27 changes: 8 additions & 19 deletions examples/scrollable/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,18 +289,13 @@ impl Application for ScrollableDemo {
}
Direction::Horizontal => {
progress_bar(0.0..=1.0, self.current_scroll_offset.x)
.style(theme::ProgressBar::Custom(Box::new(
ProgressBarCustomStyle,
)))
.style(progress_bar_custom_style)
.into()
}
Direction::Multi => column![
progress_bar(0.0..=1.0, self.current_scroll_offset.y),
progress_bar(0.0..=1.0, self.current_scroll_offset.x).style(
theme::ProgressBar::Custom(Box::new(
ProgressBarCustomStyle,
))
)
progress_bar(0.0..=1.0, self.current_scroll_offset.x)
.style(progress_bar_custom_style)
]
.spacing(10)
.into(),
Expand Down Expand Up @@ -372,16 +367,10 @@ impl scrollable::StyleSheet for ScrollbarCustomStyle {
}
}

struct ProgressBarCustomStyle;

impl progress_bar::StyleSheet for ProgressBarCustomStyle {
type Style = Theme;

fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance {
progress_bar::Appearance {
background: style.extended_palette().background.strong.color.into(),
bar: Color::from_rgb8(250, 85, 134).into(),
border_radius: 0.0,
}
fn progress_bar_custom_style(theme: &Theme) -> progress_bar::Appearance {
progress_bar::Appearance {
background: theme.extended_palette().background.strong.color.into(),
bar: Color::from_rgb8(250, 85, 134).into(),
border_radius: 0.0,
}
}
28 changes: 16 additions & 12 deletions style/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,18 @@ impl application::StyleSheet for Theme {
}
}

impl application::StyleSheet for fn(&Theme) -> application::Appearance {
impl<T: Fn(&Theme) -> application::Appearance> application::StyleSheet for T {
type Style = Theme;

fn appearance(&self, style: &Self::Style) -> application::Appearance {
(self)(style)
}
}

impl From<fn(&Theme) -> application::Appearance> for Application {
fn from(f: fn(&Theme) -> application::Appearance) -> Self {
impl<T: Fn(&Theme) -> application::Appearance + 'static> From<T>
for Application
{
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
Expand Down Expand Up @@ -363,8 +365,8 @@ pub enum Container {
Custom(Box<dyn container::StyleSheet<Style = Theme>>),
}

impl From<fn(&Theme) -> container::Appearance> for Container {
fn from(f: fn(&Theme) -> container::Appearance) -> Self {
impl<T: Fn(&Theme) -> container::Appearance + 'static> From<T> for Container {
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
Expand All @@ -391,7 +393,7 @@ impl container::StyleSheet for Theme {
}
}

impl container::StyleSheet for fn(&Theme) -> container::Appearance {
impl<T: Fn(&Theme) -> container::Appearance> container::StyleSheet for T {
type Style = Theme;

fn appearance(&self, style: &Self::Style) -> container::Appearance {
Expand Down Expand Up @@ -777,8 +779,10 @@ pub enum ProgressBar {
Custom(Box<dyn progress_bar::StyleSheet<Style = Theme>>),
}

impl From<fn(&Theme) -> progress_bar::Appearance> for ProgressBar {
fn from(f: fn(&Theme) -> progress_bar::Appearance) -> Self {
impl<T: Fn(&Theme) -> progress_bar::Appearance + 'static> From<T>
for ProgressBar
{
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
Expand Down Expand Up @@ -808,7 +812,7 @@ impl progress_bar::StyleSheet for Theme {
}
}

impl progress_bar::StyleSheet for fn(&Theme) -> progress_bar::Appearance {
impl<T: Fn(&Theme) -> progress_bar::Appearance> progress_bar::StyleSheet for T {
type Style = Theme;

fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance {
Expand All @@ -826,8 +830,8 @@ pub enum Rule {
Custom(Box<dyn rule::StyleSheet<Style = Theme>>),
}

impl From<fn(&Theme) -> rule::Appearance> for Rule {
fn from(f: fn(&Theme) -> rule::Appearance) -> Self {
impl<T: Fn(&Theme) -> rule::Appearance + 'static> From<T> for Rule {
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
Expand All @@ -850,7 +854,7 @@ impl rule::StyleSheet for Theme {
}
}

impl rule::StyleSheet for fn(&Theme) -> rule::Appearance {
impl<T: Fn(&Theme) -> rule::Appearance> rule::StyleSheet for T {
type Style = Theme;

fn appearance(&self, style: &Self::Style) -> rule::Appearance {
Expand Down

0 comments on commit d20493c

Please sign in to comment.