mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 07:28:11 +08:00
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:
committed by
Keavon Chambers
parent
57b8ee0e86
commit
363b9c7ffa
@@ -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;
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,5 +1,6 @@
|
||||
// already implemented
|
||||
pub mod ellipse;
|
||||
pub mod fill;
|
||||
pub mod line;
|
||||
pub mod pen;
|
||||
pub mod rectangle;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user