Implement fill tool (#254)

* Implement fill tool

* Add fill tool shortcut

* Add getters and setters to styles

* Make fill tool act on the topmost layer clicked

* Refactor fill operation

* Refactor and unify selection tolerance

* Add mark_as_dirty function

* Fix getter names
This commit is contained in:
Henry Sloan
2021-07-14 03:49:12 -04:00
committed by Keavon Chambers
parent 57b8ee0e86
commit 363b9c7ffa
13 changed files with 96 additions and 5 deletions
+2
View File
@@ -10,3 +10,5 @@ pub const WHEEL_ZOOM_RATE: f64 = 1. / 600.;
pub const MOUSE_ZOOM_RATE: f64 = 1. / 400.;
pub const ROTATE_SNAP_INTERVAL: f64 = 15.;
pub const SELECTION_TOLERANCE: f64 = 5.0;
+3
View File
@@ -169,7 +169,10 @@ impl Default for Mapping {
entry! {action=PenMessage::Confirm, key_down=Rmb},
entry! {action=PenMessage::Confirm, key_down=KeyEscape},
entry! {action=PenMessage::Confirm, key_down=KeyEnter},
// Fill
entry! {action=FillMessage::MouseDown, key_down=Lmb},
// Tool Actions
entry! {action=ToolMessage::SelectTool(ToolType::Fill), key_down=KeyF},
entry! {action=ToolMessage::SelectTool(ToolType::Rectangle), key_down=KeyM},
entry! {action=ToolMessage::SelectTool(ToolType::Ellipse), key_down=KeyE},
entry! {action=ToolMessage::SelectTool(ToolType::Select), key_down=KeyV},
+1
View File
@@ -60,6 +60,7 @@ pub mod message_prelude {
pub use super::tool::tool_messages::*;
pub use super::tool::tools::crop::{CropMessage, CropMessageDiscriminant};
pub use super::tool::tools::eyedropper::{EyedropperMessage, EyedropperMessageDiscriminant};
pub use super::tool::tools::fill::{FillMessage, FillMessageDiscriminant};
pub use super::tool::tools::line::{LineMessage, LineMessageDiscriminant};
pub use super::tool::tools::navigate::{NavigateMessage, NavigateMessageDiscriminant};
pub use super::tool::tools::path::{PathMessage, PathMessageDiscriminant};
+1
View File
@@ -83,6 +83,7 @@ impl Default for ToolFsmState {
Line => line::Line,
Shape => shape::Shape,
Ellipse => ellipse::Ellipse,
Fill => fill::Fill,
},
},
document_tool_data: DocumentToolData {
@@ -17,6 +17,8 @@ pub enum ToolMessage {
SwapColors,
ResetColors,
#[child]
Fill(FillMessage),
#[child]
Rectangle(RectangleMessage),
#[child]
Ellipse(EllipseMessage),
@@ -89,6 +91,7 @@ impl MessageHandler<ToolMessage, (&SvgDocument, &InputPreprocessor)> for ToolMes
}
message => {
let tool_type = match message {
Fill(_) => ToolType::Fill,
Rectangle(_) => ToolType::Rectangle,
Ellipse(_) => ToolType::Ellipse,
Shape(_) => ToolType::Shape,
+43
View File
@@ -0,0 +1,43 @@
use crate::consts::SELECTION_TOLERANCE;
use crate::message_prelude::*;
use crate::tool::ToolActionHandlerData;
use document_core::Operation;
use glam::DVec2;
#[derive(Default)]
pub struct Fill;
#[impl_message(Message, ToolMessage, Fill)]
#[derive(PartialEq, Clone, Debug)]
pub enum FillMessage {
MouseDown,
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Fill {
fn process_action(&mut self, _action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
let mouse_pos = data.2.mouse.position;
let (x, y) = (mouse_pos.x as f64, mouse_pos.y as f64);
let (point_1, point_2) = (
DVec2::new(x - SELECTION_TOLERANCE, y - SELECTION_TOLERANCE),
DVec2::new(x + SELECTION_TOLERANCE, y + SELECTION_TOLERANCE),
);
let quad = [
DVec2::new(point_1.x, point_1.y),
DVec2::new(point_2.x, point_1.y),
DVec2::new(point_2.x, point_2.y),
DVec2::new(point_1.x, point_2.y),
];
if let Some(path) = data.0.intersects_quad_root(quad).last() {
responses.push_back(
Operation::FillLayer {
path: path.to_vec(),
color: data.1.primary_color,
}
.into(),
);
}
}
advertise_actions!(FillMessageDiscriminant; MouseDown);
}
+1
View File
@@ -1,5 +1,6 @@
// already implemented
pub mod ellipse;
pub mod fill;
pub mod line;
pub mod pen;
pub mod rectangle;
+2 -2
View File
@@ -1,13 +1,13 @@
use document_core::color::Color;
use document_core::layers::style;
use document_core::layers::style::Fill;
use document_core::layers::style::Stroke;
use document_core::layers::{style, SELECTION_TOLERANCE};
use document_core::Operation;
use glam::{DAffine2, DVec2};
use crate::input::{mouse::ViewportPosition, InputPreprocessor};
use crate::tool::{DocumentToolData, Fsm, ToolActionHandlerData};
use crate::{message_prelude::*, SvgDocument};
use crate::{consts::SELECTION_TOLERANCE, message_prelude::*, SvgDocument};
#[derive(Default)]
pub struct Select {