iced
iced copied to clipboard
Add docs for how styling works in iced
It's difficult to understand how to change the styling of widgets in iced, so I've added a write-up to the crate docs that tries to explain how iced's styling system works.
Here's the section rendered:
Styling
In iced
, each widget has a StyleSheet
trait (at widget::_::StyleSheet
) that governs how it is rendered onto the screen. This trait is implemented by the Theme
associated type of the [Application
] (which is returned by [Application::theme
]) which allows styles to be dynamically updated based on the state of the application.
This, however, means that the individual widgets do not have much control over their styling, which is why most widgets have their StyleSheet
s include an associated Style
generic type that can be set by a widget's style
method. This Style
generic is passed to the StyleSheet
implementation and used to calculate the final Appearance
.
Generally, Style
is an enum that has a set of predefined styles and occasionally a custom style variant that can be given an arbitrary StyleSheet
implementation for maximum flexibility, but any further than that requires a custom Theme
to be created.
For example, take the Button
widget.
The Button
uses the button::StyleSheet
trait for its styling, which is implemented by the default theme. The default theme's implementation defines the stylesheet's Style
as [theme::Button
], which is what should be passed to Button::style
to change the theming of the button on the default theme.
The default theme defines a set of styles that the default theme has predefined the Appearance
-returning method implementations for, as well as a Custom
variant that takes a boxed implementor of the button StyleSheet
.
Essentially, the application's Theme
must implement the button's StyleSheet
which has a method called according to the button's state with the application's button theme's Style
that was either defaulted or set by Button::style
, which finally produces the button::Appearance
that the renderer uses to display the widget to the screen.
The theming for the other widgets are similar, but some are a bit simpler such as Text
's default Style
which only has the default text color or a custom [Color
].
use iced::{widget::{button, text}, theme};
// To set the style of the button to a predefined 'Positive' style:
let positive_button = button("+").style(theme::Button::Positive);
// If you wish to radically change the theming of the application, use a different type
// for Application::Theme and implement custom stylesheets for the widgets you use on that.
let custom_button = button("-").style(theme::Button::Custom(Box::new({
struct anon_theme;
impl button::StyleSheet for anon_theme {
type Style = iced::Theme;
fn active(&self, style: &Self::Style) -> button::Appearance {
// `match` on `style` if you want to change anything for different themes.
button::Appearance {
text_color: Color::new(1.0, 1.0, 0.0, 0.75),
..Default::default()
}
}
}
anon_theme
})));
// Text is easy to change the color for.
let custom_text = text("foo").style(theme::Text::Color(Color::new(1.0, 1.0, 0.0, 1.0)));