ColorPicker
ColorPicker 是一个通用的颜色选择组件,提供直观的颜色选择界面。它支持颜色面板、十六进制输入、精选颜色,以及 RGB、HSL 和十六进制格式,并支持 alpha 透明通道。
导入
rust
use gpui_component::color_picker::{ColorPicker, ColorPickerState, ColorPickerEvent};用法
基础 Color Picker
rust
use gpui::{Entity, Window, Context};
let color_picker = cx.new(|cx|
ColorPickerState::new(window, cx)
.default_value(cx.theme().primary)
);
ColorPicker::new(&color_picker)处理事件
rust
use gpui::{Subscription, Entity};
let color_picker = cx.new(|cx| ColorPickerState::new(window, cx));
let _subscription = cx.subscribe(&color_picker, |this, _, ev, _| match ev {
ColorPickerEvent::Change(color) => {
if let Some(color) = color {
println!("Selected color: {}", color.to_hex());
// Handle color change
}
}
});
ColorPicker::new(&color_picker)设置默认颜色
rust
use gpui::Hsla;
let color_picker = cx.new(|cx|
ColorPickerState::new(window, cx)
.default_value(cx.theme().blue)
);不同尺寸
rust
ColorPicker::new(&color_picker).small()
ColorPicker::new(&color_picker)
ColorPicker::new(&color_picker).large()
ColorPicker::new(&color_picker).xsmall()自定义精选颜色
rust
use gpui::Hsla;
let featured_colors = vec![
cx.theme().red,
cx.theme().green,
cx.theme().blue,
cx.theme().yellow,
];
ColorPicker::new(&color_picker)
.featured_colors(featured_colors)用图标替代色块
rust
use gpui_component::IconName;
ColorPicker::new(&color_picker)
.icon(IconName::Palette)带标签
rust
ColorPicker::new(&color_picker)
.label("Background Color")自定义锚点位置
rust
use gpui::Corner;
ColorPicker::new(&color_picker)
.anchor(Corner::TopRight)颜色选择界面
调色板
组件内置多组颜色家族:
- Stone:中性色与石灰灰阶
- Red:红色系
- Orange:橙色系
- Yellow:黄色系
- Green:绿色系
- Cyan:青色系
- Blue:蓝色系
- Purple:紫色系
- Pink:粉色系
每个颜色家族都提供多个深浅层级,方便精准选色。
精选颜色区域
顶部的精选颜色区域可用于放置品牌色或常用色。若未指定,则默认使用当前主题中的核心颜色:
- 当前主题的主色
- 主题颜色的浅色变体
- 常用界面色,如 red、blue、green、yellow、cyan、magenta
Hex 输入框
组件提供十六进制输入框,可直接输入颜色值:
- 支持标准 6 位格式
#RRGGBB - 实时校验并预览
- 会自动同步到组件状态
- 按 Enter 确认
颜色格式
RGB
颜色内部使用 GPUI 的 Hsla 表示,但可以转换为 RGB 相关值:
rust
let color = cx.theme().blue;
// Access RGB components through Hsla methodsHSL
ColorPicker 原生使用 HSL/HSLA 表示:
rust
use gpui::Hsla;
let color = Hsla::hsl(240.0, 100.0, 50.0);
let hue = color.h;
let saturation = color.s;
let lightness = color.l;Hex
标准 Web 十六进制格式:
rust
let hex_string = color.to_hex();
if let Ok(color) = Hsla::parse_hex("#3366FF") {
// Use parsed color
}Alpha 通道
支持透明度:
rust
use gpui::hsla;
let semi_transparent = hsla(0.5, 0.8, 0.6, 0.7);
let transparent_blue = cx.theme().blue.opacity(0.5);ColorPicker 在选择颜色时会保留 alpha 值,也可通过 HSLA 的 alpha 分量进一步修改。
API 参考
示例
主题颜色编辑器
rust
struct ThemeEditor {
primary_color: Entity<ColorPickerState>,
secondary_color: Entity<ColorPickerState>,
accent_color: Entity<ColorPickerState>,
}
impl ThemeEditor {
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let primary_color = cx.new(|cx|
ColorPickerState::new(window, cx)
.default_value(cx.theme().primary)
);
let secondary_color = cx.new(|cx|
ColorPickerState::new(window, cx)
.default_value(cx.theme().secondary)
);
let accent_color = cx.new(|cx|
ColorPickerState::new(window, cx)
.default_value(cx.theme().accent)
);
Self {
primary_color,
secondary_color,
accent_color,
}
}
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
v_flex()
.gap_4()
.child(
h_flex()
.gap_2()
.items_center()
.child("Primary Color:")
.child(ColorPicker::new(&self.primary_color))
)
.child(
h_flex()
.gap_2()
.items_center()
.child("Secondary Color:")
.child(ColorPicker::new(&self.secondary_color))
)
.child(
h_flex()
.gap_2()
.items_center()
.child("Accent Color:")
.child(ColorPicker::new(&self.accent_color))
)
}
}品牌色选择器
rust
use gpui_component::Sizable as _;
let brand_colors = vec![
Hsla::parse_hex("#FF6B6B").unwrap(),
Hsla::parse_hex("#4ECDC4").unwrap(),
Hsla::parse_hex("#45B7D1").unwrap(),
Hsla::parse_hex("#96CEB4").unwrap(),
Hsla::parse_hex("#FFEAA7").unwrap(),
];
ColorPicker::new(&color_picker)
.featured_colors(brand_colors)
.label("Brand Color")
.large()工具栏颜色选择器
rust
use gpui_component::{Sizable as _, IconName};
ColorPicker::new(&text_color_picker)
.icon(IconName::Type)
.small()
.anchor(Corner::BottomLeft)调色板构建器
rust
struct ColorPalette {
colors: Vec<Entity<ColorPickerState>>,
}
impl ColorPalette {
fn add_color(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let color_picker = cx.new(|cx| ColorPickerState::new(window, cx));
cx.subscribe(&color_picker, |this, _, ev, _| match ev {
ColorPickerEvent::Change(color) => {
if let Some(color) = color {
this.update_palette_preview();
}
}
});
self.colors.push(color_picker);
cx.notify();
}
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
h_flex()
.gap_2()
.children(
self.colors.iter().map(|color_picker| {
ColorPicker::new(color_picker).small()
})
)
.child(
Button::new("add-color")
.icon(IconName::Plus)
.ghost()
.on_click(cx.listener(|this, _, window, cx| {
this.add_color(window, cx);
}))
)
}
}颜色校验
rust
let color_picker = cx.new(|cx| ColorPickerState::new(window, cx));
let _subscription = cx.subscribe(&color_picker, |this, _, ev, _| match ev {
ColorPickerEvent::Change(color) => {
if let Some(color) = color {
if this.validate_contrast(color) {
this.apply_color(color);
} else {
this.show_contrast_warning();
}
}
}
});