summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-03-04 19:31:26 +0100
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-03-04 19:32:13 +0100
commit4130ae4be95ce850263fbc55f490b68a95361d58 (patch)
tree25b1acc723e217e5890e20aa8e796db0f35be231
parentce309db37b8eb9860ae1f1be1710fb39e7a9edea (diff)
downloadiced-4130ae4be95ce850263fbc55f490b68a95361d58.tar.gz
iced-4130ae4be95ce850263fbc55f490b68a95361d58.tar.bz2
iced-4130ae4be95ce850263fbc55f490b68a95361d58.zip
Simplify theming for `Text` widget
-rw-r--r--core/src/widget/text.rs65
-rw-r--r--examples/integration/src/controls.rs103
-rw-r--r--examples/lazy/src/main.rs3
-rw-r--r--examples/pane_grid/src/main.rs2
-rw-r--r--examples/pokedex/src/main.rs6
-rw-r--r--examples/todos/src/main.rs6
-rw-r--r--examples/tour/src/main.rs2
-rw-r--r--examples/visible_bounds/src/main.rs14
-rw-r--r--examples/websocket/src/main.rs4
-rw-r--r--style/src/theme.rs27
-rw-r--r--widget/src/checkbox.rs2
-rw-r--r--widget/src/tooltip.rs4
12 files changed, 116 insertions, 122 deletions
diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs
index 0796c4e4..217ad8b3 100644
--- a/core/src/widget/text.rs
+++ b/core/src/widget/text.rs
@@ -29,7 +29,7 @@ where
vertical_alignment: alignment::Vertical,
font: Option<Renderer::Font>,
shaping: Shaping,
- style: Theme::Style,
+ style: Style<Theme>,
}
impl<'a, Theme, Renderer> Text<'a, Theme, Renderer>
@@ -49,7 +49,7 @@ where
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: Shaping::Basic,
- style: Default::default(),
+ style: Style::Themed(Theme::default()),
}
}
@@ -74,8 +74,20 @@ where
}
/// Sets the style of the [`Text`].
- pub fn style(mut self, style: impl Into<Theme::Style>) -> Self {
- self.style = style.into();
+ pub fn style(mut self, style: fn(&Theme) -> Appearance) -> Self {
+ self.style = Style::Themed(style);
+ self
+ }
+
+ /// Sets the [`Color`] of the [`Text`].
+ pub fn color(mut self, color: impl Into<Color>) -> Self {
+ self.style = Style::Colored(Some(color.into()));
+ self
+ }
+
+ /// Sets the [`Color`] of the [`Text`].
+ pub fn color_maybe(mut self, color: Option<impl Into<Color>>) -> Self {
+ self.style = Style::Colored(color.map(Into::into));
self
}
@@ -175,14 +187,12 @@ where
) {
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();
- draw(
- renderer,
- style,
- layout,
- state,
- theme.appearance(self.style.clone()),
- viewport,
- );
+ let appearance = match self.style {
+ Style::Themed(f) => f(theme),
+ Style::Colored(color) => Appearance { color },
+ };
+
+ draw(renderer, style, layout, state, appearance, viewport);
}
}
@@ -298,7 +308,7 @@ where
horizontal_alignment: self.horizontal_alignment,
vertical_alignment: self.vertical_alignment,
font: self.font,
- style: self.style.clone(),
+ style: self.style,
shaping: self.shaping,
}
}
@@ -327,11 +337,18 @@ where
/// The style sheet of some text.
pub trait StyleSheet {
- /// The supported style of the [`StyleSheet`].
- type Style: Default + Clone;
+ /// Returns the default styling strategy for [`Text`].
+ fn default() -> fn(&Self) -> Appearance {
+ |_| Appearance::default()
+ }
+}
- /// Produces the [`Appearance`] of some text.
- fn appearance(&self, style: Self::Style) -> Appearance;
+impl StyleSheet for Color {
+ fn default() -> fn(&Self) -> Appearance {
+ |color| Appearance {
+ color: Some(*color),
+ }
+ }
}
/// The apperance of some text.
@@ -342,3 +359,17 @@ pub struct Appearance {
/// The default, `None`, means using the inherited color.
pub color: Option<Color>,
}
+
+#[derive(Debug)]
+enum Style<Theme> {
+ Themed(fn(&Theme) -> Appearance),
+ Colored(Option<Color>),
+}
+
+impl<Theme> Clone for Style<Theme> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<Theme> Copy for Style<Theme> {}
diff --git a/examples/integration/src/controls.rs b/examples/integration/src/controls.rs
index c9bab828..473a7138 100644
--- a/examples/integration/src/controls.rs
+++ b/examples/integration/src/controls.rs
@@ -1,25 +1,26 @@
use iced_wgpu::Renderer;
-use iced_widget::{slider, text_input, Column, Row, Text};
-use iced_winit::core::{Alignment, Color, Element, Length};
+use iced_widget::{column, container, row, slider, text, text_input};
+use iced_winit::core::alignment;
+use iced_winit::core::{Color, Element, Length};
use iced_winit::runtime::{Command, Program};
use iced_winit::style::Theme;
pub struct Controls {
background_color: Color,
- text: String,
+ input: String,
}
#[derive(Debug, Clone)]
pub enum Message {
BackgroundColorChanged(Color),
- TextChanged(String),
+ InputChanged(String),
}
impl Controls {
pub fn new() -> Controls {
Controls {
background_color: Color::BLACK,
- text: String::default(),
+ input: String::default(),
}
}
@@ -38,8 +39,8 @@ impl Program for Controls {
Message::BackgroundColorChanged(color) => {
self.background_color = color;
}
- Message::TextChanged(text) => {
- self.text = text;
+ Message::InputChanged(input) => {
+ self.input = input;
}
}
@@ -48,60 +49,48 @@ impl Program for Controls {
fn view(&self) -> Element<Message, Theme, Renderer> {
let background_color = self.background_color;
- let text = &self.text;
- let sliders = Row::new()
- .width(500)
- .spacing(20)
- .push(
- slider(0.0..=1.0, background_color.r, move |r| {
- Message::BackgroundColorChanged(Color {
- r,
- ..background_color
- })
+ let sliders = row![
+ slider(0.0..=1.0, background_color.r, move |r| {
+ Message::BackgroundColorChanged(Color {
+ r,
+ ..background_color
})
- .step(0.01),
- )
- .push(
- slider(0.0..=1.0, background_color.g, move |g| {
- Message::BackgroundColorChanged(Color {
- g,
- ..background_color
- })
+ })
+ .step(0.01),
+ slider(0.0..=1.0, background_color.g, move |g| {
+ Message::BackgroundColorChanged(Color {
+ g,
+ ..background_color
})
- .step(0.01),
- )
- .push(
- slider(0.0..=1.0, background_color.b, move |b| {
- Message::BackgroundColorChanged(Color {
- b,
- ..background_color
- })
+ })
+ .step(0.01),
+ slider(0.0..=1.0, background_color.b, move |b| {
+ Message::BackgroundColorChanged(Color {
+ b,
+ ..background_color
})
- .step(0.01),
- );
+ })
+ .step(0.01),
+ ]
+ .width(500)
+ .spacing(20);
- Row::new()
- .height(Length::Fill)
- .align_items(Alignment::End)
- .push(
- Column::new().align_items(Alignment::End).push(
- Column::new()
- .padding(10)
- .spacing(10)
- .push(Text::new("Background color").style(Color::WHITE))
- .push(sliders)
- .push(
- Text::new(format!("{background_color:?}"))
- .size(14)
- .style(Color::WHITE),
- )
- .push(
- text_input("Placeholder", text)
- .on_input(Message::TextChanged),
- ),
- ),
- )
- .into()
+ container(
+ column![
+ text("Background color").color(Color::WHITE),
+ text(format!("{background_color:?}"))
+ .size(14)
+ .color(Color::WHITE),
+ text_input("Placeholder", &self.input)
+ .on_input(Message::InputChanged),
+ sliders,
+ ]
+ .spacing(10),
+ )
+ .padding(10)
+ .height(Length::Fill)
+ .align_y(alignment::Vertical::Bottom)
+ .into()
}
}
diff --git a/examples/lazy/src/main.rs b/examples/lazy/src/main.rs
index 9d8c0e35..37b5d52c 100644
--- a/examples/lazy/src/main.rs
+++ b/examples/lazy/src/main.rs
@@ -184,8 +184,7 @@ impl Sandbox for App {
.style(theme::Button::Destructive);
row![
- text(&item.name)
- .style(theme::Text::Color(item.color.into())),
+ text(&item.name).color(item.color),
horizontal_space(),
pick_list(Color::ALL, Some(item.color), move |color| {
Message::ItemColorChanged(item.clone(), color)
diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs
index 39719420..c4bedccc 100644
--- a/examples/pane_grid/src/main.rs
+++ b/examples/pane_grid/src/main.rs
@@ -162,7 +162,7 @@ impl Application for Example {
let title = row![
pin_button,
"Pane",
- text(pane.id.to_string()).style(if is_focused {
+ text(pane.id.to_string()).color(if is_focused {
PANE_ID_COLOR_FOCUSED
} else {
PANE_ID_COLOR_UNFOCUSED
diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs
index 8b71a269..193f85f2 100644
--- a/examples/pokedex/src/main.rs
+++ b/examples/pokedex/src/main.rs
@@ -1,8 +1,6 @@
use iced::futures;
use iced::widget::{self, column, container, image, row, text};
-use iced::{
- Alignment, Application, Color, Command, Element, Length, Settings, Theme,
-};
+use iced::{Alignment, Application, Command, Element, Length, Settings, Theme};
pub fn main() -> iced::Result {
Pokedex::run(Settings::default())
@@ -116,7 +114,7 @@ impl Pokemon {
text(&self.name).size(30).width(Length::Fill),
text(format!("#{}", self.number))
.size(20)
- .style(Color::from([0.5, 0.5, 0.5])),
+ .color([0.5, 0.5, 0.5]),
]
.align_items(Alignment::Center)
.spacing(20),
diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs
index eae127f7..b1aeb4a7 100644
--- a/examples/todos/src/main.rs
+++ b/examples/todos/src/main.rs
@@ -8,7 +8,7 @@ use iced::widget::{
};
use iced::window;
use iced::{Application, Element};
-use iced::{Color, Command, Length, Settings, Size, Subscription};
+use iced::{Command, Length, Settings, Size, Subscription};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
@@ -209,7 +209,7 @@ impl Application for Todos {
let title = text("todos")
.width(Length::Fill)
.size(100)
- .style(Color::from([0.5, 0.5, 0.5]))
+ .color([0.5, 0.5, 0.5])
.horizontal_alignment(alignment::Horizontal::Center);
let input = text_input("What needs to be done?", input_value)
@@ -467,7 +467,7 @@ fn empty_message(message: &str) -> Element<'_, Message> {
.width(Length::Fill)
.size(25)
.horizontal_alignment(alignment::Horizontal::Center)
- .style(Color::from([0.7, 0.7, 0.7])),
+ .color([0.7, 0.7, 0.7]),
)
.height(200)
.center_y()
diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs
index 1e2f1ef8..52e1bbb7 100644
--- a/examples/tour/src/main.rs
+++ b/examples/tour/src/main.rs
@@ -474,7 +474,7 @@ impl<'a> Step {
let color_section = column![
"And its color:",
- text(format!("{color:?}")).style(color),
+ text(format!("{color:?}")).color(color),
color_sliders,
]
.padding(20)
diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs
index bef5d296..10cdc783 100644
--- a/examples/visible_bounds/src/main.rs
+++ b/examples/visible_bounds/src/main.rs
@@ -82,7 +82,10 @@ impl Application for Example {
row![
text(label),
horizontal_space(),
- text(value).font(Font::MONOSPACE).size(14).style(color),
+ text(value)
+ .font(Font::MONOSPACE)
+ .size(14)
+ .color_maybe(color),
]
.height(40)
.align_items(Alignment::Center)
@@ -102,13 +105,12 @@ impl Application for Example {
})
.unwrap_or_default()
{
- Color {
+ Some(Color {
g: 1.0,
..Color::BLACK
- }
- .into()
+ })
} else {
- theme::Text::Default
+ None
},
)
};
@@ -120,7 +122,7 @@ impl Application for Example {
Some(Point { x, y }) => format!("({x}, {y})"),
None => "unknown".to_string(),
},
- theme::Text::Default,
+ None,
),
view_bounds("Outer container", self.outer_bounds),
view_bounds("Inner container", self.inner_bounds),
diff --git a/examples/websocket/src/main.rs b/examples/websocket/src/main.rs
index 38a6db1e..47c1898a 100644
--- a/examples/websocket/src/main.rs
+++ b/examples/websocket/src/main.rs
@@ -6,7 +6,7 @@ use iced::widget::{
button, column, container, row, scrollable, text, text_input,
};
use iced::{
- Application, Color, Command, Element, Length, Settings, Subscription, Theme,
+ color, Application, Command, Element, Length, Settings, Subscription, Theme,
};
use once_cell::sync::Lazy;
@@ -99,7 +99,7 @@ impl Application for WebSocket {
let message_log: Element<_> = if self.messages.is_empty() {
container(
text("Your messages will appear here...")
- .style(Color::from_rgb8(0x88, 0x88, 0x88)),
+ .color(color!(0x888888)),
)
.width(Length::Fill)
.height(Length::Fill)
diff --git a/style/src/theme.rs b/style/src/theme.rs
index 656d6bf9..43e7cafd 100644
--- a/style/src/theme.rs
+++ b/style/src/theme.rs
@@ -1203,32 +1203,7 @@ impl scrollable::StyleSheet for Theme {
}
}
-/// The style of text.
-#[derive(Clone, Copy, Default)]
-pub enum Text {
- /// The default style.
- #[default]
- Default,
- /// Colored text.
- Color(Color),
-}
-
-impl From<Color> for Text {
- fn from(color: Color) -> Self {
- Text::Color(color)
- }
-}
-
-impl text::StyleSheet for Theme {
- type Style = Text;
-
- fn appearance(&self, style: Self::Style) -> text::Appearance {
- match style {
- Text::Default => text::Appearance::default(),
- Text::Color(c) => text::Appearance { color: Some(c) },
- }
- }
-}
+impl text::StyleSheet for Theme {}
/// The style of a text input.
#[derive(Default)]
diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs
index 0ff4d58b..3a192fba 100644
--- a/widget/src/checkbox.rs
+++ b/widget/src/checkbox.rs
@@ -39,7 +39,7 @@ pub struct Checkbox<
Theme = crate::Theme,
Renderer = crate::Renderer,
> where
- Theme: StyleSheet + crate::text::StyleSheet,
+ Theme: StyleSheet,
Renderer: text::Renderer,
{
is_checked: bool,
diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs
index d8a1e131..51969aec 100644
--- a/widget/src/tooltip.rs
+++ b/widget/src/tooltip.rs
@@ -20,7 +20,7 @@ pub struct Tooltip<
Theme = crate::Theme,
Renderer = crate::Renderer,
> where
- Theme: container::StyleSheet + crate::text::StyleSheet,
+ Theme: container::StyleSheet,
Renderer: text::Renderer,
{
content: Element<'a, Message, Theme, Renderer>,
@@ -34,7 +34,7 @@ pub struct Tooltip<
impl<'a, Message, Theme, Renderer> Tooltip<'a, Message, Theme, Renderer>
where
- Theme: container::StyleSheet + crate::text::StyleSheet,
+ Theme: container::StyleSheet,
Renderer: text::Renderer,
{
/// The default padding of a [`Tooltip`] drawn by this renderer.