mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 17:38:12 +08:00
Welcome screen, refactor to allow zero documents, and add TS typing to widgets (#702)
* unfinished implementation * Add frontend for the empty panel screen * Add an icon for Folder based on NodeFolder * fixed messages causing peicees of ui not to render on new document * Standardize nextTick syntax * WIP generisization of component subscriptions (not compiling yet) * Fix crash when loading font and there is no active document * Only advertise tool actions with a document * Fix failure to create new document * Initalise the properties panel * Fix highlight tab, canvas jump, warns and layer tree * Fix tests * Possibly fix some things? * Move WorkingColors layout definition to backend * Standardize action macro formatting * Provide typing for widgets in TS/Vue and associated cleanup * Fix viewport positioning initialization * Fix menu bar init at startup not document creation * Fix no viewport bounds bug * Change !=0 to >0 * Simplify the init system Closes #656 Co-authored-by: Keavon Chambers <keavon@keavon.com> Co-authored-by: 0hypercube <0hypercube@gmail.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Keavon Chambers
0hypercube
parent
b4b667ded6
commit
a0c22d20b6
@@ -40,6 +40,7 @@ pub struct SignalToMessageMap {
|
||||
|
||||
pub trait ToolTransition {
|
||||
fn signal_to_message_map(&self) -> SignalToMessageMap;
|
||||
|
||||
fn activate(&self, responses: &mut VecDeque<Message>) {
|
||||
let mut subscribe_message = |broadcast_to_tool_mapping: Option<ToolMessage>, signal: BroadcastSignal| {
|
||||
if let Some(mapping) = broadcast_to_tool_mapping {
|
||||
@@ -78,6 +79,7 @@ pub trait ToolTransition {
|
||||
unsubscribe_message(signal_to_tool_map.selection_changed, BroadcastSignal::SelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToolMetadata {
|
||||
fn icon_name(&self) -> String;
|
||||
fn tooltip(&self) -> String;
|
||||
|
||||
@@ -75,10 +75,10 @@ pub enum ToolMessage {
|
||||
// Detail(DetailToolMessage),
|
||||
|
||||
// Messages
|
||||
#[remain::unsorted]
|
||||
ActivateTool {
|
||||
tool_type: ToolType,
|
||||
},
|
||||
DeactivateTools,
|
||||
InitTools,
|
||||
ResetColors,
|
||||
SelectPrimaryColor {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use super::tool::{message_to_tool_type, DocumentToolData, ToolFsmState};
|
||||
use super::tool::{message_to_tool_type, ToolFsmState};
|
||||
use crate::document::DocumentMessageHandler;
|
||||
use crate::input::InputPreprocessorMessageHandler;
|
||||
use crate::layout::layout_message::LayoutTarget;
|
||||
use crate::layout::widgets::PropertyHolder;
|
||||
use crate::layout::widgets::{IconButton, Layout, LayoutGroup, SwatchPairInput, Widget, WidgetCallback, WidgetHolder, WidgetLayout};
|
||||
use crate::message_prelude::*;
|
||||
use crate::viewport_tools::tool::DocumentToolData;
|
||||
|
||||
use graphene::color::Color;
|
||||
use graphene::layers::text_layer::FontCache;
|
||||
@@ -73,12 +75,16 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, &InputPreprocessorMes
|
||||
// Notify the frontend about the new active tool to be displayed
|
||||
tool_data.register_properties(responses, LayoutTarget::ToolShelf);
|
||||
}
|
||||
DeactivateTools => {
|
||||
let tool_data = &mut self.tool_state.tool_data;
|
||||
tool_data.tools.get(&tool_data.active_tool_type).unwrap().deactivate(responses);
|
||||
}
|
||||
InitTools => {
|
||||
let tool_data = &mut self.tool_state.tool_data;
|
||||
let document_data = &self.tool_state.document_tool_data;
|
||||
let active_tool = &tool_data.active_tool_type;
|
||||
|
||||
// subscribe tool to broadcast messages
|
||||
// Subscribe tool to broadcast messages
|
||||
tool_data.tools.get(active_tool).unwrap().activate(responses);
|
||||
|
||||
// Register initial properties
|
||||
@@ -87,6 +93,10 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, &InputPreprocessorMes
|
||||
// Notify the frontend about the initial active tool
|
||||
tool_data.register_properties(responses, LayoutTarget::ToolShelf);
|
||||
|
||||
// Notify the frontend about the initial working colors
|
||||
update_working_colors(document_data, responses);
|
||||
responses.push_back(FrontendMessage::TriggerRefreshBoundsOfViewports.into());
|
||||
|
||||
// Set initial hints and cursor
|
||||
tool_data
|
||||
.active_tool_mut()
|
||||
@@ -156,7 +166,12 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, &InputPreprocessorMes
|
||||
}
|
||||
|
||||
fn actions(&self) -> ActionList {
|
||||
let mut list = actions!(ToolMessageDiscriminant; SelectRandomPrimaryColor, ResetColors, SwapColors, ActivateTool);
|
||||
let mut list = actions!(ToolMessageDiscriminant;
|
||||
ActivateTool,
|
||||
SelectRandomPrimaryColor,
|
||||
ResetColors,
|
||||
SwapColors,
|
||||
);
|
||||
list.extend(self.tool_state.tool_data.active_tool().actions());
|
||||
|
||||
list
|
||||
@@ -164,10 +179,37 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, &InputPreprocessorMes
|
||||
}
|
||||
|
||||
fn update_working_colors(document_data: &DocumentToolData, responses: &mut VecDeque<Message>) {
|
||||
let layout = WidgetLayout::new(vec![
|
||||
LayoutGroup::Row {
|
||||
widgets: vec![WidgetHolder::new(Widget::SwatchPairInput(SwatchPairInput {
|
||||
primary: document_data.primary_color,
|
||||
secondary: document_data.secondary_color,
|
||||
}))],
|
||||
},
|
||||
LayoutGroup::Row {
|
||||
widgets: vec![
|
||||
WidgetHolder::new(Widget::IconButton(IconButton {
|
||||
size: 16,
|
||||
icon: "Swap".into(),
|
||||
tooltip: "Swap (Shift+X)".into(), // TODO: Customize this tooltip for the Mac version of the keyboard shortcut
|
||||
on_update: WidgetCallback::new(|_| ToolMessage::SwapColors.into()),
|
||||
..Default::default()
|
||||
})),
|
||||
WidgetHolder::new(Widget::IconButton(IconButton {
|
||||
size: 16,
|
||||
icon: "ResetColors".into(), // TODO: Customize this tooltip for the Mac version of the keyboard shortcut
|
||||
tooltip: "Reset (Ctrl+Shift+X)".into(),
|
||||
on_update: WidgetCallback::new(|_| ToolMessage::ResetColors.into()),
|
||||
..Default::default()
|
||||
})),
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
responses.push_back(
|
||||
FrontendMessage::UpdateWorkingColors {
|
||||
primary: document_data.primary_color,
|
||||
secondary: document_data.secondary_color,
|
||||
LayoutMessage::SendLayout {
|
||||
layout: Layout::WidgetLayout(layout),
|
||||
layout_target: LayoutTarget::WorkingColors,
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
@@ -73,7 +73,13 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for ArtboardTool
|
||||
}
|
||||
}
|
||||
|
||||
advertise_actions!(ArtboardToolMessageDiscriminant; PointerDown, PointerUp, PointerMove, DeleteSelected, Abort);
|
||||
advertise_actions!(ArtboardToolMessageDiscriminant;
|
||||
PointerDown,
|
||||
PointerUp,
|
||||
PointerMove,
|
||||
DeleteSelected,
|
||||
Abort,
|
||||
);
|
||||
}
|
||||
|
||||
impl PropertyHolder for ArtboardTool {}
|
||||
|
||||
@@ -75,8 +75,14 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for EllipseTool
|
||||
use EllipseToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(EllipseToolMessageDiscriminant; DragStart),
|
||||
Drawing => actions!(EllipseToolMessageDiscriminant; DragStop, Abort, Resize),
|
||||
Ready => actions!(EllipseToolMessageDiscriminant;
|
||||
DragStart,
|
||||
),
|
||||
Drawing => actions!(EllipseToolMessageDiscriminant;
|
||||
DragStop,
|
||||
Abort,
|
||||
Resize,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,10 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for EyedropperTo
|
||||
}
|
||||
}
|
||||
|
||||
advertise_actions!(EyedropperToolMessageDiscriminant; LeftMouseDown, RightMouseDown);
|
||||
advertise_actions!(EyedropperToolMessageDiscriminant;
|
||||
LeftMouseDown,
|
||||
RightMouseDown,
|
||||
);
|
||||
}
|
||||
|
||||
impl ToolTransition for EyedropperTool {
|
||||
|
||||
@@ -67,7 +67,10 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for FillTool {
|
||||
}
|
||||
}
|
||||
|
||||
advertise_actions!(FillToolMessageDiscriminant; LeftMouseDown, RightMouseDown);
|
||||
advertise_actions!(FillToolMessageDiscriminant;
|
||||
LeftMouseDown,
|
||||
RightMouseDown,
|
||||
);
|
||||
}
|
||||
|
||||
impl ToolTransition for FillTool {
|
||||
|
||||
@@ -115,8 +115,16 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for FreehandTool
|
||||
use FreehandToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(FreehandToolMessageDiscriminant; DragStart, DragStop, Abort),
|
||||
Drawing => actions!(FreehandToolMessageDiscriminant; DragStop, PointerMove, Abort),
|
||||
Ready => actions!(FreehandToolMessageDiscriminant;
|
||||
DragStart,
|
||||
DragStop,
|
||||
Abort,
|
||||
),
|
||||
Drawing => actions!(FreehandToolMessageDiscriminant;
|
||||
DragStop,
|
||||
PointerMove,
|
||||
Abort,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,12 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for GradientTool
|
||||
}
|
||||
}
|
||||
|
||||
advertise_actions!(GradientToolMessageDiscriminant; PointerDown, PointerUp, PointerMove, Abort);
|
||||
advertise_actions!(GradientToolMessageDiscriminant;
|
||||
PointerDown,
|
||||
PointerUp,
|
||||
PointerMove,
|
||||
Abort,
|
||||
);
|
||||
}
|
||||
|
||||
impl PropertyHolder for GradientTool {
|
||||
|
||||
@@ -116,8 +116,14 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for LineTool {
|
||||
use LineToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(LineToolMessageDiscriminant; DragStart),
|
||||
Drawing => actions!(LineToolMessageDiscriminant; DragStop, Redraw, Abort),
|
||||
Ready => actions!(LineToolMessageDiscriminant;
|
||||
DragStart,
|
||||
),
|
||||
Drawing => actions!(LineToolMessageDiscriminant;
|
||||
DragStop,
|
||||
Redraw,
|
||||
Abort,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,16 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for NavigateTool
|
||||
use NavigateToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(NavigateToolMessageDiscriminant; TranslateCanvasBegin, RotateCanvasBegin, ZoomCanvasBegin),
|
||||
_ => actions!(NavigateToolMessageDiscriminant; ClickZoom, PointerMove, TransformCanvasEnd),
|
||||
Ready => actions!(NavigateToolMessageDiscriminant;
|
||||
TranslateCanvasBegin,
|
||||
RotateCanvasBegin,
|
||||
ZoomCanvasBegin,
|
||||
),
|
||||
_ => actions!(NavigateToolMessageDiscriminant;
|
||||
ClickZoom,
|
||||
PointerMove,
|
||||
TransformCanvasEnd,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +85,15 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for PathTool {
|
||||
use PathToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(PathToolMessageDiscriminant; DragStart, Delete),
|
||||
Dragging => actions!(PathToolMessageDiscriminant; DragStop, PointerMove, Delete),
|
||||
Ready => actions!(PathToolMessageDiscriminant;
|
||||
DragStart,
|
||||
Delete,
|
||||
),
|
||||
Dragging => actions!(PathToolMessageDiscriminant;
|
||||
DragStop,
|
||||
PointerMove,
|
||||
Delete,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +131,20 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for PenTool {
|
||||
|
||||
fn actions(&self) -> ActionList {
|
||||
match self.fsm_state {
|
||||
PenToolFsmState::Ready => actions!(PenToolMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
|
||||
PenToolFsmState::DraggingHandle | PenToolFsmState::PlacingAnchor => actions!(PenToolMessageDiscriminant; DragStart, DragStop, PointerMove, Confirm, Abort),
|
||||
PenToolFsmState::Ready => actions!(PenToolMessageDiscriminant;
|
||||
Undo,
|
||||
DragStart,
|
||||
DragStop,
|
||||
Confirm,
|
||||
Abort,
|
||||
),
|
||||
PenToolFsmState::DraggingHandle | PenToolFsmState::PlacingAnchor => actions!(PenToolMessageDiscriminant;
|
||||
DragStart,
|
||||
DragStop,
|
||||
PointerMove,
|
||||
Confirm,
|
||||
Abort,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,14 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for RectangleToo
|
||||
use RectangleToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(RectangleToolMessageDiscriminant; DragStart),
|
||||
Drawing => actions!(RectangleToolMessageDiscriminant; DragStop, Abort, Resize),
|
||||
Ready => actions!(RectangleToolMessageDiscriminant;
|
||||
DragStart,
|
||||
),
|
||||
Drawing => actions!(RectangleToolMessageDiscriminant;
|
||||
DragStop,
|
||||
Abort,
|
||||
Resize,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,8 +161,9 @@ impl PropertyHolder for SelectTool {
|
||||
separator_type: SeparatorType::Related,
|
||||
})),
|
||||
WidgetHolder::new(Widget::PopoverButton(PopoverButton {
|
||||
title: "Align".into(),
|
||||
header: "Align".into(),
|
||||
text: "The contents of this popover menu are coming soon".into(),
|
||||
..Default::default()
|
||||
})),
|
||||
WidgetHolder::new(Widget::Separator(Separator {
|
||||
direction: SeparatorDirection::Horizontal,
|
||||
@@ -187,8 +188,9 @@ impl PropertyHolder for SelectTool {
|
||||
separator_type: SeparatorType::Related,
|
||||
})),
|
||||
WidgetHolder::new(Widget::PopoverButton(PopoverButton {
|
||||
title: "Flip".into(),
|
||||
header: "Flip".into(),
|
||||
text: "The contents of this popover menu are coming soon".into(),
|
||||
..Default::default()
|
||||
})),
|
||||
WidgetHolder::new(Widget::Separator(Separator {
|
||||
direction: SeparatorDirection::Horizontal,
|
||||
@@ -234,8 +236,9 @@ impl PropertyHolder for SelectTool {
|
||||
separator_type: SeparatorType::Related,
|
||||
})),
|
||||
WidgetHolder::new(Widget::PopoverButton(PopoverButton {
|
||||
title: "Boolean".into(),
|
||||
header: "Boolean".into(),
|
||||
text: "The contents of this popover menu are coming soon".into(),
|
||||
..Default::default()
|
||||
})),
|
||||
],
|
||||
}]))
|
||||
@@ -266,8 +269,18 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for SelectTool {
|
||||
use SelectToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(SelectToolMessageDiscriminant; DragStart, PointerMove, Abort, EditLayer),
|
||||
_ => actions!(SelectToolMessageDiscriminant; DragStop, PointerMove, Abort, EditLayer),
|
||||
Ready => actions!(SelectToolMessageDiscriminant;
|
||||
DragStart,
|
||||
PointerMove,
|
||||
Abort,
|
||||
EditLayer,
|
||||
),
|
||||
_ => actions!(SelectToolMessageDiscriminant;
|
||||
DragStop,
|
||||
PointerMove,
|
||||
Abort,
|
||||
EditLayer,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,8 +114,14 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for ShapeTool {
|
||||
use ShapeToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(ShapeToolMessageDiscriminant; DragStart),
|
||||
Drawing => actions!(ShapeToolMessageDiscriminant; DragStop, Abort, Resize),
|
||||
Ready => actions!(ShapeToolMessageDiscriminant;
|
||||
DragStart,
|
||||
),
|
||||
Drawing => actions!(ShapeToolMessageDiscriminant;
|
||||
DragStop,
|
||||
Abort,
|
||||
Resize,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,8 +119,19 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for SplineTool {
|
||||
use SplineToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(SplineToolMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
|
||||
Drawing => actions!(SplineToolMessageDiscriminant; DragStop, PointerMove, Confirm, Abort),
|
||||
Ready => actions!(SplineToolMessageDiscriminant;
|
||||
Undo,
|
||||
DragStart,
|
||||
DragStop,
|
||||
Confirm,
|
||||
Abort,
|
||||
),
|
||||
Drawing => actions!(SplineToolMessageDiscriminant;
|
||||
DragStop,
|
||||
PointerMove,
|
||||
Confirm,
|
||||
Abort,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ impl PropertyHolder for TextTool {
|
||||
})
|
||||
.into()
|
||||
}),
|
||||
..Default::default()
|
||||
})),
|
||||
WidgetHolder::new(Widget::Separator(Separator {
|
||||
direction: SeparatorDirection::Horizontal,
|
||||
@@ -112,6 +113,7 @@ impl PropertyHolder for TextTool {
|
||||
})
|
||||
.into()
|
||||
}),
|
||||
..Default::default()
|
||||
})),
|
||||
WidgetHolder::new(Widget::Separator(Separator {
|
||||
direction: SeparatorDirection::Horizontal,
|
||||
@@ -169,8 +171,14 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for TextTool {
|
||||
use TextToolFsmState::*;
|
||||
|
||||
match self.fsm_state {
|
||||
Ready => actions!(TextMessageDiscriminant; Interact),
|
||||
Editing => actions!(TextMessageDiscriminant; Interact, Abort, CommitText),
|
||||
Ready => actions!(TextMessageDiscriminant;
|
||||
Interact,
|
||||
),
|
||||
Editing => actions!(TextMessageDiscriminant;
|
||||
Interact,
|
||||
Abort,
|
||||
CommitText,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user