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:
Keavon Chambers 2023-04-03 01:52:25 -07:00
parent d710285029
commit 0a9427fe6e
25 changed files with 104 additions and 98 deletions

View file

@ -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"),
}
}
}

View file

@ -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,

View file

@ -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 {

View file

@ -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 => {

View file

@ -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");

View file

@ -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(),

View file

@ -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()

View file

@ -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};

View file

@ -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(),

View file

@ -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 {

View file

@ -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
}

View file

@ -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;

View file

@ -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());

View file

@ -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,

View file

@ -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]

View 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

View file

@ -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

View 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

View file

@ -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

View file

@ -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)}

View file

@ -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 },

View file

@ -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);

View file

@ -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" },
};

View file

@ -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 };

View file

@ -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() },