mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 16:48:12 +08:00
Move gradient picking into the color picker (#1778)
* Gradient picker * Fix up color picker layout CSS problems * Begin hooking up SpectrumInput for gradient in the ColorPicker * Working gradient picking on the frontend only * Plumb FillColorChoice into the backend * Hook everything else up, just with a weird bug remaining * Fix some svelty reactivity issues * Add and remove stops * Cleanup * Rename type * Fill node document format upgrading * Fix lint * Polish the color picker UX and fix a bug --------- Co-authored-by: 0hypercube <0hypercube@gmail.com>
This commit is contained in:
co-authored by
0hypercube
parent
449729f1e1
commit
a9a4b5cd19
@@ -4,6 +4,7 @@ use crate::messages::prelude::*;
|
||||
|
||||
use graphene_core::raster::color::Color;
|
||||
use graphene_core::text::Font;
|
||||
use graphene_std::vector::style::{FillChoice, GradientStops};
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -83,24 +84,63 @@ impl LayoutMessageHandler {
|
||||
let callback_message = match action {
|
||||
WidgetValueAction::Commit => (color_button.on_commit.callback)(&()),
|
||||
WidgetValueAction::Update => {
|
||||
let update_value = value.as_object().expect("ColorButton update was not of type: object");
|
||||
let parsed_color = (|| {
|
||||
let is_none = update_value.get("none")?.as_bool()?;
|
||||
let decode_color = |color: &serde_json::map::Map<String, serde_json::value::Value>| -> Option<Color> {
|
||||
let red = color.get("red").and_then(|x| x.as_f64()).map(|x| x as f32);
|
||||
let green = color.get("green").and_then(|x| x.as_f64()).map(|x| x as f32);
|
||||
let blue = color.get("blue").and_then(|x| x.as_f64()).map(|x| x as f32);
|
||||
let alpha = color.get("alpha").and_then(|x| x.as_f64()).map(|x| x as f32);
|
||||
|
||||
if !is_none {
|
||||
Some(Some(Color::from_rgbaf32(
|
||||
update_value.get("red")?.as_f64()? as f32,
|
||||
update_value.get("green")?.as_f64()? as f32,
|
||||
update_value.get("blue")?.as_f64()? as f32,
|
||||
update_value.get("alpha")?.as_f64()? as f32,
|
||||
)?))
|
||||
} else {
|
||||
Some(None)
|
||||
if let (Some(red), Some(green), Some(blue), Some(alpha)) = (red, green, blue, alpha) {
|
||||
if let Some(color) = Color::from_rgbaf32(red, green, blue, alpha) {
|
||||
return Some(color);
|
||||
}
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
(|| {
|
||||
let update_value = value.as_object().expect("ColorButton update was not of type: object");
|
||||
|
||||
// None
|
||||
let is_none = update_value.get("none").and_then(|x| x.as_bool());
|
||||
if is_none == Some(true) {
|
||||
color_button.value = FillChoice::None;
|
||||
return (color_button.on_update.callback)(color_button);
|
||||
}
|
||||
|
||||
// Solid
|
||||
if let Some(color) = decode_color(update_value) {
|
||||
color_button.value = FillChoice::Solid(color);
|
||||
return (color_button.on_update.callback)(color_button);
|
||||
}
|
||||
|
||||
// Gradient
|
||||
let gradient = update_value.get("stops").and_then(|x| x.as_array());
|
||||
if let Some(stops) = gradient {
|
||||
let gradient_stops = stops
|
||||
.iter()
|
||||
.filter_map(|stop| {
|
||||
stop.as_object().and_then(|stop| {
|
||||
let position = stop.get("position").and_then(|x| x.as_f64());
|
||||
let color = stop.get("color").and_then(|x| x.as_object());
|
||||
|
||||
if let (Some(position), Some(color_object)) = (position, color) {
|
||||
if let Some(color) = decode_color(color_object) {
|
||||
return Some((position, color));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
color_button.value = FillChoice::Gradient(GradientStops(gradient_stops));
|
||||
return (color_button.on_update.callback)(color_button);
|
||||
}
|
||||
|
||||
panic!("ColorButton update was not able to be parsed with color data: {color_button:?}");
|
||||
})()
|
||||
.unwrap_or_else(|| panic!("ColorButton update was not able to be parsed with color data: {color_button:?}"));
|
||||
color_button.value = parsed_color;
|
||||
(color_button.on_update.callback)(color_button)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::portfolio::document::node_graph::utility_types::FrontendGraphDataType;
|
||||
|
||||
use graphene_core::raster::color::Color;
|
||||
use graphene_std::vector::style::FillChoice;
|
||||
use graphite_proc_macros::WidgetBuilder;
|
||||
|
||||
use derivative::*;
|
||||
@@ -124,7 +124,7 @@ pub struct TextButton {
|
||||
#[derivative(Debug, PartialEq, Default)]
|
||||
pub struct ColorButton {
|
||||
#[widget_builder(constructor)]
|
||||
pub value: Option<Color>,
|
||||
pub value: FillChoice,
|
||||
|
||||
pub disabled: bool,
|
||||
|
||||
@@ -137,7 +137,9 @@ pub struct ColorButton {
|
||||
#[derivative(Default(value = "true"))]
|
||||
pub allow_none: bool,
|
||||
|
||||
// TODO: Implement
|
||||
// pub disabled: bool,
|
||||
//
|
||||
pub tooltip: String,
|
||||
|
||||
#[serde(skip)]
|
||||
|
||||
Reference in New Issue
Block a user