Add responses in document for layer system (#91)

This commit is contained in:
TrueDoctor
2021-05-02 00:57:47 +02:00
committed by Keavon Chambers
parent b27eaf3fae
commit f05cb30acb
22 changed files with 219 additions and 64 deletions

View File

@@ -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())
}
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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)
}
}

View File

@@ -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;

View File

@@ -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)
}
}

View File

@@ -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;

View File

@@ -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)]

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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));

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;