mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 03:18:06 +08:00
Add responses in document for layer system (#91)
This commit is contained in:
committed by
Keavon Chambers
parent
b27eaf3fae
commit
f05cb30acb
@@ -1,6 +1,10 @@
|
||||
use crate::tools::ToolType;
|
||||
use crate::Color;
|
||||
use bitflags::bitflags;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use document_core::DocumentResponse;
|
||||
|
||||
use std::{
|
||||
fmt,
|
||||
ops::{Deref, DerefMut},
|
||||
@@ -25,12 +29,42 @@ pub enum Event {
|
||||
KeyDown(Key),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(C)]
|
||||
pub enum ToolResponse {
|
||||
SetActiveTool { tool_name: String },
|
||||
}
|
||||
|
||||
impl fmt::Display for ToolResponse {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
use ToolResponse::*;
|
||||
|
||||
let name = match_variant_name!(match (self) {
|
||||
SetActiveTool,
|
||||
});
|
||||
|
||||
formatter.write_str(name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(C)]
|
||||
// TODO - Make Copy when possible
|
||||
pub enum Response {
|
||||
UpdateCanvas { document: String },
|
||||
SetActiveTool { tool_name: String },
|
||||
Tool(ToolResponse),
|
||||
Document(DocumentResponse),
|
||||
}
|
||||
|
||||
impl From<ToolResponse> for Response {
|
||||
fn from(response: ToolResponse) -> Self {
|
||||
Response::Tool(response)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DocumentResponse> for Response {
|
||||
fn from(response: DocumentResponse) -> Self {
|
||||
Response::Document(response)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Response {
|
||||
@@ -38,11 +72,15 @@ impl fmt::Display for Response {
|
||||
use Response::*;
|
||||
|
||||
let name = match_variant_name!(match (self) {
|
||||
UpdateCanvas,
|
||||
SetActiveTool
|
||||
Tool,
|
||||
Document
|
||||
});
|
||||
let appendix = match self {
|
||||
Tool(t) => t.to_string(),
|
||||
Document(d) => d.to_string(),
|
||||
};
|
||||
|
||||
formatter.write_str(name)
|
||||
formatter.write_str(format!("{}::{}", name, appendix).as_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod events;
|
||||
use crate::{tools::ToolType, Color, Document, EditorError, EditorState};
|
||||
use document_core::Operation;
|
||||
use events::{Event, Key, Response};
|
||||
use events::{Event, Key, Response, ToolResponse};
|
||||
|
||||
pub type Callback = Box<dyn Fn(Response)>;
|
||||
pub struct Dispatcher {
|
||||
@@ -15,7 +15,7 @@ impl Dispatcher {
|
||||
match event {
|
||||
Event::SelectTool(tool_name) => {
|
||||
editor_state.tool_state.tool_data.active_tool_type = *tool_name;
|
||||
self.dispatch_response(Response::SetActiveTool { tool_name: tool_name.to_string() });
|
||||
self.dispatch_response(ToolResponse::SetActiveTool { tool_name: tool_name.to_string() });
|
||||
}
|
||||
Event::SelectPrimaryColor(color) => {
|
||||
editor_state.tool_state.document_tool_data.primary_color = *color;
|
||||
@@ -71,31 +71,31 @@ impl Dispatcher {
|
||||
}
|
||||
Key::KeyV => {
|
||||
editor_state.tool_state.tool_data.active_tool_type = ToolType::Select;
|
||||
self.dispatch_response(Response::SetActiveTool {
|
||||
self.dispatch_response(ToolResponse::SetActiveTool {
|
||||
tool_name: ToolType::Select.to_string(),
|
||||
});
|
||||
}
|
||||
Key::KeyL => {
|
||||
editor_state.tool_state.tool_data.active_tool_type = ToolType::Line;
|
||||
self.dispatch_response(Response::SetActiveTool {
|
||||
self.dispatch_response(ToolResponse::SetActiveTool {
|
||||
tool_name: ToolType::Line.to_string(),
|
||||
});
|
||||
}
|
||||
Key::KeyM => {
|
||||
editor_state.tool_state.tool_data.active_tool_type = ToolType::Rectangle;
|
||||
self.dispatch_response(Response::SetActiveTool {
|
||||
self.dispatch_response(ToolResponse::SetActiveTool {
|
||||
tool_name: ToolType::Rectangle.to_string(),
|
||||
});
|
||||
}
|
||||
Key::KeyY => {
|
||||
editor_state.tool_state.tool_data.active_tool_type = ToolType::Shape;
|
||||
self.dispatch_response(Response::SetActiveTool {
|
||||
self.dispatch_response(ToolResponse::SetActiveTool {
|
||||
tool_name: ToolType::Shape.to_string(),
|
||||
});
|
||||
}
|
||||
Key::KeyE => {
|
||||
editor_state.tool_state.tool_data.active_tool_type = ToolType::Ellipse;
|
||||
self.dispatch_response(Response::SetActiveTool {
|
||||
self.dispatch_response(ToolResponse::SetActiveTool {
|
||||
tool_name: ToolType::Ellipse.to_string(),
|
||||
});
|
||||
}
|
||||
@@ -128,19 +128,19 @@ impl Dispatcher {
|
||||
}
|
||||
|
||||
fn dispatch_operation(&self, document: &mut Document, operation: Operation) -> Result<(), EditorError> {
|
||||
document.handle_operation(operation, &|svg: String| self.dispatch_response(Response::UpdateCanvas { document: svg }))?;
|
||||
document.handle_operation(operation, &|responses| self.dispatch_responses(responses))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dispatch_responses<I: IntoIterator<Item = Response>>(&self, responses: I) {
|
||||
pub fn dispatch_responses<T: Into<Response>, I: IntoIterator<Item = T>>(&self, responses: I) {
|
||||
for response in responses {
|
||||
self.dispatch_response(response);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dispatch_response(&self, response: Response) {
|
||||
pub fn dispatch_response<T: Into<Response>>(&self, response: T) {
|
||||
let func = &self.callback;
|
||||
func(response)
|
||||
func(response.into())
|
||||
}
|
||||
|
||||
pub fn new(callback: Callback) -> Dispatcher {
|
||||
|
||||
@@ -16,6 +16,9 @@ pub use error::EditorError;
|
||||
#[doc(inline)]
|
||||
pub use document_core::color::Color;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use document_core::LayerId;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use dispatcher::events;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
@@ -9,7 +9,7 @@ use super::DocumentToolData;
|
||||
pub struct Crop;
|
||||
|
||||
impl Tool for Crop {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
todo!("{}::handle_input {:?} {:?} {:?}", module_path!(), event, document, tool_data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
@@ -14,7 +14,7 @@ pub struct Ellipse {
|
||||
}
|
||||
|
||||
impl Tool for Ellipse {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
@@ -42,7 +42,7 @@ struct EllipseToolData {
|
||||
impl Fsm for EllipseToolFsmState {
|
||||
type ToolData = EllipseToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<ToolResponse>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(EllipseToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
@@ -9,7 +9,7 @@ use super::DocumentToolData;
|
||||
pub struct Eyedropper;
|
||||
|
||||
impl Tool for Eyedropper {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
todo!("{}::handle_input {:?} {:?} {:?}", module_path!(), event, document, tool_data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
@@ -14,7 +14,7 @@ pub struct Line {
|
||||
}
|
||||
|
||||
impl Tool for Line {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
@@ -42,7 +42,7 @@ struct LineToolData {
|
||||
impl Fsm for LineToolFsmState {
|
||||
type ToolData = LineToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<ToolResponse>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(LineToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
|
||||
@@ -9,7 +9,7 @@ mod rectangle;
|
||||
mod select;
|
||||
mod shape;
|
||||
|
||||
use crate::events::{Event, ModKeys, MouseState, Response, Trace, TracePoint};
|
||||
use crate::events::{Event, ModKeys, MouseState, ToolResponse, Trace, TracePoint};
|
||||
use crate::Color;
|
||||
use crate::Document;
|
||||
use crate::EditorError;
|
||||
@@ -17,12 +17,12 @@ use document_core::Operation;
|
||||
use std::{collections::HashMap, fmt};
|
||||
|
||||
pub trait Tool {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>);
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>);
|
||||
}
|
||||
|
||||
pub trait Fsm {
|
||||
type ToolData;
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self;
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<ToolResponse>, operations: &mut Vec<Operation>) -> Self;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
@@ -9,7 +9,7 @@ use super::DocumentToolData;
|
||||
pub struct Navigate;
|
||||
|
||||
impl Tool for Navigate {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
todo!("{}::handle_input {:?} {:?} {:?}", module_path!(), event, document, tool_data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
@@ -9,7 +9,7 @@ use super::DocumentToolData;
|
||||
pub struct Path;
|
||||
|
||||
impl Tool for Path {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
todo!("{}::handle_input {:?} {:?} {:?}", module_path!(), event, document, tool_data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
@@ -15,7 +15,7 @@ pub struct Pen {
|
||||
}
|
||||
|
||||
impl Tool for Pen {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
@@ -43,7 +43,7 @@ struct PenToolData {
|
||||
impl Fsm for PenToolFsmState {
|
||||
type ToolData = PenToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<ToolResponse>, operations: &mut Vec<Operation>) -> Self {
|
||||
let stroke = style::Stroke::new(tool_data.primary_color, 5.);
|
||||
let fill = style::Fill::none();
|
||||
let style = style::PathStyle::new(Some(stroke), Some(fill));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
@@ -14,7 +14,7 @@ pub struct Rectangle {
|
||||
}
|
||||
|
||||
impl Tool for Rectangle {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
@@ -42,7 +42,7 @@ struct RectangleToolData {
|
||||
impl Fsm for RectangleToolFsmState {
|
||||
type ToolData = RectangleToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<ToolResponse>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(RectangleToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
@@ -12,7 +12,7 @@ pub struct Select {
|
||||
}
|
||||
|
||||
impl Tool for Select {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
@@ -40,7 +40,7 @@ struct SelectToolData;
|
||||
impl Fsm for SelectToolFsmState {
|
||||
type ToolData = SelectToolData;
|
||||
|
||||
fn transition(self, event: &Event, _document: &Document, _tool_data: &DocumentToolData, _data: &mut Self::ToolData, _responses: &mut Vec<Response>, _operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, _document: &Document, _tool_data: &DocumentToolData, _data: &mut Self::ToolData, _responses: &mut Vec<ToolResponse>, _operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(SelectToolFsmState::Ready, Event::LmbDown(_mouse_state)) => SelectToolFsmState::LmbDown,
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::events::{Event, Response};
|
||||
use crate::events::{Event, ToolResponse};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
@@ -14,7 +14,7 @@ pub struct Shape {
|
||||
}
|
||||
|
||||
impl Tool for Shape {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<ToolResponse>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
@@ -43,7 +43,7 @@ struct ShapeToolData {
|
||||
impl Fsm for ShapeToolFsmState {
|
||||
type ToolData = ShapeToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<ToolResponse>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(ShapeToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
|
||||
Reference in New Issue
Block a user