Let a Theme control the text_color of an application
This commit is contained in:
parent
3a820b45f3
commit
822a3cd04f
5 changed files with 49 additions and 19 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
|
use crate::theme;
|
||||||
use crate::user_interface::{self, UserInterface};
|
use crate::user_interface::{self, UserInterface};
|
||||||
use crate::{Clipboard, Command, Debug, Event, Point, Program, Size};
|
use crate::{Clipboard, Command, Debug, Event, Point, Program, Size};
|
||||||
|
|
||||||
|
|
@ -19,6 +20,7 @@ where
|
||||||
impl<P> State<P>
|
impl<P> State<P>
|
||||||
where
|
where
|
||||||
P: Program + 'static,
|
P: Program + 'static,
|
||||||
|
<P::Renderer as crate::Renderer>::Theme: theme::Definition,
|
||||||
{
|
{
|
||||||
/// Creates a new [`State`] with the provided [`Program`], initializing its
|
/// Creates a new [`State`] with the provided [`Program`], initializing its
|
||||||
/// primitive with the given logical bounds and renderer.
|
/// primitive with the given logical bounds and renderer.
|
||||||
|
|
@ -164,7 +166,10 @@ fn build_user_interface<'a, P: Program>(
|
||||||
renderer: &mut P::Renderer,
|
renderer: &mut P::Renderer,
|
||||||
size: Size,
|
size: Size,
|
||||||
debug: &mut Debug,
|
debug: &mut Debug,
|
||||||
) -> UserInterface<'a, P::Message, P::Renderer> {
|
) -> UserInterface<'a, P::Message, P::Renderer>
|
||||||
|
where
|
||||||
|
<P::Renderer as crate::Renderer>::Theme: theme::Definition,
|
||||||
|
{
|
||||||
debug.view_started();
|
debug.view_started();
|
||||||
let view = program.view();
|
let view = program.view();
|
||||||
debug.view_finished();
|
debug.view_finished();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::event::{self, Event};
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
|
use crate::theme::{self, Definition as _};
|
||||||
use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
||||||
|
|
||||||
/// A set of interactive graphical elements with a specific [`Layout`].
|
/// A set of interactive graphical elements with a specific [`Layout`].
|
||||||
|
|
@ -28,6 +29,7 @@ pub struct UserInterface<'a, Message, Renderer> {
|
||||||
impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer>
|
impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: crate::Renderer,
|
Renderer: crate::Renderer,
|
||||||
|
Renderer::Theme: theme::Definition,
|
||||||
{
|
{
|
||||||
/// Builds a user interface for an [`Element`].
|
/// Builds a user interface for an [`Element`].
|
||||||
///
|
///
|
||||||
|
|
@ -370,7 +372,9 @@ where
|
||||||
self.root.widget.draw(
|
self.root.widget.draw(
|
||||||
renderer,
|
renderer,
|
||||||
theme,
|
theme,
|
||||||
&renderer::Style::default(),
|
&renderer::Style {
|
||||||
|
text_color: theme.text_color(),
|
||||||
|
},
|
||||||
Layout::new(&self.base),
|
Layout::new(&self.base),
|
||||||
base_cursor,
|
base_cursor,
|
||||||
&viewport,
|
&viewport,
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,14 @@ impl Theme {
|
||||||
|
|
||||||
impl Default for Theme {
|
impl Default for Theme {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Light
|
Self::Dark
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Definition {
|
pub trait Definition {
|
||||||
fn background_color(&self) -> Color;
|
fn background_color(&self) -> Color;
|
||||||
|
|
||||||
|
fn text_color(&self) -> Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Definition for Theme {
|
impl Definition for Theme {
|
||||||
|
|
@ -45,6 +47,12 @@ impl Definition for Theme {
|
||||||
|
|
||||||
palette.background.base
|
palette.background.base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn text_color(&self) -> Color {
|
||||||
|
let palette = self.extended_palette();
|
||||||
|
|
||||||
|
palette.background.text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,12 @@ impl Palette {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DARK: Self = Self {
|
pub const DARK: Self = Self {
|
||||||
background: Color::WHITE,
|
background: Color::from_rgb(
|
||||||
text: Color::BLACK,
|
0x20 as f32 / 255.0,
|
||||||
|
0x22 as f32 / 255.0,
|
||||||
|
0x25 as f32 / 255.0,
|
||||||
|
),
|
||||||
|
text: Color::from_rgb(0.90, 0.90, 0.90),
|
||||||
primary: Color::from_rgb(
|
primary: Color::from_rgb(
|
||||||
0x5E as f32 / 255.0,
|
0x5E as f32 / 255.0,
|
||||||
0x7C as f32 / 255.0,
|
0x7C as f32 / 255.0,
|
||||||
|
|
@ -119,21 +123,17 @@ pub struct Group {
|
||||||
|
|
||||||
impl Group {
|
impl Group {
|
||||||
pub fn new(base: Color, background: Color, text: Color) -> Self {
|
pub fn new(base: Color, background: Color, text: Color) -> Self {
|
||||||
|
let strong = if is_dark(base) {
|
||||||
|
lighten(base, 0.1)
|
||||||
|
} else {
|
||||||
|
darken(base, 0.1)
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
base,
|
base,
|
||||||
weak: mix(base, background, 0.4),
|
weak: mix(base, background, 0.4),
|
||||||
strong: if is_dark(background) {
|
strong,
|
||||||
lighten(base, 0.1)
|
text: readable(strong, text),
|
||||||
} else {
|
|
||||||
darken(base, 0.1)
|
|
||||||
},
|
|
||||||
text: if is_readable(base, text) {
|
|
||||||
text
|
|
||||||
} else if is_dark(text) {
|
|
||||||
Color::WHITE
|
|
||||||
} else {
|
|
||||||
Color::BLACK
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -184,8 +184,18 @@ fn lighten(color: Color, amount: f32) -> Color {
|
||||||
from_hsl(hsl)
|
from_hsl(hsl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn readable(background: Color, text: Color) -> Color {
|
||||||
|
if is_readable(background, text) {
|
||||||
|
text
|
||||||
|
} else if is_dark(background) {
|
||||||
|
Color::WHITE
|
||||||
|
} else {
|
||||||
|
Color::BLACK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_dark(color: Color) -> bool {
|
fn is_dark(color: Color) -> bool {
|
||||||
to_hsl(color).lightness < 0.5
|
to_hsl(color).lightness < 0.6
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_readable(a: Color, b: Color) -> bool {
|
fn is_readable(a: Color, b: Color) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,10 @@ pub fn build_user_interface<'a, A: Application>(
|
||||||
renderer: &mut A::Renderer,
|
renderer: &mut A::Renderer,
|
||||||
size: Size,
|
size: Size,
|
||||||
debug: &mut Debug,
|
debug: &mut Debug,
|
||||||
) -> UserInterface<'a, A::Message, A::Renderer> {
|
) -> UserInterface<'a, A::Message, A::Renderer>
|
||||||
|
where
|
||||||
|
<A::Renderer as crate::Renderer>::Theme: theme::Definition,
|
||||||
|
{
|
||||||
debug.view_started();
|
debug.view_started();
|
||||||
let view = application.view();
|
let view = application.view();
|
||||||
debug.view_finished();
|
debug.view_finished();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue