mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-12-23 10:11:54 +00:00
Add responses in document for layer system (#91)
This commit is contained in:
parent
b27eaf3fae
commit
f05cb30acb
22 changed files with 219 additions and 64 deletions
|
|
@ -328,10 +328,10 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
registerResponseHandler(ResponseType.UpdateCanvas, (responseData) => {
|
||||
registerResponseHandler(ResponseType["Document::UpdateCanvas"], (responseData) => {
|
||||
this.viewportSvg = responseData;
|
||||
});
|
||||
registerResponseHandler(ResponseType.SetActiveTool, (responseData) => {
|
||||
registerResponseHandler(ResponseType["Tool::SetActiveTool"], (responseData) => {
|
||||
this.activeTool = responseData;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,22 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import { ResponseType, registerResponseHandler } from "../../response-handler";
|
||||
|
||||
export default defineComponent({
|
||||
components: {},
|
||||
props: {},
|
||||
methods: {},
|
||||
mounted() {
|
||||
registerResponseHandler(ResponseType["Document::ExpandFolder"], (responseData) => {
|
||||
console.log("ExpandFolder: ", responseData);
|
||||
});
|
||||
registerResponseHandler(ResponseType["Document::CollapseFolder"], (responseData) => {
|
||||
console.log("CollapseFolder: ", responseData);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ declare global {
|
|||
}
|
||||
|
||||
export enum ResponseType {
|
||||
UpdateCanvas = "UpdateCanvas",
|
||||
SetActiveTool = "SetActiveTool",
|
||||
"Document::UpdateCanvas" = "Document::UpdateCanvas",
|
||||
"Document::ExpandFolder" = "Document::ExpandFolder",
|
||||
"Document::CollapseFolder" = "Document::CollapseFolder",
|
||||
"Tool::SetActiveTool" = "Tool::SetActiveTool",
|
||||
}
|
||||
|
||||
export function attachResponseHandlerToPage() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ pub mod utils;
|
|||
pub mod window;
|
||||
pub mod wrappers;
|
||||
|
||||
use editor_core::{events::Response, Editor};
|
||||
use editor_core::{
|
||||
events::{DocumentResponse, Response, ToolResponse},
|
||||
Editor, LayerId,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use utils::WasmLog;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
|
@ -20,17 +23,36 @@ pub fn init() {
|
|||
log::set_max_level(log::LevelFilter::Debug);
|
||||
}
|
||||
|
||||
fn path_to_string(path: Vec<LayerId>) -> String {
|
||||
path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join(",")
|
||||
}
|
||||
|
||||
fn handle_response(response: Response) {
|
||||
let response_type = response.to_string();
|
||||
match response {
|
||||
Response::UpdateCanvas { document } => handleResponse(response_type, document),
|
||||
Response::SetActiveTool { tool_name } => handleResponse(response_type, tool_name),
|
||||
Response::Document(doc) => match doc {
|
||||
DocumentResponse::UpdateCanvas { document } => send_response(response_type, &[document]),
|
||||
DocumentResponse::ExpandFolder { path, children } => {
|
||||
let children = children
|
||||
.iter()
|
||||
.map(|c| format!("name:{},visible:{},type:{}", c.name, c.visible, c.layer_type))
|
||||
.collect::<Vec<String>>()
|
||||
.join(";");
|
||||
send_response(response_type, &[path_to_string(path), children])
|
||||
}
|
||||
DocumentResponse::CollapseFolder { path } => send_response(response_type, &[path_to_string(path)]),
|
||||
},
|
||||
Response::Tool(ToolResponse::SetActiveTool { tool_name }) => send_response(response_type, &[tool_name]),
|
||||
}
|
||||
}
|
||||
fn send_response(response_type: String, response_data: &[String]) {
|
||||
let data = response_data.iter().map(JsValue::from).collect();
|
||||
handleResponse(response_type, data);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(module = "/../src/response-handler.ts")]
|
||||
extern "C" {
|
||||
fn handleResponse(responseType: String, responseData: String);
|
||||
fn handleResponse(responseType: String, responseData: Vec<JsValue>);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use layers::PolyLine;
|
|||
|
||||
use crate::{
|
||||
layers::{self, Folder, Layer, LayerData, LayerDataTypes, Line, Rect, Shape},
|
||||
DocumentError, LayerId, Operation,
|
||||
response::{LayerPanelEntry, LayerType},
|
||||
DocumentError, DocumentResponse, LayerId, Operation,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
|
@ -57,6 +58,11 @@ impl Document {
|
|||
out
|
||||
}
|
||||
|
||||
/// Wrapper around render, that returns the whole document as a Response
|
||||
pub fn render_root(&self) -> DocumentResponse {
|
||||
DocumentResponse::UpdateCanvas { document: self.render(&mut vec![]) }
|
||||
}
|
||||
|
||||
fn is_mounted(&self, mount_path: &[LayerId], path: &[LayerId]) -> bool {
|
||||
path.starts_with(mount_path) && self.work_mounted
|
||||
}
|
||||
|
|
@ -138,13 +144,28 @@ impl Document {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_operation<F: Fn(String)>(&mut self, operation: Operation, update_frontend: &F) -> Result<(), DocumentError> {
|
||||
pub fn layer_panel(&self, path: &[LayerId]) -> Result<Vec<LayerPanelEntry>, DocumentError> {
|
||||
let folder = self.document_folder(path)?;
|
||||
let l_type = |layer: &LayerDataTypes| match layer {
|
||||
LayerDataTypes::Folder(_) => LayerType::Folder,
|
||||
_ => LayerType::Shape,
|
||||
};
|
||||
let translate = |layer: &Layer| LayerPanelEntry {
|
||||
name: layer.name.clone().unwrap_or_else(|| String::from("UnnamedFolder")),
|
||||
visible: layer.visible,
|
||||
layer_type: l_type(&layer.data),
|
||||
};
|
||||
let entries = folder.layers().iter().map(|layer| translate(layer)).collect();
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
pub fn handle_operation<F: Fn(Vec<DocumentResponse>)>(&mut self, operation: Operation, send_response: &F) -> Result<(), DocumentError> {
|
||||
self.work_operations.push(operation.clone());
|
||||
match operation {
|
||||
Operation::AddCircle { path, insert_index, cx, cy, r, style } => {
|
||||
self.add_layer(&path, Layer::new(LayerDataTypes::Circle(layers::Circle::new(kurbo::Point::new(cx, cy), r, style))), insert_index)?;
|
||||
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
send_response(vec![self.render_root()]);
|
||||
}
|
||||
Operation::AddRect {
|
||||
path,
|
||||
|
|
@ -161,7 +182,7 @@ impl Document {
|
|||
insert_index,
|
||||
)?;
|
||||
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
send_response(vec![self.render_root()]);
|
||||
}
|
||||
Operation::AddLine {
|
||||
path,
|
||||
|
|
@ -178,13 +199,13 @@ impl Document {
|
|||
insert_index,
|
||||
)?;
|
||||
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
send_response(vec![self.render_root()]);
|
||||
}
|
||||
Operation::AddPen { path, insert_index, points, style } => {
|
||||
let points: Vec<kurbo::Point> = points.into_iter().map(|it| it.into()).collect();
|
||||
let polyline = PolyLine::new(points, style);
|
||||
self.add_layer(&path, Layer::new(LayerDataTypes::PolyLine(polyline)), insert_index)?;
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
send_response(vec![self.render_root()]);
|
||||
}
|
||||
Operation::AddShape {
|
||||
path,
|
||||
|
|
@ -199,12 +220,12 @@ impl Document {
|
|||
let s = Shape::new(kurbo::Point::new(x0, y0), kurbo::Vec2 { x: x0 - x1, y: y0 - y1 }, sides, style);
|
||||
self.add_layer(&path, Layer::new(LayerDataTypes::Shape(s)), insert_index)?;
|
||||
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
send_response(vec![self.render_root()]);
|
||||
}
|
||||
Operation::DeleteLayer { path } => {
|
||||
self.delete(&path)?;
|
||||
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
send_response(vec![self.render_root()]);
|
||||
}
|
||||
Operation::AddFolder { path } => self.set_layer(&path, Layer::new(LayerDataTypes::Folder(Folder::default())))?,
|
||||
Operation::MountWorkingFolder { path } => {
|
||||
|
|
@ -225,16 +246,19 @@ impl Document {
|
|||
}
|
||||
Operation::CommitTransaction => {
|
||||
let mut ops = Vec::new();
|
||||
let mut path: Vec<LayerId> = vec![];
|
||||
std::mem::swap(&mut path, &mut self.work_mount_path);
|
||||
std::mem::swap(&mut ops, &mut self.work_operations);
|
||||
let len = ops.len() - 1;
|
||||
self.work_mounted = false;
|
||||
self.work_mount_path = vec![];
|
||||
self.work = Folder::default();
|
||||
for operation in ops.into_iter().take(len) {
|
||||
self.handle_operation(operation, update_frontend)?
|
||||
self.handle_operation(operation, send_response)?
|
||||
}
|
||||
|
||||
update_frontend(self.render(&mut vec![]));
|
||||
let children = self.layer_panel(path.as_slice())?;
|
||||
send_response(vec![self.render_root(), DocumentResponse::ExpandFolder { path, children }]);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ impl Folder {
|
|||
self.layer_ids.as_slice()
|
||||
}
|
||||
|
||||
pub fn layers(&self) -> &[Layer] {
|
||||
self.layers.as_slice()
|
||||
}
|
||||
|
||||
pub fn layer(&self, id: LayerId) -> Option<&Layer> {
|
||||
let pos = self.layer_ids.iter().position(|x| *x == id)?;
|
||||
Some(&self.layers[pos])
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ pub mod color;
|
|||
pub mod document;
|
||||
pub mod layers;
|
||||
pub mod operation;
|
||||
pub mod response;
|
||||
mod shape_points;
|
||||
|
||||
pub use operation::Operation;
|
||||
pub use response::DocumentResponse;
|
||||
|
||||
type LayerId = u64;
|
||||
pub type LayerId = u64;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DocumentError {
|
||||
|
|
|
|||
47
core/document/src/response.rs
Normal file
47
core/document/src/response.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use crate::LayerId;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LayerPanelEntry {
|
||||
pub name: String,
|
||||
pub visible: bool,
|
||||
pub layer_type: LayerType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LayerType {
|
||||
Folder,
|
||||
Shape,
|
||||
}
|
||||
|
||||
impl fmt::Display for LayerType {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let name = match self {
|
||||
LayerType::Folder => "folder",
|
||||
LayerType::Shape => "shape",
|
||||
};
|
||||
|
||||
formatter.write_str(name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(C)]
|
||||
// TODO - Make Copy when possible
|
||||
pub enum DocumentResponse {
|
||||
UpdateCanvas { document: String },
|
||||
CollapseFolder { path: Vec<LayerId> },
|
||||
ExpandFolder { path: Vec<LayerId>, children: Vec<LayerPanelEntry> },
|
||||
}
|
||||
|
||||
impl fmt::Display for DocumentResponse {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let name = match self {
|
||||
DocumentResponse::UpdateCanvas { .. } => "UpdateCanvas",
|
||||
DocumentResponse::CollapseFolder { .. } => "CollapseFolder",
|
||||
DocumentResponse::ExpandFolder { .. } => "ExpandFolder",
|
||||
};
|
||||
|
||||
formatter.write_str(name)
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue