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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions editor/src/messages/layout/layout_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,22 @@ impl LayoutMessageHandler {
}
LayoutGroup::Table(WidgetTable { rows, .. }) => {
for (row_index, row) in rows.iter().enumerate() {
for (cell_index, cell) in row.iter().enumerate() {
for (value_index, value) in row.iter().enumerate() {
// Return if this is the correct ID
if cell.widget_id == widget_id {
if value.widget_id == widget_id {
widget_path.push(row_index);
widget_path.push(cell_index);
return Some((cell, widget_path));
widget_path.push(value_index);
return Some((value, widget_path));
}

if let Widget::PopoverButton(popover) = &*cell.widget {
if let Widget::PopoverButton(popover) = &*value.widget {
stack.extend(
popover
.popover_layout
.0
.iter()
.enumerate()
.map(|(child, val)| ([widget_path.as_slice(), &[row_index, cell_index, child]].concat(), val)),
.map(|(child, val)| ([widget_path.as_slice(), &[row_index, value_index, child]].concat(), val)),
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions editor/src/messages/layout/utility_types/layout_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ macro_rules! define_layout_target {
};
}
define_layout_target!(
/// The spreadsheet panel allows for the visualisation of data in the graph.
/// The Data panel visualizes the output data flowing through the selected node in the graph.
DataPanel,
/// Contains the action buttons at the bottom of the dialog. Must be shown with the `FrontendMessage::DisplayDialog` message.
DialogButtons,
Expand Down Expand Up @@ -785,7 +785,7 @@ pub enum Widget {
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct WidgetDiff {
/// A path to the change
/// e.g. [0, 1, 2] in the properties panel is the first section, second row and third widget.
/// e.g. [0, 1, 2] in the Properties panel is the first section, second row and third widget.
/// An empty path [] shows that the entire panel has changed and is sent when the UI is first created.
#[serde(rename = "widgetPath")]
pub widget_path: Vec<usize>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ pub enum DataPanelMessage {
},
}

/// One hop in the breadcrumb path through nested data the data panel is displaying.
/// Drilling into a row's element produces an `Element` step; drilling into one of a row's attributes produces an `Attribute` step.
/// One hop in the breadcrumb path through nested data the Data panel is displaying.
/// Drilling into an item's element produces an `Element` step; drilling into one of an item's attributes produces an `Attribute` step.
#[derive(PartialEq, Eq, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum PathStep {
Element(usize),
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion editor/src/messages/portfolio/document/document_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ pub enum DocumentMessage {
undo_count: usize,
},
ToggleLayerExpansion {
instance_path: Vec<NodeId>,
tree_path: Vec<NodeId>,
recursive: bool,
},
ToggleSelectedVisibility,
Expand Down
66 changes: 33 additions & 33 deletions editor/src/messages/portfolio/document/document_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub struct DocumentMessageHandler {
//
// Contains the NodeNetwork and acts an an interface to manipulate the NodeNetwork with custom setters in order to keep NetworkMetadata in sync
pub network_interface: NodeNetworkInterface,
/// Tracks which layer instances are collapsed in the Layers panel, keyed by instance path.
/// Tracks which layer occurrences are collapsed in the Layers panel, keyed by tree path.
#[serde(deserialize_with = "deserialize_collapsed_layers", default)]
pub collapsed: CollapsedLayers,
/// The full Git commit hash of the Graphite repository that was used to build the editor.
Expand Down Expand Up @@ -1183,27 +1183,27 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
responses.add(OverlaysMessage::Draw);
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
}
DocumentMessage::ToggleLayerExpansion { instance_path, recursive } => {
let is_collapsed = self.collapsed.0.contains(&instance_path);
DocumentMessage::ToggleLayerExpansion { tree_path, recursive } => {
let is_collapsed = self.collapsed.0.contains(&tree_path);

if is_collapsed {
if recursive {
// Remove this path and all descendant paths (paths that start with this one)
self.collapsed.0.retain(|path| !path.starts_with(&instance_path));
self.collapsed.0.retain(|path| !path.starts_with(&tree_path));
} else {
self.collapsed.0.retain(|path| *path != instance_path);
self.collapsed.0.retain(|path| *path != tree_path);
}
} else {
if recursive {
// Collapse all expanded descendant instances by collecting their paths from the structure tree
let descendant_paths = self.collect_descendant_instance_paths(&instance_path);
// Collapse all expanded descendant occurrences by collecting their tree paths from the structure tree
let descendant_paths = self.collect_descendant_tree_paths(&tree_path);
for path in descendant_paths {
if !self.collapsed.0.contains(&path) {
self.collapsed.0.push(path);
}
}
}
self.collapsed.0.push(instance_path);
self.collapsed.0.push(tree_path);
}

responses.add(NodeGraphMessage::SendGraph);
Expand Down Expand Up @@ -1782,19 +1782,19 @@ impl DocumentMessageHandler {
let selected_layers: HashSet<NodeId> = network.selected_nodes().selected_layers(self.metadata()).map(LayerNodeIdentifier::to_node).collect();

let ancestors = HashSet::new();
let instance_path = Vec::new();
let tree_path = Vec::new();
let mut root_entries = Vec::new();

// The first root layer is the topmost entry
root_entries.push(self.build_layer_entry(first_root_layer_id, &ancestors, &selected_layers, &instance_path));
root_entries.push(self.build_layer_entry(first_root_layer_id, &ancestors, &selected_layers, &tree_path));

// Layers in the primary flow (input[0] chain) from the first root layer are root-level siblings
let mut root_ancestors = HashSet::new();
root_ancestors.insert(first_root_layer_id);

for sibling_id in network.upstream_flow_back_from_nodes(vec![first_root_layer_id], &[], FlowType::PrimaryFlow).skip(1) {
if network.is_layer(&sibling_id, &[]) && !root_ancestors.contains(&sibling_id) {
root_entries.push(self.build_layer_entry(sibling_id, &root_ancestors, &selected_layers, &instance_path));
root_entries.push(self.build_layer_entry(sibling_id, &root_ancestors, &selected_layers, &tree_path));
}
}

Expand All @@ -1803,19 +1803,19 @@ impl DocumentMessageHandler {

/// Builds a single `LayerStructureEntry` for the given layer, including its `children_present` flag,
/// `descendant_selected` flag, and (if expanded) its children collected from the graph.
fn build_layer_entry(&self, layer_id: NodeId, ancestors: &HashSet<NodeId>, selected_layers: &HashSet<NodeId>, parent_instance_path: &[NodeId]) -> LayerStructureEntry {
let mut instance_path = parent_instance_path.to_vec();
instance_path.push(layer_id);
fn build_layer_entry(&self, layer_id: NodeId, ancestors: &HashSet<NodeId>, selected_layers: &HashSet<NodeId>, parent_tree_path: &[NodeId]) -> LayerStructureEntry {
let mut tree_path = parent_tree_path.to_vec();
tree_path.push(layer_id);

let mut child_ancestors = ancestors.clone();
child_ancestors.insert(layer_id);

let children_present = self.has_layer_children_in_graph(layer_id, &child_ancestors);

let collapsed = self.collapsed.0.contains(&instance_path);
let collapsed = self.collapsed.0.contains(&tree_path);

let children = if children_present && !collapsed {
self.collect_layer_children(layer_id, &child_ancestors, selected_layers, &instance_path)
self.collect_layer_children(layer_id, &child_ancestors, selected_layers, &tree_path)
} else {
Vec::new()
};
Expand Down Expand Up @@ -1896,7 +1896,7 @@ impl DocumentMessageHandler {
/// The horizontal flow (a layer's secondary input chain) finds nested content layers, and the
/// primary flow from those (their stack's top output) finds stacked siblings at the same depth.
/// `ancestors` contains layer IDs in the current path from root, used for cycle prevention.
fn collect_layer_children(&self, layer_id: NodeId, ancestors: &HashSet<NodeId>, selected_layers: &HashSet<NodeId>, instance_path: &[NodeId]) -> Vec<LayerStructureEntry> {
fn collect_layer_children(&self, layer_id: NodeId, ancestors: &HashSet<NodeId>, selected_layers: &HashSet<NodeId>, tree_path: &[NodeId]) -> Vec<LayerStructureEntry> {
let network = &self.network_interface;

// Find the first nested layer via horizontal flow (content inside this layer)
Expand All @@ -1914,22 +1914,22 @@ impl DocumentMessageHandler {
}

// The nested layer is the first child at this depth level
let mut children = vec![self.build_layer_entry(nested_id, ancestors, selected_layers, instance_path)];
let mut children = vec![self.build_layer_entry(nested_id, ancestors, selected_layers, tree_path)];

// Primary flow from the nested layer finds stacked siblings (more children of this layer)
for sibling_id in network.upstream_flow_back_from_nodes(vec![nested_id], &[], FlowType::PrimaryFlow).skip(1) {
if network.is_layer(&sibling_id, &[]) && !ancestors.contains(&sibling_id) {
children.push(self.build_layer_entry(sibling_id, ancestors, selected_layers, instance_path));
children.push(self.build_layer_entry(sibling_id, ancestors, selected_layers, tree_path));
}
}

children
}

/// Collects instance paths for all descendant layers of the given instance path by traversing the graph.
/// Collects tree paths for all descendant layers of the given tree path by traversing the graph.
/// Used for recursive collapse to find all expandable descendants.
fn collect_descendant_instance_paths(&self, instance_path: &[NodeId]) -> Vec<Vec<NodeId>> {
let Some(&layer_id) = instance_path.last() else { return Vec::new() };
fn collect_descendant_tree_paths(&self, tree_path: &[NodeId]) -> Vec<Vec<NodeId>> {
let Some(&layer_id) = tree_path.last() else { return Vec::new() };
let network = &self.network_interface;

let mut paths = Vec::new();
Expand All @@ -1938,22 +1938,22 @@ impl DocumentMessageHandler {
// Seed with child layers via horizontal flow
for node_id in network.upstream_flow_back_from_nodes(vec![layer_id], &[], FlowType::HorizontalFlow).skip(1) {
if network.is_layer(&node_id, &[]) {
let mut child_path = instance_path.to_vec();
let mut child_path = tree_path.to_vec();
child_path.push(node_id);
stack.push((node_id, child_path));
}
}

let mut visited = HashSet::new();

// Depth-first traversal collecting all unique descendant instance paths
// Depth-first traversal collecting all unique descendant tree paths
while let Some((current_id, current_path)) = stack.pop() {
// Skip paths we've already visited to prevent cycles
if !visited.insert(current_path.clone()) {
continue;
}

// Record this descendant's instance path for collapsing
// Record this descendant's tree path for collapsing
paths.push(current_path.clone());

// Add nested content layers found via horizontal flow
Expand Down Expand Up @@ -2218,18 +2218,18 @@ impl DocumentMessageHandler {
responses.add(NodeGraphMessage::SendGraph);

// The control path layer (Blend Path / Morph Path) should start collapsed.
let instance_path = {
// Build instance path from root down to the control path layer, which is a sibling of the main layer under `parent`.
let mut instance_path: Vec<NodeId> = parent
let tree_path = {
// Build tree path from root down to the control path layer, which is a sibling of the main layer under `parent`.
let mut tree_path: Vec<NodeId> = parent
.ancestors(network_interface.document_metadata())
.take_while(|&ancestor| ancestor != LayerNodeIdentifier::ROOT_PARENT)
.map(LayerNodeIdentifier::to_node)
.collect();
instance_path.reverse();
instance_path.push(control_path_id);
instance_path
tree_path.reverse();
tree_path.push(control_path_id);
tree_path
};
responses.add(DocumentMessage::ToggleLayerExpansion { instance_path, recursive: false });
responses.add(DocumentMessage::ToggleLayerExpansion { tree_path, recursive: false });

return folder_id;
}
Expand Down Expand Up @@ -2375,7 +2375,7 @@ impl DocumentMessageHandler {
});

if layer_to_move.parent(self.metadata()) != Some(parent) {
// TODO: Fix this so it works when dragging a layer into a group parent which has a Transform node, which used to work before #2689 caused this regression by removing the empty vector table row.
// TODO: Fix this so it works when dragging a layer into a group parent which has a Transform node, which used to work before #2689 caused this regression by removing the empty `Table<Vector>` item.
// TODO: See #2688 for this issue.
let layer_local_transform = self.network_interface.document_metadata().transform_to_viewport(layer_to_move);
let undo_transform = self.network_interface.document_metadata().transform_to_viewport(parent).inverse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct GraphOperationMessageContext<'a> {
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize, ExtractField)]
pub struct GraphOperationMessageHandler {}

// GraphOperationMessageHandler always modified the document network. This is so changes to the layers panel will only affect the document network.
// GraphOperationMessageHandler always modified the document network. This is so changes to the Layers panel will only affect the document network.
// For changes to the selected network, use NodeGraphMessageHandler. No NodeGraphMessage's should be added here, since they will affect the selected nested network.
#[message_handler_data]
impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for GraphOperationMessageHandler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ impl<'a> ModifyInputsContext<'a> {
};

// If inserting a 'Path' node, insert a 'Flatten Path' node if the type is `Graphic`.
// TODO: Allow the 'Path' node to operate on table data by utilizing the reference (index or ID?) for each row.
// TODO: Allow the 'Path' node to operate on `Table` data by utilizing the reference (index or ID?) for each item.
if node_definition.identifier == "Path" {
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]);
if layer_input_type.compiled_nested_type() == Some(&concrete!(Table<Graphic>)) {
Expand Down Expand Up @@ -604,7 +604,7 @@ impl<'a> ModifyInputsContext<'a> {
self.set_input_with_refresh(InputConnector::node(artboard_node_id, 3), NodeInput::value(TaggedValue::DVec2(dimensions.into()), false), false);
}

/// Set the input, refresh the properties panel, and run the document graph if skip_rerender is false
/// Set the input, refresh the Properties panel, and run the document graph if skip_rerender is false
pub fn set_input_with_refresh(&mut self, input_connector: InputConnector, input: NodeInput, skip_rerender: bool) {
self.network_interface.set_input(&input_connector, input, &[]);
self.responses.add(PropertiesPanelMessage::Refresh);
Expand Down
Loading
Loading