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, checkbox::Checkbox,
h_flex, h_flex,
prelude::FluentBuilder, prelude::FluentBuilder,
theme::ActiveTheme, theme::{ActiveTheme, Theme},
v_flex, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, v_flex, Disableable as _, Icon, IconName, Selectable as _, Sizable as _,
}; };
@ -114,6 +114,17 @@ impl Render for ButtonStory {
view.compact = !view.compact; view.compact = !view.compact;
cx.notify(); 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( .child(

View file

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

View file

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

View file

@ -1126,7 +1126,7 @@ impl Render for TextInput {
.border_color(cx.theme().input) .border_color(cx.theme().input)
.border_1() .border_1()
.rounded(px(cx.theme().radius)) .rounded(px(cx.theme().radius))
.shadow_sm() .when(cx.theme().shadow, |this| this.shadow_sm())
.when(focused, |this| this.outline(cx)) .when(focused, |this| this.outline(cx))
.when(prefix.is_none(), |this| this.input_pl(self.size)) .when(prefix.is_none(), |this| this.input_pl(self.size))
.when(suffix.is_none(), |this| this.input_pr(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) .border_color(cx.theme().input)
.bg(cx.theme().background) .bg(cx.theme().background)
.when(is_input_focused, |this| this.border_color(cx.theme().ring)) .when(is_input_focused, |this| this.border_color(cx.theme().ring))
.shadow_sm() .when(cx.theme().shadow, |this| this.shadow_sm())
.items_center() .items_center()
.justify_center() .justify_center()
.rounded_md() .rounded_md()

View file

@ -1,8 +1,9 @@
use crate::{theme::ActiveTheme, tooltip::Tooltip}; use crate::{theme::ActiveTheme, tooltip::Tooltip};
use gpui::{ use gpui::{
canvas, div, px, relative, Axis, Bounds, DragMoveEvent, EntityId, EventEmitter, canvas, div, prelude::FluentBuilder as _, px, relative, Axis, Bounds, DragMoveEvent, EntityId,
InteractiveElement, IntoElement, MouseButton, MouseDownEvent, ParentElement as _, Pixels, EventEmitter, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, ParentElement as _,
Point, Render, StatefulInteractiveElement as _, Styled, ViewContext, VisualContext as _, Pixels, Point, Render, StatefulInteractiveElement as _, Styled, ViewContext,
VisualContext as _,
}; };
#[derive(Clone, Render)] #[derive(Clone, Render)]
@ -142,7 +143,7 @@ impl Slider {
.rounded_full() .rounded_full()
.border_1() .border_1()
.border_color(cx.theme().slider_bar.opacity(0.9)) .border_color(cx.theme().slider_bar.opacity(0.9))
.shadow_md() .when(cx.theme().shadow, |this| this.shadow_md())
.bg(cx.theme().slider_thumb) .bg(cx.theme().slider_thumb)
.tooltip(move |cx| Tooltip::new(format!("{}", value), cx)) .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 struct Theme {
pub mode: ThemeMode, pub mode: ThemeMode,
pub transparent: Hsla, pub transparent: Hsla,
@ -290,6 +290,8 @@ pub struct Theme {
pub border: Hsla, pub border: Hsla,
pub input: Hsla, pub input: Hsla,
pub ring: Hsla, pub ring: Hsla,
/// Set to true to enable shadow for Button, Input, Dropdown, DatePicker ...
pub shadow: bool,
pub selection: Hsla, pub selection: Hsla,
pub scrollbar: Hsla, pub scrollbar: Hsla,
pub scrollbar_thumb: Hsla, pub scrollbar_thumb: Hsla,
@ -343,6 +345,7 @@ impl From<Colors> for Theme {
"FreeMono".into() "FreeMono".into()
}, },
radius: 4.0, radius: 4.0,
shadow: true,
title_bar_background: colors.title_bar_background, title_bar_background: colors.title_bar_background,
background: colors.background, background: colors.background,
foreground: colors.foreground, 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 { pub enum ThemeMode {
Light, Light,
#[default] #[default]

View file

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