mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 00:48:12 +08:00
Add viewing/editing layer names, add Blend Mode node, and clean up Layer node (#1489)
This commit is contained in:
@@ -159,10 +159,6 @@ pub enum DocumentMessage {
|
||||
layer_path: Vec<LayerId>,
|
||||
set_expanded: bool,
|
||||
},
|
||||
SetLayerName {
|
||||
layer_path: Vec<LayerId>,
|
||||
name: String,
|
||||
},
|
||||
SetOpacityForSelectedLayers {
|
||||
opacity: f64,
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ impl Default for DocumentMessageHandler {
|
||||
document_legacy: DocumentLegacy::default(),
|
||||
saved_document_identifier: 0,
|
||||
auto_saved_document_identifier: 0,
|
||||
name: String::from("Untitled Document"),
|
||||
name: DEFAULT_DOCUMENT_NAME.to_string(),
|
||||
version: GRAPHITE_DOCUMENT_VERSION.to_string(),
|
||||
commit_hash: crate::application::GRAPHITE_GIT_COMMIT_HASH.to_string(),
|
||||
|
||||
@@ -211,7 +211,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
||||
// Messages
|
||||
AbortTransaction => {
|
||||
if !self.undo_in_progress {
|
||||
self.undo(responses).unwrap_or_else(|e| warn!("{e}"));
|
||||
self.undo(responses);
|
||||
responses.extend([RenderDocument.into(), DocumentStructureChanged.into()]);
|
||||
}
|
||||
}
|
||||
@@ -329,8 +329,8 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
||||
responses.add_front(DocumentMessage::DirtyRenderDocument);
|
||||
}
|
||||
}
|
||||
DocumentHistoryBackward => self.undo(responses).unwrap_or_else(|e| warn!("{e}")),
|
||||
DocumentHistoryForward => self.redo(responses).unwrap_or_else(|e| warn!("{e}")),
|
||||
DocumentHistoryBackward => self.undo(responses),
|
||||
DocumentHistoryForward => self.redo(responses),
|
||||
DocumentStructureChanged => {
|
||||
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
|
||||
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer })
|
||||
@@ -577,7 +577,11 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
||||
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
|
||||
let image_frame = ImageFrame { image, transform: DAffine2::IDENTITY };
|
||||
let image_frame = ImageFrame {
|
||||
image,
|
||||
transform: DAffine2::IDENTITY,
|
||||
blend_mode: BlendMode::Normal,
|
||||
};
|
||||
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
let layer = graph_modification_utils::new_image_layer(image_frame, generate_uuid(), self.new_layer_parent(), responses);
|
||||
@@ -649,7 +653,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
||||
});
|
||||
}
|
||||
RollbackTransaction => {
|
||||
self.rollback(responses).unwrap_or_else(|e| warn!("{e}"));
|
||||
self.rollback(responses);
|
||||
responses.extend([RenderDocument.into(), DocumentStructureChanged.into()]);
|
||||
}
|
||||
SaveDocument => {
|
||||
@@ -771,15 +775,6 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
||||
responses.add(DocumentStructureChanged);
|
||||
responses.add(LayerChanged { affected_layer_path: layer_path })
|
||||
}
|
||||
SetLayerName { layer_path, name } => {
|
||||
if let Some(layer) = self.layer_panel_entry_from_path(&layer_path, &render_data) {
|
||||
// Only save the history state if the name actually changed to something different
|
||||
if layer.name != name {
|
||||
self.backup(responses);
|
||||
responses.add(DocumentOperation::SetLayerName { path: layer_path, name });
|
||||
}
|
||||
}
|
||||
}
|
||||
SetOpacityForSelectedLayers { opacity } => {
|
||||
self.backup(responses);
|
||||
let opacity = opacity.clamp(0., 1.);
|
||||
@@ -1238,9 +1233,9 @@ impl DocumentMessageHandler {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn rollback(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
||||
pub fn rollback(&mut self, responses: &mut VecDeque<Message>) {
|
||||
self.backup(responses);
|
||||
self.undo(responses)
|
||||
self.undo(responses);
|
||||
// TODO: Consider if we should check if the document is saved
|
||||
}
|
||||
|
||||
@@ -1257,72 +1252,62 @@ impl DocumentMessageHandler {
|
||||
DocumentSave { document, layer_metadata }
|
||||
}
|
||||
|
||||
pub fn undo(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
||||
pub fn undo(&mut self, responses: &mut VecDeque<Message>) {
|
||||
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
||||
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||
|
||||
let selected_paths: Vec<Vec<LayerId>> = self.selected_layers().map(|path| path.to_vec()).collect();
|
||||
|
||||
match self.document_undo_history.pop_back() {
|
||||
Some(DocumentSave { document, layer_metadata }) => {
|
||||
// Update the currently displayed layer on the Properties panel if the selection changes after an undo action
|
||||
// Also appropriately update the Properties panel if an undo action results in a layer being deleted
|
||||
let prev_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
||||
if let Some(DocumentSave { document, layer_metadata }) = self.document_undo_history.pop_back() {
|
||||
// Update the currently displayed layer on the Properties panel if the selection changes after an undo action
|
||||
// Also appropriately update the Properties panel if an undo action results in a layer being deleted
|
||||
let prev_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
||||
|
||||
if prev_selected_paths != selected_paths {
|
||||
responses.add(BroadcastEvent::SelectionChanged);
|
||||
}
|
||||
|
||||
let document_save = self.replace_document(DocumentSave { document, layer_metadata });
|
||||
|
||||
self.document_redo_history.push_back(document_save);
|
||||
if self.document_redo_history.len() > crate::consts::MAX_UNDO_HISTORY_LEN {
|
||||
self.document_redo_history.pop_front();
|
||||
}
|
||||
|
||||
for layer in self.layer_metadata.keys() {
|
||||
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() })
|
||||
}
|
||||
|
||||
responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
|
||||
|
||||
Ok(())
|
||||
if prev_selected_paths != selected_paths {
|
||||
responses.add(BroadcastEvent::SelectionChanged);
|
||||
}
|
||||
None => Err(EditorError::NoTransactionInProgress),
|
||||
|
||||
let document_save = self.replace_document(DocumentSave { document, layer_metadata });
|
||||
|
||||
self.document_redo_history.push_back(document_save);
|
||||
if self.document_redo_history.len() > crate::consts::MAX_UNDO_HISTORY_LEN {
|
||||
self.document_redo_history.pop_front();
|
||||
}
|
||||
|
||||
for layer in self.layer_metadata.keys() {
|
||||
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() })
|
||||
}
|
||||
|
||||
responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn redo(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
||||
pub fn redo(&mut self, responses: &mut VecDeque<Message>) {
|
||||
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
||||
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||
|
||||
let selected_paths: Vec<Vec<LayerId>> = self.selected_layers().map(|path| path.to_vec()).collect();
|
||||
|
||||
match self.document_redo_history.pop_back() {
|
||||
Some(DocumentSave { document, layer_metadata }) => {
|
||||
// Update currently displayed layer on property panel if selection changes after redo action
|
||||
// Also appropriately update property panel if redo action results in a layer being added
|
||||
let next_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
||||
if let Some(DocumentSave { document, layer_metadata }) = self.document_redo_history.pop_back() {
|
||||
// Update currently displayed layer on property panel if selection changes after redo action
|
||||
// Also appropriately update property panel if redo action results in a layer being added
|
||||
let next_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
||||
|
||||
if next_selected_paths != selected_paths {
|
||||
responses.add(BroadcastEvent::SelectionChanged);
|
||||
}
|
||||
|
||||
let document_save = self.replace_document(DocumentSave { document, layer_metadata });
|
||||
self.document_undo_history.push_back(document_save);
|
||||
if self.document_undo_history.len() > crate::consts::MAX_UNDO_HISTORY_LEN {
|
||||
self.document_undo_history.pop_front();
|
||||
}
|
||||
|
||||
for layer in self.layer_metadata.keys() {
|
||||
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() })
|
||||
}
|
||||
|
||||
responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
|
||||
|
||||
Ok(())
|
||||
if next_selected_paths != selected_paths {
|
||||
responses.add(BroadcastEvent::SelectionChanged);
|
||||
}
|
||||
None => Err(EditorError::NoTransactionInProgress),
|
||||
|
||||
let document_save = self.replace_document(DocumentSave { document, layer_metadata });
|
||||
self.document_undo_history.push_back(document_save);
|
||||
if self.document_undo_history.len() > crate::consts::MAX_UNDO_HISTORY_LEN {
|
||||
self.document_undo_history.pop_front();
|
||||
}
|
||||
|
||||
for layer in self.layer_metadata.keys() {
|
||||
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() })
|
||||
}
|
||||
|
||||
responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -52,7 +52,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
error!("Tried to modify root layer");
|
||||
return None;
|
||||
};
|
||||
while document.network.nodes.get(&id)?.name != "Layer" {
|
||||
while !document.network.nodes.get(&id)?.is_layer() {
|
||||
id = document.outwards_links.get(&id)?.first().copied()?;
|
||||
}
|
||||
document.layer_node = Some(id);
|
||||
@@ -112,7 +112,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
// Locate the node output of the first sibling layer to the new layer
|
||||
if let Some((node_id, output_index)) = self.skip_artboards(&mut output) {
|
||||
let sibling_node = self.network.nodes.get(&node_id)?;
|
||||
if sibling_node.name == "Layer" {
|
||||
if sibling_node.is_layer() {
|
||||
// There is already a layer node
|
||||
sibling_layer = Some(NodeOutput::new(node_id, 0));
|
||||
} else {
|
||||
@@ -125,8 +125,8 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
// Skip some layer nodes
|
||||
for _ in 0..skip_layer_nodes {
|
||||
if let Some(old_sibling) = &sibling_layer {
|
||||
output = NodeOutput::new(old_sibling.node_id, 7);
|
||||
sibling_layer = self.network.nodes.get(&old_sibling.node_id)?.inputs[7].as_node().map(|node| NodeOutput::new(node, 0));
|
||||
output = NodeOutput::new(old_sibling.node_id, 1);
|
||||
sibling_layer = self.network.nodes.get(&old_sibling.node_id)?.inputs[1].as_node().map(|node| NodeOutput::new(node, 0));
|
||||
shift = IVec2::new(0, 3);
|
||||
}
|
||||
}
|
||||
@@ -139,14 +139,14 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
// Create node
|
||||
let layer_node = resolve_document_node_type("Layer").expect("Layer node").default_document_node();
|
||||
let new_id = if let Some(sibling_layer) = sibling_layer {
|
||||
self.insert_between(new_id, sibling_layer, output, layer_node, 7, 0, shift)
|
||||
self.insert_between(new_id, sibling_layer, output, layer_node, 1, 0, shift)
|
||||
} else {
|
||||
self.insert_node_before(new_id, output.node_id, output.node_output_index, layer_node, shift)
|
||||
};
|
||||
|
||||
// Update the document metadata structure
|
||||
if let Some(new_id) = new_id {
|
||||
let parent = if self.network.nodes.get(&output_node_id).is_some_and(|node| node.name == "Layer") {
|
||||
let parent = if self.network.nodes.get(&output_node_id).is_some_and(|node| node.is_layer()) {
|
||||
LayerNodeIdentifier::new(output_node_id, self.network)
|
||||
} else {
|
||||
LayerNodeIdentifier::ROOT
|
||||
@@ -498,7 +498,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
|
||||
LayerNodeIdentifier::new(id, self.network).delete(self.document_metadata);
|
||||
|
||||
let new_input = node.inputs[7].clone();
|
||||
let new_input = node.inputs[1].clone();
|
||||
let deleted_position = node.metadata.position;
|
||||
|
||||
for post_node in self.outwards_links.get(&id).unwrap_or(&Vec::new()) {
|
||||
|
||||
@@ -103,6 +103,14 @@ pub enum NodeGraphMessage {
|
||||
node_id: NodeId,
|
||||
hidden: bool,
|
||||
},
|
||||
SetName {
|
||||
node_id: NodeId,
|
||||
name: String,
|
||||
},
|
||||
SetNameImpl {
|
||||
node_id: NodeId,
|
||||
name: String,
|
||||
},
|
||||
TogglePreview {
|
||||
node_id: NodeId,
|
||||
},
|
||||
|
||||
@@ -73,9 +73,11 @@ pub struct FrontendGraphOutput {
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
pub struct FrontendNode {
|
||||
#[serde(rename = "isLayer")]
|
||||
pub is_layer: bool,
|
||||
pub id: graph_craft::document::NodeId,
|
||||
#[serde(rename = "displayName")]
|
||||
pub display_name: String,
|
||||
pub name: String,
|
||||
pub identifier: String,
|
||||
#[serde(rename = "primaryInput")]
|
||||
pub primary_input: Option<FrontendGraphInput>,
|
||||
#[serde(rename = "exposedInputs")]
|
||||
@@ -116,7 +118,7 @@ impl FrontendNodeType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct NodeGraphMessageHandler {
|
||||
pub layer_path: Option<Vec<LayerId>>,
|
||||
pub network: Vec<NodeId>,
|
||||
@@ -125,6 +127,21 @@ pub struct NodeGraphMessageHandler {
|
||||
pub widgets: [LayoutGroup; 2],
|
||||
}
|
||||
|
||||
impl Default for NodeGraphMessageHandler {
|
||||
fn default() -> Self {
|
||||
// TODO: Replace this with an "Add Node" button, also next to an "Add Layer" button
|
||||
let add_nodes_label = TextLabel::new("Right Click Graph to Add Nodes").italic(true).widget_holder();
|
||||
let add_nodes_label_row = LayoutGroup::Row { widgets: vec![add_nodes_label] };
|
||||
|
||||
Self {
|
||||
layer_path: None,
|
||||
network: Vec::new(),
|
||||
has_selection: false,
|
||||
widgets: [add_nodes_label_row, LayoutGroup::default()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Message> for document_legacy::document_metadata::SelectionChanged {
|
||||
fn into(self) -> Message {
|
||||
BroadcastMessage::TriggerEvent(BroadcastEvent::SelectionChanged).into()
|
||||
@@ -140,63 +157,11 @@ impl NodeGraphMessageHandler {
|
||||
});
|
||||
}
|
||||
|
||||
/// Collect the addresses of the currently viewed nested node e.g. Root -> MyFunFilter -> Exposure
|
||||
fn collect_nested_addresses(&mut self, document: &Document, document_name: &str, responses: &mut VecDeque<Message>) {
|
||||
let layer_if_selected = self.layer_path.as_ref().and_then(|path| document.layer(path).ok());
|
||||
|
||||
// Build path list for the layer, or otherwise the root document
|
||||
let path_root = match layer_if_selected {
|
||||
Some(layer) => layer.name.as_deref().unwrap_or("Untitled Layer"),
|
||||
None => document_name,
|
||||
};
|
||||
let mut path = vec![path_root.to_string()];
|
||||
|
||||
let (icon, tooltip) = match layer_if_selected {
|
||||
Some(_) => ("Layer", "Layer"),
|
||||
None => ("File", "Document"),
|
||||
};
|
||||
|
||||
let mut network = Some(&document.document_network);
|
||||
for node_id in &self.network {
|
||||
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![
|
||||
IconLabel::new(icon).tooltip(tooltip).widget_holder(),
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
BreadcrumbTrailButtons::new(path.clone())
|
||||
.on_update(move |input: &u64| {
|
||||
NodeGraphMessage::ExitNestedNetwork {
|
||||
depth_of_nesting: nesting - (*input as usize) - 1,
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.widget_holder(),
|
||||
],
|
||||
};
|
||||
|
||||
self.send_node_bar_layout(responses);
|
||||
}
|
||||
|
||||
/// Updates the buttons for disable and preview
|
||||
fn update_selection_action_buttons(&mut self, document: &Document, responses: &mut VecDeque<Message>) {
|
||||
if let Some(network) = document.document_network.nested_network(&self.network) {
|
||||
let mut widgets = Vec::new();
|
||||
|
||||
// TODO: Replace this with an add node button
|
||||
let add_nodes_label = TextLabel::new("Right Click Graph to Add Nodes").italic(true).widget_holder();
|
||||
widgets.push(add_nodes_label);
|
||||
|
||||
// Don't allow disabling input or output nodes
|
||||
let mut selected_nodes = document.metadata.selected_nodes().filter(|&&id| !network.inputs.contains(&id) && !network.original_outputs_contain(id));
|
||||
|
||||
@@ -330,8 +295,10 @@ impl NodeGraphMessageHandler {
|
||||
let _graph_identifier = GraphIdentifier::new(layer_id);
|
||||
|
||||
nodes.push(FrontendNode {
|
||||
is_layer: node.is_layer(),
|
||||
id: *id,
|
||||
display_name: node.name.clone(),
|
||||
name: node.alias.clone(),
|
||||
identifier: node.name.clone(),
|
||||
primary_input,
|
||||
exposed_inputs,
|
||||
primary_output,
|
||||
@@ -354,7 +321,7 @@ impl NodeGraphMessageHandler {
|
||||
|
||||
fn remove_references_from_network(network: &mut NodeNetwork, deleting_node_id: NodeId, reconnect: bool) -> bool {
|
||||
if network.inputs.contains(&deleting_node_id) {
|
||||
warn!("Deleting input node");
|
||||
warn!("Deleting input node!");
|
||||
return false;
|
||||
}
|
||||
if network.outputs_contain(deleting_node_id) {
|
||||
@@ -368,7 +335,7 @@ impl NodeGraphMessageHandler {
|
||||
// Check whether the being-deleted node's first (primary) input is a node
|
||||
if let Some(node) = network.nodes.get(&deleting_node_id) {
|
||||
// Reconnect to the node below when deleting a layer node.
|
||||
let reconnect_from_input_index = if node.name == "Layer" { 7 } else { 0 };
|
||||
let reconnect_from_input_index = if node.is_layer() { 1 } else { 0 };
|
||||
if matches!(&node.inputs.get(reconnect_from_input_index), Some(NodeInput::Node { .. })) {
|
||||
reconnect_to_input = Some(node.inputs[reconnect_from_input_index].clone());
|
||||
}
|
||||
@@ -614,7 +581,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
if let Some(network) = document.document_network.nested_network(&self.network) {
|
||||
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
|
||||
}
|
||||
self.collect_nested_addresses(document, data.document_name, responses);
|
||||
self.update_selected(document, responses);
|
||||
}
|
||||
NodeGraphMessage::DuplicateSelectedNodes => {
|
||||
@@ -651,7 +617,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
if let Some(network) = document.document_network.nested_network(&self.network) {
|
||||
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
|
||||
}
|
||||
self.collect_nested_addresses(document, data.document_name, responses);
|
||||
self.update_selected(document, responses);
|
||||
}
|
||||
NodeGraphMessage::ExposeInput { node_id, input_index, new_exposed } => {
|
||||
@@ -713,7 +678,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
let node_types = document_node_types::collect_node_types();
|
||||
responses.add(FrontendMessage::UpdateNodeTypes { node_types });
|
||||
}
|
||||
self.collect_nested_addresses(document, data.document_name, responses);
|
||||
self.update_selected(document, responses);
|
||||
}
|
||||
NodeGraphMessage::PasteNodes { serialized_nodes } => {
|
||||
@@ -925,6 +889,18 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
}
|
||||
self.update_selection_action_buttons(document, responses);
|
||||
}
|
||||
NodeGraphMessage::SetName { node_id, name } => {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
responses.add(NodeGraphMessage::SetNameImpl { node_id, name });
|
||||
}
|
||||
NodeGraphMessage::SetNameImpl { node_id, name } => {
|
||||
if let Some(network) = document.document_network.nested_network_mut(&self.network) {
|
||||
if let Some(node) = network.nodes.get_mut(&node_id) {
|
||||
node.alias = name;
|
||||
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
NodeGraphMessage::TogglePreview { node_id } => {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
responses.add(NodeGraphMessage::TogglePreviewImpl { node_id });
|
||||
@@ -958,7 +934,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
let node_types = document_node_types::collect_node_types();
|
||||
responses.add(FrontendMessage::UpdateNodeTypes { node_types });
|
||||
}
|
||||
self.collect_nested_addresses(document, data.document_name, responses);
|
||||
self.update_selected(document, responses);
|
||||
}
|
||||
}
|
||||
|
||||
+39
-36
@@ -96,8 +96,10 @@ impl NodeImplementation {
|
||||
/// Acts as a description for a [DocumentNode] before it gets instantiated as one.
|
||||
#[derive(Clone)]
|
||||
pub struct DocumentNodeBlueprint {
|
||||
// TODO: Rename to `identifier` (also rename the TODOs in the `DocumentNode` struct)
|
||||
pub name: &'static str,
|
||||
pub category: &'static str,
|
||||
// TODO: Rename to `implementation` (also rename the TODOs in the `DocumentNode` struct)
|
||||
pub identifier: NodeImplementation,
|
||||
pub inputs: Vec<DocumentInputType>,
|
||||
pub outputs: Vec<DocumentOutputType>,
|
||||
@@ -115,7 +117,7 @@ impl Default for DocumentNodeBlueprint {
|
||||
inputs: Default::default(),
|
||||
outputs: Default::default(),
|
||||
has_primary_output: true,
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
manual_composition: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -198,7 +200,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
name: "Layer",
|
||||
category: "General",
|
||||
identifier: NodeImplementation::DocumentNode(NodeNetwork {
|
||||
inputs: vec![0, 2, 2, 2, 2, 2, 2, 2],
|
||||
inputs: vec![0, 2],
|
||||
outputs: vec![NodeOutput::new(2, 0)],
|
||||
nodes: [
|
||||
(
|
||||
@@ -225,15 +227,9 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
manual_composition: Some(concrete!(Footprint)),
|
||||
inputs: vec![
|
||||
NodeInput::node(1, 0),
|
||||
NodeInput::Network(concrete!(String)),
|
||||
NodeInput::Network(concrete!(BlendMode)),
|
||||
NodeInput::Network(concrete!(f32)),
|
||||
NodeInput::Network(concrete!(bool)),
|
||||
NodeInput::Network(concrete!(bool)),
|
||||
NodeInput::Network(concrete!(bool)),
|
||||
NodeInput::Network(graphene_core::Type::Fn(Box::new(concrete!(Footprint)), Box::new(concrete!(graphene_core::GraphicGroup)))),
|
||||
],
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::ConstructLayerNode<_, _, _, _, _, _, _, _>"),
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::ConstructLayerNode<_, _>"),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
@@ -242,17 +238,11 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
..Default::default()
|
||||
}),
|
||||
inputs: vec![
|
||||
DocumentInputType::value("Vector Data", TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
DocumentInputType::value("Name", TaggedValue::String(String::new()), false),
|
||||
DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false),
|
||||
DocumentInputType::value("Opacity", TaggedValue::F32(100.), false),
|
||||
DocumentInputType::value("Visible", TaggedValue::Bool(true), false),
|
||||
DocumentInputType::value("Locked", TaggedValue::Bool(false), false),
|
||||
DocumentInputType::value("Collapsed", TaggedValue::Bool(false), false),
|
||||
DocumentInputType::value("Graphical Data", TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
DocumentInputType::value("Stack", TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||
],
|
||||
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::GraphicGroup)],
|
||||
properties: node_properties::layer_properties,
|
||||
properties: node_properties::layer_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -748,12 +738,12 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
name: "Blend Mode",
|
||||
category: "Image Adjustments",
|
||||
name: "Blend Mode Value",
|
||||
category: "Inputs",
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
|
||||
inputs: vec![DocumentInputType::value("Mode", TaggedValue::BlendMode(BlendMode::Normal), false)],
|
||||
inputs: vec![DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false)],
|
||||
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::General)],
|
||||
properties: node_properties::blend_mode_properties,
|
||||
properties: node_properties::blend_mode_value_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1442,7 +1432,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
DocumentInputType::value("Second", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false),
|
||||
DocumentInputType::value("Opacity", TaggedValue::F32(100.0), false),
|
||||
DocumentInputType::value("Opacity", TaggedValue::F32(100.), false),
|
||||
],
|
||||
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
|
||||
properties: node_properties::blend_properties,
|
||||
@@ -1708,7 +1698,19 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
DocumentInputType::value("Factor", TaggedValue::F32(100.), false),
|
||||
],
|
||||
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
|
||||
properties: node_properties::multiply_opacity,
|
||||
properties: node_properties::opacity_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
name: "Blend Mode",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeImplementation::proto("graphene_core::raster::BlendModeNode<_>"),
|
||||
inputs: vec![
|
||||
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false),
|
||||
],
|
||||
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
|
||||
properties: node_properties::blend_mode_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1803,7 +1805,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::FloorNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1812,7 +1814,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::CeilNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1821,7 +1823,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::RoundNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1830,7 +1832,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::AbsoluteNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1851,7 +1853,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::NaturalLogNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1860,7 +1862,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::SineNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1869,7 +1871,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::CosineNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1878,7 +1880,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::ops::TangentNode"),
|
||||
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1935,7 +1937,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::logic::LogToConsoleNode"),
|
||||
inputs: vec![DocumentInputType::value("Input", TaggedValue::String("Not Connected to a value yet".into()), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::General)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -1980,7 +1982,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::logic::LogicNotNode"),
|
||||
inputs: vec![DocumentInputType::value("Input", TaggedValue::Bool(false), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Boolean)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
(*IMAGINATE_NODE).clone(),
|
||||
@@ -2077,6 +2079,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::vector::generator_nodes::PathGenerator<_>"),
|
||||
inputs: vec![
|
||||
DocumentInputType::value("Path Data", TaggedValue::Subpaths(vec![]), false),
|
||||
// TODO: Keavon asks: what is this for? Is it dead code? It seems to only be set, never read.
|
||||
DocumentInputType::value("Mirror", TaggedValue::ManipulatorGroupIds(vec![]), false),
|
||||
],
|
||||
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
|
||||
@@ -2234,7 +2237,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::vector::BoundingBoxNode"),
|
||||
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
|
||||
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -2269,7 +2272,7 @@ fn static_nodes() -> Vec<DocumentNodeBlueprint> {
|
||||
identifier: NodeImplementation::proto("graphene_core::vector::SplineFromPointsNode"),
|
||||
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
|
||||
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
|
||||
properties: node_properties::no_properties,
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeBlueprint {
|
||||
@@ -2471,7 +2474,7 @@ impl DocumentNodeBlueprint {
|
||||
self.to_document_node(inputs, metadata)
|
||||
}
|
||||
|
||||
/// Converts the [DocumentNodeBlueprint] type to a [DocumentNode], completly default
|
||||
/// Converts the [DocumentNodeBlueprint] type to a [DocumentNode], completely default
|
||||
pub fn default_document_node(&self) -> DocumentNode {
|
||||
self.to_document_node(self.inputs.iter().map(|input| input.default.clone()), DocumentNodeMetadata::default())
|
||||
}
|
||||
|
||||
+16
-25
@@ -777,10 +777,6 @@ pub fn mask_properties(document_node: &DocumentNode, node_id: NodeId, _context:
|
||||
vec![mask]
|
||||
}
|
||||
|
||||
pub fn blend_mode_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
vec![blend_mode(document_node, node_id, 0, "Blend Mode", true)]
|
||||
}
|
||||
|
||||
pub fn color_channel_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
vec![color_channel(document_node, node_id, 0, "Channel", true)]
|
||||
}
|
||||
@@ -803,7 +799,7 @@ pub fn extract_channel_properties(document_node: &DocumentNode, node_id: NodeId,
|
||||
vec![color_channel]
|
||||
}
|
||||
|
||||
// Noise Type is commented out for now as ther is only one type of noise (White Noise).
|
||||
// Noise Type is commented out for now as there is only one type of noise (White Noise).
|
||||
// As soon as there are more types of noise, this should be uncommented.
|
||||
pub fn pixel_noise_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let width = number_widget(document_node, node_id, 0, "Width", NumberInput::default().unit("px").min(1.), true);
|
||||
@@ -1025,12 +1021,20 @@ pub fn _gpu_map_properties(document_node: &DocumentNode, node_id: NodeId, _conte
|
||||
vec![LayoutGroup::Row { widgets: map }]
|
||||
}
|
||||
|
||||
pub fn multiply_opacity(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let gamma = number_widget(document_node, node_id, 1, "Factor", NumberInput::default().min(0.).max(100.).unit("%"), true);
|
||||
pub fn opacity_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let gamma = number_widget(document_node, node_id, 1, "Factor", NumberInput::default().mode_range().min(0.).max(100.).unit("%"), true);
|
||||
|
||||
vec![LayoutGroup::Row { widgets: gamma }]
|
||||
}
|
||||
|
||||
pub fn blend_mode_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
vec![blend_mode(document_node, node_id, 1, "Blend Mode", true)]
|
||||
}
|
||||
|
||||
pub fn blend_mode_value_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
vec![blend_mode(document_node, node_id, 0, "Blend Mode", true)]
|
||||
}
|
||||
|
||||
pub fn posterize_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let value = number_widget(document_node, node_id, 1, "Levels", NumberInput::default().min(2.).max(255.).int(), true);
|
||||
|
||||
@@ -1769,10 +1773,14 @@ fn unknown_node_properties(document_node: &DocumentNode) -> Vec<LayoutGroup> {
|
||||
string_properties(format!("Node '{}' cannot be found in library", document_node.name))
|
||||
}
|
||||
|
||||
pub fn no_properties(_document_node: &DocumentNode, _node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
pub fn node_no_properties(_document_node: &DocumentNode, _node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
string_properties("Node has no properties")
|
||||
}
|
||||
|
||||
pub fn layer_no_properties(_document_node: &DocumentNode, _node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
string_properties("Layer has no properties")
|
||||
}
|
||||
|
||||
pub fn index_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let index = number_widget(document_node, node_id, 1, "Index", NumberInput::default().min(0.), true);
|
||||
|
||||
@@ -1875,23 +1883,6 @@ pub fn fill_properties(document_node: &DocumentNode, node_id: NodeId, _context:
|
||||
widgets
|
||||
}
|
||||
|
||||
pub fn layer_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let name = text_widget(document_node, node_id, 1, "Name", true);
|
||||
let blend_mode = blend_mode(document_node, node_id, 2, "Blend Mode", true);
|
||||
let opacity = number_widget(document_node, node_id, 3, "Opacity", NumberInput::default().percentage(), true);
|
||||
let visible = bool_widget(document_node, node_id, 4, "Visible", true);
|
||||
let locked = bool_widget(document_node, node_id, 5, "Locked", true);
|
||||
let collapsed = bool_widget(document_node, node_id, 6, "Collapsed", true);
|
||||
|
||||
vec![
|
||||
LayoutGroup::Row { widgets: name },
|
||||
blend_mode,
|
||||
LayoutGroup::Row { widgets: opacity },
|
||||
LayoutGroup::Row { widgets: visible },
|
||||
LayoutGroup::Row { widgets: locked },
|
||||
LayoutGroup::Row { widgets: collapsed },
|
||||
]
|
||||
}
|
||||
pub fn artboard_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let location = vec2_widget(document_node, node_id, 1, "Location", "X", "Y", " px", add_blank_assist);
|
||||
let dimensions = vec2_widget(document_node, node_id, 2, "Dimensions", "W", "H", " px", add_blank_assist);
|
||||
|
||||
@@ -18,7 +18,6 @@ pub enum PropertiesPanelMessage {
|
||||
Deactivate,
|
||||
Init,
|
||||
ModifyFill { fill: Fill },
|
||||
ModifyName { name: String },
|
||||
ModifyPreserveAspect { preserve_aspect: bool },
|
||||
ModifyStroke { stroke: Stroke },
|
||||
ModifyTransform { value: f64, transform_op: TransformOp },
|
||||
|
||||
+3
-6
@@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct PropertiesPanelMessageHandler {
|
||||
active_selection: Option<Vec<LayerId>>,
|
||||
active_selection: Option<Vec<LayerId>>, // TODO: Delete this if it's indeed dead code?
|
||||
}
|
||||
|
||||
impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPanelMessageHandlerData<'a>)> for PropertiesPanelMessageHandler {
|
||||
@@ -38,7 +38,7 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
||||
responses.add(NodeGraphMessage::CloseNodeGraph);
|
||||
} else {
|
||||
let path = paths.into_iter().next().unwrap();
|
||||
if Some(&path) != self.active_selection.as_ref() {
|
||||
if self.active_selection.as_ref() != Some(&path) {
|
||||
// Update the layer visibility
|
||||
if artwork_document
|
||||
.layer(&path)
|
||||
@@ -86,10 +86,6 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
||||
|
||||
self.create_document_operation(Operation::SetLayerTransform { path: path.clone(), transform }, true, responses);
|
||||
}
|
||||
ModifyName { name } => {
|
||||
let path = self.active_selection.clone().expect("Received update for properties panel with no active layer");
|
||||
self.create_document_operation(Operation::SetLayerName { path, name }, true, responses);
|
||||
}
|
||||
ModifyPreserveAspect { preserve_aspect } => {
|
||||
let layer_path = self.active_selection.clone().expect("Received update for properties panel with no active layer");
|
||||
self.create_document_operation(Operation::SetLayerPreserveAspect { layer_path, preserve_aspect }, true, responses);
|
||||
@@ -131,6 +127,7 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
||||
}
|
||||
ResendActiveProperties => {
|
||||
if let Some(path) = self.active_selection.clone() {
|
||||
// TODO: Remove this conditional now that the document graph is the only form of graph? (Also any other related code.)
|
||||
let layer = artwork_document.layer(&path).unwrap();
|
||||
register_artwork_layer_properties(artwork_document, path, layer, responses, persistent_data, node_graph_message_handler, executor);
|
||||
} else {
|
||||
|
||||
@@ -82,7 +82,7 @@ pub fn register_artwork_layer_properties(
|
||||
},
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
TextInput::new(layer.name.clone().unwrap_or_else(|| "Untitled Layer".to_string()))
|
||||
.on_update(|text_input: &TextInput| PropertiesPanelMessage::ModifyName { name: text_input.value.clone() }.into())
|
||||
.on_update(|_text_input: &TextInput| panic!("This is presumed to be dead code, but if you are seeing this crash, please file a bug report."))
|
||||
.widget_holder(),
|
||||
Separator::new(SeparatorType::Related).widget_holder(),
|
||||
PopoverButton::new("Additional Options", "Coming soon").widget_holder(),
|
||||
|
||||
@@ -21,9 +21,6 @@ pub enum EditorError {
|
||||
#[error("This document was created in an older version of the editor.\n\nBackwards compatibility is, regrettably, not present in the current alpha release.\n\nTechnical details:\n{0:?}")]
|
||||
DocumentDeserialization(String),
|
||||
|
||||
#[error("A rollback was initiated but no transaction was in progress")]
|
||||
NoTransactionInProgress,
|
||||
|
||||
#[error("{0}")]
|
||||
Misc(String),
|
||||
}
|
||||
|
||||
@@ -58,6 +58,8 @@ pub struct LayerPanelEntry {
|
||||
}
|
||||
|
||||
impl LayerPanelEntry {
|
||||
// TODO: Deprecate this because it's using document-legacy layer data which is no longer linked to data from the node graph,
|
||||
// TODO: so this doesn't feed `name` (that's fed elsewhere) or `visible` (that's broken entirely), etc.
|
||||
pub fn new(layer_metadata: &LayerMetadata, transform: DAffine2, layer: &Layer, path: Vec<LayerId>, render_data: &RenderData) -> Self {
|
||||
let name = layer.name.clone().unwrap_or_else(|| String::from(""));
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ impl<'a> NodeGraphLayer<'a> {
|
||||
error!("Tried to modify root layer");
|
||||
return None;
|
||||
};
|
||||
while node_graph.nodes.get(&layer_node)?.name != "Layer" {
|
||||
while !node_graph.nodes.get(&layer_node)?.is_layer() {
|
||||
layer_node = outwards_links.get(&layer_node)?.first().copied()?;
|
||||
}
|
||||
Some(Self {
|
||||
|
||||
@@ -533,14 +533,7 @@ impl NodeGraphExecutor {
|
||||
let layer = LayerNodeIdentifier::new(node_id, &document.document_network);
|
||||
responses.add(FrontendMessage::UpdateDocumentLayerDetails {
|
||||
data: LayerPanelEntry {
|
||||
name: if document.metadata.is_artboard(layer) {
|
||||
"Artboard"
|
||||
} else if document.metadata.is_folder(layer) {
|
||||
"Folder"
|
||||
} else {
|
||||
"Layer"
|
||||
}
|
||||
.to_string(),
|
||||
name: document.document_network.nodes.get(&node_id).map(|node| node.alias.clone()).unwrap_or_default(),
|
||||
tooltip: if cfg!(debug_assertions) { format!("Layer ID: {node_id}") } else { "".into() },
|
||||
visible: !document.document_network.disabled.contains(&layer.to_node()),
|
||||
layer_type: if document.metadata.is_artboard(layer) {
|
||||
|
||||
Reference in New Issue
Block a user