187 lines
5.7 KiB
Rust
187 lines
5.7 KiB
Rust
use super::tool_prelude::*;
|
|
use crate::messages::tool::common_functionality::resize::Resize;
|
|
|
|
#[derive(Default)]
|
|
pub struct ImaginateTool {
|
|
fsm_state: ImaginateToolFsmState,
|
|
tool_data: ImaginateToolData,
|
|
}
|
|
|
|
#[impl_message(Message, ToolMessage, Imaginate)]
|
|
#[derive(PartialEq, Eq, Clone, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
|
pub enum ImaginateToolMessage {
|
|
// Standard messages
|
|
Abort,
|
|
|
|
// Tool-specific messages
|
|
DragStart,
|
|
DragStop,
|
|
Resize { center: Key, lock_ratio: Key },
|
|
}
|
|
|
|
impl LayoutHolder for ImaginateTool {
|
|
fn layout(&self) -> Layout {
|
|
Layout::WidgetLayout(WidgetLayout::default())
|
|
}
|
|
}
|
|
|
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ImaginateTool {
|
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
|
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, true);
|
|
}
|
|
|
|
fn actions(&self) -> ActionList {
|
|
match self.fsm_state {
|
|
ImaginateToolFsmState::Ready => actions!(ImaginateToolMessageDiscriminant;
|
|
DragStart,
|
|
),
|
|
ImaginateToolFsmState::Drawing => actions!(ImaginateToolMessageDiscriminant;
|
|
DragStop,
|
|
Abort,
|
|
Resize,
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ToolMetadata for ImaginateTool {
|
|
fn icon_name(&self) -> String {
|
|
"RasterImaginateTool".into()
|
|
}
|
|
fn tooltip(&self) -> String {
|
|
"Imaginate Tool".into()
|
|
}
|
|
fn tool_type(&self) -> crate::messages::tool::utility_types::ToolType {
|
|
ToolType::Imaginate
|
|
}
|
|
}
|
|
|
|
impl ToolTransition for ImaginateTool {
|
|
fn event_to_message_map(&self) -> EventToMessageMap {
|
|
EventToMessageMap {
|
|
tool_abort: Some(ImaginateToolMessage::Abort.into()),
|
|
..Default::default()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
|
enum ImaginateToolFsmState {
|
|
#[default]
|
|
Ready,
|
|
Drawing,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default)]
|
|
struct ImaginateToolData {
|
|
data: Resize,
|
|
}
|
|
|
|
impl Fsm for ImaginateToolFsmState {
|
|
type ToolData = ImaginateToolData;
|
|
type ToolOptions = ();
|
|
|
|
fn transition(
|
|
self,
|
|
event: ToolMessage,
|
|
tool_data: &mut Self::ToolData,
|
|
ToolActionHandlerData { document, input, .. }: &mut ToolActionHandlerData,
|
|
_tool_options: &Self::ToolOptions,
|
|
responses: &mut VecDeque<Message>,
|
|
) -> Self {
|
|
let shape_data = &mut tool_data.data;
|
|
|
|
let ToolMessage::Imaginate(event) = event else {
|
|
return self;
|
|
};
|
|
match (self, event) {
|
|
(ImaginateToolFsmState::Ready, ImaginateToolMessage::DragStart) => {
|
|
shape_data.start(document, input);
|
|
// responses.add(DocumentMessage::AddTransaction);
|
|
//shape_data.layer = Some(LayerNodeIdentifier::new(NodeId(generate_uuid()), &document.network_interface));
|
|
responses.add(DocumentMessage::DeselectAllLayers);
|
|
|
|
// // Utility function to offset the position of each consecutive node
|
|
// let mut pos = 8;
|
|
// let mut next_pos = || {
|
|
// pos += 8;
|
|
// DocumentNodeMetadata::position((pos, 4))
|
|
// };
|
|
|
|
// // Get the node type for the Transform and Imaginate nodes
|
|
// let Some(transform_node_type) = resolve_document_node_type("Transform") else {
|
|
// warn!("Transform node should be in registry");
|
|
// return ImaginateToolFsmState::Drawing;
|
|
// };
|
|
// let imaginate_node_type = &*IMAGINATE_NODE;
|
|
|
|
// // Give them a unique ID
|
|
// let transform_node_id = NodeId(100);
|
|
//let imaginate_node_id = NodeId(101);
|
|
|
|
// Create the network based on the Input -> Output passthrough default network
|
|
// let mut network = new_image_network(16, imaginate_node_id);
|
|
|
|
// // Insert the nodes into the default network
|
|
// network.insert_node(
|
|
// transform_node_id,
|
|
// transform_node_type.to_document_node_default_inputs([Some(NodeInput::node(NodeId(0), 0))], next_pos()),
|
|
// );
|
|
// network.insert_node(
|
|
// imaginate_node_id,
|
|
// imaginate_node_type.to_document_node_default_inputs([Some(NodeInput::node(transform_node_id, 0))], next_pos()),
|
|
// );
|
|
// responses.add(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id });
|
|
|
|
// // Add a layer with a frame to the document
|
|
// responses.add(Operation::AddFrame {
|
|
// path: shape_data.layer.unwrap().to_path(),
|
|
// insert_index: -1,
|
|
// transform: DAffine2::ZERO.to_cols_array(),
|
|
// network,
|
|
// });
|
|
|
|
ImaginateToolFsmState::Drawing
|
|
}
|
|
(state, ImaginateToolMessage::Resize { center, lock_ratio }) => {
|
|
let message = shape_data.calculate_transform(document, input, center, lock_ratio, true);
|
|
responses.try_add(message);
|
|
|
|
state
|
|
}
|
|
(ImaginateToolFsmState::Drawing, ImaginateToolMessage::DragStop) => {
|
|
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
|
shape_data.cleanup(responses);
|
|
|
|
ImaginateToolFsmState::Ready
|
|
}
|
|
(ImaginateToolFsmState::Drawing, ImaginateToolMessage::Abort) => {
|
|
responses.add(DocumentMessage::AbortTransaction);
|
|
|
|
shape_data.cleanup(responses);
|
|
|
|
ImaginateToolFsmState::Ready
|
|
}
|
|
(_, ImaginateToolMessage::Abort) => ImaginateToolFsmState::Ready,
|
|
_ => self,
|
|
}
|
|
}
|
|
|
|
fn update_hints(&self, responses: &mut VecDeque<Message>) {
|
|
let hint_data = match self {
|
|
ImaginateToolFsmState::Ready => HintData(vec![HintGroup(vec![
|
|
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Repaint Frame"),
|
|
HintInfo::keys([Key::Shift], "Constrain Square").prepend_plus(),
|
|
HintInfo::keys([Key::Alt], "From Center").prepend_plus(),
|
|
])]),
|
|
ImaginateToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
|
};
|
|
|
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
|
}
|
|
|
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
|
}
|
|
}
|