mirror of
https://github.com/danbulant/cushy
synced 2026-05-24 12:28:23 +00:00
Merge pull request #74 from ModProg/button-fun
button outline without drawing
This commit is contained in:
commit
cc7d4bac45
12 changed files with 431 additions and 52 deletions
208
Cargo.lock
generated
208
Cargo.lock
generated
|
|
@ -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"
|
||||
|
|
@ -316,6 +344,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"
|
||||
|
|
@ -338,6 +372,18 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[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 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
|
|
@ -416,6 +462,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"
|
||||
|
|
@ -437,6 +494,12 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
|
|
@ -658,6 +721,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"ahash",
|
||||
"alot",
|
||||
"gooey-macros",
|
||||
"intentional",
|
||||
"interner",
|
||||
"kempt",
|
||||
|
|
@ -668,6 +732,20 @@ dependencies = [
|
|||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[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 = "gpu-alloc"
|
||||
version = "0.6.0"
|
||||
|
|
@ -792,6 +870,19 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[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 = "intentional"
|
||||
version = "0.1.0"
|
||||
|
|
@ -804,6 +895,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"
|
||||
|
|
@ -938,6 +1035,12 @@ dependencies = [
|
|||
"redox_syscall 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.11"
|
||||
|
|
@ -1001,6 +1104,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"
|
||||
|
|
@ -1442,6 +1591,16 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
||||
|
||||
[[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-crate"
|
||||
version = "2.0.0"
|
||||
|
|
@ -1451,6 +1610,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"
|
||||
|
|
@ -1484,6 +1654,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"
|
||||
|
|
@ -1711,6 +1904,12 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
|
|
@ -2698,6 +2897,15 @@ version = "0.13.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi"
|
||||
version = "0.1.6"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
[workspace]
|
||||
|
||||
[package]
|
||||
name = "gooey"
|
||||
version = "0.1.0"
|
||||
|
|
@ -22,6 +24,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"]
|
||||
|
|
|
|||
|
|
@ -1,17 +1,28 @@
|
|||
use gooey::value::Dynamic;
|
||||
use gooey::widget::MakeWidget;
|
||||
use gooey::widgets::button::ButtonOutline;
|
||||
use gooey::widgets::Button;
|
||||
use gooey::Run;
|
||||
use kludgine::Color;
|
||||
|
||||
// begin rustme snippet: readme
|
||||
fn main() -> gooey::Result {
|
||||
// Create a dynamic usize.
|
||||
let count = Dynamic::new(0_usize);
|
||||
let count = Dynamic::new(0_isize);
|
||||
|
||||
// Create a new button with a label that is produced by mapping the contents
|
||||
// of `count`.
|
||||
Button::new(count.map_each(ToString::to_string))
|
||||
// Set the `on_click` callback to a closure that increments the counter.
|
||||
.on_click(count.with_clone(|count| move |_| count.set(count.get() + 1)))
|
||||
.and(
|
||||
// Creates a second, outlined button
|
||||
Button::new(count.map_each(ToString::to_string))
|
||||
// Set the `on_click` callback to a closure that decrements the counter.
|
||||
.on_click(count.with_clone(|count| move |_| count.set(count.get() - 1)))
|
||||
.with(&ButtonOutline, Color::DARKRED),
|
||||
)
|
||||
.into_columns()
|
||||
// Run the button as an an application.
|
||||
.run()
|
||||
}
|
||||
|
|
|
|||
21
gooey-macros/Cargo.toml
Normal file
21
gooey-macros/Cargo.toml
Normal 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"
|
||||
66
gooey-macros/src/animation.rs
Normal file
66
gooey-macros/src/animation.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
use manyhow::bail;
|
||||
use quote::ToTokens;
|
||||
use syn::{Field, ItemStruct};
|
||||
|
||||
use crate::*;
|
||||
|
||||
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 { ident, .. })| {
|
||||
let ident = ident
|
||||
.map(ToTokens::into_token_stream)
|
||||
.unwrap_or_else(|| proc_macro2::Literal::usize_unsuffixed(idx).into_token_stream());
|
||||
quote!(#ident: ::gooey::animation::LinearInterpolate::lerp(&self.#ident, &__target.#ident, __percent),)
|
||||
}),
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
impl ::gooey::animation::LinearInterpolate for #ident {
|
||||
fn lerp(&self, __target: &Self, __percent: f32) -> Self {
|
||||
#ident{#(#fields)*}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
macro_rules! expansion_snapshot {
|
||||
(#[derive($fn:expr)]$($tokens:tt)*) => {{
|
||||
use insta::assert_snapshot;
|
||||
use prettyplease::unparse;
|
||||
use syn::{parse2, parse_quote};
|
||||
let input = parse_quote!($($tokens)*);
|
||||
let output = $fn(input).unwrap();
|
||||
assert_snapshot!(unparse(&parse2(output).unwrap()))
|
||||
}};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
expansion_snapshot! {
|
||||
#[derive(linear_interpolate)]
|
||||
struct HelloWorld {
|
||||
fielda: Hello,
|
||||
fieldb: World,
|
||||
}
|
||||
};
|
||||
expansion_snapshot! {
|
||||
#[derive(linear_interpolate)]
|
||||
struct HelloWorld(Hello, World);
|
||||
};
|
||||
}
|
||||
7
gooey-macros/src/lib.rs
Normal file
7
gooey-macros/src/lib.rs
Normal 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;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
source: gooey-macros/src/animation.rs
|
||||
expression: unparse(&parse2(output).unwrap())
|
||||
---
|
||||
impl ::gooey::animation::LinearInterpolate for HelloWorld {
|
||||
fn lerp(&self, __target: &Self, __percent: f32) -> Self {
|
||||
HelloWorld {
|
||||
0: ::gooey::animation::LinearInterpolate::lerp(
|
||||
&self.0,
|
||||
&__target.0,
|
||||
__percent,
|
||||
),
|
||||
1: ::gooey::animation::LinearInterpolate::lerp(
|
||||
&self.1,
|
||||
&__target.1,
|
||||
__percent,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ use std::panic::UnwindSafe;
|
|||
use std::time::Duration;
|
||||
|
||||
use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseButton};
|
||||
use kludgine::figures::units::{Px, UPx};
|
||||
use kludgine::figures::units::{Lp, Px, UPx};
|
||||
use kludgine::figures::{IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, Size};
|
||||
use kludgine::shapes::StrokeOptions;
|
||||
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 +29,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 +49,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 +83,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 +156,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);
|
||||
|
||||
context.stroke_outline::<Lp>(style.outline, StrokeOptions::default());
|
||||
|
||||
if context.focused() {
|
||||
context.draw_focus_ring();
|
||||
|
|
@ -322,5 +331,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", Color::CLEAR_BLACK)
|
||||
/// 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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,10 +321,7 @@ impl Widget for Input {
|
|||
if window_focused && cursor_state.visible {
|
||||
context.gfx.draw_shape(
|
||||
&Shape::filled_rect(
|
||||
Rect::new(
|
||||
location,
|
||||
Size::new(Px(1), line_height),
|
||||
),
|
||||
Rect::new(location, Size::new(Px(1), line_height)),
|
||||
highlight, // TODO cursor should be a bold color, highlight probably not. This should have its own color.
|
||||
),
|
||||
padding,
|
||||
|
|
|
|||
Loading…
Reference in a new issue