mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 10:58:04 +08:00
Add colors in Rust (#78)
* 🎨 Add colors in Rust * 🌿 Use an option for the properties and #[repr(C)] * ❌ Remove WASM dependency on document. * 😎 Wrap Fill and stroke in a style struct. * 📦 Use crate::Color * Merge Add transactions for temporary modifications to the document * Run cargo fmt * Color without a 'U'
This commit is contained in:
committed by
Keavon Chambers
parent
2849b99b59
commit
46c9ef02ca
@@ -1,58 +0,0 @@
|
||||
use crate::EditorError;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Color {
|
||||
red: f32,
|
||||
green: f32,
|
||||
blue: f32,
|
||||
alpha: f32,
|
||||
}
|
||||
|
||||
impl Color {
|
||||
pub const BLACK: Color = Color::from_unsafe(0., 0., 0.);
|
||||
pub const WHITE: Color = Color::from_unsafe(1., 1., 1.);
|
||||
pub const RED: Color = Color::from_unsafe(1., 0., 0.);
|
||||
pub const GREEN: Color = Color::from_unsafe(0., 1., 0.);
|
||||
pub const BLUE: Color = Color::from_unsafe(0., 0., 1.);
|
||||
|
||||
pub fn from_rgbaf32(red: f32, green: f32, blue: f32, alpha: f32) -> Result<Color, EditorError> {
|
||||
let color = Color { red, green, blue, alpha };
|
||||
if [red, green, blue, alpha].iter().any(|c| c.is_sign_negative() || !c.is_finite()) {
|
||||
Err(color)?
|
||||
}
|
||||
Ok(color)
|
||||
}
|
||||
|
||||
const fn from_unsafe(red: f32, green: f32, blue: f32) -> Color {
|
||||
Color { red, green, blue, alpha: 1. }
|
||||
}
|
||||
|
||||
pub fn from_rgb8(red: u8, green: u8, blue: u8) -> Color {
|
||||
Color::from_rgba8(red, green, blue, 255)
|
||||
}
|
||||
pub fn from_rgba8(red: u8, green: u8, blue: u8, alpha: u8) -> Color {
|
||||
let map = |int_color| int_color as f32 / 255.0;
|
||||
Color {
|
||||
red: map(red),
|
||||
green: map(green),
|
||||
blue: map(blue),
|
||||
alpha: map(alpha),
|
||||
}
|
||||
}
|
||||
pub fn r(&self) -> f32 {
|
||||
self.red
|
||||
}
|
||||
pub fn g(&self) -> f32 {
|
||||
self.green
|
||||
}
|
||||
pub fn b(&self) -> f32 {
|
||||
self.blue
|
||||
}
|
||||
pub fn a(&self) -> f32 {
|
||||
self.alpha
|
||||
}
|
||||
pub fn components(&self) -> (f32, f32, f32, f32) {
|
||||
(self.red, self.green, self.blue, self.alpha)
|
||||
}
|
||||
}
|
||||
@@ -14,30 +14,30 @@ impl Dispatcher {
|
||||
|
||||
match event {
|
||||
Event::SelectTool(tool_name) => {
|
||||
editor_state.tool_state.active_tool_type = *tool_name;
|
||||
editor_state.tool_state.tool_data.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;
|
||||
editor_state.tool_state.document_tool_data.primary_color = *color;
|
||||
}
|
||||
Event::SelectSecondaryColor(color) => {
|
||||
editor_state.tool_state.secondary_color = *color;
|
||||
editor_state.tool_state.document_tool_data.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;
|
||||
editor_state.tool_state.document_tool_data.primary_color = Color::BLACK;
|
||||
editor_state.tool_state.document_tool_data.secondary_color = Color::WHITE;
|
||||
}
|
||||
Event::MouseDown(mouse_state) => {
|
||||
editor_state.tool_state.mouse_state = *mouse_state;
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::MouseUp(mouse_state) => {
|
||||
editor_state.tool_state.mouse_state = *mouse_state;
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::MouseMove(pos) => {
|
||||
editor_state.tool_state.mouse_state.position = *pos;
|
||||
editor_state.tool_state.document_tool_data.mouse_state.position = *pos;
|
||||
}
|
||||
Event::KeyUp(key) => (),
|
||||
Event::KeyDown(key) => {
|
||||
@@ -58,31 +58,31 @@ impl Dispatcher {
|
||||
log::debug!("set log verbosity to trace");
|
||||
}
|
||||
Key::KeyV => {
|
||||
editor_state.tool_state.active_tool_type = ToolType::Select;
|
||||
editor_state.tool_state.tool_data.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;
|
||||
editor_state.tool_state.tool_data.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;
|
||||
editor_state.tool_state.tool_data.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;
|
||||
editor_state.tool_state.tool_data.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;
|
||||
editor_state.tool_state.tool_data.active_tool_type = ToolType::Ellipse;
|
||||
self.dispatch_response(Response::SetActiveTool {
|
||||
tool_name: ToolType::Ellipse.to_string(),
|
||||
});
|
||||
@@ -95,7 +95,11 @@ impl Dispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
let (responses, operations) = editor_state.tool_state.active_tool()?.handle_input(event, &editor_state.document);
|
||||
let (responses, operations) = editor_state
|
||||
.tool_state
|
||||
.tool_data
|
||||
.active_tool()?
|
||||
.handle_input(event, &editor_state.document, &editor_state.tool_state.document_tool_data);
|
||||
|
||||
self.dispatch_operations(&mut editor_state.document, operations);
|
||||
// TODO - Dispatch Responses
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod color;
|
||||
mod dispatcher;
|
||||
mod error;
|
||||
pub mod hint;
|
||||
@@ -12,7 +11,7 @@ pub mod workspace;
|
||||
pub use error::EditorError;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use color::Color;
|
||||
pub use document_core::color::Color;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use dispatcher::events;
|
||||
@@ -21,7 +20,7 @@ pub use dispatcher::events;
|
||||
pub use dispatcher::Callback;
|
||||
|
||||
use dispatcher::Dispatcher;
|
||||
use document_core::Document;
|
||||
use document_core::document::Document;
|
||||
use tools::ToolFsmState;
|
||||
use workspace::Workspace;
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Crop;
|
||||
|
||||
impl Tool for Crop {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Ellipse {
|
||||
fsm_state: EllipseToolFsmState,
|
||||
@@ -11,10 +14,10 @@ pub struct Ellipse {
|
||||
}
|
||||
|
||||
impl Tool for Ellipse {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, &mut self.data, &mut responses, &mut operations);
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
|
||||
(responses, operations)
|
||||
}
|
||||
@@ -39,7 +42,7 @@ struct EllipseToolData {
|
||||
impl Fsm for EllipseToolFsmState {
|
||||
type ToolData = EllipseToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, 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<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(EllipseToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
@@ -62,6 +65,7 @@ impl Fsm for EllipseToolFsmState {
|
||||
cx: data.drag_start.x as f64,
|
||||
cy: data.drag_start.y as f64,
|
||||
r: data.drag_start.distance(&mouse_state),
|
||||
style: style::PathStyle::new(None, Some(style::Fill::new(tool_data.primary_color))),
|
||||
});
|
||||
|
||||
EllipseToolFsmState::LmbDown
|
||||
@@ -78,6 +82,7 @@ impl Fsm for EllipseToolFsmState {
|
||||
cx: data.drag_start.x as f64,
|
||||
cy: data.drag_start.y as f64,
|
||||
r: data.drag_start.distance(&mouse_state.position),
|
||||
style: style::PathStyle::new(None, Some(style::Fill::new(tool_data.primary_color))),
|
||||
});
|
||||
operations.push(Operation::CommitTransaction);
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@ use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Line {
|
||||
fsm_state: LineToolFsmState,
|
||||
@@ -11,10 +14,10 @@ pub struct Line {
|
||||
}
|
||||
|
||||
impl Tool for Line {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, &mut self.data, &mut responses, &mut operations);
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
|
||||
(responses, operations)
|
||||
}
|
||||
@@ -39,7 +42,7 @@ struct LineToolData {
|
||||
impl Fsm for LineToolFsmState {
|
||||
type ToolData = LineToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, 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<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(LineToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
@@ -64,6 +67,7 @@ impl Fsm for LineToolFsmState {
|
||||
y0: start.y as f64,
|
||||
x1: end.x as f64,
|
||||
y1: end.y as f64,
|
||||
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, 5.)), None),
|
||||
});
|
||||
|
||||
LineToolFsmState::Ready
|
||||
|
||||
@@ -17,47 +17,64 @@ use document_core::Operation;
|
||||
use std::{collections::HashMap, fmt};
|
||||
|
||||
pub trait Tool {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>);
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>);
|
||||
}
|
||||
|
||||
pub trait Fsm {
|
||||
type ToolData;
|
||||
fn transition(self, event: &Event, document: &Document, 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<Response>, operations: &mut Vec<Operation>) -> Self;
|
||||
}
|
||||
|
||||
pub struct ToolFsmState {
|
||||
pub struct DocumentToolData {
|
||||
pub mouse_state: MouseState,
|
||||
pub mod_keys: ModKeys,
|
||||
pub trace: Trace,
|
||||
pub primary_color: Color,
|
||||
pub secondary_color: Color,
|
||||
}
|
||||
pub struct ToolData {
|
||||
pub active_tool_type: ToolType,
|
||||
pub tools: HashMap<ToolType, Box<dyn Tool>>,
|
||||
tool_settings: HashMap<ToolType, ToolSettings>,
|
||||
}
|
||||
|
||||
impl ToolData {
|
||||
pub fn active_tool(&mut self) -> Result<&mut Box<dyn Tool>, EditorError> {
|
||||
self.tools.get_mut(&self.active_tool_type).ok_or(EditorError::UnknownTool)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ToolFsmState {
|
||||
pub document_tool_data: DocumentToolData,
|
||||
pub tool_data: ToolData,
|
||||
pub trace: Trace,
|
||||
}
|
||||
|
||||
impl Default for ToolFsmState {
|
||||
fn default() -> Self {
|
||||
ToolFsmState {
|
||||
mouse_state: MouseState::default(),
|
||||
mod_keys: ModKeys::default(),
|
||||
trace: Trace::new(),
|
||||
primary_color: Color::BLACK,
|
||||
secondary_color: Color::WHITE,
|
||||
active_tool_type: ToolType::Select,
|
||||
tools: gen_tools_hash_map! {
|
||||
Select => select::Select,
|
||||
Crop => crop::Crop,
|
||||
Navigate => navigate::Navigate,
|
||||
Sample => sample::Sample,
|
||||
Path => path::Path,
|
||||
Pen => pen::Pen,
|
||||
Line => line::Line,
|
||||
Rectangle => rectangle::Rectangle,
|
||||
Ellipse => ellipse::Ellipse,
|
||||
Shape => shape::Shape,
|
||||
tool_data: ToolData {
|
||||
active_tool_type: ToolType::Select,
|
||||
tools: gen_tools_hash_map! {
|
||||
Select => select::Select,
|
||||
Crop => crop::Crop,
|
||||
Navigate => navigate::Navigate,
|
||||
Sample => sample::Sample,
|
||||
Path => path::Path,
|
||||
Pen => pen::Pen,
|
||||
Line => line::Line,
|
||||
Rectangle => rectangle::Rectangle,
|
||||
Ellipse => ellipse::Ellipse,
|
||||
Shape => shape::Shape,
|
||||
},
|
||||
tool_settings: default_tool_settings(),
|
||||
},
|
||||
document_tool_data: DocumentToolData {
|
||||
mouse_state: MouseState::default(),
|
||||
mod_keys: ModKeys::default(),
|
||||
primary_color: Color::BLACK,
|
||||
secondary_color: Color::WHITE,
|
||||
},
|
||||
tool_settings: default_tool_settings(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,17 +86,13 @@ impl ToolFsmState {
|
||||
|
||||
pub fn record_trace_point(&mut self) {
|
||||
self.trace.push(TracePoint {
|
||||
mouse_state: self.mouse_state,
|
||||
mod_keys: self.mod_keys,
|
||||
mouse_state: self.document_tool_data.mouse_state,
|
||||
mod_keys: self.document_tool_data.mod_keys,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn active_tool(&mut self) -> Result<&mut Box<dyn Tool>, EditorError> {
|
||||
self.tools.get_mut(&self.active_tool_type).ok_or(EditorError::UnknownTool)
|
||||
}
|
||||
|
||||
pub fn swap_colors(&mut self) {
|
||||
std::mem::swap(&mut self.primary_color, &mut self.secondary_color);
|
||||
std::mem::swap(&mut self.document_tool_data.primary_color, &mut self.document_tool_data.secondary_color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Navigate;
|
||||
|
||||
impl Tool for Navigate {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Path;
|
||||
|
||||
impl Tool for Path {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Pen;
|
||||
|
||||
impl Tool for Pen {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Rectangle {
|
||||
fsm_state: RectangleToolFsmState,
|
||||
@@ -11,10 +14,10 @@ pub struct Rectangle {
|
||||
}
|
||||
|
||||
impl Tool for Rectangle {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, &mut self.data, &mut responses, &mut operations);
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
|
||||
(responses, operations)
|
||||
}
|
||||
@@ -39,7 +42,7 @@ struct RectangleToolData {
|
||||
impl Fsm for RectangleToolFsmState {
|
||||
type ToolData = RectangleToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, 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<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(RectangleToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
@@ -65,6 +68,7 @@ impl Fsm for RectangleToolFsmState {
|
||||
y0: start.y as f64,
|
||||
x1: end.x as f64,
|
||||
y1: end.y as f64,
|
||||
style: style::PathStyle::new(None, Some(style::Fill::new(tool_data.primary_color))),
|
||||
});
|
||||
|
||||
RectangleToolFsmState::Ready
|
||||
|
||||
@@ -3,11 +3,13 @@ use crate::tools::Tool;
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Sample;
|
||||
|
||||
impl Tool for Sample {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Select {
|
||||
fsm_state: SelectToolFsmState,
|
||||
@@ -11,10 +13,10 @@ pub struct Select {
|
||||
}
|
||||
|
||||
impl Tool for Select {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, &mut self.data, &mut responses, &mut operations);
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
|
||||
(responses, operations)
|
||||
}
|
||||
@@ -39,7 +41,7 @@ struct SelectToolData;
|
||||
impl Fsm for SelectToolFsmState {
|
||||
type ToolData = SelectToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, 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<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(SelectToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => SelectToolFsmState::LmbDown,
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@ use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
use document_core::Operation;
|
||||
|
||||
use super::DocumentToolData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Shape {
|
||||
fsm_state: ShapeToolFsmState,
|
||||
@@ -11,10 +14,10 @@ pub struct Shape {
|
||||
}
|
||||
|
||||
impl Tool for Shape {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec<Response>, Vec<Operation>) {
|
||||
fn handle_input(&mut self, event: &Event, document: &Document, tool_data: &DocumentToolData) -> (Vec<Response>, Vec<Operation>) {
|
||||
let mut responses = Vec::new();
|
||||
let mut operations = Vec::new();
|
||||
self.fsm_state = self.fsm_state.transition(event, document, &mut self.data, &mut responses, &mut operations);
|
||||
self.fsm_state = self.fsm_state.transition(event, document, tool_data, &mut self.data, &mut responses, &mut operations);
|
||||
|
||||
(responses, operations)
|
||||
}
|
||||
@@ -40,7 +43,7 @@ struct ShapeToolData {
|
||||
impl Fsm for ShapeToolFsmState {
|
||||
type ToolData = ShapeToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, 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<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(ShapeToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
@@ -60,6 +63,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
|
||||
let start = data.drag_start;
|
||||
let end = mouse_state.position;
|
||||
// TODO: Set the sides value and use it for the operation.
|
||||
let sides = data.sides;
|
||||
operations.push(Operation::AddShape {
|
||||
path: vec![],
|
||||
@@ -69,6 +73,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
x1: end.x as f64,
|
||||
y1: end.y as f64,
|
||||
sides: 6,
|
||||
style: style::PathStyle::new(None, Some(style::Fill::new(tool_data.primary_color))),
|
||||
});
|
||||
|
||||
ShapeToolFsmState::Ready
|
||||
|
||||
Reference in New Issue
Block a user