Use Style struct pattern instead of trait for all widgets

This commit is contained in:
Héctor Ramón Jiménez 2024-03-06 20:30:58 +01:00
parent 8a63774b24
commit 34e7c6593a
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
25 changed files with 466 additions and 282 deletions

View file

@ -17,7 +17,6 @@ pub use text::{LineHeight, Shaping};
#[allow(missing_debug_implementations)]
pub struct Text<'a, Theme, Renderer>
where
Theme: StyleSheet,
Renderer: text::Renderer,
{
content: Cow<'a, str>,
@ -34,7 +33,6 @@ where
impl<'a, Theme, Renderer> Text<'a, Theme, Renderer>
where
Theme: StyleSheet,
Renderer: text::Renderer,
{
/// Create a new fragment of [`Text`] with the given contents.
@ -49,7 +47,7 @@ where
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: Shaping::Basic,
style: Style::Themed(Theme::default()),
style: Style::default(),
}
}
@ -135,7 +133,6 @@ pub struct State<P: Paragraph>(P);
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
for Text<'a, Theme, Renderer>
where
Theme: StyleSheet,
Renderer: text::Renderer,
{
fn tag(&self) -> tree::Tag {
@ -283,7 +280,7 @@ pub fn draw<Renderer>(
impl<'a, Message, Theme, Renderer> From<Text<'a, Theme, Renderer>>
for Element<'a, Message, Theme, Renderer>
where
Theme: StyleSheet + 'a,
Theme: 'a,
Renderer: text::Renderer + 'a,
{
fn from(
@ -295,7 +292,6 @@ where
impl<'a, Theme, Renderer> Clone for Text<'a, Theme, Renderer>
where
Theme: StyleSheet,
Renderer: text::Renderer,
{
fn clone(&self) -> Self {
@ -316,7 +312,6 @@ where
impl<'a, Theme, Renderer> From<&'a str> for Text<'a, Theme, Renderer>
where
Theme: StyleSheet,
Renderer: text::Renderer,
{
fn from(content: &'a str) -> Self {
@ -327,7 +322,7 @@ where
impl<'a, Message, Theme, Renderer> From<&'a str>
for Element<'a, Message, Theme, Renderer>
where
Theme: StyleSheet + 'a,
Theme: 'a,
Renderer: text::Renderer + 'a,
{
fn from(content: &'a str) -> Self {
@ -335,22 +330,6 @@ where
}
}
/// The style sheet of some text.
pub trait StyleSheet {
/// Returns the default styling strategy for [`Text`].
fn default() -> fn(&Self) -> Appearance {
|_| Appearance::default()
}
}
impl StyleSheet for Color {
fn default() -> fn(&Self) -> Appearance {
|color| Appearance {
color: Some(*color),
}
}
}
/// The apperance of some text.
#[derive(Debug, Clone, Copy, Default)]
pub struct Appearance {
@ -373,3 +352,15 @@ impl<Theme> Clone for Style<Theme> {
}
impl<Theme> Copy for Style<Theme> {}
impl<Theme> Default for Style<Theme> {
fn default() -> Self {
Style::Colored(None)
}
}
impl<Theme> From<fn(&Theme) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme) -> Appearance) -> Self {
Style::Themed(f)
}
}

View file

@ -84,7 +84,7 @@ impl Sandbox for Gradient {
};
let gradient_box = themer(
move |_| appearance,
appearance,
container(horizontal_space())
.width(Length::Fill)
.height(Length::Fill),

View file

@ -4,7 +4,6 @@ pub mod palette;
pub use palette::Palette;
use crate::application;
use crate::core::widget::text;
use std::fmt;
use std::sync::Arc;
@ -265,5 +264,3 @@ impl<T: Fn(&Theme) -> application::Appearance> application::StyleSheet for T {
(self)(style)
}
}
impl text::StyleSheet for Theme {}

View file

@ -53,7 +53,6 @@ use crate::style::Theme;
#[allow(missing_debug_implementations)]
pub struct Button<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
where
Theme: Style,
Renderer: crate::core::Renderer,
{
content: Element<'a, Message, Theme, Renderer>,
@ -62,18 +61,20 @@ where
height: Length,
padding: Padding,
clip: bool,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Button<'a, Message, Theme, Renderer>
where
Theme: Style,
Renderer: crate::core::Renderer,
{
/// Creates a new [`Button`] with the given content.
pub fn new(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Self {
) -> Self
where
Style<Theme>: Default,
{
let content = content.into();
let size = content.as_widget().size_hint();
@ -84,7 +85,7 @@ where
height: size.height.fluid(),
padding: Padding::new(5.0),
clip: false,
style: Theme::DEFAULT,
style: Style::default(),
}
}
@ -125,7 +126,7 @@ where
/// Sets the style variant of this [`Button`].
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style.into();
self.style = Style(style);
self
}
@ -146,7 +147,6 @@ impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
for Button<'a, Message, Theme, Renderer>
where
Message: 'a + Clone,
Theme: Style,
Renderer: 'a + crate::core::Renderer,
{
fn tag(&self) -> tree::Tag {
@ -306,7 +306,7 @@ where
Status::Active
};
let styling = (self.style)(theme, status);
let styling = (self.style.0)(theme, status);
if styling.background.is_some()
|| styling.border.width > 0.0
@ -380,7 +380,7 @@ impl<'a, Message, Theme, Renderer> From<Button<'a, Message, Theme, Renderer>>
for Element<'a, Message, Theme, Renderer>
where
Message: Clone + 'a,
Theme: Style + 'a,
Theme: 'a,
Renderer: crate::core::Renderer + 'a,
{
fn from(button: Button<'a, Message, Theme, Renderer>) -> Self {
@ -428,14 +428,28 @@ impl std::default::Default for Appearance {
}
}
/// The default style of a [`Button`] for a given theme.
pub trait Style {
/// The default style.
const DEFAULT: fn(&Self, Status) -> Appearance;
/// The style of a [`Button`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
const DEFAULT: fn(&Self, Status) -> Appearance = primary;
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(primary)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}
/// A primary button; denoting a main action.

View file

@ -53,13 +53,12 @@ pub struct Checkbox<
text_shaping: text::Shaping,
font: Option<Renderer::Font>,
icon: Icon<Renderer::Font>,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Checkbox<'a, Message, Theme, Renderer>
where
Renderer: text::Renderer,
Theme: Style,
{
/// The default size of a [`Checkbox`].
const DEFAULT_SIZE: f32 = 15.0;
@ -72,7 +71,10 @@ where
/// It expects:
/// * the label of the [`Checkbox`]
/// * a boolean describing whether the [`Checkbox`] is checked or not
pub fn new(label: impl Into<String>, is_checked: bool) -> Self {
pub fn new(label: impl Into<String>, is_checked: bool) -> Self
where
Style<Theme>: Default,
{
Checkbox {
is_checked,
on_toggle: None,
@ -91,7 +93,7 @@ where
line_height: text::LineHeight::default(),
shaping: text::Shaping::Basic,
},
style: Theme::style(),
style: Style::default(),
}
}
@ -175,7 +177,7 @@ where
/// Sets the style of the [`Checkbox`].
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style.into();
self.style = Style(style);
self
}
}
@ -301,7 +303,7 @@ where
Status::Active { is_checked }
};
let appearance = (self.style)(theme, status);
let appearance = (self.style.0)(theme, status);
{
let layout = children.next().unwrap();
@ -423,15 +425,27 @@ pub struct Appearance {
pub text_color: Option<Color>,
}
/// A set of rules that dictate the style of a checkbox.
pub trait Style {
/// The supported style of the [`StyleSheet`].
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`Checkbox`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
primary
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(primary)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -1,5 +1,4 @@
//! Display a dropdown list of searchable and selectable options.
use crate::container;
use crate::core::event::{self, Event};
use crate::core::keyboard;
use crate::core::keyboard::key;
@ -14,7 +13,6 @@ use crate::core::{
Clipboard, Element, Length, Padding, Rectangle, Shell, Size, Vector,
};
use crate::overlay::menu;
use crate::scrollable;
use crate::style::Theme;
use crate::text::LineHeight;
use crate::text_input::{self, TextInput};
@ -65,14 +63,16 @@ where
on_selected: impl Fn(T) -> Message + 'static,
) -> Self
where
Theme: text_input::Style,
Style<Theme>: Default,
{
let style = Style::<Theme>::default();
let text_input = TextInput::new(placeholder, &state.value())
.on_input(TextInputEvent::TextChanged)
.style(style.text_input);
let text_input = TextInput::with_style(
placeholder,
&state.value(),
style.text_input,
)
.on_input(TextInputEvent::TextChanged);
let selection = selection.map(T::to_string).unwrap_or_default();
@ -294,7 +294,6 @@ impl<'a, T, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
where
T: Display + Clone + 'static,
Message: Clone,
Theme: scrollable::Style + container::Style,
Renderer: text::Renderer,
{
fn size(&self) -> Size<Length> {
@ -711,7 +710,7 @@ impl<'a, T, Message, Theme, Renderer>
where
T: Display + Clone + 'static,
Message: Clone + 'a,
Theme: scrollable::Style + container::Style + 'a,
Theme: 'a,
Renderer: text::Renderer + 'a,
{
fn from(combo_box: ComboBox<'a, T, Message, Theme, Renderer>) -> Self {

View file

@ -34,21 +34,30 @@ pub struct Container<
max_height: f32,
horizontal_alignment: alignment::Horizontal,
vertical_alignment: alignment::Vertical,
style: fn(&Theme, Status) -> Appearance,
clip: bool,
content: Element<'a, Message, Theme, Renderer>,
style: Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Container<'a, Message, Theme, Renderer>
where
Renderer: crate::core::Renderer,
{
/// Creates an empty [`Container`].
pub fn new<T>(content: T) -> Self
/// Creates a [`Container`] with the given content.
pub fn new(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Self
where
Theme: Style,
T: Into<Element<'a, Message, Theme, Renderer>>,
Style<Theme>: Default,
{
Self::with_style(content, Style::default().0)
}
/// Creates a [`Container`] with the given content and style.
pub fn with_style(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
style: fn(&Theme, Status) -> Appearance,
) -> Self {
let content = content.into();
let size = content.as_widget().size_hint();
@ -61,9 +70,9 @@ where
max_height: f32::INFINITY,
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
style: Theme::style(),
clip: false,
content,
style: Style(style),
}
}
@ -129,7 +138,7 @@ where
/// Sets the style of the [`Container`].
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style;
self.style = Style(style);
self
}
@ -267,7 +276,7 @@ where
Status::Idle
};
let style = (self.style)(theme, status);
let style = (self.style.0)(theme, status);
if let Some(clipped_viewport) = bounds.intersection(viewport) {
draw_background(renderer, &style, bounds);
@ -537,26 +546,46 @@ pub enum Status {
Hovered,
}
/// The style of a [`Container`] for a theme.
pub trait Style {
/// The default style of a [`Container`].
fn style() -> fn(&Self, Status) -> Appearance;
}
/// The style of a [`Container`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
transparent
impl<Theme> Style<Theme> {
/// Resolves the [`Style`] with the given `Theme` and [`Status`] to
/// produce an [`Appearance`].
pub fn resolve(self, theme: &Theme, status: Status) -> Appearance {
(self.0)(theme, status)
}
}
impl Style for Appearance {
fn style() -> fn(&Self, Status) -> Appearance {
|appearance, _status| *appearance
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(transparent)
}
}
impl Default for Style<Appearance> {
fn default() -> Self {
Style(|appearance, _status| *appearance)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}
/// A transparent [`Container`].
pub fn transparent(_theme: &Theme, _status: Status) -> Appearance {
pub fn transparent<Theme>(_theme: &Theme, _status: Status) -> Appearance {
Appearance::default()
}

View file

@ -14,7 +14,7 @@ use crate::rule::{self, Rule};
use crate::runtime::Command;
use crate::scrollable::{self, Scrollable};
use crate::slider::{self, Slider};
use crate::text::{self, Text};
use crate::text::Text;
use crate::text_editor::{self, TextEditor};
use crate::text_input::{self, TextInput};
use crate::toggler::{self, Toggler};
@ -58,8 +58,8 @@ pub fn container<'a, Message, Theme, Renderer>(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Container<'a, Message, Theme, Renderer>
where
Theme: container::Style,
Renderer: core::Renderer,
container::Style<Theme>: Default,
{
Container::new(content)
}
@ -104,8 +104,8 @@ pub fn scrollable<'a, Message, Theme, Renderer>(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Scrollable<'a, Message, Theme, Renderer>
where
Theme: scrollable::Style,
Renderer: core::Renderer,
scrollable::Style<Theme>: Default,
{
Scrollable::new(content)
}
@ -118,7 +118,7 @@ pub fn button<'a, Message, Theme, Renderer>(
) -> Button<'a, Message, Theme, Renderer>
where
Renderer: core::Renderer,
Theme: button::Style,
button::Style<Theme>: Default,
{
Button::new(content)
}
@ -134,8 +134,8 @@ pub fn tooltip<'a, Message, Theme, Renderer>(
position: tooltip::Position,
) -> crate::Tooltip<'a, Message, Theme, Renderer>
where
Theme: container::Style + text::StyleSheet,
Renderer: core::text::Renderer,
container::Style<Theme>: Default,
{
Tooltip::new(content, tooltip, position)
}
@ -147,7 +147,6 @@ pub fn text<'a, Theme, Renderer>(
text: impl ToString,
) -> Text<'a, Theme, Renderer>
where
Theme: text::StyleSheet,
Renderer: core::text::Renderer,
{
Text::new(text.to_string())
@ -161,8 +160,8 @@ pub fn checkbox<'a, Message, Theme, Renderer>(
is_checked: bool,
) -> Checkbox<'a, Message, Theme, Renderer>
where
Theme: checkbox::Style,
Renderer: core::text::Renderer,
checkbox::Style<Theme>: Default,
{
Checkbox::new(label, is_checked)
}
@ -178,9 +177,9 @@ pub fn radio<Message, Theme, Renderer, V>(
) -> Radio<Message, Theme, Renderer>
where
Message: Clone,
Theme: radio::Style,
Renderer: core::text::Renderer,
V: Copy + Eq,
radio::Style<Theme>: Default,
{
Radio::new(label, value, selected, on_click)
}
@ -195,7 +194,7 @@ pub fn toggler<'a, Message, Theme, Renderer>(
) -> Toggler<'a, Message, Theme, Renderer>
where
Renderer: core::text::Renderer,
Theme: toggler::Style,
toggler::Style<Theme>: Default,
{
Toggler::new(label, is_checked, f)
}
@ -209,8 +208,8 @@ pub fn text_input<'a, Message, Theme, Renderer>(
) -> TextInput<'a, Message, Theme, Renderer>
where
Message: Clone,
Theme: text_input::Style,
Renderer: core::text::Renderer,
text_input::Style<Theme>: Default,
{
TextInput::new(placeholder, value)
}
@ -223,8 +222,8 @@ pub fn text_editor<Message, Theme, Renderer>(
) -> TextEditor<'_, core::text::highlighter::PlainText, Message, Theme, Renderer>
where
Message: Clone,
Theme: text_editor::Style,
Renderer: core::text::Renderer,
text_editor::Style<Theme>: Default,
{
TextEditor::new(content)
}
@ -240,7 +239,7 @@ pub fn slider<'a, T, Message, Theme>(
where
T: Copy + From<u8> + std::cmp::PartialOrd,
Message: Clone,
Theme: slider::Style,
slider::Style<Theme>: Default,
{
Slider::new(range, value, on_change)
}
@ -256,7 +255,7 @@ pub fn vertical_slider<'a, T, Message, Theme>(
where
T: Copy + From<u8> + std::cmp::PartialOrd,
Message: Clone,
Theme: vertical_slider::Style,
vertical_slider::Style<Theme>: Default,
{
VerticalSlider::new(range, value, on_change)
}
@ -291,7 +290,6 @@ pub fn combo_box<'a, T, Message, Theme, Renderer>(
) -> ComboBox<'a, T, Message, Theme, Renderer>
where
T: std::fmt::Display + Clone,
Theme: text_input::Style,
Renderer: core::text::Renderer,
combo_box::Style<Theme>: Default,
{
@ -319,7 +317,7 @@ pub fn vertical_space() -> Space {
/// [`Rule`]: crate::Rule
pub fn horizontal_rule<Theme>(height: impl Into<Pixels>) -> Rule<Theme>
where
Theme: rule::Style,
rule::Style<Theme>: Default,
{
Rule::horizontal(height)
}
@ -329,7 +327,7 @@ where
/// [`Rule`]: crate::Rule
pub fn vertical_rule<Theme>(width: impl Into<Pixels>) -> Rule<Theme>
where
Theme: rule::Style,
rule::Style<Theme>: Default,
{
Rule::vertical(width)
}
@ -346,7 +344,7 @@ pub fn progress_bar<Theme>(
value: f32,
) -> ProgressBar<Theme>
where
Theme: progress_bar::Style,
progress_bar::Style<Theme>: Default,
{
ProgressBar::new(range, value)
}
@ -392,7 +390,7 @@ where
#[cfg(feature = "qr_code")]
pub fn qr_code<Theme>(data: &crate::qr_code::Data) -> crate::QRCode<'_, Theme>
where
Theme: crate::qr_code::Style,
crate::qr_code::Style<Theme>: Default,
{
crate::QRCode::new(data)
}
@ -435,13 +433,20 @@ where
}
/// A widget that applies any `Theme` to its contents.
pub fn themer<'a, Message, OldTheme, NewTheme, F, Renderer>(
to_theme: F,
pub fn themer<'a, Message, OldTheme, NewTheme, Renderer>(
new_theme: NewTheme,
content: impl Into<Element<'a, Message, NewTheme, Renderer>>,
) -> Themer<'a, Message, OldTheme, NewTheme, F, Renderer>
) -> Themer<
'a,
Message,
OldTheme,
NewTheme,
impl Fn(&OldTheme) -> NewTheme,
Renderer,
>
where
F: Fn(&OldTheme) -> NewTheme,
Renderer: core::Renderer,
NewTheme: Clone,
{
Themer::new(to_theme, content)
Themer::new(move |_| new_theme.clone(), content)
}

View file

@ -46,7 +46,7 @@ impl<'a, T, Message, Theme, Renderer> Menu<'a, T, Message, Theme, Renderer>
where
T: ToString + Clone,
Message: 'a,
Theme: container::Style + scrollable::Style + 'a,
Theme: 'a,
Renderer: text::Renderer + 'a,
{
/// Creates a new [`Menu`] with the given [`State`], a list of options, and
@ -197,7 +197,7 @@ where
impl<'a, Message, Theme, Renderer> Overlay<'a, Message, Theme, Renderer>
where
Message: 'a,
Theme: container::Style + scrollable::Style + 'a,
Theme: 'a,
Renderer: text::Renderer + 'a,
{
pub fn new<T>(
@ -223,20 +223,24 @@ where
style,
} = menu;
let container = Container::new(
Scrollable::new(List {
options,
hovered_option,
on_selected,
on_option_hovered,
font,
text_size,
text_line_height,
text_shaping,
padding,
style: style.menu,
})
.style(style.scrollable),
let container = Container::with_style(
Scrollable::with_direction_and_style(
List {
options,
hovered_option,
on_selected,
on_option_hovered,
font,
text_size,
text_line_height,
text_shaping,
padding,
style: style.menu,
},
scrollable::Direction::default(),
style.scrollable,
),
container::transparent,
);
state.tree.diff(&container as &dyn Widget<_, _, _>);

View file

@ -112,7 +112,7 @@ pub struct PaneGrid<
on_click: Option<Box<dyn Fn(Pane) -> Message + 'a>>,
on_drag: Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
on_resize: Option<(f32, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,
style: fn(&Theme) -> Appearance,
style: Style<Theme>,
}
impl<'a, Message, Theme, Renderer> PaneGrid<'a, Message, Theme, Renderer>
@ -128,7 +128,7 @@ where
view: impl Fn(Pane, &'a T, bool) -> Content<'a, Message, Theme, Renderer>,
) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
let contents = if let Some((pane, pane_state)) =
state.maximized.and_then(|pane| {
@ -160,7 +160,7 @@ where
on_click: None,
on_drag: None,
on_resize: None,
style: Theme::style(),
style: Style::default(),
}
}
@ -221,7 +221,7 @@ where
/// Sets the style of the [`PaneGrid`].
pub fn style(mut self, style: fn(&Theme) -> Appearance) -> Self {
self.style = style;
self.style = Style(style);
self
}
@ -679,7 +679,7 @@ where
None
};
let appearance = (self.style)(theme);
let appearance = (self.style.0)(theme);
for ((id, (content, tree)), pane_layout) in
contents.zip(layout.children())
@ -1147,15 +1147,27 @@ pub struct Line {
pub width: f32,
}
/// The definiton of the default style of a [`PaneGrid`].
pub trait Style {
/// Returns the default style of a [`PaneGrid`].
fn style() -> fn(&Self) -> Appearance;
/// The style of a [`PaneGrid`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -24,7 +24,7 @@ pub struct Content<
{
title_bar: Option<TitleBar<'a, Message, Theme, Renderer>>,
body: Element<'a, Message, Theme, Renderer>,
style: fn(&Theme, container::Status) -> container::Appearance,
style: container::Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Content<'a, Message, Theme, Renderer>
@ -34,12 +34,12 @@ where
/// Creates a new [`Content`] with the provided body.
pub fn new(body: impl Into<Element<'a, Message, Theme, Renderer>>) -> Self
where
Theme: container::Style,
container::Style<Theme>: Default,
{
Self {
title_bar: None,
body: body.into(),
style: Theme::style(),
style: container::Style::default(),
}
}
@ -57,7 +57,7 @@ where
mut self,
style: fn(&Theme, container::Status) -> container::Appearance,
) -> Self {
self.style = style;
self.style = style.into();
self
}
}
@ -114,7 +114,7 @@ where
container::Status::Idle
};
(self.style)(theme, status)
self.style.resolve(theme, status)
};
container::draw_background(renderer, &style, bounds);
@ -403,8 +403,8 @@ impl<'a, T, Message, Theme, Renderer> From<T>
for Content<'a, Message, Theme, Renderer>
where
T: Into<Element<'a, Message, Theme, Renderer>>,
Theme: container::Style,
Renderer: crate::core::Renderer,
container::Style<Theme>: Default,
{
fn from(element: T) -> Self {
Self::new(element)

View file

@ -25,7 +25,7 @@ pub struct TitleBar<
controls: Option<Element<'a, Message, Theme, Renderer>>,
padding: Padding,
always_show_controls: bool,
style: fn(&Theme, container::Status) -> container::Appearance,
style: container::Style<Theme>,
}
impl<'a, Message, Theme, Renderer> TitleBar<'a, Message, Theme, Renderer>
@ -33,17 +33,18 @@ where
Renderer: crate::core::Renderer,
{
/// Creates a new [`TitleBar`] with the given content.
pub fn new<E>(content: E) -> Self
pub fn new(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Self
where
Theme: container::Style,
E: Into<Element<'a, Message, Theme, Renderer>>,
container::Style<Theme>: Default,
{
Self {
content: content.into(),
controls: None,
padding: Padding::ZERO,
always_show_controls: false,
style: Theme::style(),
style: container::Style::default(),
}
}
@ -67,7 +68,7 @@ where
mut self,
style: fn(&Theme, container::Status) -> container::Appearance,
) -> Self {
self.style = style;
self.style = style.into();
self
}
@ -137,7 +138,7 @@ where
container::Status::Idle
};
(self.style)(theme, status)
self.style.resolve(theme, status)
};
let inherited_style = renderer::Style {

View file

@ -1,5 +1,4 @@
//! Display a dropdown list of selectable values.
use crate::container;
use crate::core::alignment;
use crate::core::event::{self, Event};
use crate::core::keyboard;
@ -15,7 +14,6 @@ use crate::core::{
Pixels, Point, Rectangle, Shell, Size, Vector, Widget,
};
use crate::overlay::menu::{self, Menu};
use crate::scrollable;
use crate::style::Theme;
use std::borrow::Borrow;
@ -169,7 +167,6 @@ where
L: Borrow<[T]>,
V: Borrow<T>,
Message: Clone + 'a,
Theme: scrollable::Style + container::Style,
Renderer: text::Renderer + 'a,
{
fn tag(&self) -> tree::Tag {
@ -426,7 +423,7 @@ where
L: Borrow<[T]> + 'a,
V: Borrow<T> + 'a,
Message: Clone + 'a,
Theme: scrollable::Style + container::Style + 'a,
Theme: 'a,
Renderer: text::Renderer + 'a,
{
fn from(

View file

@ -28,7 +28,7 @@ pub struct ProgressBar<Theme = crate::Theme> {
value: f32,
width: Length,
height: Option<Length>,
style: fn(&Theme) -> Appearance,
style: Style<Theme>,
}
impl<Theme> ProgressBar<Theme> {
@ -42,14 +42,14 @@ impl<Theme> ProgressBar<Theme> {
/// * the current value of the [`ProgressBar`]
pub fn new(range: RangeInclusive<f32>, value: f32) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
ProgressBar {
value: value.clamp(*range.start(), *range.end()),
range,
width: Length::Fill,
height: None,
style: Theme::style(),
style: Style::default(),
}
}
@ -67,7 +67,7 @@ impl<Theme> ProgressBar<Theme> {
/// Sets the style of the [`ProgressBar`].
pub fn style(mut self, style: fn(&Theme) -> Appearance) -> Self {
self.style = style;
self.style = style.into();
self
}
}
@ -117,7 +117,7 @@ where
/ (range_end - range_start)
};
let appearance = (self.style)(theme);
let appearance = (self.style.0)(theme);
renderer.fill_quad(
renderer::Quad {
@ -169,15 +169,27 @@ pub struct Appearance {
pub border: Border,
}
/// The definiton of the default style of a [`ProgressBar`].
pub trait Style {
/// Returns the default style of a [`ProgressBar`].
fn style() -> fn(&Self) -> Appearance;
/// The style of a [`ProgressBar`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self) -> Appearance {
primary
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(primary)
}
}
impl<Theme> From<fn(&Theme) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -23,19 +23,19 @@ const QUIET_ZONE: usize = 2;
pub struct QRCode<'a, Theme = crate::Theme> {
data: &'a Data,
cell_size: u16,
style: fn(&Theme) -> Appearance,
style: Style<Theme>,
}
impl<'a, Theme> QRCode<'a, Theme> {
/// Creates a new [`QRCode`] with the provided [`Data`].
pub fn new(data: &'a Data) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Self {
data,
cell_size: DEFAULT_CELL_SIZE,
style: Theme::style(),
style: Style::default(),
}
}
@ -47,7 +47,7 @@ impl<'a, Theme> QRCode<'a, Theme> {
/// Sets the style of the [`QRCode`].
pub fn style(mut self, style: fn(&Theme) -> Appearance) -> Self {
self.style = style;
self.style = style.into();
self
}
}
@ -97,7 +97,7 @@ impl<'a, Message, Theme> Widget<Message, Theme, Renderer>
let bounds = layout.bounds();
let side_length = self.data.width + 2 * QUIET_ZONE;
let appearance = (self.style)(theme);
let appearance = (self.style.0)(theme);
let mut last_appearance = state.last_appearance.borrow_mut();
if Some(appearance) != *last_appearance {
@ -335,15 +335,27 @@ pub struct Appearance {
pub background: Color,
}
/// The definiton of the default style of a [`QRCode`].
pub trait Style {
/// Returns the default style of a [`QRCode`].
fn style() -> fn(&Self) -> Appearance;
/// The style of a [`QRCode`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -82,7 +82,7 @@ where
text_line_height: text::LineHeight,
text_shaping: text::Shaping,
font: Option<Renderer::Font>,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<Message, Theme, Renderer> Radio<Message, Theme, Renderer>
@ -111,7 +111,7 @@ where
f: F,
) -> Self
where
Theme: Style,
Style<Theme>: Default,
V: Eq + Copy,
F: FnOnce(V) -> Message,
{
@ -126,7 +126,7 @@ where
text_line_height: text::LineHeight::default(),
text_shaping: text::Shaping::Basic,
font: None,
style: Theme::style(),
style: Style::default(),
}
}
@ -177,7 +177,7 @@ where
/// Sets the style of the [`Radio`] button.
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style.into();
self.style = Style(style);
self
}
}
@ -298,7 +298,7 @@ where
Status::Active { is_selected }
};
let appearance = (self.style)(theme, status);
let appearance = (self.style.0)(theme, status);
{
let layout = children.next().unwrap();
@ -398,15 +398,27 @@ pub struct Appearance {
pub text_color: Option<Color>,
}
/// The definiton of the default style of a [`Radio`] button.
pub trait Style {
/// Returns the default style of a [`Radio`] button.
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`Radio`] button.
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -15,39 +15,39 @@ pub struct Rule<Theme = crate::Theme> {
width: Length,
height: Length,
is_horizontal: bool,
style: fn(&Theme) -> Appearance,
style: Style<Theme>,
}
impl<Theme> Rule<Theme> {
/// Creates a horizontal [`Rule`] with the given height.
pub fn horizontal(height: impl Into<Pixels>) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Rule {
width: Length::Fill,
height: Length::Fixed(height.into().0),
is_horizontal: true,
style: Theme::style(),
style: Style::default(),
}
}
/// Creates a vertical [`Rule`] with the given width.
pub fn vertical(width: impl Into<Pixels>) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Rule {
width: Length::Fixed(width.into().0),
height: Length::Fill,
is_horizontal: false,
style: Theme::style(),
style: Style::default(),
}
}
/// Sets the style of the [`Rule`].
pub fn style(mut self, style: fn(&Theme) -> Appearance) -> Self {
self.style = style;
self.style = Style(style);
self
}
}
@ -83,7 +83,7 @@ where
_viewport: &Rectangle,
) {
let bounds = layout.bounds();
let appearance = (self.style)(theme);
let appearance = (self.style.0)(theme);
let bounds = if self.is_horizontal {
let line_y = (bounds.y + (bounds.height / 2.0)
@ -216,15 +216,27 @@ impl FillMode {
}
}
/// The definiton of the default style of a [`Rule`].
pub trait Style {
/// Returns the default style of a [`Rule`].
fn style() -> fn(&Self) -> Appearance;
/// The style of a [`Rule`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -37,7 +37,7 @@ pub struct Scrollable<
direction: Direction,
content: Element<'a, Message, Theme, Renderer>,
on_scroll: Option<Box<dyn Fn(Viewport) -> Message + 'a>>,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Scrollable<'a, Message, Theme, Renderer>
@ -49,7 +49,7 @@ where
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Self::with_direction(content, Direction::default())
}
@ -60,8 +60,17 @@ where
direction: Direction,
) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Self::with_direction_and_style(content, direction, Style::default().0)
}
/// Creates a new [`Scrollable`] with the given [`Direction`] and style.
pub fn with_direction_and_style(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
direction: Direction,
style: fn(&Theme, Status) -> Appearance,
) -> Self {
let content = content.into();
debug_assert!(
@ -83,7 +92,7 @@ where
direction,
content,
on_scroll: None,
style: Theme::style(),
style: style.into(),
}
}
@ -115,7 +124,7 @@ where
/// Sets the style of the [`Scrollable`] .
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style;
self.style = style.into();
self
}
}
@ -399,7 +408,7 @@ where
Status::Active
};
let appearance = (self.style)(theme, status);
let appearance = (self.style.0)(theme, status);
container::draw_background(
renderer,
@ -1653,15 +1662,27 @@ pub struct Scroller {
pub border: Border,
}
/// The definition of the default style of a [`Scrollable`].
pub trait Style {
/// Returns the default style of a [`Scrollable`].
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`Scrollable`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -53,7 +53,7 @@ pub struct Slider<'a, T, Message, Theme = crate::Theme> {
on_release: Option<Message>,
width: Length,
height: f32,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<'a, T, Message, Theme> Slider<'a, T, Message, Theme>
@ -74,7 +74,7 @@ where
/// `Message`.
pub fn new<F>(range: RangeInclusive<T>, value: T, on_change: F) -> Self
where
Theme: Style,
Style<Theme>: Default,
F: 'a + Fn(T) -> Message,
{
let value = if value >= *range.start() {
@ -99,7 +99,7 @@ where
on_release: None,
width: Length::Fill,
height: Self::DEFAULT_HEIGHT,
style: Theme::style(),
style: Style::default(),
}
}
@ -136,7 +136,7 @@ where
/// Sets the style of the [`Slider`].
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style;
self.style = style.into();
self
}
@ -350,7 +350,7 @@ where
let bounds = layout.bounds();
let is_mouse_over = cursor.is_over(bounds);
let style = (self.style)(
let style = (self.style.0)(
theme,
if state.is_dragging {
Status::Dragged
@ -550,15 +550,27 @@ pub enum HandleShape {
},
}
/// The definiton of the default style of a [`TextInput`].
pub trait Style {
/// Returns the default style of a [`TextInput`].
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`Slider`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(pub(crate) fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -81,7 +81,7 @@ impl<Theme> Svg<Theme> {
/// Sets the style variant of this [`Svg`].
#[must_use]
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style.into();
self.style = Style(style);
self
}
}

View file

@ -42,7 +42,7 @@ pub struct TextEditor<
width: Length,
height: Length,
padding: Padding,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
on_edit: Option<Box<dyn Fn(Action) -> Message + 'a>>,
highlighter_settings: Highlighter::Settings,
highlighter_format: fn(
@ -59,7 +59,7 @@ where
/// Creates new [`TextEditor`] with the given [`Content`].
pub fn new(content: &'a Content<Renderer>) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Self {
content,
@ -69,7 +69,7 @@ where
width: Length::Fill,
height: Length::Shrink,
padding: Padding::new(5.0),
style: Theme::style(),
style: Style::default(),
on_edit: None,
highlighter_settings: (),
highlighter_format: |_highlight, _theme| {
@ -144,7 +144,7 @@ where
/// Sets the style of the [`TextEditor`].
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style;
self.style = style.into();
self
}
}
@ -506,7 +506,7 @@ where
Status::Active
};
let appearance = (self.style)(theme, status);
let appearance = (self.style.0)(theme, status);
renderer.fill_quad(
renderer::Quad {
@ -809,15 +809,27 @@ pub struct Appearance {
pub selection: Color,
}
/// The definiton of the default style of a [`TextInput`].
pub trait Style {
/// Returns the default style of a [`TextInput`].
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`TextEditor`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -77,7 +77,7 @@ pub struct TextInput<
on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,
on_submit: Option<Message>,
icon: Option<Icon<Renderer::Font>>,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
/// The default [`Padding`] of a [`TextInput`].
@ -88,15 +88,22 @@ where
Message: Clone,
Renderer: text::Renderer,
{
/// Creates a new [`TextInput`].
///
/// It expects:
/// - a placeholder,
/// - the current value
/// Creates a new [`TextInput`] with the given placeholder and
/// its current value.
pub fn new(placeholder: &str, value: &str) -> Self
where
Theme: Style,
Style<Theme>: Default,
{
Self::with_style(placeholder, value, Style::default().0)
}
/// Creates a new [`TextInput`] with the given placeholder,
/// its current value, and its style.
pub fn with_style(
placeholder: &str,
value: &str,
style: fn(&Theme, Status) -> Appearance,
) -> Self {
TextInput {
id: None,
placeholder: String::from(placeholder),
@ -111,7 +118,7 @@ where
on_paste: None,
on_submit: None,
icon: None,
style: Theme::style(),
style: style.into(),
}
}
@ -199,7 +206,7 @@ where
/// Sets the style of the [`TextInput`].
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style;
self.style = style.into();
self
}
@ -337,7 +344,7 @@ where
Status::Active
};
let appearance = (self.style)(theme, status);
let appearance = (self.style.0)(theme, status);
renderer.fill_quad(
renderer::Quad {
@ -1406,15 +1413,27 @@ pub struct Appearance {
pub selection: Color,
}
/// The definiton of the default style of a [`TextInput`].
pub trait Style {
/// Returns the default style of a [`TextInput`].
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`TextInput`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -50,7 +50,7 @@ pub struct Toggler<
text_shaping: text::Shaping,
spacing: f32,
font: Option<Renderer::Font>,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Toggler<'a, Message, Theme, Renderer>
@ -74,7 +74,7 @@ where
f: F,
) -> Self
where
Theme: Style,
Style<Theme>: Default,
F: 'a + Fn(bool) -> Message,
{
Toggler {
@ -89,7 +89,7 @@ where
text_shaping: text::Shaping::Basic,
spacing: Self::DEFAULT_SIZE / 2.0,
font: None,
style: Theme::style(),
style: Style::default(),
}
}
@ -301,7 +301,7 @@ where
}
};
let appearance = (self.style)(theme, status);
let appearance = (self.style.0)(theme, status);
let border_radius = bounds.height / BORDER_RADIUS_RATIO;
let space = SPACE_RATIO * bounds.height;
@ -399,15 +399,27 @@ pub struct Appearance {
pub foreground_border_color: Color,
}
/// The definiton of the default style of a [`Toggler`].
pub trait Style {
/// Returns the default style of a [`Toggler`].
fn style() -> fn(&Self, Status) -> Appearance;
/// The style of a [`Toggler`].
#[derive(Debug, PartialEq, Eq)]
pub struct Style<Theme>(fn(&Theme, Status) -> Appearance);
impl<Theme> Clone for Style<Theme> {
fn clone(&self) -> Self {
*self
}
}
impl Style for Theme {
fn style() -> fn(&Self, Status) -> Appearance {
default
impl<Theme> Copy for Style<Theme> {}
impl Default for Style<Theme> {
fn default() -> Self {
Style(default)
}
}
impl<Theme> From<fn(&Theme, Status) -> Appearance> for Style<Theme> {
fn from(f: fn(&Theme, Status) -> Appearance) -> Self {
Style(f)
}
}

View file

@ -28,7 +28,7 @@ pub struct Tooltip<
gap: f32,
padding: f32,
snap_within_viewport: bool,
style: fn(&Theme, container::Status) -> container::Appearance,
style: container::Style<Theme>,
}
impl<'a, Message, Theme, Renderer> Tooltip<'a, Message, Theme, Renderer>
@ -47,7 +47,7 @@ where
position: Position,
) -> Self
where
Theme: container::Style,
container::Style<Theme>: Default,
{
Tooltip {
content: content.into(),
@ -56,7 +56,7 @@ where
gap: 0.0,
padding: Self::DEFAULT_PADDING,
snap_within_viewport: true,
style: Theme::style(),
style: container::Style::default(),
}
}
@ -83,7 +83,7 @@ where
mut self,
style: fn(&Theme, container::Status) -> container::Appearance,
) -> Self {
self.style = style;
self.style = style.into();
self
}
}
@ -309,7 +309,7 @@ where
positioning: Position,
gap: f32,
padding: f32,
style: fn(&Theme, container::Status) -> container::Appearance,
style: container::Style<Theme>,
}
impl<'a, 'b, Message, Theme, Renderer>
@ -424,7 +424,7 @@ where
layout: Layout<'_>,
cursor_position: mouse::Cursor,
) {
let style = (self.style)(theme, container::Status::Idle);
let style = self.style.resolve(theme, container::Status::Idle);
container::draw_background(renderer, &style, layout.bounds());

View file

@ -54,7 +54,7 @@ pub struct VerticalSlider<'a, T, Message, Theme = crate::Theme> {
on_release: Option<Message>,
width: f32,
height: Length,
style: fn(&Theme, Status) -> Appearance,
style: Style<Theme>,
}
impl<'a, T, Message, Theme> VerticalSlider<'a, T, Message, Theme>
@ -75,7 +75,7 @@ where
/// `Message`.
pub fn new<F>(range: RangeInclusive<T>, value: T, on_change: F) -> Self
where
Theme: Style,
Style<Theme>: Default,
F: 'a + Fn(T) -> Message,
{
let value = if value >= *range.start() {
@ -100,7 +100,7 @@ where
on_release: None,
width: Self::DEFAULT_WIDTH,
height: Length::Fill,
style: Theme::style(),
style: Style::default(),
}
}
@ -136,10 +136,7 @@ where
}
/// Sets the style of the [`VerticalSlider`].
pub fn style(
mut self,
style: impl Into<fn(&Theme, Status) -> Appearance>,
) -> Self {
pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style.into();
self
}
@ -357,7 +354,7 @@ where
let bounds = layout.bounds();
let is_mouse_over = cursor.is_over(bounds);
let style = (self.style)(
let style = (self.style.0)(
theme,
if state.is_dragging {
Status::Dragged