color_picker: Add icon use icon as color picker button. (#711)

This commit is contained in:
Jason Lee 2025-03-11 21:14:14 +08:00 committed by GitHub
parent d0abcb2456
commit 89170eea1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 22 deletions

View file

@ -5,6 +5,7 @@ use gpui::{
use gpui_component::{ use gpui_component::{
button::{Button, ButtonGroup}, button::{Button, ButtonGroup},
checkbox::Checkbox, checkbox::Checkbox,
color_picker::ColorPicker,
date_picker::DatePicker, date_picker::DatePicker,
divider::Divider, divider::Divider,
form::{form_field, v_form}, form::{form_field, v_form},
@ -20,6 +21,7 @@ pub struct FormStory {
name_input: Entity<TextInput>, name_input: Entity<TextInput>,
email_input: Entity<TextInput>, email_input: Entity<TextInput>,
bio_input: Entity<TextInput>, bio_input: Entity<TextInput>,
color_picker: Entity<ColorPicker>,
subscribe_email: bool, subscribe_email: bool,
date_picker: Entity<DatePicker>, date_picker: Entity<DatePicker>,
layout: Axis, layout: Axis,
@ -51,6 +53,11 @@ impl FormStory {
input.set_text("Jason Lee", window, cx); input.set_text("Jason Lee", window, cx);
input input
}); });
let color_picker = cx.new(|cx| {
ColorPicker::new("color-picker-1", window, cx)
.small()
.label("Theme color")
});
let email_input = cx.new(|cx| TextInput::new(window, cx).placeholder("Enter text here...")); let email_input = cx.new(|cx| TextInput::new(window, cx).placeholder("Enter text here..."));
let bio_input = cx.new(|cx| { let bio_input = cx.new(|cx| {
@ -68,6 +75,7 @@ impl FormStory {
email_input, email_input,
bio_input, bio_input,
date_picker, date_picker,
color_picker,
subscribe_email: false, subscribe_email: false,
layout: Axis::Vertical, layout: Axis::Vertical,
size: Size::default(), size: Size::default(),
@ -197,6 +205,7 @@ impl Render for FormStory {
})), })),
), ),
) )
.child(form_field().child(self.color_picker.clone()))
.child( .child(
form_field().child( form_field().child(
Checkbox::new("use-vertical-layout") Checkbox::new("use-vertical-layout")

View file

@ -45,9 +45,9 @@ impl AppTitleBar {
let theme_color_picker = cx.new(|cx| { let theme_color_picker = cx.new(|cx| {
let mut picker = ColorPicker::new("theme-color-picker", window, cx) let mut picker = ColorPicker::new("theme-color-picker", window, cx)
.xsmall() .small()
.anchor(Corner::TopRight) .anchor(Corner::TopRight)
.label("Theme Color"); .icon(IconName::Palette);
picker.set_value(cx.theme().primary, window, cx); picker.set_value(cx.theme().primary, window, cx);
picker picker
}); });
@ -122,8 +122,8 @@ impl Render for AppTitleBar {
.px_2() .px_2()
.gap_2() .gap_2()
.on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation()) .on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())
.child(self.theme_color_picker.clone())
.child((self.child.clone())(window, cx)) .child((self.child.clone())(window, cx))
.child(self.theme_color_picker.clone())
.child( .child(
Button::new("theme-mode") Button::new("theme-mode")
.map(|this| { .map(|this| {

View file

@ -6,12 +6,13 @@ use gpui::{
}; };
use crate::{ use crate::{
button::{Button, ButtonVariants},
divider::Divider, divider::Divider,
h_flex, h_flex,
input::{InputEvent, TextInput}, input::{InputEvent, TextInput},
popover::Escape, popover::Escape,
tooltip::Tooltip, tooltip::Tooltip,
v_flex, ActiveTheme as _, Colorize as _, Sizable, Size, StyleSized, v_flex, ActiveTheme as _, Colorize as _, Icon, Selectable as _, Sizable, Size, StyleSized,
}; };
const KEY_CONTEXT: &'static str = "ColorPicker"; const KEY_CONTEXT: &'static str = "ColorPicker";
@ -60,6 +61,7 @@ pub struct ColorPicker {
featured_colors: Vec<Hsla>, featured_colors: Vec<Hsla>,
hovered_color: Option<Hsla>, hovered_color: Option<Hsla>,
label: Option<SharedString>, label: Option<SharedString>,
icon: Option<Icon>,
size: Size, size: Size,
anchor: Corner, anchor: Corner,
color_input: Entity<TextInput>, color_input: Entity<TextInput>,
@ -114,6 +116,7 @@ impl ColorPicker {
hovered_color: None, hovered_color: None,
size: Size::Medium, size: Size::Medium,
label: None, label: None,
icon: None,
anchor: Corner::TopLeft, anchor: Corner::TopLeft,
color_input, color_input,
open: false, open: false,
@ -142,6 +145,15 @@ impl ColorPicker {
self self
} }
/// Set the icon to the color picker button.
///
/// If this is set the color picker button will display the icon.
/// Else it will display the square color of the current value.
pub fn icon(mut self, icon: impl Into<Icon>) -> Self {
self.icon = Some(icon.into());
self
}
/// Set the label to be displayed above the color picker. /// Set the label to be displayed above the color picker.
/// ///
/// Default is `None`. /// Default is `None`.
@ -314,24 +326,38 @@ impl Render for ColorPicker {
.items_center() .items_center()
.input_text_size(self.size) .input_text_size(self.size)
.line_height(relative(1.)) .line_height(relative(1.))
.child( .when_some(self.icon.clone(), |this, icon| {
div() this.child(
.id("color-picker-square") Button::new("btn")
.bg(cx.theme().background) .ghost()
.border_1() .selected(self.open)
.border_color(cx.theme().input) .with_size(self.size)
.rounded(cx.theme().radius) .icon(icon.clone()),
.bg(cx.theme().background) )
.shadow_sm() })
.overflow_hidden() .when_none(&self.icon, |this| {
.size_with(self.size) this.child(
.when_some(self.value, |this, value| { div()
this.bg(value).border_color(value.darken(0.3)) .id("color-picker-square")
}) .bg(cx.theme().background)
.tooltip(move |window, cx| { .border_1()
Tooltip::new(display_title.clone(), window, cx) .border_color(cx.theme().input)
}), .rounded(cx.theme().radius)
) .shadow_sm()
.overflow_hidden()
.size_with(self.size)
.when_some(self.value, |this, value| {
this.bg(value)
.border_color(value.darken(0.3))
.when(self.open, |this| this.border_2())
})
.when(!display_title.is_empty(), |this| {
this.tooltip(move |window, cx| {
Tooltip::new(display_title.clone(), window, cx)
})
}),
)
})
.when_some(self.label.clone(), |this, label| this.child(label)) .when_some(self.label.clone(), |this, label| this.child(label))
.on_click(cx.listener(Self::toggle_picker)) .on_click(cx.listener(Self::toggle_picker))
.on_mouse_up_out( .on_mouse_up_out(