wip: add plus icon to empty color picker button

This commit is contained in:
Ashley Wulber 2023-10-12 12:45:57 -04:00
parent 931f0011b4
commit 0c02266aa7
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
2 changed files with 124 additions and 97 deletions

View file

@ -160,12 +160,7 @@ impl Default for State {
"card 4".to_string(), "card 4".to_string(),
], ],
timeline: Rc::new(RefCell::new(Default::default())), timeline: Rc::new(RefCell::new(Default::default())),
color_picker_model: ColorPickerModel::new( color_picker_model: ColorPickerModel::new("Hex", "RGB", None, None),
"Hex",
"RGB",
Some(Color::new(0.8, 0.3, 0.8, 1.0)),
None,
),
} }
} }
} }
@ -525,6 +520,8 @@ impl State {
.into(), .into(),
self.color_picker_model self.color_picker_model
.picker_button(Message::ColorPickerUpdate) .picker_button(Message::ColorPickerUpdate)
.width(Length::Fixed(128.0))
.height(Length::Fixed(128.0))
.into(), .into(),
if self.color_picker_model.get_is_active() { if self.color_picker_model.get_is_active() {
self.color_picker_model self.color_picker_model

View file

@ -17,20 +17,21 @@ use iced_core::gradient::{ColorStop, Linear};
use iced_core::renderer::Quad; use iced_core::renderer::Quad;
use iced_core::widget::{tree, Tree}; use iced_core::widget::{tree, Tree};
use iced_core::{ use iced_core::{
layout, mouse, renderer, Clipboard, Color, Layout, Length, Radians, Rectangle, Renderer, Shell, layout, mouse, renderer, Background, Clipboard, Color, Layout, Length, Radians, Rectangle,
Vector, Widget, Renderer, Shell, Vector, Widget,
}; };
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
use iced_sctk::commands::data_device::set_selection; use iced_sctk::commands::data_device::set_selection;
use iced_style::slider::{HandleShape, RailBackground}; use iced_style::slider::{HandleShape, RailBackground};
use iced_widget::{canvas, column, scrollable, vertical_space, Row}; use iced_widget::{canvas, column, horizontal_space, row, scrollable, vertical_space, Row};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use palette::{FromColor, RgbHue}; use palette::{FromColor, RgbHue};
use super::button::StyleSheet;
use super::divider::horizontal; use super::divider::horizontal;
use super::icon::from_name; use super::icon::{self, from_name};
use super::segmented_button::{self, Model, SingleSelect}; use super::segmented_button::{self, Model, SingleSelect};
use super::{button, segmented_selection, text, text_input, tooltip}; use super::{button, segmented_selection, text, text_input, tooltip, Icon};
// TODO is this going to look correct enough? // TODO is this going to look correct enough?
lazy_static! { lazy_static! {
@ -74,8 +75,6 @@ pub struct ColorPickerModel {
#[setters(skip)] #[setters(skip)]
applied_color: Option<Color>, applied_color: Option<Color>,
#[setters(skip)] #[setters(skip)]
initial_color: Option<Color>,
#[setters(skip)]
fallback_color: Option<Color>, fallback_color: Option<Color>,
#[setters(skip)] #[setters(skip)]
recent_colors: Vec<Color>, recent_colors: Vec<Color>,
@ -108,7 +107,6 @@ impl ColorPickerModel {
save_next: None, save_next: None,
input_color: color_to_string(hsv, true), input_color: color_to_string(hsv, true),
applied_color: initial, applied_color: initial,
initial_color,
fallback_color, fallback_color,
recent_colors: Vec::new(), // TODO should all color pickers show the same recent colors? recent_colors: Vec::new(), // TODO should all color pickers show the same recent colors?
active: false, active: false,
@ -121,13 +119,13 @@ impl ColorPickerModel {
/// Get a color picker button that displays the applied color /// Get a color picker button that displays the applied color
/// ///
pub fn picker_button<'a, Message: 'a, T: Fn(ColorPickerUpdate) -> Message>( pub fn picker_button<'a, Message: 'static, T: Fn(ColorPickerUpdate) -> Message>(
&self, &self,
f: T, f: T,
) -> crate::widget::Button<'a, Message, crate::Renderer> { ) -> crate::widget::Button<'a, Message, crate::Renderer> {
color_button( color_button(
Some(f(ColorPickerUpdate::ToggleColorPicker)), Some(f(ColorPickerUpdate::ToggleColorPicker)),
self.applied_color.unwrap_or(Color::BLACK), self.applied_color,
) )
} }
@ -360,7 +358,7 @@ where
.leading_icon( .leading_icon(
color_button( color_button(
None, None,
Color::from(palette::Srgb::from_color(self.active_color)) Some(Color::from(palette::Srgb::from_color(self.active_color)))
) )
.into() .into()
) )
@ -416,7 +414,7 @@ where
let hsv = palette::Hsv::from_color(initial_srgb); let hsv = palette::Hsv::from_color(initial_srgb);
color_button( color_button(
Some(on_update(ColorPickerUpdate::ActiveColor(hsv))), Some(on_update(ColorPickerUpdate::ActiveColor(hsv))),
*c, Some(*c),
) )
.into() .into()
}) })
@ -743,13 +741,39 @@ fn color_to_string(c: palette::Hsv, is_hex: bool) -> String {
} }
} }
fn color_button<'a, Message: 'a>( fn color_button<'a, Message: 'static>(
on_press: Option<Message>, on_press: Option<Message>,
color: Color, color: Option<Color>,
) -> crate::widget::Button<'a, Message, crate::Renderer> { ) -> crate::widget::Button<'a, Message, crate::Renderer> {
let spacing = THEME.with(|t| t.borrow().cosmic().spacing); let spacing = THEME.with(|t| t.borrow().cosmic().spacing);
button(vertical_space(Length::Fixed(f32::from(spacing.space_s)))) button(if color.is_some() {
Element::from(vertical_space(Length::Fixed(f32::from(spacing.space_s))))
} else {
Element::from(column![
vertical_space(Length::FillPortion(1)),
vertical_space(Length::FillPortion(1)),
row![
horizontal_space(Length::FillPortion(1)),
horizontal_space(Length::FillPortion(1)),
Icon::from(
icon::from_name("list-add-symbolic")
.prefer_svg(true)
.symbolic(true)
.size(64)
)
.width(Length::FillPortion(2))
.height(Length::Fill)
.content_fit(iced_core::ContentFit::Contain),
horizontal_space(Length::FillPortion(1)),
horizontal_space(Length::FillPortion(1)),
]
.height(Length::FillPortion(2))
.width(Length::Fill),
vertical_space(Length::FillPortion(1)),
vertical_space(Length::FillPortion(1)),
])
})
.width(Length::Fixed(f32::from(spacing.space_s))) .width(Length::Fixed(f32::from(spacing.space_s)))
.height(Length::Fixed(f32::from(spacing.space_s))) .height(Length::Fixed(f32::from(spacing.space_s)))
.on_press_maybe(on_press) .on_press_maybe(on_press)
@ -762,9 +786,10 @@ fn color_button<'a, Message: 'a>(
} else { } else {
(0.0, Color::TRANSPARENT) (0.0, Color::TRANSPARENT)
}; };
let standard = theme.active(focused, &Button::Standard);
button::Appearance { button::Appearance {
shadow_offset: Vector::default(), shadow_offset: Vector::default(),
background: Some(color.into()), background: color.map(Background::from).or(standard.background),
border_radius: cosmic.radius_xs().into(), border_radius: cosmic.radius_xs().into(),
border_width: 1.0, border_width: 1.0,
border_color: cosmic.on_bg_color().into(), border_color: cosmic.on_bg_color().into(),
@ -777,9 +802,10 @@ fn color_button<'a, Message: 'a>(
disabled: Box::new(move |theme| { disabled: Box::new(move |theme| {
let cosmic = theme.cosmic(); let cosmic = theme.cosmic();
let standard = theme.disabled(&Button::Standard);
button::Appearance { button::Appearance {
shadow_offset: Vector::default(), shadow_offset: Vector::default(),
background: Some(color.into()), background: color.map(Background::from).or(standard.background),
border_radius: cosmic.radius_xs().into(), border_radius: cosmic.radius_xs().into(),
border_width: 1.0, border_width: 1.0,
border_color: cosmic.on_bg_color().into(), border_color: cosmic.on_bg_color().into(),
@ -797,9 +823,11 @@ fn color_button<'a, Message: 'a>(
} else { } else {
(0.0, Color::TRANSPARENT) (0.0, Color::TRANSPARENT)
}; };
let standard = theme.hovered(focused, &Button::Standard);
button::Appearance { button::Appearance {
shadow_offset: Vector::default(), shadow_offset: Vector::default(),
background: Some(color.into()), background: color.map(Background::from).or(standard.background),
border_radius: cosmic.radius_xs().into(), border_radius: cosmic.radius_xs().into(),
border_width: 1.0, border_width: 1.0,
border_color: cosmic.on_bg_color().into(), border_color: cosmic.on_bg_color().into(),
@ -817,9 +845,11 @@ fn color_button<'a, Message: 'a>(
} else { } else {
(0.0, Color::TRANSPARENT) (0.0, Color::TRANSPARENT)
}; };
let standard = theme.pressed(focused, &Button::Standard);
button::Appearance { button::Appearance {
shadow_offset: Vector::default(), shadow_offset: Vector::default(),
background: Some(color.into()), background: color.map(Background::from).or(standard.background),
border_radius: cosmic.radius_xs().into(), border_radius: cosmic.radius_xs().into(),
border_width: 1.0, border_width: 1.0,
border_color: cosmic.on_bg_color().into(), border_color: cosmic.on_bg_color().into(),