mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-18 07:48:02 +08:00
Auto-generate enum type widget boilerplate for radio buttons and dropdown menus (#2589)
* First draft of factoring out the dropdown boilerplate * Add proc macro for enum boilerplate * Detect whether to say `crate` or the name * Clean up the input and naming of the enum macro * Rename a file * Do the rename of code too * Use the attribute-driven selection of radio vs dropdown * Add a metadata struct and tooltips * Move the new traits to a better place. * Use ChoiceType, part 1 * Use ChoiceType, part 2 * Introduce a builder API for choice widgets * Start using the new new API * DomainWarpType should be a dropdown still * Handle the case where a node property can never have a socket * Rustfmt * Code review * Update stable node IDs in test --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -3,7 +3,8 @@ use glam::DVec2;
|
||||
use kurbo::Point;
|
||||
|
||||
/// Represents different ways of calculating the centroid.
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type)]
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum CentroidType {
|
||||
/// The center of mass for the area of a solid shape's interior, as if made out of an infinitely flat material.
|
||||
#[default]
|
||||
@@ -12,41 +13,28 @@ pub enum CentroidType {
|
||||
Length,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type)]
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum BooleanOperation {
|
||||
#[default]
|
||||
#[icon("BooleanUnion")]
|
||||
Union,
|
||||
#[icon("BooleanSubtractFront")]
|
||||
SubtractFront,
|
||||
#[icon("BooleanSubtractBack")]
|
||||
SubtractBack,
|
||||
#[icon("BooleanIntersect")]
|
||||
Intersect,
|
||||
#[icon("BooleanDifference")]
|
||||
Difference,
|
||||
}
|
||||
|
||||
impl BooleanOperation {
|
||||
pub fn list() -> [BooleanOperation; 5] {
|
||||
[
|
||||
BooleanOperation::Union,
|
||||
BooleanOperation::SubtractFront,
|
||||
BooleanOperation::SubtractBack,
|
||||
BooleanOperation::Intersect,
|
||||
BooleanOperation::Difference,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn icons() -> [&'static str; 5] {
|
||||
["BooleanUnion", "BooleanSubtractFront", "BooleanSubtractBack", "BooleanIntersect", "BooleanDifference"]
|
||||
}
|
||||
pub trait AsU32 {
|
||||
fn as_u32(&self) -> u32;
|
||||
}
|
||||
|
||||
impl core::fmt::Display for BooleanOperation {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
BooleanOperation::Union => write!(f, "Union"),
|
||||
BooleanOperation::SubtractFront => write!(f, "Subtract Front"),
|
||||
BooleanOperation::SubtractBack => write!(f, "Subtract Back"),
|
||||
BooleanOperation::Intersect => write!(f, "Intersect"),
|
||||
BooleanOperation::Difference => write!(f, "Difference"),
|
||||
}
|
||||
impl AsU32 for u32 {
|
||||
fn as_u32(&self) -> u32 {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +76,8 @@ impl AsI64 for f64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type)]
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum GridType {
|
||||
#[default]
|
||||
Rectangular,
|
||||
@@ -96,7 +85,8 @@ pub enum GridType {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum ArcType {
|
||||
#[default]
|
||||
Open,
|
||||
|
||||
@@ -5,9 +5,10 @@ use crate::consts::{LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WEIGHT};
|
||||
use crate::renderer::format_transform_matrix;
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use std::fmt::{self, Display, Write};
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, serde::Serialize, serde::Deserialize, DynAny, specta::Type)]
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, serde::Serialize, serde::Deserialize, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum GradientType {
|
||||
#[default]
|
||||
Linear,
|
||||
@@ -462,7 +463,8 @@ impl From<Fill> for FillChoice {
|
||||
|
||||
/// Enum describing the type of [Fill].
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, serde::Serialize, serde::Deserialize, DynAny, Hash, specta::Type)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, serde::Serialize, serde::Deserialize, DynAny, Hash, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum FillType {
|
||||
#[default]
|
||||
Solid,
|
||||
@@ -471,7 +473,8 @@ pub enum FillType {
|
||||
|
||||
/// The stroke (outline) style of an SVG element.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum LineCap {
|
||||
#[default]
|
||||
Butt,
|
||||
@@ -479,18 +482,19 @@ pub enum LineCap {
|
||||
Square,
|
||||
}
|
||||
|
||||
impl Display for LineCap {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl LineCap {
|
||||
fn svg_name(&self) -> &'static str {
|
||||
match self {
|
||||
LineCap::Butt => write!(f, "butt"),
|
||||
LineCap::Round => write!(f, "round"),
|
||||
LineCap::Square => write!(f, "square"),
|
||||
LineCap::Butt => "butt",
|
||||
LineCap::Round => "round",
|
||||
LineCap::Square => "square",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, DynAny, specta::Type, node_macro::ChoiceType)]
|
||||
#[widget(Radio)]
|
||||
pub enum LineJoin {
|
||||
#[default]
|
||||
Miter,
|
||||
@@ -498,12 +502,12 @@ pub enum LineJoin {
|
||||
Round,
|
||||
}
|
||||
|
||||
impl Display for LineJoin {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl LineJoin {
|
||||
fn svg_name(&self) -> &'static str {
|
||||
match self {
|
||||
LineJoin::Bevel => write!(f, "bevel"),
|
||||
LineJoin::Miter => write!(f, "miter"),
|
||||
LineJoin::Round => write!(f, "round"),
|
||||
LineJoin::Bevel => "bevel",
|
||||
LineJoin::Miter => "miter",
|
||||
LineJoin::Round => "round",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -652,10 +656,10 @@ impl Stroke {
|
||||
let _ = write!(&mut attributes, r#" stroke-dashoffset="{}""#, dash_offset);
|
||||
}
|
||||
if let Some(line_cap) = line_cap {
|
||||
let _ = write!(&mut attributes, r#" stroke-linecap="{}""#, line_cap);
|
||||
let _ = write!(&mut attributes, r#" stroke-linecap="{}""#, line_cap.svg_name());
|
||||
}
|
||||
if let Some(line_join) = line_join {
|
||||
let _ = write!(&mut attributes, r#" stroke-linejoin="{}""#, line_join);
|
||||
let _ = write!(&mut attributes, r#" stroke-linejoin="{}""#, line_join.svg_name());
|
||||
}
|
||||
if let Some(line_join_miter_limit) = line_join_miter_limit {
|
||||
let _ = write!(&mut attributes, r#" stroke-miterlimit="{}""#, line_join_miter_limit);
|
||||
|
||||
Reference in New Issue
Block a user