Graphite/core/editor/src/dispatcher/mod.rs

135 lines
4.0 KiB
Rust

pub mod events;
use crate::{tools::ToolType, Color, Document, EditorError, EditorState};
use document_core::Operation;
use events::{Event, Key, Response};
pub type Callback = Box<dyn Fn(Response)>;
pub struct Dispatcher {
callback: Callback,
}
impl Dispatcher {
pub fn handle_event(&self, editor_state: &mut EditorState, event: &Event) -> Result<(), EditorError> {
log::trace!("{:?}", event);
match event {
Event::SelectTool(tool_name) => {
editor_state.tool_state.active_tool_type = *tool_name;
self.dispatch_response(Response::SetActiveTool { tool_name: tool_name.to_string() });
}
Event::SelectPrimaryColor(color) => {
editor_state.tool_state.primary_color = *color;
}
Event::SelectSecondaryColor(color) => {
editor_state.tool_state.secondary_color = *color;
}
Event::SwapColors => {
editor_state.tool_state.swap_colors();
}
Event::ResetColors => {
editor_state.tool_state.primary_color = Color::BLACK;
editor_state.tool_state.secondary_color = Color::WHITE;
}
Event::MouseDown(mouse_state) => {
editor_state.tool_state.mouse_state = *mouse_state;
}
Event::MouseUp(mouse_state) => {
editor_state.tool_state.mouse_state = *mouse_state;
}
Event::MouseMove(pos) => {
editor_state.tool_state.mouse_state.position = *pos;
}
Event::KeyUp(key) => (),
Event::KeyDown(key) => {
log::trace!("pressed key {:?}", key);
log::debug!("pressed key {:?}", key);
match key {
Key::Key0 => {
log::set_max_level(log::LevelFilter::Info);
log::debug!("set log verbosity to info");
}
Key::Key1 => {
log::set_max_level(log::LevelFilter::Debug);
log::debug!("set log verbosity to debug");
}
Key::Key2 => {
log::set_max_level(log::LevelFilter::Trace);
log::debug!("set log verbosity to trace");
}
Key::KeyV => {
editor_state.tool_state.active_tool_type = ToolType::Select;
self.dispatch_response(Response::SetActiveTool {
tool_name: ToolType::Select.to_string(),
});
}
Key::KeyL => {
editor_state.tool_state.active_tool_type = ToolType::Line;
self.dispatch_response(Response::SetActiveTool {
tool_name: ToolType::Line.to_string(),
});
}
Key::KeyM => {
editor_state.tool_state.active_tool_type = ToolType::Rectangle;
self.dispatch_response(Response::SetActiveTool {
tool_name: ToolType::Rectangle.to_string(),
});
}
Key::KeyY => {
editor_state.tool_state.active_tool_type = ToolType::Shape;
self.dispatch_response(Response::SetActiveTool {
tool_name: ToolType::Shape.to_string(),
});
}
Key::KeyE => {
editor_state.tool_state.active_tool_type = ToolType::Ellipse;
self.dispatch_response(Response::SetActiveTool {
tool_name: ToolType::Ellipse.to_string(),
});
}
Key::KeyX => {
editor_state.tool_state.swap_colors();
}
_ => (),
}
}
}
let (responses, operations) = editor_state.tool_state.active_tool()?.handle_input(event, &editor_state.document);
self.dispatch_operations(&mut editor_state.document, operations);
// TODO - Dispatch Responses
Ok(())
}
fn dispatch_operations<I: IntoIterator<Item = Operation>>(&self, document: &mut Document, operations: I) {
for operation in operations {
if let Err(error) = self.dispatch_operation(document, operation) {
log::error!("{}", error);
}
}
}
fn dispatch_operation(&self, document: &mut Document, operation: Operation) -> Result<(), EditorError> {
document.handle_operation(operation, &|svg: String| self.dispatch_response(Response::UpdateCanvas { document: svg }))?;
Ok(())
}
pub fn dispatch_responses<I: IntoIterator<Item = Response>>(&self, responses: I) {
for response in responses {
self.dispatch_response(response);
}
}
pub fn dispatch_response(&self, response: Response) {
let func = &self.callback;
// TODO - Remove clone if possible
func(response)
}
pub fn new(callback: Callback) -> Dispatcher {
Dispatcher { callback }
}
}