mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 07:08:12 +08:00
Refactor the TypeScript data flow for full type safety and auto-generation of Rust types (#3865)
* Migrate Specta to Tsify to auto-generate messages.ts, working except colors and widgets * Adopt the generated FillColor/Color/GradientStops * Fix widget typing * Separate WidgetGroup enum variants into wrapper structs * Small rename * Simplify widgets further * Clean up message type references * Switch type imports to the auto-generated file * Remove lowercase serde rename * Fix FillChoice deserialization * Fix small regression from #3837 * Improve type safety * Make WidgetSpan type-safe * More cleanup and type safety * More type safety * More type safety * Get the rest to type-check without errors; improve widget builder macro to have optional icons; improve Svelte 5 configs * Cargo fmt * Fix imports * Update outdated readme info * Fix lint command rename references * Fix typos * One more typos fix * Remove unnecessary dep: prefix from the edited Cargo.toml files * Remove excess parts from Cargo.toml * Fix compiling on desktop * Revert "Remove excess parts from Cargo.toml" This reverts commit 6b711117b3a5d5d8a3ee20f36a43bc74930b7c82. * Update dev docs with simpler, more accurate instructions
This commit is contained in:
@@ -4,7 +4,8 @@ use crate::messages::prelude::*;
|
||||
use graphene_std::Color;
|
||||
use graphene_std::vector::style::FillChoice;
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ToolColorType {
|
||||
Primary,
|
||||
Secondary,
|
||||
|
||||
@@ -150,7 +150,8 @@ impl PivotGizmo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PivotGizmoType {
|
||||
// Pivot
|
||||
#[default]
|
||||
@@ -161,7 +162,8 @@ pub enum PivotGizmoType {
|
||||
// TODO: Add "Individual"
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Default, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Default, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub struct PivotGizmoState {
|
||||
pub enabled: bool,
|
||||
pub gizmo_type: PivotGizmoType,
|
||||
|
||||
@@ -23,7 +23,8 @@ use kurbo::{BezPath, PathEl, Shape};
|
||||
use std::collections::VecDeque;
|
||||
use std::f64::consts::{PI, TAU};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ShapeType {
|
||||
#[default]
|
||||
Polygon = 0,
|
||||
|
||||
@@ -22,7 +22,8 @@ pub struct ArtboardTool {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Artboard)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ArtboardToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
|
||||
@@ -13,7 +13,8 @@ use graphene_std::raster::BlendMode;
|
||||
|
||||
const BRUSH_MAX_SIZE: f64 = 5000.;
|
||||
|
||||
#[derive(PartialEq, Copy, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Copy, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum DrawMode {
|
||||
Draw = 0,
|
||||
Erase,
|
||||
@@ -52,7 +53,8 @@ impl Default for BrushOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Brush)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum BrushToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -65,7 +67,8 @@ pub enum BrushToolMessage {
|
||||
UpdateOptions { options: BrushToolMessageOptionsUpdate },
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum BrushToolMessageOptionsUpdate {
|
||||
BlendMode(BlendMode),
|
||||
ChangeDiameter(f64),
|
||||
@@ -220,7 +223,7 @@ impl LayoutHolder for BrushTool {
|
||||
.widget_instance(),
|
||||
);
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ pub struct EyedropperTool {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Eyedropper)]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum EyedropperToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -46,9 +47,9 @@ impl LayoutHolder for EyedropperTool {
|
||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionMessageContext<'a>> for EyedropperTool {
|
||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, context: &mut ToolActionMessageContext<'a>) {
|
||||
if let ToolMessage::Eyedropper(EyedropperToolMessage::PreviewImage { data, width, height }) = message {
|
||||
let image = EyedropperPreviewImage { data, width, height };
|
||||
let image = EyedropperPreviewImage { data: data.into(), width, height };
|
||||
|
||||
update_cursor_preview_common(responses, Some(image), context.input, context.global_tool_data, self.data.color_choice.clone());
|
||||
update_cursor_preview_common(responses, Some(image), context.input, context.global_tool_data, self.data.color_choice);
|
||||
|
||||
if !self.data.preview {
|
||||
disable_cursor_preview(responses, &mut self.data);
|
||||
@@ -87,10 +88,18 @@ enum EyedropperToolFsmState {
|
||||
SamplingSecondary,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PrimarySecondary {
|
||||
#[default]
|
||||
Primary,
|
||||
Secondary,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct EyedropperToolData {
|
||||
preview: bool,
|
||||
color_choice: Option<String>,
|
||||
color_choice: Option<PrimarySecondary>,
|
||||
}
|
||||
|
||||
impl Fsm for EyedropperToolFsmState {
|
||||
@@ -127,7 +136,11 @@ impl Fsm for EyedropperToolFsmState {
|
||||
}
|
||||
// Sampling -> Ready
|
||||
(EyedropperToolFsmState::SamplingPrimary, EyedropperToolMessage::SamplePrimaryColorEnd) | (EyedropperToolFsmState::SamplingSecondary, EyedropperToolMessage::SampleSecondaryColorEnd) => {
|
||||
let set_color_choice = if self == EyedropperToolFsmState::SamplingPrimary { "Primary" } else { "Secondary" }.to_string();
|
||||
let set_color_choice = match self {
|
||||
EyedropperToolFsmState::SamplingPrimary => PrimarySecondary::Primary,
|
||||
EyedropperToolFsmState::SamplingSecondary => PrimarySecondary::Secondary,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
update_cursor_preview(responses, tool_data, input, global_tool_data, Some(set_color_choice));
|
||||
disable_cursor_preview(responses, tool_data);
|
||||
|
||||
@@ -185,7 +198,7 @@ fn update_cursor_preview(
|
||||
tool_data: &mut EyedropperToolData,
|
||||
_input: &InputPreprocessorMessageHandler,
|
||||
_global_tool_data: &DocumentToolData,
|
||||
set_color_choice: Option<String>,
|
||||
set_color_choice: Option<PrimarySecondary>,
|
||||
) {
|
||||
tool_data.preview = true;
|
||||
tool_data.color_choice = set_color_choice;
|
||||
@@ -198,7 +211,7 @@ fn update_cursor_preview(
|
||||
tool_data: &mut EyedropperToolData,
|
||||
input: &InputPreprocessorMessageHandler,
|
||||
global_tool_data: &DocumentToolData,
|
||||
set_color_choice: Option<String>,
|
||||
set_color_choice: Option<PrimarySecondary>,
|
||||
) {
|
||||
tool_data.preview = true;
|
||||
tool_data.color_choice = set_color_choice.clone();
|
||||
@@ -211,7 +224,7 @@ fn update_cursor_preview_common(
|
||||
image: Option<EyedropperPreviewImage>,
|
||||
input: &InputPreprocessorMessageHandler,
|
||||
global_tool_data: &DocumentToolData,
|
||||
set_color_choice: Option<String>,
|
||||
set_color_choice: Option<PrimarySecondary>,
|
||||
) {
|
||||
responses.add(FrontendMessage::UpdateEyedropperSamplingState {
|
||||
image,
|
||||
|
||||
@@ -9,7 +9,8 @@ pub struct FillTool {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Fill)]
|
||||
#[derive(PartialEq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum FillToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
|
||||
@@ -37,7 +37,8 @@ impl Default for FreehandOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Freehand)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum FreehandToolMessage {
|
||||
// Standard messages
|
||||
Overlays { context: OverlayContext },
|
||||
@@ -51,7 +52,8 @@ pub enum FreehandToolMessage {
|
||||
UpdateOptions { options: FreehandOptionsUpdate },
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum FreehandOptionsUpdate {
|
||||
FillColor(Option<Color>),
|
||||
FillColorType(ToolColorType),
|
||||
@@ -151,7 +153,7 @@ impl LayoutHolder for FreehandTool {
|
||||
widgets.push(Separator::new(SeparatorStyle::Unrelated).widget_instance());
|
||||
widgets.push(create_weight_widget(self.options.line_weight));
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ pub struct GradientOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Gradient)]
|
||||
#[derive(PartialEq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum GradientToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -46,7 +47,8 @@ pub enum GradientToolMessage {
|
||||
UpdateOptions { options: GradientOptionsUpdate },
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum GradientOptionsUpdate {
|
||||
Type(GradientType),
|
||||
ReverseStops,
|
||||
@@ -199,7 +201,7 @@ impl LayoutHolder for GradientTool {
|
||||
widgets.push(reverse_direction);
|
||||
}
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -770,8 +772,8 @@ impl Fsm for GradientToolFsmState {
|
||||
if stop_index < gradient.stops.position.len() {
|
||||
let color = gradient.stops.color[stop_index].to_gamma_srgb();
|
||||
let position = gradient.stops.position[stop_index];
|
||||
let DVec2 { x, y } = transform.transform_point2(gradient.start.lerp(gradient.end, position));
|
||||
responses.add(FrontendMessage::UpdateGradientStopColorPickerPosition { color, x, y });
|
||||
let position = transform.transform_point2(gradient.start.lerp(gradient.end, position)).into();
|
||||
responses.add(FrontendMessage::UpdateGradientStopColorPickerPosition { color, position });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,13 +826,10 @@ impl Fsm for GradientToolFsmState {
|
||||
let viewport_pos = selected_gradient
|
||||
.transform
|
||||
.transform_point2(selected_gradient.gradient.start.lerp(selected_gradient.gradient.end, stop_pos));
|
||||
let position = viewport_pos.into();
|
||||
let color = selected_gradient.gradient.stops.color[stop_index].to_gamma_srgb();
|
||||
tool_data.color_picker_editing_color_stop = Some(stop_index);
|
||||
responses.add(FrontendMessage::UpdateGradientStopColorPickerPosition {
|
||||
color,
|
||||
x: viewport_pos.x,
|
||||
y: viewport_pos.y,
|
||||
});
|
||||
responses.add(FrontendMessage::UpdateGradientStopColorPickerPosition { color, position });
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub struct NavigateTool {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Navigate)]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum NavigateToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
|
||||
@@ -50,7 +50,8 @@ pub struct PathToolOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Path)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PathToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -155,7 +156,8 @@ pub enum PathToolMessage {
|
||||
ToggleSegmentEditing,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PathOverlayMode {
|
||||
AllHandles = 0,
|
||||
#[default]
|
||||
@@ -178,7 +180,8 @@ impl Default for PathEditingMode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PathOptionsUpdate {
|
||||
OverlayModeType(PathOverlayMode),
|
||||
PointEditingMode { enabled: bool },
|
||||
@@ -326,7 +329,7 @@ impl LayoutHolder for PathTool {
|
||||
|
||||
// Works only if a single layer is selected and its type is Vector
|
||||
let path_node_button = TextButton::new("Make Path Editable")
|
||||
.icon(Some("NodeShape".into()))
|
||||
.icon("NodeShape")
|
||||
.tooltip_label("Make Path Editable")
|
||||
.tooltip_description(
|
||||
"Enables the Pen and Path tools to directly edit layer geometry resulting from nondestructive operations. This inserts a 'Path' node as the last operation of the selected layer.",
|
||||
@@ -349,32 +352,30 @@ impl LayoutHolder for PathTool {
|
||||
|
||||
let _pin_pivot = pin_pivot_widget(self.tool_data.pivot_gizmo.pin_active(), false, PivotToolSource::Path);
|
||||
|
||||
Layout(vec![LayoutGroup::Row {
|
||||
widgets: vec![
|
||||
x_location,
|
||||
related_seperator.clone(),
|
||||
y_location,
|
||||
unrelated_seperator.clone(),
|
||||
colinear_handle_checkbox,
|
||||
related_seperator.clone(),
|
||||
colinear_handles_label,
|
||||
unrelated_seperator.clone(),
|
||||
point_editing_mode,
|
||||
related_seperator.clone(),
|
||||
segment_editing_mode,
|
||||
unrelated_seperator.clone(),
|
||||
path_overlay_mode_widget,
|
||||
unrelated_seperator.clone(),
|
||||
path_node_button,
|
||||
// checkbox.clone(),
|
||||
// related_seperator.clone(),
|
||||
// dropdown.clone(),
|
||||
// unrelated_seperator,
|
||||
// pivot_reference,
|
||||
// related_seperator.clone(),
|
||||
// pin_pivot,
|
||||
],
|
||||
}])
|
||||
Layout(vec![LayoutGroup::row(vec![
|
||||
x_location,
|
||||
related_seperator.clone(),
|
||||
y_location,
|
||||
unrelated_seperator.clone(),
|
||||
colinear_handle_checkbox,
|
||||
related_seperator.clone(),
|
||||
colinear_handles_label,
|
||||
unrelated_seperator.clone(),
|
||||
point_editing_mode,
|
||||
related_seperator.clone(),
|
||||
segment_editing_mode,
|
||||
unrelated_seperator.clone(),
|
||||
path_overlay_mode_widget,
|
||||
unrelated_seperator.clone(),
|
||||
path_node_button,
|
||||
// checkbox.clone(),
|
||||
// related_seperator.clone(),
|
||||
// dropdown.clone(),
|
||||
// unrelated_seperator,
|
||||
// pivot_reference,
|
||||
// related_seperator.clone(),
|
||||
// pin_pivot,
|
||||
])])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ impl Default for PenOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Pen)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PenToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -107,13 +108,15 @@ enum PenToolFsmState {
|
||||
GRSHandle,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PenOverlayMode {
|
||||
AllHandles = 0,
|
||||
FrontierHandles = 1,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum PenOptionsUpdate {
|
||||
FillColor(Option<Color>),
|
||||
FillColorType(ToolColorType),
|
||||
@@ -238,7 +241,7 @@ impl LayoutHolder for PenTool {
|
||||
.widget_instance(),
|
||||
);
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ pub struct SelectOptions {
|
||||
nested_selection_behavior: NestedSelectionBehavior,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum SelectOptionsUpdate {
|
||||
NestedSelectionBehavior(NestedSelectionBehavior),
|
||||
PivotGizmoType(PivotGizmoType),
|
||||
@@ -50,7 +51,8 @@ pub enum SelectOptionsUpdate {
|
||||
TogglePivotPinned,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum NestedSelectionBehavior {
|
||||
#[default]
|
||||
Shallowest,
|
||||
@@ -66,7 +68,8 @@ impl fmt::Display for NestedSelectionBehavior {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct SelectToolPointerKeys {
|
||||
pub axis_align: Key,
|
||||
pub snap_angle: Key,
|
||||
@@ -75,7 +78,8 @@ pub struct SelectToolPointerKeys {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Select)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum SelectToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -265,7 +269,7 @@ impl LayoutHolder for SelectTool {
|
||||
widgets.push(Separator::new(SeparatorStyle::Unrelated).widget_instance());
|
||||
widgets.extend(self.boolean_widgets(self.tool_data.selected_layers_count));
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ impl Default for ShapeToolOptions {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ShapeOptionsUpdate {
|
||||
FillColor(Option<Color>),
|
||||
FillColorType(ToolColorType),
|
||||
@@ -88,7 +89,8 @@ pub enum ShapeOptionsUpdate {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Shape)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ShapeToolMessage {
|
||||
// Standard messages
|
||||
Overlays { context: OverlayContext },
|
||||
@@ -423,7 +425,7 @@ impl LayoutHolder for ShapeTool {
|
||||
widgets.push(Separator::new(SeparatorStyle::Unrelated).widget_instance());
|
||||
widgets.push(create_weight_widget(self.options.line_weight));
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ impl Default for SplineOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Spline)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum SplineToolMessage {
|
||||
// Standard messages
|
||||
Overlays { context: OverlayContext },
|
||||
@@ -65,7 +66,8 @@ enum SplineToolFsmState {
|
||||
MergingEndpoints,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum SplineOptionsUpdate {
|
||||
FillColor(Option<Color>),
|
||||
FillColorType(ToolColorType),
|
||||
@@ -158,7 +160,7 @@ impl LayoutHolder for SplineTool {
|
||||
widgets.push(Separator::new(SeparatorStyle::Unrelated).widget_instance());
|
||||
widgets.push(create_weight_widget(self.options.line_weight));
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ impl Default for TextOptions {
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Text)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum TextToolMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
@@ -75,7 +76,8 @@ pub enum TextToolMessage {
|
||||
RefreshEditingFontData,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum TextOptionsUpdate {
|
||||
FillColor(Option<Color>),
|
||||
FillColorType(ToolColorType),
|
||||
@@ -271,7 +273,7 @@ impl TextTool {
|
||||
},
|
||||
));
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +415,7 @@ impl TextToolData {
|
||||
line_height_ratio: editing_text.typesetting.line_height_ratio,
|
||||
font_size: editing_text.typesetting.font_size,
|
||||
color: editing_text.color.map_or("#000000".to_string(), |color| format!("#{}", color.to_rgba_hex_srgb())),
|
||||
font_data: font_cache.get(&editing_text.font).map(|(data, _)| data.clone()).unwrap_or_default(),
|
||||
font_data: font_cache.get(&editing_text.font).map(|(data, _)| data.clone()).unwrap_or_default().into(),
|
||||
transform: editing_text.transform.to_cols_array(),
|
||||
max_width: editing_text.typesetting.max_width,
|
||||
max_height: editing_text.typesetting.max_height,
|
||||
@@ -925,7 +927,7 @@ impl Fsm for TextToolFsmState {
|
||||
(TextToolFsmState::Editing, TextToolMessage::RefreshEditingFontData) => {
|
||||
let font = Font::new(tool_options.font.font_family.clone(), tool_options.font.font_style.clone());
|
||||
responses.add(FrontendMessage::DisplayEditableTextboxUpdateFontData {
|
||||
font_data: font_cache.get(&font).map(|(data, _)| data.clone()).unwrap_or_default(),
|
||||
font_data: font_cache.get(&font).map(|(data, _)| data.clone()).unwrap_or_default().into(),
|
||||
});
|
||||
|
||||
TextToolFsmState::Editing
|
||||
|
||||
@@ -128,23 +128,21 @@ pub struct DocumentToolData {
|
||||
impl DocumentToolData {
|
||||
pub fn update_working_colors(&self, responses: &mut VecDeque<Message>) {
|
||||
let layout = Layout(vec![
|
||||
LayoutGroup::Row {
|
||||
widgets: vec![WorkingColorsInput::new(self.primary_color.to_gamma_srgb(), self.secondary_color.to_gamma_srgb()).widget_instance()],
|
||||
},
|
||||
LayoutGroup::Row {
|
||||
widgets: vec![
|
||||
IconButton::new("SwapVertical", 16)
|
||||
.tooltip_label("Swap Working Colors")
|
||||
.tooltip_shortcut(action_shortcut!(ToolMessageDiscriminant::SwapColors))
|
||||
.on_update(|_| ToolMessage::SwapColors.into())
|
||||
.widget_instance(),
|
||||
IconButton::new("WorkingColors", 16)
|
||||
.tooltip_label("Reset Working Colors")
|
||||
.tooltip_shortcut(action_shortcut!(ToolMessageDiscriminant::ResetColors))
|
||||
.on_update(|_| ToolMessage::ResetColors.into())
|
||||
.widget_instance(),
|
||||
],
|
||||
},
|
||||
LayoutGroup::row(vec![
|
||||
WorkingColorsInput::new(self.primary_color.to_gamma_srgb(), self.secondary_color.to_gamma_srgb()).widget_instance(),
|
||||
]),
|
||||
LayoutGroup::row(vec![
|
||||
IconButton::new("SwapVertical", 16)
|
||||
.tooltip_label("Swap Working Colors")
|
||||
.tooltip_shortcut(action_shortcut!(ToolMessageDiscriminant::SwapColors))
|
||||
.on_update(|_| ToolMessage::SwapColors.into())
|
||||
.widget_instance(),
|
||||
IconButton::new("WorkingColors", 16)
|
||||
.tooltip_label("Reset Working Colors")
|
||||
.tooltip_shortcut(action_shortcut!(ToolMessageDiscriminant::ResetColors))
|
||||
.on_update(|_| ToolMessage::ResetColors.into())
|
||||
.widget_instance(),
|
||||
]),
|
||||
]);
|
||||
|
||||
responses.add(LayoutMessage::SendLayout {
|
||||
@@ -308,7 +306,7 @@ impl ToolData {
|
||||
.skip(1)
|
||||
.collect();
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets: tool_groups_layout }])
|
||||
Layout(vec![LayoutGroup::row(tool_groups_layout)])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +358,8 @@ impl ToolFsmState {
|
||||
}
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Default, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Default)]
|
||||
pub enum ToolType {
|
||||
// General tool group
|
||||
#[default]
|
||||
@@ -524,7 +523,8 @@ pub fn tool_type_to_activate_tool_message(tool_type: ToolType) -> ToolMessageDis
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct HintData(pub Vec<HintGroup>);
|
||||
|
||||
impl HintData {
|
||||
@@ -558,7 +558,7 @@ impl HintData {
|
||||
}
|
||||
}
|
||||
|
||||
Layout(vec![LayoutGroup::Row { widgets }])
|
||||
Layout(vec![LayoutGroup::row(widgets)])
|
||||
}
|
||||
|
||||
pub fn send_layout(&self, responses: &mut VecDeque<Message>) {
|
||||
@@ -576,10 +576,12 @@ impl HintData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct HintGroup(pub Vec<HintInfo>);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct HintInfo {
|
||||
/// A `KeysGroup` specifies all the keys pressed simultaneously to perform an action (like "Ctrl C" to copy).
|
||||
/// Usually at most one is given, but less commonly, multiple can be used to describe additional hotkeys not used simultaneously (like the four different arrow keys to nudge a layer).
|
||||
|
||||
Reference in New Issue
Block a user