mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-03 21:08:18 +00:00
Polish node graph frames and rename them for clarity (#1104)
* Polish layer panel UI and layer type icons/text * Assorted UI text and comment cleanup * Insert Transform node before Imaginate node via tool * Rename "Node Graph Frame" to Layer type and Frame tool * Rename "Node Graph Frame" to "Frame" tool * Update Node Graph Frame -> Frame tool icon * Fix lint warnings
This commit is contained in:
parent
d710285029
commit
0a9427fe6e
25 changed files with 104 additions and 98 deletions
|
@ -54,7 +54,6 @@ pub enum LayerDataTypeDiscriminant {
|
|||
Folder,
|
||||
Shape,
|
||||
Text,
|
||||
Image,
|
||||
NodeGraphFrame,
|
||||
}
|
||||
|
||||
|
@ -64,8 +63,7 @@ impl fmt::Display for LayerDataTypeDiscriminant {
|
|||
LayerDataTypeDiscriminant::Folder => write!(f, "Folder"),
|
||||
LayerDataTypeDiscriminant::Shape => write!(f, "Shape"),
|
||||
LayerDataTypeDiscriminant::Text => write!(f, "Text"),
|
||||
LayerDataTypeDiscriminant::Image => write!(f, "Image"),
|
||||
LayerDataTypeDiscriminant::NodeGraphFrame => write!(f, "Node Graph Frame"),
|
||||
LayerDataTypeDiscriminant::NodeGraphFrame => write!(f, "Layer"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1941,7 +1941,7 @@ impl DocumentMessageHandler {
|
|||
direction: SeparatorDirection::Horizontal,
|
||||
})),
|
||||
WidgetHolder::new(Widget::IconButton(IconButton {
|
||||
icon: "NodeFolder".into(),
|
||||
icon: "Folder".into(),
|
||||
tooltip: "New Folder".into(),
|
||||
tooltip_shortcut: action_keys!(DocumentMessageDiscriminant::CreateEmptyFolder),
|
||||
size: 24,
|
||||
|
|
|
@ -115,7 +115,7 @@ impl<'a> ModifyInputsContext<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
fn transform_change(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, bounds: LayerBounds) {
|
||||
fn transform_change(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2) {
|
||||
self.modify_inputs("Transform", |inputs| {
|
||||
let layer_transform = transform_utils::get_current_transform(inputs);
|
||||
let to = match transform_in {
|
||||
|
@ -123,7 +123,6 @@ impl<'a> ModifyInputsContext<'a> {
|
|||
TransformIn::Scope { scope } => scope * parent_transform,
|
||||
TransformIn::Viewport => parent_transform,
|
||||
};
|
||||
let pivot = DAffine2::from_translation(bounds.layerspace_pivot(transform_utils::get_current_normalized_pivot(inputs)));
|
||||
let transform = to.inverse() * transform * to * layer_transform;
|
||||
transform_utils::update_transform(inputs, transform);
|
||||
});
|
||||
|
@ -217,9 +216,8 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
|
|||
|
||||
GraphOperationMessage::TransformChange { layer, transform, transform_in } => {
|
||||
let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default();
|
||||
let bounds = LayerBounds::new(document, &layer);
|
||||
if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) {
|
||||
modify_inputs.transform_change(transform, transform_in, parent_transform, bounds);
|
||||
modify_inputs.transform_change(transform, transform_in, parent_transform);
|
||||
} else {
|
||||
let transform = transform.to_cols_array();
|
||||
responses.add(match transform_in {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
pub use self::document_node_types::*;
|
||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||
use crate::messages::layout::utility_types::layout_widget::{Layout, LayoutGroup, Widget, WidgetCallback, WidgetHolder, WidgetLayout};
|
||||
use crate::messages::layout::utility_types::widgets::button_widgets::{BreadcrumbTrailButtons, TextButton};
|
||||
use crate::messages::layout::utility_types::widgets::button_widgets::TextButton;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
use document_legacy::document::Document;
|
||||
use document_legacy::layers::layer_info::LayerDataTypeDiscriminant;
|
||||
use document_legacy::layers::nodegraph_layer::NodeGraphFrameLayer;
|
||||
use document_legacy::LayerId;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
|
@ -148,34 +147,34 @@ impl NodeGraphMessageHandler {
|
|||
}
|
||||
|
||||
/// Collect the addresses of the currently viewed nested node e.g. Root -> MyFunFilter -> Exposure
|
||||
fn collect_nested_addresses(&mut self, document: &Document, responses: &mut VecDeque<Message>) {
|
||||
// Build path list
|
||||
let mut path = vec!["Root".to_string()];
|
||||
let mut network = self.get_root_network(document);
|
||||
for node_id in &self.nested_path {
|
||||
let node = network.and_then(|network| network.nodes.get(node_id));
|
||||
if let Some(DocumentNode { name, .. }) = node {
|
||||
path.push(name.clone());
|
||||
}
|
||||
network = node.and_then(|node| node.implementation.get_network());
|
||||
}
|
||||
let nesting = path.len();
|
||||
fn collect_nested_addresses(&mut self, _document: &Document, _responses: &mut VecDeque<Message>) {
|
||||
// // Build path list
|
||||
// let mut path = vec!["Root".to_string()];
|
||||
// let mut network = self.get_root_network(document);
|
||||
// for node_id in &self.nested_path {
|
||||
// let node = network.and_then(|network| network.nodes.get(node_id));
|
||||
// if let Some(DocumentNode { name, .. }) = node {
|
||||
// path.push(name.clone());
|
||||
// }
|
||||
// network = node.and_then(|node| node.implementation.get_network());
|
||||
// }
|
||||
// let nesting = path.len();
|
||||
|
||||
// Update UI
|
||||
self.widgets[0] = LayoutGroup::Row {
|
||||
widgets: vec![WidgetHolder::new(Widget::BreadcrumbTrailButtons(BreadcrumbTrailButtons {
|
||||
labels: path.clone(),
|
||||
on_update: WidgetCallback::new(move |input: &u64| {
|
||||
NodeGraphMessage::ExitNestedNetwork {
|
||||
depth_of_nesting: nesting - (*input as usize) - 1,
|
||||
}
|
||||
.into()
|
||||
}),
|
||||
..Default::default()
|
||||
}))],
|
||||
};
|
||||
// // Update UI
|
||||
// self.widgets[0] = LayoutGroup::Row {
|
||||
// widgets: vec![WidgetHolder::new(Widget::BreadcrumbTrailButtons(BreadcrumbTrailButtons {
|
||||
// labels: path.clone(),
|
||||
// on_update: WidgetCallback::new(move |input: &u64| {
|
||||
// NodeGraphMessage::ExitNestedNetwork {
|
||||
// depth_of_nesting: nesting - (*input as usize) - 1,
|
||||
// }
|
||||
// .into()
|
||||
// }),
|
||||
// ..Default::default()
|
||||
// }))],
|
||||
// };
|
||||
|
||||
self.send_node_bar_layout(responses);
|
||||
// self.send_node_bar_layout(responses);
|
||||
}
|
||||
|
||||
/// Updates the buttons for disable and preview
|
||||
|
@ -405,7 +404,7 @@ impl NodeGraphMessageHandler {
|
|||
|
||||
impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &[LayerId]>)> for NodeGraphMessageHandler {
|
||||
#[remain::check]
|
||||
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, (document, selected): (&mut Document, &mut dyn Iterator<Item = &[LayerId]>)) {
|
||||
fn process_message(&mut self, message: NodeGraphMessage, responses: &mut VecDeque<Message>, (document, _selected): (&mut Document, &mut dyn Iterator<Item = &[LayerId]>)) {
|
||||
#[remain::sorted]
|
||||
match message {
|
||||
NodeGraphMessage::CloseNodeGraph => {
|
||||
|
|
|
@ -141,7 +141,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||
properties: |_document_node, _node_id, _context| node_properties::string_properties("Downscale the image to a lower resolution"),
|
||||
},
|
||||
// DocumentNodeType {
|
||||
// name: "Input",
|
||||
// name: "Input Frame",
|
||||
// category: "Ignore",
|
||||
// identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
|
||||
// inputs: vec![DocumentInputType {
|
||||
|
@ -153,7 +153,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||
// properties: node_properties::input_properties,
|
||||
// },
|
||||
DocumentNodeType {
|
||||
name: "Input",
|
||||
name: "Input Frame",
|
||||
category: "Ignore",
|
||||
identifier: NodeImplementation::DocumentNode(NodeNetwork {
|
||||
inputs: vec![0, 1],
|
||||
|
@ -260,8 +260,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||
name: "Frame",
|
||||
data_type: FrontendGraphDataType::Raster,
|
||||
}],
|
||||
|
||||
properties: |_document_node, _node_id, _context| node_properties::string_properties("The graph's output is rendered into the frame"),
|
||||
properties: |_document_node, _node_id, _context| node_properties::string_properties("The graph's output is drawn in the layer"),
|
||||
},
|
||||
DocumentNodeType {
|
||||
name: "Output",
|
||||
|
@ -273,7 +272,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||
default: NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
}],
|
||||
outputs: vec![],
|
||||
properties: |_document_node, _node_id, _context| node_properties::string_properties("The graph's output is rendered into the frame"),
|
||||
properties: |_document_node, _node_id, _context| node_properties::string_properties("The graph's output is drawn in the layer"),
|
||||
},
|
||||
DocumentNodeType {
|
||||
name: "Image Frame",
|
||||
|
@ -865,8 +864,8 @@ pub fn new_image_network(output_offset: i32, output_node_id: NodeId) -> NodeNetw
|
|||
inputs: vec![0],
|
||||
outputs: vec![NodeOutput::new(1, 0)],
|
||||
nodes: [
|
||||
resolve_document_node_type("Input")
|
||||
.expect("Input node does not exist")
|
||||
resolve_document_node_type("Input Frame")
|
||||
.expect("Input Frame node does not exist")
|
||||
.to_document_node_default_inputs([], DocumentNodeMetadata::position((8, 4))),
|
||||
resolve_document_node_type("Output")
|
||||
.expect("Output node does not exist")
|
||||
|
@ -881,7 +880,7 @@ pub fn new_image_network(output_offset: i32, output_node_id: NodeId) -> NodeNetw
|
|||
}
|
||||
|
||||
pub fn new_vector_network(subpaths: Vec<bezier_rs::Subpath<uuid::ManipulatorGroupId>>) -> NodeNetwork {
|
||||
let input = resolve_document_node_type("Input").expect("Input node does not exist");
|
||||
let input = resolve_document_node_type("Input Frame").expect("Input Frame node does not exist");
|
||||
let path_generator = resolve_document_node_type("Path Generator").expect("Path Generator node does not exist");
|
||||
let transform = resolve_document_node_type("Transform").expect("Transform node does not exist");
|
||||
let fill = resolve_document_node_type("Fill").expect("Fill node does not exist");
|
||||
|
|
|
@ -421,10 +421,10 @@ fn color_widget(document_node: &DocumentNode, node_id: u64, index: usize, name:
|
|||
}
|
||||
/// Properties for the input node, with information describing how frames work and a refresh button
|
||||
pub fn input_properties(_document_node: &DocumentNode, _node_id: NodeId, context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let information = WidgetHolder::text_widget("The graph's input is the artwork under the frame layer");
|
||||
let information = WidgetHolder::text_widget("The graph's input frame is the rasterized artwork under the layer");
|
||||
let layer_path = context.layer_path.to_vec();
|
||||
let refresh_button = TextButton::new("Refresh Input")
|
||||
.tooltip("Refresh the artwork under the frame")
|
||||
.tooltip("Refresh the artwork under the layer")
|
||||
.on_update(move |_| DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() }.into())
|
||||
.widget_holder();
|
||||
vec![LayoutGroup::Row { widgets: vec![information] }, LayoutGroup::Row { widgets: vec![refresh_button] }]
|
||||
|
@ -936,8 +936,6 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
|||
LayoutGroup::Row { widgets }.with_tooltip("Seed determines the random outcome, enabling limitless unique variations")
|
||||
};
|
||||
|
||||
// Get the existing layer transform
|
||||
let transform = context.document.root.transform.inverse() * context.document.multiply_transforms(context.layer_path).unwrap();
|
||||
// Create the input to the graph using an empty image
|
||||
let image_frame = std::borrow::Cow::Owned(graphene_core::raster::ImageFrame {
|
||||
image: graphene_core::raster::Image::empty(),
|
||||
|
@ -976,7 +974,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
|||
widgets.extend_from_slice(&[
|
||||
WidgetHolder::unrelated_separator(),
|
||||
IconButton::new("Rescale", 24)
|
||||
.tooltip("Set the Node Graph Frame layer dimensions to this resolution")
|
||||
.tooltip("Set the layer dimensions to this resolution")
|
||||
.on_update(move |_| {
|
||||
Operation::SetLayerScaleAroundPivot {
|
||||
path: layer_path.clone(),
|
||||
|
|
|
@ -77,7 +77,7 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ
|
|||
tooltip: "Artboard".into(),
|
||||
..Default::default()
|
||||
})),
|
||||
WidgetHolder::related_separator(),
|
||||
WidgetHolder::unrelated_separator(),
|
||||
WidgetHolder::new(Widget::TextLabel(TextLabel {
|
||||
value: "Artboard".into(),
|
||||
..TextLabel::default()
|
||||
|
@ -256,7 +256,7 @@ pub fn register_artwork_layer_properties(
|
|||
widgets: vec![
|
||||
match &layer.data {
|
||||
LayerDataType::Folder(_) => WidgetHolder::new(Widget::IconLabel(IconLabel {
|
||||
icon: "NodeFolder".into(),
|
||||
icon: "Folder".into(),
|
||||
tooltip: "Folder".into(),
|
||||
..Default::default()
|
||||
})),
|
||||
|
@ -271,15 +271,15 @@ pub fn register_artwork_layer_properties(
|
|||
..Default::default()
|
||||
})),
|
||||
LayerDataType::NodeGraphFrame(_) => WidgetHolder::new(Widget::IconLabel(IconLabel {
|
||||
icon: "NodeNodes".into(),
|
||||
tooltip: "Node Graph Frame".into(),
|
||||
icon: "Layer".into(),
|
||||
tooltip: "Layer".into(),
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
WidgetHolder::related_separator(),
|
||||
WidgetHolder::unrelated_separator(),
|
||||
WidgetHolder::new(Widget::TextLabel(TextLabel {
|
||||
value: match &layer.data {
|
||||
LayerDataType::NodeGraphFrame(_) => "Node Graph Frame".into(),
|
||||
LayerDataType::NodeGraphFrame(_) => "Layer".into(),
|
||||
other => LayerDataTypeDiscriminant::from(other).to_string(),
|
||||
},
|
||||
..TextLabel::default()
|
||||
|
|
|
@ -35,12 +35,12 @@ pub use crate::messages::tool::tool_messages::artboard_tool::{ArtboardToolMessag
|
|||
pub use crate::messages::tool::tool_messages::ellipse_tool::{EllipseToolMessage, EllipseToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::eyedropper_tool::{EyedropperToolMessage, EyedropperToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::fill_tool::{FillToolMessage, FillToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::frame_tool::{NodeGraphFrameToolMessage, NodeGraphFrameToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::freehand_tool::{FreehandToolMessage, FreehandToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::gradient_tool::{GradientToolMessage, GradientToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::imaginate_tool::{ImaginateToolMessage, ImaginateToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::line_tool::{LineToolMessage, LineToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::navigate_tool::{NavigateToolMessage, NavigateToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::node_graph_frame_tool::{NodeGraphFrameToolMessage, NodeGraphFrameToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::path_tool::{PathToolMessage, PathToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::pen_tool::{PenToolMessage, PenToolMessageDiscriminant};
|
||||
pub use crate::messages::tool::tool_messages::rectangle_tool::{RectangleToolMessage, RectangleToolMessageDiscriminant};
|
||||
|
|
|
@ -11,8 +11,8 @@ use std::collections::VecDeque;
|
|||
/// Create a new vector layer from a vector of [`bezier_rs::Subpath`].
|
||||
pub fn new_vector_layer(subpaths: Vec<Subpath<ManipulatorGroupId>>, layer_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
||||
let network = node_graph::new_vector_network(subpaths);
|
||||
|
||||
let network = node_graph::new_vector_network(subpaths);
|
||||
responses.push_back(
|
||||
Operation::AddNodeGraphFrame {
|
||||
path: layer_path.clone(),
|
||||
|
|
|
@ -60,10 +60,10 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NodeGra
|
|||
|
||||
impl ToolMetadata for NodeGraphFrameTool {
|
||||
fn icon_name(&self) -> String {
|
||||
"RasterNodesTool".into()
|
||||
"RasterFrameTool".into()
|
||||
}
|
||||
fn tooltip(&self) -> String {
|
||||
"Node Graph Frame Tool".into()
|
||||
"Frame Tool".into()
|
||||
}
|
||||
fn tool_type(&self) -> crate::messages::tool::utility_types::ToolType {
|
||||
ToolType::NodeGraphFrame
|
||||
|
@ -117,7 +117,7 @@ impl Fsm for NodeGraphToolFsmState {
|
|||
shape_data.path = Some(document.get_path_for_new_layer());
|
||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
||||
|
||||
let network = node_graph::new_image_network(20, 0);
|
||||
let network = node_graph::new_image_network(8, 0);
|
||||
|
||||
responses.push_back(
|
||||
Operation::AddNodeGraphFrame {
|
|
@ -119,18 +119,36 @@ impl Fsm for ImaginateToolFsmState {
|
|||
|
||||
use graph_craft::document::*;
|
||||
|
||||
// Utility function to offset the position of each consecutive node
|
||||
let mut pos = 8;
|
||||
let mut next_pos = || {
|
||||
pos += 8;
|
||||
graph_craft::document::DocumentNodeMetadata::position((pos, 4))
|
||||
};
|
||||
|
||||
// Get the node type for the Transform and Imaginate nodes
|
||||
let Some(transform_node_type) = crate::messages::portfolio::document::node_graph::resolve_document_node_type("Transform") else {
|
||||
warn!("Transform node should be in registry");
|
||||
return Drawing;
|
||||
};
|
||||
let imaginate_node_type = &*IMAGINATE_NODE;
|
||||
|
||||
let mut imaginate_inputs: Vec<NodeInput> = imaginate_node_type.inputs.iter().map(|input| input.default.clone()).collect();
|
||||
imaginate_inputs[0] = NodeInput::node(0, 0);
|
||||
// Give them a unique ID
|
||||
let [transform_node_id, imaginate_node_id] = [100, 101];
|
||||
|
||||
let imaginate_node_id = 100;
|
||||
// Create the network based on the Input -> Output passthrough default network
|
||||
let mut network = node_graph::new_image_network(16, imaginate_node_id);
|
||||
|
||||
// Insert the nodes into the default network
|
||||
network
|
||||
.nodes
|
||||
.insert(transform_node_id, transform_node_type.to_document_node_default_inputs([Some(NodeInput::node(0, 0))], next_pos()));
|
||||
network.nodes.insert(
|
||||
imaginate_node_id,
|
||||
imaginate_node_type.to_document_node(imaginate_inputs, graph_craft::document::DocumentNodeMetadata::position((16, 4))),
|
||||
imaginate_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
||||
);
|
||||
|
||||
// Add the node graph frame layer to the document
|
||||
responses.push_back(
|
||||
Operation::AddNodeGraphFrame {
|
||||
path: shape_data.path.clone().unwrap(),
|
||||
|
@ -140,6 +158,7 @@ impl Fsm for ImaginateToolFsmState {
|
|||
}
|
||||
.into(),
|
||||
);
|
||||
responses.push_back(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id }.into());
|
||||
|
||||
Drawing
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ pub mod artboard_tool;
|
|||
pub mod ellipse_tool;
|
||||
pub mod eyedropper_tool;
|
||||
pub mod fill_tool;
|
||||
pub mod frame_tool;
|
||||
pub mod freehand_tool;
|
||||
pub mod gradient_tool;
|
||||
pub mod imaginate_tool;
|
||||
pub mod line_tool;
|
||||
pub mod navigate_tool;
|
||||
pub mod node_graph_frame_tool;
|
||||
pub mod path_tool;
|
||||
pub mod pen_tool;
|
||||
pub mod rectangle_tool;
|
||||
|
|
|
@ -472,7 +472,7 @@ impl Fsm for SelectToolFsmState {
|
|||
if let Ok(intersect) = document.document_legacy.layer(intersect_layer_path) {
|
||||
match tool_data.nested_selection_behavior {
|
||||
NestedSelectionBehavior::Shallowest => edit_layer_shallowest_manipulation(document, intersect_layer_path, tool_data, responses),
|
||||
NestedSelectionBehavior::Deepest => edit_layer_deepest_manipulation(intersect, intersect_layer_path, responses),
|
||||
NestedSelectionBehavior::Deepest => edit_layer_deepest_manipulation(intersect, responses),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1201,7 +1201,7 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, interse
|
|||
}
|
||||
}
|
||||
|
||||
fn edit_layer_deepest_manipulation(intersect: &Layer, intersect_layer_path: &Vec<u64>, responses: &mut VecDeque<Message>) {
|
||||
fn edit_layer_deepest_manipulation(intersect: &Layer, responses: &mut VecDeque<Message>) {
|
||||
match &intersect.data {
|
||||
LayerDataType::Text(_) => {
|
||||
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Text }.into());
|
||||
|
|
|
@ -408,7 +408,7 @@ fn list_tools_in_groups() -> Vec<Vec<ToolAvailability>> {
|
|||
],
|
||||
vec![
|
||||
// Raster tool group
|
||||
ToolAvailability::Available(Box::<node_graph_frame_tool::NodeGraphFrameTool>::default()),
|
||||
ToolAvailability::Available(Box::<frame_tool::NodeGraphFrameTool>::default()),
|
||||
ToolAvailability::Available(Box::<imaginate_tool::ImaginateTool>::default()),
|
||||
ToolAvailability::ComingSoon(ToolEntry {
|
||||
tool_type: ToolType::Brush,
|
||||
|
|
|
@ -7,7 +7,7 @@ pub struct WorkspaceMessageHandler {
|
|||
|
||||
impl MessageHandler<WorkspaceMessage, ()> for WorkspaceMessageHandler {
|
||||
#[remain::check]
|
||||
fn process_message(&mut self, message: WorkspaceMessage, responses: &mut VecDeque<Message>, _data: ()) {
|
||||
fn process_message(&mut self, message: WorkspaceMessage, _responses: &mut VecDeque<Message>, _data: ()) {
|
||||
use WorkspaceMessage::*;
|
||||
|
||||
#[remain::sorted]
|
||||
|
|
3
frontend/assets/icon-16px-solid/layer.svg
Normal file
3
frontend/assets/icon-16px-solid/layer.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0,2v7.3L4.7,14H16V2H0z M15,13H6V9H1V3h14V13z" />
|
||||
</svg>
|
After Width: | Height: | Size: 128 B |
|
@ -1,4 +0,0 @@
|
|||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14,13H2c-0.55,0-1-0.45-1-1V6h5.42l1-1H15v7C15,12.55,14.55,13,14,13z" />
|
||||
<path d="M6,2H2C1.45,2,1,2.45,1,3v2h5l1-1h8c0-0.55-0.45-1-1-1H7L6,2z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 225 B |
4
frontend/assets/icon-24px-two-tone/raster-frame-tool.svg
Normal file
4
frontend/assets/icon-24px-two-tone/raster-frame-tool.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path class="color-raster" d="M18,8v8H6V8H18 M19,6H5C4.5,6,4,6.4,4,7v10c0,0.5,0.5,1,1,1h14c0.5,0,1-0.5,1-1V7C20,6.4,19.5,6,19,6L19,6z" />
|
||||
<path class="color-solid" d="M2,8V6c0-1.1,0.9-2,2-2h2v1H4C3.4,5,3,5.4,3,6v2H2z M21,16v2c0,0.6-0.4,1-1,1h-2v1h2c1.1,0,2-0.9,2-2v-2H21z M18,5h2c0.6,0,1,0.4,1,1v2h1V6c0-1.1-0.9-2-2-2h-2V5z M6,19H4c-0.6,0-1-0.4-1-1v-2H2v2c0,1.1,0.9,2,2,2h2V19z" />
|
||||
</svg>
|
After Width: | Height: | Size: 452 B |
|
@ -1,6 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path class="color-raster" d="M23,18c0,1.1-0.9,2-2,2h-4c-1.1,0-2-0.9-2-2v-2c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2V18z" />
|
||||
<path class="color-raster" d="M23,8c0,1.1-0.9,2-2,2h-4c-1.1,0-2-0.9-2-2V6c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2V8z" />
|
||||
<path class="color-raster" d="M9,13c0,1.1-0.9,2-2,2H3c-1.1,0-2-0.9-2-2v-2c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2V13z" />
|
||||
<path class="color-solid" d="M12.9,9.3c0.2-1,0.4-1.6,1.1-1.8v-1l-0.1,0c-1.5,0.3-1.7,1.6-2,2.6c-0.3,1.2-0.5,2.1-1.9,2.4v1c1.5,0.2,1.7,1.2,1.9,2.4c0.2,1,0.5,2.3,2,2.6l0.1,0v-1c-0.7-0.2-0.9-0.8-1.1-1.8c-0.2-0.9-0.4-2-1.4-2.7C12.5,11.3,12.7,10.2,12.9,9.3z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 677 B |
|
@ -359,15 +359,16 @@
|
|||
on:dragstart={(e) => draggable && dragStart(e, listing)}
|
||||
on:click={(e) => selectLayerWithModifiers(e, listing)}
|
||||
>
|
||||
{@const layerType = getLayerTypeData(listing.entry.layerType)}
|
||||
<LayoutRow class="layer-type-icon">
|
||||
<IconLabel icon={getLayerTypeData(listing.entry.layerType).icon} tooltip={getLayerTypeData(listing.entry.layerType).name} />
|
||||
<IconLabel icon={layerType.icon} />
|
||||
</LayoutRow>
|
||||
<LayoutRow class="layer-name" on:dblclick={() => onEditLayerName(listing)}>
|
||||
<input
|
||||
data-text-input
|
||||
type="text"
|
||||
value={listing.entry.name}
|
||||
placeholder={getLayerTypeData(listing.entry.layerType).name}
|
||||
placeholder={"Untitled " + layerType.name}
|
||||
disabled={!listing.editingName}
|
||||
on:blur={() => onEditLayerNameDeselect(listing)}
|
||||
on:keydown={(e) => e.key === "Escape" && onEditLayerNameDeselect(listing)}
|
||||
|
|
|
@ -95,19 +95,19 @@ import BooleanUnion from "@graphite/../assets/icon-16px-solid/boolean-union.svg"
|
|||
import CheckboxChecked from "@graphite/../assets/icon-16px-solid/checkbox-checked.svg";
|
||||
import CheckboxUnchecked from "@graphite/../assets/icon-16px-solid/checkbox-unchecked.svg";
|
||||
import Copy from "@graphite/../assets/icon-16px-solid/copy.svg";
|
||||
import Eyedropper from "@graphite/../assets/icon-16px-solid/eyedropper.svg";
|
||||
import EyeHidden from "@graphite/../assets/icon-16px-solid/eye-hidden.svg";
|
||||
import EyeVisible from "@graphite/../assets/icon-16px-solid/eye-visible.svg";
|
||||
import Eyedropper from "@graphite/../assets/icon-16px-solid/eyedropper.svg";
|
||||
import File from "@graphite/../assets/icon-16px-solid/file.svg";
|
||||
import FlipHorizontal from "@graphite/../assets/icon-16px-solid/flip-horizontal.svg";
|
||||
import FlipVertical from "@graphite/../assets/icon-16px-solid/flip-vertical.svg";
|
||||
import Folder from "@graphite/../assets/icon-16px-solid/folder.svg";
|
||||
import GraphiteLogo from "@graphite/../assets/icon-16px-solid/graphite-logo.svg";
|
||||
import Layer from "@graphite/../assets/icon-16px-solid/layer.svg";
|
||||
import NodeArtboard from "@graphite/../assets/icon-16px-solid/node-artboard.svg";
|
||||
import NodeBlur from "@graphite/../assets/icon-16px-solid/node-blur.svg";
|
||||
import NodeBrushwork from "@graphite/../assets/icon-16px-solid/node-brushwork.svg";
|
||||
import NodeColorCorrection from "@graphite/../assets/icon-16px-solid/node-color-correction.svg";
|
||||
import NodeFolder from "@graphite/../assets/icon-16px-solid/node-folder.svg";
|
||||
import NodeGradient from "@graphite/../assets/icon-16px-solid/node-gradient.svg";
|
||||
import NodeImage from "@graphite/../assets/icon-16px-solid/node-image.svg";
|
||||
import NodeImaginate from "@graphite/../assets/icon-16px-solid/node-imaginate.svg";
|
||||
|
@ -160,11 +160,11 @@ const SOLID_16PX = {
|
|||
FlipVertical: { svg: FlipVertical, size: 16 },
|
||||
Folder: { svg: Folder, size: 16 },
|
||||
GraphiteLogo: { svg: GraphiteLogo, size: 16 },
|
||||
Layer: { svg: Layer, size: 16 },
|
||||
NodeArtboard: { svg: NodeArtboard, size: 16 },
|
||||
NodeBlur: { svg: NodeBlur, size: 16 },
|
||||
NodeBrushwork: { svg: NodeBrushwork, size: 16 },
|
||||
NodeColorCorrection: { svg: NodeColorCorrection, size: 16 },
|
||||
NodeFolder: { svg: NodeFolder, size: 16 },
|
||||
NodeGradient: { svg: NodeGradient, size: 16 },
|
||||
NodeImage: { svg: NodeImage, size: 16 },
|
||||
NodeImaginate: { svg: NodeImaginate, size: 16 },
|
||||
|
@ -232,9 +232,9 @@ import GeneralSelectTool from "@graphite/../assets/icon-24px-two-tone/general-se
|
|||
import RasterBrushTool from "@graphite/../assets/icon-24px-two-tone/raster-brush-tool.svg";
|
||||
import RasterCloneTool from "@graphite/../assets/icon-24px-two-tone/raster-clone-tool.svg";
|
||||
import RasterDetailTool from "@graphite/../assets/icon-24px-two-tone/raster-detail-tool.svg";
|
||||
import RasterFrameTool from "@graphite/../assets/icon-24px-two-tone/raster-frame-tool.svg";
|
||||
import RasterHealTool from "@graphite/../assets/icon-24px-two-tone/raster-heal-tool.svg";
|
||||
import RasterImaginateTool from "@graphite/../assets/icon-24px-two-tone/raster-imaginate-tool.svg";
|
||||
import RasterNodesTool from "@graphite/../assets/icon-24px-two-tone/raster-nodes-tool.svg";
|
||||
import RasterPatchTool from "@graphite/../assets/icon-24px-two-tone/raster-patch-tool.svg";
|
||||
import RasterRelightTool from "@graphite/../assets/icon-24px-two-tone/raster-relight-tool.svg";
|
||||
import VectorEllipseTool from "@graphite/../assets/icon-24px-two-tone/vector-ellipse-tool.svg";
|
||||
|
@ -254,12 +254,12 @@ const TWO_TONE_24PX = {
|
|||
GeneralGradientTool: { svg: GeneralGradientTool, size: 24 },
|
||||
GeneralNavigateTool: { svg: GeneralNavigateTool, size: 24 },
|
||||
GeneralSelectTool: { svg: GeneralSelectTool, size: 24 },
|
||||
RasterImaginateTool: { svg: RasterImaginateTool, size: 24 },
|
||||
RasterNodesTool: { svg: RasterNodesTool, size: 24 },
|
||||
RasterBrushTool: { svg: RasterBrushTool, size: 24 },
|
||||
RasterCloneTool: { svg: RasterCloneTool, size: 24 },
|
||||
RasterDetailTool: { svg: RasterDetailTool, size: 24 },
|
||||
RasterFrameTool: { svg: RasterFrameTool, size: 24 },
|
||||
RasterHealTool: { svg: RasterHealTool, size: 24 },
|
||||
RasterImaginateTool: { svg: RasterImaginateTool, size: 24 },
|
||||
RasterPatchTool: { svg: RasterPatchTool, size: 24 },
|
||||
RasterRelightTool: { svg: RasterRelightTool, size: 24 },
|
||||
VectorEllipseTool: { svg: VectorEllipseTool, size: 24 },
|
||||
|
|
|
@ -58,7 +58,7 @@ export async function initWasm(): Promise<void> {
|
|||
|
||||
// Import the WASM module JS bindings and wrap them in the panic proxy
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
wasmImport = await import("@graphite/../wasm/pkg").then(panicProxy);
|
||||
wasmImport = await import("@graphite/../wasm/pkg");
|
||||
|
||||
// Provide a random starter seed which must occur after initializing the WASM module, since WASM can't generate its own random numbers
|
||||
const randomSeedFloat = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
||||
|
|
|
@ -745,7 +745,7 @@ export class LayerMetadata {
|
|||
selected!: boolean;
|
||||
}
|
||||
|
||||
export type LayerType = "Imaginate" | "NodeGraphFrame" | "Folder" | "Image" | "Shape" | "Text";
|
||||
export type LayerType = "Folder" | "NodeGraphFrame" | "Text";
|
||||
|
||||
export type LayerTypeData = {
|
||||
name: string;
|
||||
|
@ -754,11 +754,8 @@ export type LayerTypeData = {
|
|||
|
||||
export function layerTypeData(layerType: LayerType): LayerTypeData | undefined {
|
||||
const entries: Record<string, LayerTypeData> = {
|
||||
Imaginate: { name: "Imaginate", icon: "NodeImaginate" },
|
||||
NodeGraphFrame: { name: "Node Graph Frame", icon: "NodeNodes" },
|
||||
Folder: { name: "Folder", icon: "NodeFolder" },
|
||||
Image: { name: "Image", icon: "NodeImage" },
|
||||
Shape: { name: "Shape", icon: "NodeShape" },
|
||||
NodeGraphFrame: { name: "Layer", icon: "Layer" },
|
||||
Folder: { name: "Folder", icon: "Folder" },
|
||||
Text: { name: "Text", icon: "NodeText" },
|
||||
};
|
||||
|
||||
|
|
|
@ -588,7 +588,7 @@ impl JsEditorHandle {
|
|||
self.dispatch(message);
|
||||
}
|
||||
|
||||
/// Shifts the node and its children to stop nodes going ontop of each other
|
||||
/// Shifts the node and its children to stop nodes going on top of each other
|
||||
#[wasm_bindgen(js_name = shiftNode)]
|
||||
pub fn shift_node(&self, node_id: u64) {
|
||||
let message = NodeGraphMessage::ShiftNode { node_id };
|
||||
|
|
|
@ -124,7 +124,7 @@ impl DocumentNode {
|
|||
|
||||
/// Represents the possible inputs to a node.
|
||||
///
|
||||
/// # Short circuting
|
||||
/// # More about short circuting
|
||||
///
|
||||
/// In Graphite nodes are functions and by default, these are composed into a single function
|
||||
/// by inserting Compose nodes.
|
||||
|
@ -493,7 +493,7 @@ impl NodeNetwork {
|
|||
(
|
||||
0,
|
||||
DocumentNode {
|
||||
name: "Input".into(),
|
||||
name: "Input Frame".into(),
|
||||
inputs: vec![NodeInput::Network(concrete!(u32))],
|
||||
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::IdNode".into()),
|
||||
metadata: DocumentNodeMetadata { position: (8, 4).into() },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue