fix: color picker
This commit is contained in:
parent
0dfaa4d158
commit
36b3cfa13a
1 changed files with 233 additions and 135 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
//! Widgets for selecting colors with a color picker.
|
//! Widgets for selecting colors with a color picker.
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::iter;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
@ -23,7 +24,7 @@ use iced_core::{
|
||||||
Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
|
Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use iced_widget::slider::{HandleShape, RailBackground};
|
use iced_widget::slider::HandleShape;
|
||||||
use iced_widget::{canvas, column, horizontal_space, row, 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};
|
||||||
|
|
@ -38,15 +39,14 @@ pub use ColorPickerModel as Model;
|
||||||
|
|
||||||
// TODO is this going to look correct enough?
|
// TODO is this going to look correct enough?
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref HSV_RAINBOW: Vec<ColorStop> = (0u16..8)
|
pub static ref HSV_RAINBOW: Vec<iced::Color> = (0u16..8)
|
||||||
.map(|h| ColorStop {
|
.map(
|
||||||
color: iced::Color::from(palette::Srgba::from_color(palette::Hsv::new_srgb_const(
|
|h| iced::Color::from(palette::Srgba::from_color(palette::Hsv::new_srgb_const(
|
||||||
RgbHue::new(f32::from(h) * 360.0 / 7.0),
|
RgbHue::new(f32::from(h) * 360.0 / 7.0),
|
||||||
1.0,
|
1.0,
|
||||||
1.0
|
1.0
|
||||||
))),
|
)))
|
||||||
offset: f32::from(h) / 7.0
|
)
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,7 +287,8 @@ where
|
||||||
) -> ColorPicker<'a, Message> {
|
) -> ColorPicker<'a, Message> {
|
||||||
let on_update = self.on_update;
|
let on_update = self.on_update;
|
||||||
let spacing = THEME.lock().unwrap().cosmic().spacing;
|
let spacing = THEME.lock().unwrap().cosmic().spacing;
|
||||||
let mut inner = column![
|
let mut inner =
|
||||||
|
column![
|
||||||
// segmented buttons
|
// segmented buttons
|
||||||
segmented_control::horizontal(self.model)
|
segmented_control::horizontal(self.model)
|
||||||
.on_activate(Box::new(move |e| on_update(
|
.on_activate(Box::new(move |e| on_update(
|
||||||
|
|
@ -309,18 +310,102 @@ where
|
||||||
on_update(ColorPickerUpdate::ActiveColor(new))
|
on_update(ColorPickerUpdate::ActiveColor(new))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.on_release(on_update(ColorPickerUpdate::ActionFinished))
|
||||||
.class(Slider::Custom {
|
.class(Slider::Custom {
|
||||||
active: Rc::new(|t| {
|
active: Rc::new(move |t| {
|
||||||
let cosmic = t.cosmic();
|
let cosmic = t.cosmic();
|
||||||
let mut a =
|
let mut a =
|
||||||
slider::Catalog::style(t, &Slider::default(), slider::Status::Active);
|
slider::Catalog::style(t, &Slider::default(), slider::Status::Active);
|
||||||
// a.rail.colors = RailBackground::Gradient {
|
|
||||||
// gradient: Linear::new(Radians(0.0)).add_stops(HSV_RAINBOW.clone()),
|
let hue = self.active_color.hue.into_positive_degrees();
|
||||||
// auto_angle: true,
|
let pivot = hue * 7.0 / 360.;
|
||||||
// };
|
|
||||||
|
let low_end = pivot.floor() as usize;
|
||||||
|
let high_start = pivot.ceil() as usize;
|
||||||
|
let pivot_color = palette::Hsv::new_srgb(RgbHue::new(hue), 1.0, 1.0);
|
||||||
|
let low_range = HSV_RAINBOW[0..=low_end]
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, color)| ColorStop {
|
||||||
|
color: *color,
|
||||||
|
offset: i as f32 / pivot.max(0.0001),
|
||||||
|
})
|
||||||
|
.chain(iter::once(ColorStop {
|
||||||
|
color: iced::Color::from(palette::Srgba::from_color(pivot_color)),
|
||||||
|
offset: 1.,
|
||||||
|
}))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let high_range =
|
||||||
|
iter::once(ColorStop {
|
||||||
|
color: iced::Color::from(palette::Srgba::from_color(pivot_color)),
|
||||||
|
offset: 0.,
|
||||||
|
})
|
||||||
|
.chain(HSV_RAINBOW[high_start..].iter().enumerate().map(
|
||||||
|
|(i, color)| ColorStop {
|
||||||
|
color: *color,
|
||||||
|
offset: (i as f32 + (1. - pivot.fract()))
|
||||||
|
/ (7. - pivot).max(0.0001),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
a.rail.backgrounds = (
|
a.rail.backgrounds = (
|
||||||
Background::Color(Color::TRANSPARENT),
|
Background::Gradient(iced::Gradient::Linear(
|
||||||
Background::Color(Color::TRANSPARENT),
|
Linear::new(Radians(90.0)).add_stops(low_range),
|
||||||
|
)),
|
||||||
|
Background::Gradient(iced::Gradient::Linear(
|
||||||
|
Linear::new(Radians(90.0)).add_stops(high_range),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
a.rail.width = 8.0;
|
||||||
|
a.handle.background = Color::TRANSPARENT.into();
|
||||||
|
a.handle.shape = HandleShape::Circle { radius: 8.0 };
|
||||||
|
a.handle.border_color = cosmic.palette.neutral_10.into();
|
||||||
|
a.handle.border_width = 4.0;
|
||||||
|
a
|
||||||
|
}),
|
||||||
|
hovered: Rc::new(move |t| {
|
||||||
|
let cosmic = t.cosmic();
|
||||||
|
let mut a =
|
||||||
|
slider::Catalog::style(t, &Slider::default(), slider::Status::Active);
|
||||||
|
let hue = self.active_color.hue.into_positive_degrees();
|
||||||
|
let pivot = hue * 7.0 / 360.;
|
||||||
|
|
||||||
|
let low_end = pivot.floor() as usize;
|
||||||
|
let high_start = pivot.ceil() as usize;
|
||||||
|
let pivot_color = palette::Hsv::new_srgb(RgbHue::new(hue), 1.0, 1.0);
|
||||||
|
let low_range = HSV_RAINBOW[0..=low_end]
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, color)| ColorStop {
|
||||||
|
color: *color,
|
||||||
|
offset: i as f32 / pivot.max(0.0001),
|
||||||
|
})
|
||||||
|
.chain(iter::once(ColorStop {
|
||||||
|
color: iced::Color::from(palette::Srgba::from_color(pivot_color)),
|
||||||
|
offset: 1.,
|
||||||
|
}))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let high_range =
|
||||||
|
iter::once(ColorStop {
|
||||||
|
color: iced::Color::from(palette::Srgba::from_color(pivot_color)),
|
||||||
|
offset: 0.,
|
||||||
|
})
|
||||||
|
.chain(HSV_RAINBOW[high_start..].iter().enumerate().map(
|
||||||
|
|(i, color)| ColorStop {
|
||||||
|
color: *color,
|
||||||
|
offset: (i as f32 + (1. - pivot.fract()))
|
||||||
|
/ (7. - pivot).max(0.0001),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
a.rail.backgrounds = (
|
||||||
|
Background::Gradient(iced::Gradient::Linear(
|
||||||
|
Linear::new(Radians(90.0)).add_stops(low_range),
|
||||||
|
)),
|
||||||
|
Background::Gradient(iced::Gradient::Linear(
|
||||||
|
Linear::new(Radians(90.0)).add_stops(high_range),
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
a.rail.width = 8.0;
|
a.rail.width = 8.0;
|
||||||
a.handle.background = Color::TRANSPARENT.into();
|
a.handle.background = Color::TRANSPARENT.into();
|
||||||
|
|
@ -329,38 +414,49 @@ where
|
||||||
a.handle.border_width = 4.0;
|
a.handle.border_width = 4.0;
|
||||||
a
|
a
|
||||||
}),
|
}),
|
||||||
hovered: Rc::new(|t| {
|
dragging: Rc::new(move |t| {
|
||||||
let cosmic = t.cosmic();
|
let cosmic = t.cosmic();
|
||||||
let mut a =
|
let mut a =
|
||||||
slider::Catalog::style(t, &Slider::default(), slider::Status::Active);
|
slider::Catalog::style(t, &Slider::default(), slider::Status::Active);
|
||||||
// a.rail.colors = RailBackground::Gradient {
|
let hue = self.active_color.hue.into_positive_degrees();
|
||||||
// gradient: Linear::new(Radians(0.0)).add_stops(HSV_RAINBOW.clone()),
|
let pivot = hue * 7.0 / 360.;
|
||||||
// auto_angle: true,
|
|
||||||
// };
|
let low_end = pivot.floor() as usize;
|
||||||
a.rail.backgrounds = (Color::TRANSPARENT.into(), Color::TRANSPARENT.into());
|
let high_start = pivot.ceil() as usize;
|
||||||
a.rail.width = 8.0;
|
let pivot_color = palette::Hsv::new_srgb(RgbHue::new(hue), 1.0, 1.0);
|
||||||
a.handle.background = Color::TRANSPARENT.into();
|
let low_range = HSV_RAINBOW[0..=low_end]
|
||||||
a.handle.shape = HandleShape::Circle { radius: 8.0 };
|
.iter()
|
||||||
a.handle.border_color = cosmic.palette.neutral_10.into();
|
.enumerate()
|
||||||
a.handle.border_width = 4.0;
|
.map(|(i, color)| ColorStop {
|
||||||
a
|
color: *color,
|
||||||
}),
|
offset: i as f32 / pivot.max(0.0001),
|
||||||
dragging: Rc::new(|t| {
|
})
|
||||||
let cosmic = t.cosmic();
|
.chain(iter::once(ColorStop {
|
||||||
let mut a =
|
color: iced::Color::from(palette::Srgba::from_color(pivot_color)),
|
||||||
slider::Catalog::style(t, &Slider::default(), slider::Status::Active);
|
offset: 1.,
|
||||||
// a.rail.backgrounds = (
|
}))
|
||||||
// RailBackground::Gradient(Gradient {
|
.collect::<Vec<_>>();
|
||||||
// gradient: Linear::new(Radians(0.0)).add_stops(HSV_RAINBOW.clone()),
|
let high_range =
|
||||||
// auto_angle: true,
|
iter::once(ColorStop {
|
||||||
// }),
|
color: iced::Color::from(palette::Srgba::from_color(pivot_color)),
|
||||||
// RailBackground::Gradient {
|
offset: 0.,
|
||||||
// gradient: Linear::new(Radians(0.0)).add_stops(HSV_RAINBOW.clone()),
|
})
|
||||||
// auto_angle: true,
|
.chain(HSV_RAINBOW[high_start..].iter().enumerate().map(
|
||||||
// },
|
|(i, color)| ColorStop {
|
||||||
// );
|
color: *color,
|
||||||
a.rail.backgrounds =
|
offset: (i as f32 + (1. - pivot.fract()))
|
||||||
(iced::Color::TRANSPARENT.into(), Color::TRANSPARENT.into());
|
/ (7. - pivot).max(0.0001),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
a.rail.backgrounds = (
|
||||||
|
Background::Gradient(iced::Gradient::Linear(
|
||||||
|
Linear::new(Radians(90.0)).add_stops(low_range),
|
||||||
|
)),
|
||||||
|
Background::Gradient(iced::Gradient::Linear(
|
||||||
|
Linear::new(Radians(90.0)).add_stops(high_range),
|
||||||
|
)),
|
||||||
|
);
|
||||||
a.rail.width = 8.0;
|
a.rail.width = 8.0;
|
||||||
a.handle.background = Color::TRANSPARENT.into();
|
a.handle.background = Color::TRANSPARENT.into();
|
||||||
a.handle.shape = HandleShape::Circle { radius: 8.0 };
|
a.handle.shape = HandleShape::Circle { radius: 8.0 };
|
||||||
|
|
@ -391,7 +487,9 @@ where
|
||||||
.class(Button::Text);
|
.class(Button::Text);
|
||||||
|
|
||||||
match self.copied_at.take() {
|
match self.copied_at.take() {
|
||||||
Some(t) if Instant::now().duration_since(t) > Duration::from_secs(2) => {
|
Some(t)
|
||||||
|
if Instant::now().duration_since(t) > Duration::from_secs(2) =>
|
||||||
|
{
|
||||||
button.into()
|
button.into()
|
||||||
}
|
}
|
||||||
Some(_) => tooltip(
|
Some(_) => tooltip(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue