button outline without drawing

This commit is contained in:
Roland Fredenhagen 2023-11-13 01:11:58 +01:00
parent 07b93397c5
commit 4a4578bdd6
No known key found for this signature in database
GPG key ID: 094AF99241035EB6
10 changed files with 657 additions and 46 deletions

144
Cargo.lock generated
View file

@ -154,6 +154,34 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "attribute-derive"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c94f43ede6f25dab1dea046bff84d85dea61bd49aba7a9011ad66c0d449077b"
dependencies = [
"attribute-derive-macro",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "attribute-derive-macro"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b409e2b2d2dc206d2c0ad3575a93f001ae21a1593e2d0c69b69c308e63f3b422"
dependencies = [
"collection_literals",
"interpolator",
"manyhow 0.8.1",
"proc-macro-utils",
"proc-macro2",
"quote",
"quote-use",
"syn",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -317,6 +345,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "collection_literals"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271"
[[package]]
name = "color_quant"
version = "1.1.0"
@ -417,6 +451,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "derive-where"
version = "1.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "146398d62142a0f35248a608f17edf0dde57338354966d6e41d0eb2d16980ccb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "dispatch"
version = "0.2.0"
@ -659,6 +704,7 @@ version = "0.1.0"
dependencies = [
"ahash",
"alot",
"gooey-macros",
"intentional",
"interner",
"kempt",
@ -669,6 +715,18 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "gooey-macros"
version = "0.1.0"
dependencies = [
"attribute-derive",
"manyhow 0.9.0",
"proc-macro2",
"quote",
"quote-use",
"syn",
]
[[package]]
name = "gpu-alloc"
version = "0.6.0"
@ -805,6 +863,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8c60687056b35a996f2213287048a7092d801b61df5fee3bd5bd9bf6f17a2d0"
[[package]]
name = "interpolator"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8"
[[package]]
name = "io-lifetimes"
version = "1.0.11"
@ -1011,6 +1075,52 @@ dependencies = [
"libc",
]
[[package]]
name = "manyhow"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "516b76546495d933baa165075b95c0a15e8f7ef75e53f56b19b7144d80fd52bd"
dependencies = [
"manyhow-macros 0.8.1",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "manyhow"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aebef87880bafc898c6bed1435e8fdc58634275ff97693a4bb96ad561c73c43"
dependencies = [
"manyhow-macros 0.9.0",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "manyhow-macros"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ba072c0eadade3160232e70893311f1f8903974488096e2eb8e48caba2f0cf1"
dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
]
[[package]]
name = "manyhow-macros"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f74cc8a0d8b05a7e919011c78a2744e7dea66567c05fb046666f3bae383d8d04"
dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
]
[[package]]
name = "matchers"
version = "0.1.0"
@ -1461,6 +1571,17 @@ dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro-utils"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8"
dependencies = [
"proc-macro2",
"quote",
"smallvec",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
@ -1494,6 +1615,29 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "quote-use"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7b5abe3fe82fdeeb93f44d66a7b444dedf2e4827defb0a8e69c437b2de2ef94"
dependencies = [
"quote",
"quote-use-macros",
"syn",
]
[[package]]
name = "quote-use-macros"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97ea44c7e20f16017a76a245bb42188517e13d16dcb1aa18044bc406cdc3f4af"
dependencies = [
"derive-where",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "rand"
version = "0.8.5"

View file

@ -22,6 +22,7 @@ tracing-subscriber = { version = "0.3", optional = true, features = [
] }
palette = "0.7.3"
ahash = "0.8.6"
gooey-macros = { version = "0.1.0", path = "gooey-macros" }
# [patch."https://github.com/khonsulabs/kludgine"]

329
gooey-macros/Cargo.lock generated Normal file
View file

@ -0,0 +1,329 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "attribute-derive"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c94f43ede6f25dab1dea046bff84d85dea61bd49aba7a9011ad66c0d449077b"
dependencies = [
"attribute-derive-macro",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "attribute-derive-macro"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b409e2b2d2dc206d2c0ad3575a93f001ae21a1593e2d0c69b69c308e63f3b422"
dependencies = [
"collection_literals",
"interpolator",
"manyhow 0.8.1",
"proc-macro-utils",
"proc-macro2",
"quote",
"quote-use",
"syn",
]
[[package]]
name = "collection_literals"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271"
[[package]]
name = "console"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"windows-sys",
]
[[package]]
name = "derive-where"
version = "1.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "146398d62142a0f35248a608f17edf0dde57338354966d6e41d0eb2d16980ccb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "gooey-macros"
version = "0.1.0"
dependencies = [
"attribute-derive",
"insta",
"manyhow 0.9.0",
"prettyplease",
"proc-macro2",
"quote",
"quote-use",
"syn",
]
[[package]]
name = "insta"
version = "1.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc"
dependencies = [
"console",
"lazy_static",
"linked-hash-map",
"similar",
"yaml-rust",
]
[[package]]
name = "interpolator"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "manyhow"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "516b76546495d933baa165075b95c0a15e8f7ef75e53f56b19b7144d80fd52bd"
dependencies = [
"manyhow-macros 0.8.1",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "manyhow"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aebef87880bafc898c6bed1435e8fdc58634275ff97693a4bb96ad561c73c43"
dependencies = [
"manyhow-macros 0.9.0",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "manyhow-macros"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ba072c0eadade3160232e70893311f1f8903974488096e2eb8e48caba2f0cf1"
dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
]
[[package]]
name = "manyhow-macros"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f74cc8a0d8b05a7e919011c78a2744e7dea66567c05fb046666f3bae383d8d04"
dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
]
[[package]]
name = "prettyplease"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro-utils"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8"
dependencies = [
"proc-macro2",
"quote",
"smallvec",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "quote-use"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7b5abe3fe82fdeeb93f44d66a7b444dedf2e4827defb0a8e69c437b2de2ef94"
dependencies = [
"quote",
"quote-use-macros",
"syn",
]
[[package]]
name = "quote-use-macros"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97ea44c7e20f16017a76a245bb42188517e13d16dcb1aa18044bc406cdc3f4af"
dependencies = [
"derive-where",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "similar"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597"
[[package]]
name = "smallvec"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

21
gooey-macros/Cargo.toml Normal file
View file

@ -0,0 +1,21 @@
[package]
name = "gooey-macros"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
attribute-derive = "0.8.1"
manyhow = "0.9.0"
proc-macro2 = "1.0.69"
quote = "1.0.33"
quote-use = "0.7.2"
syn = "2.0.39"
[dev-dependencies]
insta = "1.34.0"
prettyplease = "0.2.15"

View file

@ -0,0 +1,65 @@
use attribute_derive::FromAttr;
use manyhow::bail;
use quote::ToTokens;
use syn::{Field, ItemStruct};
use crate::*;
#[derive(FromAttr)]
#[attribute(ident = interpolate)]
struct FieldAttributes {
skip: bool,
}
pub fn linear_interpolate(
ItemStruct {
ident,
generics,
fields,
..
}: ItemStruct,
) -> Result<TokenStream> {
if let Some(generic) = generics.type_params().next() {
bail!(generic, "generics not supported");
}
let fields = match fields {
syn::Fields::Unit => bail!(ident, "unit structs are not supported"),
fields => fields
.into_iter()
.enumerate()
.map(|(idx, Field { attrs, ident, .. })| {
let ident = ident
.map(ToTokens::into_token_stream)
.unwrap_or_else(|| proc_macro2::Literal::usize_unsuffixed(idx).into_token_stream());
Ok(if FieldAttributes::from_attributes(&attrs)?.skip {
quote!(#ident: __target.#ident,)
} else {
quote!(#ident: ::gooey::animation::LinearInterpolate::lerp(&self.#ident, &__target.#ident, __percent),)
})
}),
}.collect::<Result>()?;
Ok(quote! {
impl ::gooey::animation::LinearInterpolate for #ident {
fn lerp(&self, __target: &Self, __percent: f32) -> Self {
#ident{#fields}
}
}
})
}
#[test]
fn test() {
use insta::assert_snapshot;
use prettyplease::unparse;
use syn::{parse2, parse_quote};
let input = parse_quote!(
struct HelloWorld {
fielda: Hello,
fieldb: World,
}
);
let output = linear_interpolate(input).unwrap();
assert_snapshot!(unparse(&parse2(output).unwrap()))
}

7
gooey-macros/src/lib.rs Normal file
View file

@ -0,0 +1,7 @@
use manyhow::{manyhow, Result};
use quote_use::quote_use as quote;
use proc_macro2::TokenStream;
mod animation;
#[manyhow(proc_macro_derive(LinearInterpolate))]
pub use animation::linear_interpolate;

View file

@ -0,0 +1,21 @@
---
source: src/animation.rs
expression: unparse(&parse2(output).unwrap())
---
impl ::gooey::animation::LinearInterpolate for HelloWorld {
fn lerp(&self, __target: &Self, __percent: f32) -> Self {
HelloWorld {
fielda: ::gooey::animation::LinearInterpolate::lerp(
&self.fielda,
&__target.fielda,
__percent,
),
fieldb: ::gooey::animation::LinearInterpolate::lerp(
&self.fieldb,
&__target.fieldb,
__percent,
),
}
}
}

View file

@ -616,6 +616,8 @@ pub trait LinearInterpolate: PartialEq {
fn lerp(&self, target: &Self, percent: f32) -> Self;
}
pub use gooey_macros::LinearInterpolate;
macro_rules! impl_lerp_for_int {
($type:ident, $unsigned:ident, $float:ident) => {
impl LinearInterpolate for $type {

View file

@ -2,6 +2,9 @@
#![warn(clippy::pedantic, missing_docs)]
#![allow(clippy::module_name_repetitions, clippy::missing_errors_doc)]
// for proc-macros
extern crate self as gooey;
#[macro_use]
mod utils;

View file

@ -7,7 +7,7 @@ use kludgine::figures::units::{Px, UPx};
use kludgine::figures::{IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, Size};
use kludgine::Color;
use crate::animation::{AnimationHandle, AnimationTarget, Spawn};
use crate::animation::{AnimationHandle, AnimationTarget, LinearInterpolate, Spawn};
use crate::context::{AsEventContext, EventContext, GraphicsContext, LayoutContext, WidgetContext};
use crate::styles::components::{
AutoFocusableControls, Easing, IntrinsicPadding, OpaqueWidgetColor, SurfaceColor, TextColor,
@ -28,11 +28,17 @@ pub struct Button {
pub enabled: Value<bool>,
currently_enabled: bool,
buttons_pressed: usize,
background_color: Option<Dynamic<Color>>,
text_color: Option<Dynamic<Color>>,
active_style: Option<Dynamic<ButtonStyle>>,
color_animation: AnimationHandle,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, LinearInterpolate)]
struct ButtonStyle {
background: Color,
foreground: Color,
outline: Color,
}
impl Button {
/// Returns a new button with the provided label.
pub fn new(content: impl MakeWidget) -> Self {
@ -42,8 +48,7 @@ impl Button {
enabled: Value::Constant(true),
currently_enabled: true,
buttons_pressed: 0,
background_color: None,
text_color: None,
active_style: None,
color_animation: AnimationHandle::default(),
}
}
@ -77,62 +82,63 @@ impl Button {
}
fn update_colors(&mut self, context: &WidgetContext<'_, '_>, immediate: bool) {
let (background_color, text_color) = match () {
() if !self.enabled.get() => (
context.get(&ButtonDisabledBackground),
context.get(&ButtonDisabledForeground),
),
let new_style = match () {
() if !self.enabled.get() => ButtonStyle {
background: context.get(&ButtonDisabledBackground),
foreground: context.get(&ButtonDisabledForeground),
outline: context.get(&ButtonDisabledOutline),
},
// TODO this probably should use actual style.
() if context.is_default() => (
context.theme().primary.color,
context.theme().primary.on_color,
),
() if context.active() => (
context.get(&ButtonActiveBackground),
context.get(&ButtonActiveForeground),
),
() if context.hovered() => (
context.get(&ButtonHoverBackground),
context.get(&ButtonHoverForeground),
),
() => (
context.get(&ButtonBackground),
context.get(&ButtonForeground),
),
() if context.is_default() => ButtonStyle {
background: context.theme().primary.color,
foreground: context.theme().primary.on_color,
outline: Color::CLEAR_BLACK,
},
() if context.active() => ButtonStyle {
background: context.get(&ButtonActiveBackground),
foreground: context.get(&ButtonActiveForeground),
outline: context.get(&ButtonActiveOutline),
},
() if context.hovered() => ButtonStyle {
background: context.get(&ButtonHoverBackground),
foreground: context.get(&ButtonHoverForeground),
outline: context.get(&ButtonHoverOutline),
},
() => ButtonStyle {
background: context.get(&ButtonBackground),
foreground: context.get(&ButtonForeground),
outline: context.get(&ButtonOutline),
},
};
match (immediate, &self.background_color, &self.text_color) {
(false, Some(bg), Some(text)) => {
self.color_animation = (
bg.transition_to(background_color),
text.transition_to(text_color),
)
match (immediate, &self.active_style) {
(false, Some(style)) => {
self.color_animation = (style.transition_to(new_style))
.over(Duration::from_millis(150))
.with_easing(context.get(&Easing))
.spawn();
}
(true, Some(bg), Some(text)) => {
bg.update(background_color);
text.update(text_color);
(true, Some(style)) => {
style.update(new_style);
self.color_animation.clear();
}
_ => {
self.background_color = Some(Dynamic::new(background_color));
let text_color = Dynamic::new(text_color);
self.text_color = Some(text_color.clone());
context.attach_styles(Styles::new().with(&TextColor, text_color));
let new_style = Dynamic::new(new_style);
let foreground = new_style.map_each(|s| s.foreground);
self.active_style = Some(new_style);
context.attach_styles(Styles::new().with(&TextColor, foreground));
}
}
}
fn current_background(&mut self, context: &WidgetContext<'_, '_>) -> Color {
if self.background_color.is_none() {
fn current_style(&mut self, context: &WidgetContext<'_, '_>) -> ButtonStyle {
if self.active_style.is_none() {
self.update_colors(context, false);
}
let background_color = self.background_color.as_ref().expect("always initialized");
context.redraw_when_changed(background_color);
background_color.get()
let style = self.active_style.as_ref().expect("always initialized");
context.redraw_when_changed(&style);
style.get()
}
}
@ -149,8 +155,10 @@ impl Widget for Button {
self.enabled.redraw_when_changed(context);
let background_color = self.current_background(context);
context.gfx.fill(background_color);
let style = self.current_style(context);
context.gfx.fill(style.background);
// TODO draw outline
if context.focused() {
context.draw_focus_ring();
@ -322,5 +330,15 @@ define_components! {
/// The foreground color of the button when the mouse cursor is hovering over
/// it.
ButtonDisabledForeground(Color, "disabled_foreground_color", contrasting!(ButtonDisabledBackground, ButtonForeground, TextColor, SurfaceColor))
/// The outline color of the button.
ButtonOutline(Color, "outline_color", contrasting!(ButtonBackground, TextColor, SurfaceColor))
/// The outline color of the button when it is active (depressed).
ButtonActiveOutline(Color, "active_outline_color", contrasting!(ButtonActiveBackground, ButtonOutline, TextColor, SurfaceColor))
/// The outline color of the button when the mouse cursor is hovering over
/// it.
ButtonHoverOutline(Color, "hover_outline_color", contrasting!(ButtonHoverBackground, ButtonOutline, TextColor, SurfaceColor))
/// The outline color of the button when the mouse cursor is hovering over
/// it.
ButtonDisabledOutline(Color, "disabled_outline_color", contrasting!(ButtonDisabledBackground, ButtonOutline, TextColor, SurfaceColor))
}
}