theme: Add shadow option to support toggle shadow for base controls, default: true. (#268)

- Add shadow to Button if it enabled.
This commit is contained in:
Jason Lee 2024-09-24 10:52:01 +08:00 committed by GitHub
parent 3fc0b70639
commit 2a331fcb79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 55 additions and 11 deletions

View file

@ -9,7 +9,7 @@ use ui::{
checkbox::Checkbox,
h_flex,
prelude::FluentBuilder,
theme::ActiveTheme,
theme::{ActiveTheme, Theme},
v_flex, Disableable as _, Icon, IconName, Selectable as _, Sizable as _,
};
@ -114,6 +114,17 @@ impl Render for ButtonStory {
view.compact = !view.compact;
cx.notify();
})),
)
.child(
Checkbox::new("shadow-button")
.label("Shadow")
.checked(cx.theme().shadow)
.on_click(cx.listener(|_, _, cx| {
let mut theme = cx.theme().clone();
theme.shadow = !theme.shadow;
cx.set_global::<Theme>(theme);
cx.refresh();
})),
),
)
.child(

View file

@ -30,6 +30,7 @@ pub struct ButtonCustomStyle {
color: Hsla,
foreground: Hsla,
border: Hsla,
shadow: bool,
hover: Hsla,
active: Hsla,
}
@ -81,6 +82,7 @@ impl ButtonCustomStyle {
border: cx.theme().border,
hover: cx.theme().secondary_hover,
active: cx.theme().secondary_active,
shadow: true,
}
}
@ -108,6 +110,11 @@ impl ButtonCustomStyle {
self.active = color;
self
}
pub fn shadow(mut self, shadow: bool) -> Self {
self.shadow = shadow;
self
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
@ -318,6 +325,9 @@ impl RenderOnce for Button {
.justify_center()
.cursor_pointer()
.overflow_hidden()
.when(cx.theme().shadow && normal_style.shadow, |this| {
this.shadow_sm()
})
.when(!style.no_padding(), |this| {
if self.label.is_none() && self.children.is_empty() {
// Icon Button
@ -450,6 +460,7 @@ struct ButtonStyles {
border: Hsla,
fg: Hsla,
underline: bool,
shadow: bool,
}
impl ButtonStyle {
@ -496,17 +507,27 @@ impl ButtonStyle {
}
}
fn shadow(&self, _: &WindowContext) -> bool {
match self {
ButtonStyle::Primary | ButtonStyle::Secondary | ButtonStyle::Danger => true,
ButtonStyle::Custom(c) => c.shadow,
_ => false,
}
}
fn normal(&self, cx: &WindowContext) -> ButtonStyles {
let bg = self.bg_color(cx);
let border = self.border_color(cx);
let fg = self.text_color(cx);
let underline = self.underline(cx);
let shadow = self.shadow(cx);
ButtonStyles {
bg,
border,
fg,
underline,
shadow,
}
}
@ -526,12 +547,14 @@ impl ButtonStyle {
_ => self.text_color(cx),
};
let underline = self.underline(cx);
let shadow = self.shadow(cx);
ButtonStyles {
bg,
border,
fg,
underline,
shadow,
}
}
@ -553,12 +576,14 @@ impl ButtonStyle {
_ => self.text_color(cx),
};
let underline = self.underline(cx);
let shadow = self.shadow(cx);
ButtonStyles {
bg,
border,
fg,
underline,
shadow,
}
}
@ -580,12 +605,14 @@ impl ButtonStyle {
_ => self.text_color(cx),
};
let underline = self.underline(cx);
let shadow = self.shadow(cx);
ButtonStyles {
bg,
border,
fg,
underline,
shadow,
}
}
@ -606,12 +633,14 @@ impl ButtonStyle {
let border = bg;
let underline = self.underline(cx);
let shadow = self.shadow(cx);
ButtonStyles {
bg,
border,
fg,
underline,
shadow,
}
}
}

View file

@ -605,7 +605,7 @@ where
.border_1()
.border_color(cx.theme().input)
.rounded(px(cx.theme().radius))
.shadow_sm()
.when(cx.theme().shadow, |this| this.shadow_sm())
.map(|this| {
if self.disabled {
this.cursor_not_allowed()

View file

@ -1126,7 +1126,7 @@ impl Render for TextInput {
.border_color(cx.theme().input)
.border_1()
.rounded(px(cx.theme().radius))
.shadow_sm()
.when(cx.theme().shadow, |this| this.shadow_sm())
.when(focused, |this| this.outline(cx))
.when(prefix.is_none(), |this| this.input_pl(self.size))
.when(suffix.is_none(), |this| this.input_pr(self.size))

View file

@ -212,7 +212,7 @@ impl Render for OtpInput {
.border_color(cx.theme().input)
.bg(cx.theme().background)
.when(is_input_focused, |this| this.border_color(cx.theme().ring))
.shadow_sm()
.when(cx.theme().shadow, |this| this.shadow_sm())
.items_center()
.justify_center()
.rounded_md()

View file

@ -1,8 +1,9 @@
use crate::{theme::ActiveTheme, tooltip::Tooltip};
use gpui::{
canvas, div, px, relative, Axis, Bounds, DragMoveEvent, EntityId, EventEmitter,
InteractiveElement, IntoElement, MouseButton, MouseDownEvent, ParentElement as _, Pixels,
Point, Render, StatefulInteractiveElement as _, Styled, ViewContext, VisualContext as _,
canvas, div, prelude::FluentBuilder as _, px, relative, Axis, Bounds, DragMoveEvent, EntityId,
EventEmitter, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, ParentElement as _,
Pixels, Point, Render, StatefulInteractiveElement as _, Styled, ViewContext,
VisualContext as _,
};
#[derive(Clone, Render)]
@ -142,7 +143,7 @@ impl Slider {
.rounded_full()
.border_1()
.border_color(cx.theme().slider_bar.opacity(0.9))
.shadow_md()
.when(cx.theme().shadow, |this| this.shadow_md())
.bg(cx.theme().slider_thumb)
.tooltip(move |cx| Tooltip::new(format!("{}", value), cx))
}

View file

@ -257,7 +257,7 @@ impl Colors {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Theme {
pub mode: ThemeMode,
pub transparent: Hsla,
@ -290,6 +290,8 @@ pub struct Theme {
pub border: Hsla,
pub input: Hsla,
pub ring: Hsla,
/// Set to true to enable shadow for Button, Input, Dropdown, DatePicker ...
pub shadow: bool,
pub selection: Hsla,
pub scrollbar: Hsla,
pub scrollbar_thumb: Hsla,
@ -343,6 +345,7 @@ impl From<Colors> for Theme {
"FreeMono".into()
},
radius: 4.0,
shadow: true,
title_bar_background: colors.title_bar_background,
background: colors.background,
foreground: colors.foreground,
@ -401,7 +404,7 @@ impl From<Colors> for Theme {
}
}
#[derive(Debug, Default, PartialEq, PartialOrd, Eq)]
#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq)]
pub enum ThemeMode {
Light,
#[default]

View file

@ -216,7 +216,7 @@ impl Render for DatePicker {
.border_1()
.border_color(cx.theme().input)
.rounded(px(cx.theme().radius))
.shadow_sm()
.when(cx.theme().shadow, |this| this.shadow_sm())
.cursor_pointer()
.overflow_hidden()
.input_text_size(self.size)