diff --git a/client/web/src/components/panels/Document.vue b/client/web/src/components/panels/Document.vue index 2c6972eae8..f85ce9b030 100644 --- a/client/web/src/components/panels/Document.vue +++ b/client/web/src/components/panels/Document.vue @@ -65,7 +65,7 @@ - + diff --git a/core/document/src/layers/style/mod.rs b/core/document/src/layers/style/mod.rs index c14c3965ea..ea4376a86a 100644 --- a/core/document/src/layers/style/mod.rs +++ b/core/document/src/layers/style/mod.rs @@ -19,6 +19,9 @@ impl Fill { pub fn new(color: Color) -> Self { Self { color: Some(color) } } + pub fn color(&self) -> Option { + self.color + } pub fn none() -> Self { Self { color: None } } @@ -41,6 +44,12 @@ impl Stroke { pub fn new(color: Color, width: f32) -> Self { Self { color, width } } + pub fn color(&self) -> Color { + self.color + } + pub fn width(&self) -> f32 { + self.width + } pub fn render(&self) -> String { format!(r##" stroke="#{}"{} stroke-width="{}""##, self.color.rgb_hex(), format_opacity("stroke", self.color.a()), self.width) } diff --git a/core/editor/src/input/input_mapper.rs b/core/editor/src/input/input_mapper.rs index 3acc83337c..79b2bd2819 100644 --- a/core/editor/src/input/input_mapper.rs +++ b/core/editor/src/input/input_mapper.rs @@ -122,6 +122,9 @@ impl Default for Mapping { entry! {action=SelectMessage::DragStop, key_up=Lmb}, entry! {action=SelectMessage::Abort, key_down=Rmb}, entry! {action=SelectMessage::Abort, key_down=KeyEscape}, + // Eyedropper + entry! {action=EyedropperMessage::LeftMouseDown, key_down=Lmb}, + entry! {action=EyedropperMessage::RightMouseDown, key_down=Rmb}, // Rectangle entry! {action=RectangleMessage::Center, key_down=KeyAlt}, entry! {action=RectangleMessage::UnCenter, key_up=KeyAlt}, @@ -181,6 +184,7 @@ impl Default for Mapping { entry! {action=ToolMessage::SelectTool(ToolType::Line), key_down=KeyL}, entry! {action=ToolMessage::SelectTool(ToolType::Pen), key_down=KeyP}, entry! {action=ToolMessage::SelectTool(ToolType::Shape), key_down=KeyY}, + entry! {action=ToolMessage::SelectTool(ToolType::Eyedropper), key_down=KeyI}, entry! {action=ToolMessage::ResetColors, key_down=KeyX, modifiers=[KeyShift, KeyControl]}, entry! {action=ToolMessage::SwapColors, key_down=KeyX, modifiers=[KeyShift]}, // Document Actions diff --git a/core/editor/src/tool/tools/eyedropper.rs b/core/editor/src/tool/tools/eyedropper.rs index 59dbaa53e8..0af41ec56c 100644 --- a/core/editor/src/tool/tools/eyedropper.rs +++ b/core/editor/src/tool/tools/eyedropper.rs @@ -1,5 +1,8 @@ +use crate::consts::SELECTION_TOLERANCE; +use crate::frontend::FrontendMessage; use crate::message_prelude::*; -use crate::tool::ToolActionHandlerData; +use crate::tool::{ToolActionHandlerData, ToolMessage}; +use glam::DVec2; #[derive(Default)] pub struct Eyedropper; @@ -7,12 +10,40 @@ pub struct Eyedropper; #[impl_message(Message, ToolMessage, Eyedropper)] #[derive(PartialEq, Clone, Debug)] pub enum EyedropperMessage { - MouseMove, + LeftMouseDown, + RightMouseDown, } impl<'a> MessageHandler> for Eyedropper { fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque) { - todo!("{}::handle_input {:?} {:?} {:?} ", module_path!(), action, data, responses); + 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.document.intersects_quad_root(quad).last() { + if let Ok(layer) = data.0.document.layer(path) { + if let Some(fill) = layer.style.fill() { + if let Some(color) = fill.color() { + let (primary, secondary) = match action { + ToolMessage::Eyedropper(EyedropperMessage::LeftMouseDown) => (color, data.1.secondary_color), + ToolMessage::Eyedropper(EyedropperMessage::RightMouseDown) => (data.1.primary_color, color), + _ => (data.1.primary_color, data.1.secondary_color), + }; + responses.push_back(FrontendMessage::UpdateWorkingColors { primary, secondary }.into()); + } + } + } + } } - advertise_actions!(); + advertise_actions!(EyedropperMessageDiscriminant; LeftMouseDown, RightMouseDown); }