Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1750,9 +1750,17 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
let is_stroke_node = reference.as_ref().is_some_and(|r| *r == DefinitionIdentifier::ProtoNode(graphene_std::vector::stroke::IDENTIFIER));
let is_fill_node = reference.as_ref().is_some_and(|r| *r == DefinitionIdentifier::ProtoNode(graphene_std::vector::fill::IDENTIFIER));
let is_shape_generator_node = reference.as_ref().is_some_and(|r| {
[regular_polygon::IDENTIFIER, star::IDENTIFIER, arc::IDENTIFIER, spiral::IDENTIFIER, grid::IDENTIFIER, arrow::IDENTIFIER]
.into_iter()
.any(|id| *r == DefinitionIdentifier::ProtoNode(id))
[
regular_polygon::IDENTIFIER,
star::IDENTIFIER,
arc::IDENTIFIER,
spiral::IDENTIFIER,
grid::IDENTIFIER,
arrow::IDENTIFIER,
teardrop::IDENTIFIER,
]
.into_iter()
.any(|id| *r == DefinitionIdentifier::ProtoNode(id))
});

let input = NodeInput::value(value, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::messages::tool::common_functionality::shapes::polygon_shape::PolygonG
use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler;
use crate::messages::tool::common_functionality::shapes::spiral_shape::SpiralGizmoHandler;
use crate::messages::tool::common_functionality::shapes::star_shape::StarGizmoHandler;
use crate::messages::tool::common_functionality::shapes::teardrop_shape::TeardropGizmoHandler;

use glam::DVec2;
use std::collections::VecDeque;

Expand All @@ -32,6 +34,7 @@ pub enum ShapeGizmoHandlers {
Circle(CircleGizmoHandler),
Grid(GridGizmoHandler),
Spiral(SpiralGizmoHandler),
Teardrop(TeardropGizmoHandler),
}

impl ShapeGizmoHandlers {
Expand All @@ -45,6 +48,7 @@ impl ShapeGizmoHandlers {
Self::Circle(_) => "circle",
Self::Grid(_) => "grid",
Self::Spiral(_) => "spiral",
Self::Teardrop(_) => "teardrop",
Self::None => "none",
}
}
Expand All @@ -58,6 +62,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.handle_state(layer, mouse_position, document, responses),
Self::Grid(h) => h.handle_state(layer, mouse_position, document, responses),
Self::Spiral(h) => h.handle_state(layer, mouse_position, document, responses),
Self::Teardrop(h) => h.handle_state(layer, mouse_position, document, responses),
Self::None => {}
}
}
Expand All @@ -71,6 +76,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.is_any_gizmo_hovered(),
Self::Grid(h) => h.is_any_gizmo_hovered(),
Self::Spiral(h) => h.is_any_gizmo_hovered(),
Self::Teardrop(h) => h.is_any_gizmo_hovered(),
Self::None => false,
}
}
Expand All @@ -84,6 +90,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.handle_click(),
Self::Grid(h) => h.handle_click(),
Self::Spiral(h) => h.handle_click(),
Self::Teardrop(h) => h.handle_click(),
Self::None => {}
}
}
Expand All @@ -97,6 +104,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.handle_update(drag_start, document, input, responses),
Self::Grid(h) => h.handle_update(drag_start, document, input, responses),
Self::Spiral(h) => h.handle_update(drag_start, document, input, responses),
Self::Teardrop(h) => h.handle_update(drag_start, document, input, responses),
Self::None => {}
}
}
Expand All @@ -110,6 +118,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.cleanup(),
Self::Grid(h) => h.cleanup(),
Self::Spiral(h) => h.cleanup(),
Self::Teardrop(h) => h.cleanup(),
Self::None => {}
}
}
Expand All @@ -131,6 +140,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::Grid(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::Spiral(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::Teardrop(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::None => {}
}
}
Expand All @@ -151,6 +161,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::Grid(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::Spiral(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::Teardrop(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::None => {}
}
}
Expand All @@ -163,6 +174,7 @@ impl ShapeGizmoHandlers {
Self::Circle(h) => h.mouse_cursor_icon(),
Self::Grid(h) => h.mouse_cursor_icon(),
Self::Spiral(h) => h.mouse_cursor_icon(),
Self::Teardrop(h) => h.mouse_cursor_icon(),
Self::None => None,
}
}
Expand Down Expand Up @@ -214,6 +226,10 @@ impl GizmoManager {
if graph_modification_utils::get_spiral_id(layer, &document.network_interface).is_some() {
return Some(ShapeGizmoHandlers::Spiral(SpiralGizmoHandler::default()));
}
// Teardrop
if graph_modification_utils::get_teardrop_id(layer, &document.network_interface).is_some() {
return Some(ShapeGizmoHandlers::Teardrop(TeardropGizmoHandler::default()));
}

None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ pub fn get_spiral_id(layer: LayerNodeIdentifier, network_interface: &NodeNetwork
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name(&DefinitionIdentifier::ProtoNode(graphene_std::vector_nodes::spiral::IDENTIFIER))
}

pub fn get_teardrop_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::teardrop::IDENTIFIER))
}

pub fn get_text_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name(&DefinitionIdentifier::ProtoNode(graphene_std::text::text::IDENTIFIER))
}
Expand Down
2 changes: 2 additions & 0 deletions editor/src/messages/tool/common_functionality/shapes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ pub mod rectangle_shape;
pub mod shape_utility;
pub mod spiral_shape;
pub mod star_shape;
pub mod teardrop_shape;

pub use super::shapes::arrow_shape::Arrow;
pub use super::shapes::ellipse_shape::Ellipse;
pub use super::shapes::line_shape::{Line, LineEnd};
pub use super::shapes::rectangle_shape::Rectangle;
pub use super::shapes::teardrop_shape::Teardrop;
pub use crate::messages::tool::tool_messages::shape_tool::ShapeToolData;
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum ShapeType {
Spiral,
Grid,
Arrow,
Teardrop,
Line, // KEEP THIS AT THE END
Rectangle, // KEEP THIS AT THE END
Ellipse, // KEEP THIS AT THE END
Expand Down Expand Up @@ -70,6 +71,7 @@ impl ShapeType {
Self::Spiral => "Spiral",
Self::Grid => "Grid",
Self::Arrow => "Arrow",
Self::Teardrop => "Teardrop",
Self::Line => "Line", // KEEP THIS AT THE END
Self::Rectangle => "Rectangle", // KEEP THIS AT THE END
Self::Ellipse => "Ellipse", // KEEP THIS AT THE END
Expand Down
158 changes: 158 additions & 0 deletions editor/src/messages/tool/common_functionality/shapes/teardrop_shape.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use super::shape_utility::{ShapeToolModifierKey, update_radius_sign};
use super::*;
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
use crate::messages::portfolio::document::node_graph::document_node_definitions::{DefinitionIdentifier, resolve_document_node_type};
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate};
use crate::messages::tool::common_functionality::gizmos::shape_gizmos::number_of_points_dial::{NumberOfPointsDial, NumberOfPointsDialState};
use crate::messages::tool::common_functionality::gizmos::shape_gizmos::point_radius_handle::{PointRadiusHandle, PointRadiusHandleState};
use crate::messages::tool::common_functionality::graph_modification_utils;
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler;
use crate::messages::tool::tool_messages::tool_prelude::*;
use glam::DAffine2;
use graph_craft::document::NodeInput;
use graph_craft::document::value::TaggedValue;
use std::collections::VecDeque;

#[derive(Clone, Debug, Default)]
pub struct TeardropGizmoHandler {
number_of_points_dial: NumberOfPointsDial,
point_radius_handle: PointRadiusHandle,
}

impl ShapeGizmoHandler for TeardropGizmoHandler {
fn is_any_gizmo_hovered(&self) -> bool {
self.number_of_points_dial.is_hovering() || self.point_radius_handle.hovered()
}

fn handle_state(&mut self, selected_teardrop_layer: LayerNodeIdentifier, mouse_position: DVec2, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
self.number_of_points_dial.handle_actions(selected_teardrop_layer, mouse_position, document, responses);
self.point_radius_handle.handle_actions(selected_teardrop_layer, document, mouse_position, responses);
}

fn handle_click(&mut self) {
if self.number_of_points_dial.is_hovering() {
self.number_of_points_dial.update_state(NumberOfPointsDialState::Dragging);
return;
}

if self.point_radius_handle.hovered() {
self.point_radius_handle.update_state(PointRadiusHandleState::Dragging);
}
}

fn handle_update(&mut self, drag_start: DVec2, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) {
if self.number_of_points_dial.is_dragging() {
self.number_of_points_dial.update_number_of_sides(document, input, responses, drag_start);
}

if self.point_radius_handle.is_dragging_or_snapped() {
self.point_radius_handle.update_inner_radius(document, input, responses, drag_start);
}
}

fn overlays(
&self,
document: &DocumentMessageHandler,
selected_teardrop_layer: Option<LayerNodeIdentifier>,
_input: &InputPreprocessorMessageHandler,
shape_editor: &mut &mut ShapeState,
mouse_position: DVec2,
overlay_context: &mut OverlayContext,
) {
self.number_of_points_dial.overlays(document, selected_teardrop_layer, shape_editor, mouse_position, overlay_context);
self.point_radius_handle.overlays(selected_teardrop_layer, document, overlay_context);
}

fn dragging_overlays(
&self,
document: &DocumentMessageHandler,
_input: &InputPreprocessorMessageHandler,
shape_editor: &mut &mut ShapeState,
mouse_position: DVec2,
overlay_context: &mut OverlayContext,
) {
if self.number_of_points_dial.is_dragging() {
self.number_of_points_dial.overlays(document, None, shape_editor, mouse_position, overlay_context);
}

if self.point_radius_handle.is_dragging_or_snapped() {
self.point_radius_handle.overlays(None, document, overlay_context);
}
}

fn cleanup(&mut self) {
self.number_of_points_dial.cleanup();
self.point_radius_handle.cleanup();
}

fn mouse_cursor_icon(&self) -> Option<MouseCursorIcon> {
if self.number_of_points_dial.is_dragging() || self.number_of_points_dial.is_hovering() {
return Some(MouseCursorIcon::EWResize);
}

if self.point_radius_handle.is_dragging_or_snapped() || self.point_radius_handle.hovered() {
return Some(MouseCursorIcon::Default);
}

None
}
}

#[derive(Default)]
pub struct Teardrop;

impl Teardrop {
pub fn create_node(_vertices: u32) -> NodeTemplate {
let identifier = DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::teardrop::IDENTIFIER);
let node_type = resolve_document_node_type(&identifier).expect("Teardrop node can't be found");
node_type.node_template_input_override([None, Some(NodeInput::value(TaggedValue::F64(50.), false)), Some(NodeInput::value(TaggedValue::F64(50.), false))])
}

pub fn update_shape(
document: &DocumentMessageHandler,
ipp: &InputPreprocessorMessageHandler,
viewport: &ViewportMessageHandler,
layer: LayerNodeIdentifier,
shape_tool_data: &mut ShapeToolData,
modifier: ShapeToolModifierKey,
responses: &mut VecDeque<Message>,
) {
let [center, lock_ratio, _] = modifier;

if let Some([start, end]) = shape_tool_data.data.calculate_points(document, ipp, viewport, center, lock_ratio) {
update_radius_sign(end, start, layer, document, responses);

let dimensions = (start - end).abs();
let radius = dimensions.x / 2.0;
let spike_radius = (dimensions.y - radius).max(0.0);

let Some(node_id) = graph_modification_utils::get_teardrop_id(layer, &document.network_interface) else {
return;
};

responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 1),
input: NodeInput::value(TaggedValue::F64(radius), false),
});

responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 2),
input: NodeInput::value(TaggedValue::F64(spike_radius), false),
});

let top = start.y.min(end.y);
let center_x = (start.x + end.x) / 2.0;
let center_y = top + spike_radius;

responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_translation(DVec2::new(center_x, center_y)),
transform_in: TransformIn::Viewport,
skip_rerender: false,
});
}
}
}
Loading