Retire layer paths used throughout the code (#1531)

* Part 1

* Part 2

* Part 3

* Part 4

* Part 5

* Part 6

* Part 7

* Part 8
This commit is contained in:
Keavon Chambers
2023-12-21 19:32:46 -08:00
committed by GitHub
parent 5c7e04a725
commit 7bfe0ce55b
73 changed files with 532 additions and 798 deletions
@@ -1,7 +1,6 @@
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis};
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::prelude::*;
use graph_craft::document::{NodeId, NodeNetwork};
@@ -42,14 +41,14 @@ pub enum DocumentMessage {
BackupDocument {
network: NodeNetwork,
},
ClearLayerTree,
ClearLayersPanel,
CommitTransaction,
CreateEmptyFolder {
parent: LayerNodeIdentifier,
},
DebugPrintDocument,
DeleteLayer {
layer_path: Vec<LayerId>,
id: NodeId,
},
DeleteSelectedLayers,
DeselectAllLayers,
@@ -61,20 +60,11 @@ pub enum DocumentMessage {
flip_axis: FlipAxis,
},
GroupSelectedLayers,
ImaginateClear {
layer_path: Vec<LayerId>,
},
ImaginateGenerate {
layer_path: Vec<LayerId>,
},
ImaginateGenerate,
ImaginateRandom {
layer_path: Vec<LayerId>,
imaginate_node: Vec<NodeId>,
then_generate: bool,
},
InputFrameRasterizeRegionBelowLayer {
layer_path: Vec<LayerId>,
},
MoveSelectedLayersTo {
parent: LayerNodeIdentifier,
insert_index: isize,
@@ -106,7 +96,7 @@ pub enum DocumentMessage {
relative_index_offset: isize,
},
SelectLayer {
layer_path: Vec<LayerId>,
id: NodeId,
ctrl: bool,
shift: bool,
},
@@ -132,7 +122,7 @@ pub enum DocumentMessage {
},
StartTransaction,
ToggleLayerExpansion {
layer: NodeId,
id: NodeId,
},
Undo,
UndoFinished,
@@ -10,7 +10,6 @@ use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
use crate::messages::portfolio::document::utility_types::document_metadata::{is_artboard, DocumentMetadata, LayerNodeIdentifier};
use crate::messages::portfolio::document::utility_types::layer_panel::RawBuffer;
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ};
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::portfolio::utility_types::PersistentData;
use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::graph_modification_utils::{get_blend_mode, get_opacity};
@@ -224,7 +223,7 @@ fn root_network() -> NodeNetwork {
}
pub struct DocumentInputs<'a> {
pub document_id: u64,
pub document_id: DocumentId,
pub ipp: &'a InputPreprocessorMessageHandler,
pub persistent_data: &'a PersistentData,
pub executor: &'a mut NodeGraphExecutor,
@@ -324,7 +323,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
};
let translation = (aggregated - center) * axis;
responses.add(GraphOperationMessage::TransformChange {
layer: layer.to_path(),
layer,
transform: DAffine2::from_translation(translation),
transform_in: TransformIn::Viewport,
skip_rerender: false,
@@ -333,10 +332,10 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add(BroadcastEvent::DocumentIsDirty);
}
BackupDocument { network } => self.backup_with_document(network, responses),
ClearLayerTree => {
// Send an empty layer tree
let data_buffer: RawBuffer = Self::default().serialize_root().as_slice().into();
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer });
ClearLayersPanel => {
// Send an empty layer list
let data_buffer: RawBuffer = Self::default().serialize_root();
responses.add(FrontendMessage::UpdateDocumentLayerStructure { data_buffer });
// Clear the options bar
responses.add(LayoutMessage::SendLayout {
@@ -359,8 +358,8 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
DebugPrintDocument => {
info!("{:#?}", self.network);
}
DeleteLayer { layer_path } => {
responses.add(GraphOperationMessage::DeleteLayer { id: layer_path[0] });
DeleteLayer { id } => {
responses.add(GraphOperationMessage::DeleteLayer { id });
responses.add_front(BroadcastEvent::ToolAbort);
}
DeleteSelectedLayers => {
@@ -368,9 +367,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add_front(BroadcastEvent::SelectionChanged);
for path in self.metadata().shallowest_unique_layers(self.metadata().selected_layers()) {
responses.add_front(DocumentMessage::DeleteLayer {
layer_path: path.last().unwrap().to_path(),
});
responses.add_front(DocumentMessage::DeleteLayer { id: path.last().unwrap().to_node() });
}
responses.add(BroadcastEvent::DocumentIsDirty);
@@ -384,8 +381,8 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
DocumentStructureChanged => {
self.update_layers_panel_options_bar_widgets(responses);
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer })
let data_buffer: RawBuffer = self.serialize_root();
responses.add(FrontendMessage::UpdateDocumentLayerStructure { data_buffer })
}
DuplicateSelectedLayers => {
// TODO: Reimplement selected layer duplication
@@ -406,7 +403,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
let bbox_trans = DAffine2::from_translation(-center);
for layer in self.metadata().selected_layers() {
responses.add(GraphOperationMessage::TransformChange {
layer: layer.to_path(),
layer,
transform: DAffine2::from_scale(scale),
transform_in: TransformIn::Scope { scope: bbox_trans },
skip_rerender: false,
@@ -438,13 +435,8 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![folder_id] });
}
ImaginateClear { layer_path } => responses.add(InputFrameRasterizeRegionBelowLayer { layer_path }),
ImaginateGenerate { layer_path } => responses.add(PortfolioMessage::SubmitGraphRender { document_id, layer_path }),
ImaginateRandom {
layer_path,
imaginate_node,
then_generate,
} => {
ImaginateGenerate => responses.add(PortfolioMessage::SubmitGraphRender { document_id }),
ImaginateRandom { imaginate_node, then_generate } => {
// Generate a random seed. We only want values between -2^53 and 2^53, because integer values
// outside of this range can get rounded in f64
let random_bits = generate_uuid();
@@ -459,10 +451,9 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
// Generate the image
if then_generate {
responses.add(DocumentMessage::ImaginateGenerate { layer_path });
responses.add(DocumentMessage::ImaginateGenerate);
}
}
InputFrameRasterizeRegionBelowLayer { layer_path } => responses.add(PortfolioMessage::SubmitGraphRender { document_id, layer_path }),
MoveSelectedLayersTo { parent, insert_index } => {
let selected_layers = self.metadata().selected_layers().collect::<Vec<_>>();
@@ -496,7 +487,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
// Nudge translation
if !ipp.keyboard.key(resize) {
responses.add(GraphOperationMessage::TransformChange {
layer: layer.to_path(),
layer,
transform: DAffine2::from_translation(delta),
transform_in: TransformIn::Local,
skip_rerender: false,
@@ -525,7 +516,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
let original_transform = self.metadata().upstream_transform(layer.to_node());
let new = to.inverse() * transformation * to * original_transform;
responses.add(GraphOperationMessage::TransformSet {
layer: layer.to_path(),
layer,
transform: new,
transform_in: TransformIn::Local,
skip_rerender: false,
@@ -561,7 +552,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![layer.to_node()] });
responses.add(GraphOperationMessage::TransformSet {
layer: layer.to_path(),
layer,
transform,
transform_in: TransformIn::Local,
skip_rerender: false,
@@ -655,16 +646,15 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
SelectedLayersReorder { relative_index_offset } => {
self.selected_layers_reorder(relative_index_offset, responses);
}
SelectLayer { layer_path, ctrl, shift } => {
let clicked_node = *layer_path.last().expect("Cannot select root");
let layer = LayerNodeIdentifier::new(clicked_node, self.network());
SelectLayer { id, ctrl, shift } => {
let layer = LayerNodeIdentifier::new(id, self.network());
let mut nodes = vec![];
// If we have shift pressed and a layer already selected then fill the range
if let Some(last_selected) = self.layer_range_selection_reference.filter(|_| shift) {
nodes.push(last_selected.to_node());
nodes.push(clicked_node);
nodes.push(id);
// Fill the selection range
self.metadata()
@@ -677,13 +667,13 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
if ctrl {
// Toggle selection when holding ctrl
if self.metadata().selected_layers_contains(layer) {
responses.add_front(NodeGraphMessage::SelectedNodesRemove { nodes: vec![clicked_node] });
responses.add_front(NodeGraphMessage::SelectedNodesRemove { nodes: vec![id] });
} else {
responses.add_front(NodeGraphMessage::SelectedNodesAdd { nodes: vec![clicked_node] });
responses.add_front(NodeGraphMessage::SelectedNodesAdd { nodes: vec![id] });
}
responses.add(BroadcastEvent::SelectionChanged);
} else {
nodes.push(clicked_node);
nodes.push(id);
}
// Set our last selection reference
@@ -703,7 +693,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
SetBlendModeForSelectedLayers { blend_mode } => {
self.backup(responses);
for layer in self.metadata().selected_layers_except_artboards() {
responses.add(GraphOperationMessage::BlendModeSet { layer: layer.to_path(), blend_mode });
responses.add(GraphOperationMessage::BlendModeSet { layer, blend_mode });
}
}
SetOpacityForSelectedLayers { opacity } => {
@@ -711,7 +701,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
let opacity = opacity.clamp(0., 1.) as f32;
for layer in self.metadata().selected_layers_except_artboards() {
responses.add(GraphOperationMessage::OpacitySet { layer: layer.to_path(), opacity });
responses.add(GraphOperationMessage::OpacitySet { layer, opacity });
}
}
SetOverlaysVisibility { visible } => {
@@ -742,8 +732,8 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
responses.add_front(NodeGraphMessage::RunDocumentGraph);
}
StartTransaction => self.backup(responses),
ToggleLayerExpansion { layer } => {
let layer = LayerNodeIdentifier::new(layer, self.network());
ToggleLayerExpansion { id } => {
let layer = LayerNodeIdentifier::new(id, self.network());
if self.collapsed.contains(&layer) {
self.collapsed.retain(|&collapsed_layer| collapsed_layer != layer);
} else {
@@ -908,23 +898,23 @@ impl DocumentMessageHandler {
std::iter::empty()
}
fn serialize_structure(&self, folder: LayerNodeIdentifier, structure: &mut Vec<u64>, data: &mut Vec<LayerId>, path: &mut Vec<LayerId>) {
fn serialize_structure(&self, folder: LayerNodeIdentifier, structure: &mut Vec<LayerNodeIdentifier>, data: &mut Vec<LayerNodeIdentifier>, path: &mut Vec<LayerNodeIdentifier>) {
let mut space = 0;
for layer_node in folder.children(self.metadata()) {
data.push(layer_node.to_node());
data.push(layer_node);
space += 1;
if layer_node.has_children(self.metadata()) && !self.collapsed.contains(&layer_node) {
path.push(layer_node.to_node());
path.push(layer_node);
// TODO: Skip if folder is not expanded.
structure.push(space);
structure.push(LayerNodeIdentifier::new_unchecked(space));
self.serialize_structure(layer_node, structure, data, path);
space = 0;
path.pop();
}
}
structure.push(space | 1 << 63);
structure.push(LayerNodeIdentifier::new_unchecked(space | 1 << 63));
}
/// Serializes the layer structure into a condensed 1D structure.
@@ -959,13 +949,15 @@ impl DocumentMessageHandler {
/// [3427872634365736244,18115028555707261608,15878401910454357952]
/// [3427872634365736244,18115028555707261608,449479075714955186]
/// ```
pub fn serialize_root(&self) -> Vec<u64> {
let (mut structure, mut data) = (vec![0], Vec::new());
pub fn serialize_root(&self) -> RawBuffer {
let mut structure = vec![LayerNodeIdentifier::ROOT];
let mut data = Vec::new();
self.serialize_structure(self.metadata().root(), &mut structure, &mut data, &mut vec![]);
structure[0] = structure.len() as u64 - 1;
structure[0] = LayerNodeIdentifier::new_unchecked(structure.len() as NodeId - 1);
structure.extend(data);
structure
structure.iter().map(|id| id.to_node()).collect::<Vec<_>>().as_slice().into()
}
/// Places a document into the history system
@@ -1064,10 +1056,9 @@ impl DocumentMessageHandler {
///
/// This function updates the insert index so that it points to the same place after the specified `layers` are deleted.
fn update_insert_index(&self, layers: &[LayerNodeIdentifier], parent: LayerNodeIdentifier, insert_index: isize) -> isize {
let layer_ids_above = parent.children(self.metadata()).take(if insert_index < 0 { usize::MAX } else { insert_index as usize });
let new_insert_index = layer_ids_above.filter(|layer_id| !layers.contains(layer_id)).count() as isize;
new_insert_index
let take_amount = if insert_index < 0 { usize::MAX } else { insert_index as usize };
let layer_ids_above = parent.children(self.metadata()).take(take_amount);
layer_ids_above.filter(|layer_id| !layers.contains(layer_id)).count() as isize
}
pub fn new_layer_parent(&self) -> LayerNodeIdentifier {
@@ -1,5 +1,4 @@
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::prelude::*;
use bezier_rs::Subpath;
@@ -16,56 +15,54 @@ use graphene_core::{Artboard, Color};
use glam::{DAffine2, DVec2, IVec2};
pub type LayerIdentifier = Vec<LayerId>;
#[impl_message(Message, DocumentMessage, GraphOperation)]
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum GraphOperationMessage {
FillSet {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
fill: Fill,
},
OpacitySet {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
opacity: f32,
},
BlendModeSet {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
blend_mode: BlendMode,
},
UpdateBounds {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
old_bounds: [DVec2; 2],
new_bounds: [DVec2; 2],
},
StrokeSet {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
stroke: Stroke,
},
TransformChange {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
transform: DAffine2,
transform_in: TransformIn,
skip_rerender: bool,
},
TransformSet {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
transform: DAffine2,
transform_in: TransformIn,
skip_rerender: bool,
},
TransformSetPivot {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
pivot: DVec2,
},
Vector {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
modification: VectorDataModification,
},
Brush {
layer: LayerIdentifier,
layer: LayerNodeIdentifier,
strokes: Vec<BrushStroke>,
},
@@ -1,6 +1,5 @@
use super::{resolve_document_node_type, VectorDataModification};
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::prelude::*;
use bezier_rs::Subpath;
@@ -26,7 +25,6 @@ struct ModifyInputsContext<'a> {
document_network: &'a mut NodeNetwork,
node_graph: &'a mut NodeGraphMessageHandler,
responses: &'a mut VecDeque<Message>,
layer: &'a [LayerId],
outwards_links: HashMap<NodeId, Vec<NodeId>>,
layer_node: Option<NodeId>,
}
@@ -38,27 +36,25 @@ impl<'a> ModifyInputsContext<'a> {
document_network,
node_graph,
responses,
layer: &[],
layer_node: None,
document_metadata,
}
}
fn new_with_layer(
layer: &'a [LayerId],
id: NodeId,
document_network: &'a mut NodeNetwork,
document_metadata: &'a mut DocumentMetadata,
node_graph: &'a mut NodeGraphMessageHandler,
responses: &'a mut VecDeque<Message>,
) -> Option<Self> {
let mut document = Self::new(document_network, document_metadata, node_graph, responses);
let Some(mut id) = layer.last().copied() else {
error!("Tried to modify root layer");
return None;
};
let mut id = id;
while !document.document_network.nodes.get(&id)?.is_layer() {
id = document.outwards_links.get(&id)?.first().copied()?;
}
document.layer_node = Some(id);
Some(document)
}
@@ -325,10 +321,9 @@ impl<'a> ModifyInputsContext<'a> {
self.node_graph.network.clear();
self.responses.add(PropertiesPanelMessage::Refresh);
let layer_path = self.layer.to_vec();
if !skip_rerender {
self.responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
self.responses.add(NodeGraphMessage::RunDocumentGraph);
} else {
// Code was removed from here which cleared the frame
}
@@ -354,10 +349,9 @@ impl<'a> ModifyInputsContext<'a> {
}
self.responses.add(PropertiesPanelMessage::Refresh);
let layer_path = self.layer.to_vec();
if !skip_rerender {
self.responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
self.responses.add(NodeGraphMessage::RunDocumentGraph);
} else {
// Code was removed from here which cleared the frame
}
@@ -509,8 +503,8 @@ impl<'a> ModifyInputsContext<'a> {
self.update_bounds([old_bounds_min, old_bounds_max], [new_bounds_min, new_bounds_max]);
if empty {
if let Some(layer) = self.layer_node {
self.responses.add(DocumentMessage::DeleteLayer { layer_path: vec![layer] })
if let Some(id) = self.layer_node {
self.responses.add(DocumentMessage::DeleteLayer { id })
}
}
}
@@ -594,27 +588,27 @@ impl MessageHandler<GraphOperationMessage, (&mut NodeNetwork, &mut DocumentMetad
) {
match message {
GraphOperationMessage::FillSet { layer, fill } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.fill_set(fill);
}
}
GraphOperationMessage::OpacitySet { layer, opacity } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.opacity_set(opacity);
}
}
GraphOperationMessage::BlendModeSet { layer, blend_mode } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.blend_mode_set(blend_mode);
}
}
GraphOperationMessage::UpdateBounds { layer, old_bounds, new_bounds } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.update_bounds(old_bounds, new_bounds);
}
}
GraphOperationMessage::StrokeSet { layer, stroke } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.stroke_set(stroke);
}
}
@@ -624,10 +618,9 @@ impl MessageHandler<GraphOperationMessage, (&mut NodeNetwork, &mut DocumentMetad
transform_in,
skip_rerender,
} => {
let layer_identifier = LayerNodeIdentifier::new(*layer.last().unwrap(), document_network);
let parent_transform = document_metadata.downstream_transform_to_viewport(layer_identifier);
let bounds = LayerBounds::new(document_network, document_metadata, &layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
let parent_transform = document_metadata.downstream_transform_to_viewport(layer);
let bounds = LayerBounds::new(document_metadata, layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.transform_change(transform, transform_in, parent_transform, bounds, skip_rerender);
}
}
@@ -637,28 +630,27 @@ impl MessageHandler<GraphOperationMessage, (&mut NodeNetwork, &mut DocumentMetad
transform_in,
skip_rerender,
} => {
let layer_identifier = LayerNodeIdentifier::new(*layer.last().unwrap(), document_network);
let parent_transform = document_metadata.downstream_transform_to_viewport(layer_identifier);
let parent_transform = document_metadata.downstream_transform_to_viewport(layer);
let current_transform = Some(document_metadata.transform_to_viewport(layer_identifier));
let bounds = LayerBounds::new(document_network, document_metadata, &layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
let current_transform = Some(document_metadata.transform_to_viewport(layer));
let bounds = LayerBounds::new(document_metadata, layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.transform_set(transform, transform_in, parent_transform, current_transform, bounds, skip_rerender);
}
}
GraphOperationMessage::TransformSetPivot { layer, pivot } => {
let bounds = LayerBounds::new(document_network, document_metadata, &layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
let bounds = LayerBounds::new(document_metadata, layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.pivot_set(pivot, bounds);
}
}
GraphOperationMessage::Vector { layer, modification } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.vector_modify(modification);
}
}
GraphOperationMessage::Brush { layer, strokes } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&layer, document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(layer.to_node(), document_network, document_metadata, node_graph, responses) {
modify_inputs.brush_modify(strokes);
}
}
@@ -744,7 +736,7 @@ impl MessageHandler<GraphOperationMessage, (&mut NodeNetwork, &mut DocumentMetad
load_network_structure(document_network, document_metadata, collapsed);
}
GraphOperationMessage::ResizeArtboard { id, location, dimensions } => {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(&[id], document_network, document_metadata, node_graph, responses) {
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(id, document_network, document_metadata, node_graph, responses) {
modify_inputs.resize_artboard(location, dimensions);
}
}
@@ -2,7 +2,6 @@ use crate::messages::portfolio::document::node_graph::VectorDataModification;
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
use bezier_rs::{ManipulatorGroup, Subpath};
use graph_craft::document::NodeNetwork;
use graph_craft::document::{value::TaggedValue, NodeInput};
use graphene_core::uuid::ManipulatorGroupId;
use graphene_core::vector::{ManipulatorPointId, SelectedType};
@@ -53,8 +52,7 @@ pub struct LayerBounds {
impl LayerBounds {
/// Extract the layer bounds and their transform for a layer.
pub fn new(document_network: &NodeNetwork, document_metadata: &DocumentMetadata, layer: &[u64]) -> Self {
let layer = LayerNodeIdentifier::new(*layer.last().unwrap(), document_network);
pub fn new(document_metadata: &DocumentMetadata, layer: LayerNodeIdentifier) -> Self {
Self {
bounds: document_metadata.nonzero_bounding_box(layer),
bounds_transform: DAffine2::IDENTITY,
@@ -1,4 +1,3 @@
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::prelude::*;
use graph_craft::document::value::TaggedValue;
@@ -11,14 +10,13 @@ pub enum NodeGraphMessage {
Init,
SelectedNodesUpdated,
ConnectNodesByLink {
output_node: u64,
output_node: NodeId,
output_node_connector_index: usize,
input_node: u64,
input_node: NodeId,
input_node_connector_index: usize,
},
Copy,
CreateNode {
// Having the caller generate the id means that we don't have to return it. This can be a random u64.
node_id: Option<NodeId>,
node_type: String,
x: i32,
@@ -83,7 +81,6 @@ pub enum NodeGraphMessage {
input: NodeInput,
},
SetQualifiedInputValue {
layer_path: Vec<LayerId>,
node_path: Vec<NodeId>,
input_index: usize,
value: TaggedValue,
@@ -3,9 +3,7 @@ use super::load_network_structure;
use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::prelude::*;
use crate::node_graph_executor::GraphIdentifier;
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork, NodeOutput};
@@ -99,13 +97,13 @@ pub struct FrontendNode {
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
pub struct FrontendNodeLink {
#[serde(rename = "linkStart")]
pub link_start: u64,
pub link_start: NodeId,
#[serde(rename = "linkStartOutputIndex")]
pub link_start_output_index: usize,
#[serde(rename = "linkEnd")]
pub link_end: u64,
pub link_end: NodeId,
#[serde(rename = "linkEndInputIndex")]
pub link_end_input_index: u64,
pub link_end_input_index: usize,
}
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
@@ -124,10 +122,9 @@ impl FrontendNodeType {
#[derive(Debug, Clone, PartialEq)]
pub struct NodeGraphMessageHandler {
pub layer_path: Option<Vec<LayerId>>,
pub network: Vec<NodeId>,
has_selection: bool,
pub widgets: [LayoutGroup; 2],
widgets: [LayoutGroup; 2],
}
impl Default for NodeGraphMessageHandler {
@@ -137,7 +134,6 @@ impl Default for NodeGraphMessageHandler {
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()],
@@ -261,15 +257,13 @@ impl NodeGraphMessageHandler {
}
}
fn send_graph(network: &NodeNetwork, layer_path: &Option<Vec<LayerId>>, graph_view_overlay_open: bool, responses: &mut VecDeque<Message>) {
fn send_graph(network: &NodeNetwork, graph_view_overlay_open: bool, responses: &mut VecDeque<Message>) {
responses.add(PropertiesPanelMessage::Refresh);
if !graph_view_overlay_open {
return;
}
let layer_id = layer_path.as_ref().and_then(|path| path.last().copied());
// List of links in format (link_start, link_end, link_end_input_index)
let links = network
.nodes
@@ -278,16 +272,16 @@ impl NodeGraphMessageHandler {
.filter_map(|(input, &link_end, link_end_input_index)| {
if let NodeInput::Node {
node_id: link_start,
output_index: link_start_index,
output_index: link_start_output_index,
// TODO: add ui for lambdas
lambda: _,
} = *input
{
Some(FrontendNodeLink {
link_start,
link_start_output_index: link_start_index,
link_start_output_index,
link_end,
link_end_input_index: link_end_input_index as u64,
link_end_input_index,
})
} else {
None
@@ -318,8 +312,6 @@ impl NodeGraphMessageHandler {
});
let primary_output = if node.has_primary_output { outputs.next() } else { None };
let _graph_identifier = GraphIdentifier::new(layer_id);
nodes.push(FrontendNode {
is_layer: node.is_layer(),
id: *id,
@@ -446,7 +438,7 @@ impl NodeGraphMessageHandler {
pub struct NodeGraphHandlerData<'a> {
pub document_network: &'a mut NodeNetwork,
pub document_metadata: &'a mut DocumentMetadata,
pub document_id: u64,
pub document_id: DocumentId,
pub document_name: &'a str,
pub collapsed: &'a mut Vec<LayerNodeIdentifier>,
pub input: &'a InputPreprocessorMessageHandler,
@@ -495,7 +487,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
error!("No network");
return;
};
let Some(input_node) = network.nodes.get(&input_node) else {
let Some(input_node) = network.nodes.get(&node_id) else {
error!("No to");
return;
};
@@ -569,11 +561,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
if let Some(network) = document_network.nested_network(&self.network) {
// Only generate node graph if one of the selected nodes is connected to the output
if metadata.selected_nodes().any(|&node_id| network.connected_to_output(node_id)) {
if let Some(layer_path) = self.layer_path.clone() {
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
} else {
responses.add(NodeGraphMessage::RunDocumentGraph);
}
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}
}
@@ -612,7 +600,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
}
}
if let Some(network) = document_network.nested_network(&self.network) {
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
}
self.update_selected(document_network, metadata, responses);
}
@@ -640,7 +628,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
responses.add(NodeGraphMessage::InsertNode { node_id, document_node });
}
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
self.update_selected(document_network, metadata, responses);
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
}
@@ -653,7 +641,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
self.network.pop();
}
if let Some(network) = document_network.nested_network(&self.network) {
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
}
self.update_selected(document_network, metadata, responses);
}
@@ -703,7 +691,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
node.metadata.position += IVec2::new(displacement_x, displacement_y)
}
}
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
}
NodeGraphMessage::PasteNodes { serialized_nodes } => {
let Some(network) = document_network.nested_network(&self.network) else {
@@ -752,7 +740,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
}
NodeGraphMessage::RunDocumentGraph => responses.add(PortfolioMessage::SubmitGraphRender { document_id, layer_path: Vec::new() }),
NodeGraphMessage::RunDocumentGraph => responses.add(PortfolioMessage::SubmitGraphRender { document_id }),
NodeGraphMessage::SelectedNodesAdd { nodes } => {
metadata.add_selected_nodes(nodes);
responses.add(BroadcastEvent::SelectionChanged);
@@ -768,13 +756,9 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
}
NodeGraphMessage::SendGraph { should_rerender } => {
if let Some(network) = document_network.nested_network(&self.network) {
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
if should_rerender {
if let Some(layer_path) = self.layer_path.clone() {
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
} else {
responses.add(NodeGraphMessage::RunDocumentGraph);
}
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}
}
@@ -787,11 +771,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
responses.add(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
responses.add(PropertiesPanelMessage::Refresh);
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id) {
if let Some(layer_path) = self.layer_path.clone() {
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
} else {
responses.add(NodeGraphMessage::RunDocumentGraph);
}
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}
}
@@ -811,12 +791,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
}
}
}
NodeGraphMessage::SetQualifiedInputValue {
layer_path,
node_path,
input_index,
value,
} => {
NodeGraphMessage::SetQualifiedInputValue { node_path, input_index, value } => {
let Some((node_id, node_path)) = node_path.split_last() else {
error!("Node path is empty");
return;
@@ -832,7 +807,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
}
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
if network.connected_to_output(*node_id) {
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}
}
@@ -908,7 +883,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
} else if !network.inputs.contains(&node_id) && !network.original_outputs().iter().any(|output| output.node_id == node_id) {
network.disabled.push(node_id);
}
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
// Only generate node graph if one of the selected nodes is connected to the output
if network.connected_to_output(node_id) {
@@ -944,21 +919,17 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
} else {
return;
}
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
}
self.update_selection_action_buttons(document_network, metadata, responses);
if let Some(layer_path) = self.layer_path.clone() {
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
} else {
responses.add(NodeGraphMessage::RunDocumentGraph);
}
responses.add(NodeGraphMessage::RunDocumentGraph);
}
NodeGraphMessage::UpdateNewNodeGraph => {
if let Some(network) = document_network.nested_network(&self.network) {
metadata.clear_selected_nodes();
responses.add(BroadcastEvent::SelectionChanged);
Self::send_graph(network, &self.layer_path, graph_view_overlay_open, responses);
Self::send_graph(network, graph_view_overlay_open, responses);
let node_types = document_node_types::collect_node_types();
responses.add(FrontendMessage::UpdateNodeTypes { node_types });
@@ -2,7 +2,6 @@ use super::{node_properties, FrontendGraphDataType, FrontendNodeType};
use crate::consts::{DEFAULT_FONT_FAMILY, DEFAULT_FONT_STYLE};
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::document_metadata::DocumentMetadata;
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::portfolio::utility_types::PersistentData;
use crate::messages::prelude::Message;
use crate::node_graph_executor::NodeGraphExecutor;
@@ -74,7 +73,6 @@ impl DocumentOutputType {
pub struct NodePropertiesContext<'a> {
pub persistent_data: &'a PersistentData,
pub responses: &'a mut VecDeque<Message>,
pub layer_path: &'a [LayerId],
pub nested_path: &'a [NodeId],
pub executor: &'a mut NodeGraphExecutor,
pub network: &'a NodeNetwork,
@@ -279,7 +277,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Image Frame",
data_type: FrontendGraphDataType::Raster,
}],
properties: node_properties::input_properties,
properties: node_properties::node_no_properties,
..Default::default()
},
DocumentNodeDefinition {
@@ -1069,7 +1067,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "OutputBuffer",
data_type: FrontendGraphDataType::General,
}],
properties: node_properties::input_properties,
properties: node_properties::node_no_properties,
..Default::default()
},
#[cfg(feature = "gpu")]
@@ -1137,7 +1135,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "CommandBuffer",
data_type: FrontendGraphDataType::General,
}],
properties: node_properties::input_properties,
properties: node_properties::node_no_properties,
..Default::default()
},
#[cfg(feature = "gpu")]
@@ -1171,7 +1169,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "PipelineLayout",
data_type: FrontendGraphDataType::General,
}],
properties: node_properties::input_properties,
properties: node_properties::node_no_properties,
..Default::default()
},
#[cfg(feature = "gpu")]
@@ -2377,7 +2375,7 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
name: "Imaginate",
category: "Image Synthesis",
implementation: NodeImplementation::DocumentNode(NodeNetwork {
inputs: vec![0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
inputs: vec![0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
outputs: vec![NodeOutput::new(1, 0)],
nodes: [
(
@@ -2404,14 +2402,13 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
NodeInput::Network(concrete!(String)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(Option<Vec<u64>>)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(ImaginateMaskStartingFill)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(bool)),
],
implementation: DocumentNodeImplementation::proto("graphene_std::raster::ImaginateNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>"),
implementation: DocumentNodeImplementation::proto("graphene_std::raster::ImaginateNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>"),
..Default::default()
},
),
@@ -2436,7 +2433,6 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
DocumentInputType::value("Negative Prompt", TaggedValue::String(String::new()), false),
DocumentInputType::value("Adapt Input Image", TaggedValue::Bool(false), false),
DocumentInputType::value("Image Creativity", TaggedValue::F32(66.), false),
DocumentInputType::value("Masking Layer", TaggedValue::LayerPath(None), false),
DocumentInputType::value("Inpaint", TaggedValue::Bool(true), false),
DocumentInputType::value("Mask Blur", TaggedValue::F32(4.), false),
DocumentInputType::value("Mask Starting Fill", TaggedValue::ImaginateMaskStartingFill(ImaginateMaskStartingFill::Fill), false),
@@ -144,16 +144,16 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
NumberInput::new(Some(dvec2.x))
.label(x)
.unit(unit)
.min(min.unwrap_or(-((1u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1u64 << std::f64::MANTISSA_DIGITS) as f64)
.min(min.unwrap_or(-((1_u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1_u64 << std::f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(move |input: &NumberInput| TaggedValue::DVec2(DVec2::new(input.value.unwrap(), dvec2.y)), node_id, index))
.widget_holder(),
Separator::new(SeparatorType::Related).widget_holder(),
NumberInput::new(Some(dvec2.y))
.label(y)
.unit(unit)
.min(min.unwrap_or(-((1u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1u64 << std::f64::MANTISSA_DIGITS) as f64)
.min(min.unwrap_or(-((1_u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1_u64 << std::f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(move |input: &NumberInput| TaggedValue::DVec2(DVec2::new(dvec2.x, input.value.unwrap())), node_id, index))
.widget_holder(),
]);
@@ -170,8 +170,8 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
.int()
.label(x)
.unit(unit)
.min(min.unwrap_or(-((1u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1u64 << std::f64::MANTISSA_DIGITS) as f64)
.min(min.unwrap_or(-((1_u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1_u64 << std::f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(update_x, node_id, index))
.widget_holder(),
Separator::new(SeparatorType::Related).widget_holder(),
@@ -179,8 +179,8 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
.int()
.label(y)
.unit(unit)
.min(min.unwrap_or(-((1u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1u64 << std::f64::MANTISSA_DIGITS) as f64)
.min(min.unwrap_or(-((1_u64 << std::f64::MANTISSA_DIGITS) as f64)))
.max((1_u64 << std::f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(update_y, node_id, index))
.widget_holder(),
]);
@@ -198,7 +198,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
.label(x)
.unit(unit)
.min(min.unwrap_or(0.))
.max((1u64 << std::f64::MANTISSA_DIGITS) as f64)
.max((1_u64 << std::f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(update_x, node_id, index))
.widget_holder(),
Separator::new(SeparatorType::Related).widget_holder(),
@@ -207,7 +207,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
.label(y)
.unit(unit)
.min(min.unwrap_or(0.))
.max((1u64 << std::f64::MANTISSA_DIGITS) as f64)
.max((1_u64 << std::f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(update_y, node_id, index))
.widget_holder(),
]);
@@ -359,7 +359,7 @@ fn number_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
}
//TODO Generalize this instead of using a separate function per dropdown menu enum
fn color_channel(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn color_channel(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::RedGreenBlue(mode),
@@ -382,7 +382,7 @@ fn color_channel(document_node: &DocumentNode, node_id: u64, index: usize, name:
}
// TODO Generalize this instead of using a separate function per dropdown menu enum
fn noise_type(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn noise_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::NoiseType(noise_type),
@@ -403,7 +403,7 @@ fn noise_type(document_node: &DocumentNode, node_id: u64, index: usize, name: &s
}
// TODO Generalize this instead of using a separate function per dropdown menu enum
fn fractal_type(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
fn fractal_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::FractalType(fractal_type),
@@ -424,7 +424,7 @@ fn fractal_type(document_node: &DocumentNode, node_id: u64, index: usize, name:
}
// TODO Generalize this instead of using a separate function per dropdown menu enum
fn cellular_distance_function(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
fn cellular_distance_function(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::CellularDistanceFunction(cellular_distance_function),
@@ -450,7 +450,7 @@ fn cellular_distance_function(document_node: &DocumentNode, node_id: u64, index:
}
// TODO Generalize this instead of using a separate function per dropdown menu enum
fn cellular_return_type(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
fn cellular_return_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::CellularReturnType(cellular_return_type),
@@ -471,7 +471,7 @@ fn cellular_return_type(document_node: &DocumentNode, node_id: u64, index: usize
}
// TODO Generalize this instead of using a separate function per dropdown menu enum
fn domain_warp_type(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
fn domain_warp_type(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool, disabled: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::DomainWarpType(domain_warp_type),
@@ -492,7 +492,7 @@ fn domain_warp_type(document_node: &DocumentNode, node_id: u64, index: usize, na
}
// TODO: Generalize this instead of using a separate function per dropdown menu enum
fn blend_mode(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn blend_mode(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::BlendMode(blend_mode),
@@ -520,7 +520,7 @@ fn blend_mode(document_node: &DocumentNode, node_id: u64, index: usize, name: &s
}
// TODO: Generalize this for all dropdowns (also see blend_mode and channel_extration)
fn luminance_calculation(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn luminance_calculation(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::LuminanceCalculation(calculation),
@@ -542,7 +542,7 @@ fn luminance_calculation(document_node: &DocumentNode, node_id: u64, index: usiz
LayoutGroup::Row { widgets }.with_tooltip("Formula used to calculate the luminance of a pixel")
}
fn line_cap_widget(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn line_cap_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::LineCap(line_cap),
@@ -562,7 +562,7 @@ fn line_cap_widget(document_node: &DocumentNode, node_id: u64, index: usize, nam
LayoutGroup::Row { widgets }
}
fn line_join_widget(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn line_join_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let &NodeInput::Value {
tagged_value: TaggedValue::LineJoin(line_join),
@@ -582,7 +582,7 @@ fn line_join_widget(document_node: &DocumentNode, node_id: u64, index: usize, na
LayoutGroup::Row { widgets }
}
fn fill_type_widget(document_node: &DocumentNode, node_id: u64, index: usize) -> LayoutGroup {
fn fill_type_widget(document_node: &DocumentNode, node_id: NodeId, index: usize) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, "Fill Type", FrontendGraphDataType::General, true);
if let &NodeInput::Value {
tagged_value: TaggedValue::FillType(fill_type),
@@ -607,7 +607,7 @@ fn fill_type_widget(document_node: &DocumentNode, node_id: u64, index: usize) ->
LayoutGroup::Row { widgets }
}
fn gradient_type_widget(document_node: &DocumentNode, node_id: u64, index: usize) -> LayoutGroup {
fn gradient_type_widget(document_node: &DocumentNode, node_id: NodeId, index: usize) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, "Gradient Type", FrontendGraphDataType::General, true);
if let &NodeInput::Value {
tagged_value: TaggedValue::GradientType(gradient_type),
@@ -699,7 +699,7 @@ fn gradient_row(row: &mut Vec<WidgetHolder>, positions: &Vec<(f64, Option<Color>
}
}
fn gradient_positions(rows: &mut Vec<LayoutGroup>, document_node: &DocumentNode, name: &str, node_id: u64, input_index: usize) {
fn gradient_positions(rows: &mut Vec<LayoutGroup>, document_node: &DocumentNode, name: &str, node_id: NodeId, input_index: usize) {
let mut widgets = vec![expose_widget(node_id, input_index, FrontendGraphDataType::General, document_node.inputs[input_index].is_exposed())];
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
if let NodeInput::Value {
@@ -742,7 +742,7 @@ fn gradient_positions(rows: &mut Vec<LayoutGroup>, document_node: &DocumentNode,
}
}
fn color_widget(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, color_props: ColorButton, blank_assist: bool) -> LayoutGroup {
fn color_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, color_props: ColorButton, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Number, blank_assist);
if let NodeInput::Value { tagged_value, exposed: false } = &document_node.inputs[index] {
@@ -767,7 +767,7 @@ fn color_widget(document_node: &DocumentNode, node_id: u64, index: usize, name:
LayoutGroup::Row { widgets }
}
fn curves_widget(document_node: &DocumentNode, node_id: u64, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
fn curves_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> LayoutGroup {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
if let NodeInput::Value {
@@ -785,17 +785,6 @@ fn curves_widget(document_node: &DocumentNode, node_id: u64, index: usize, name:
LayoutGroup::Row { widgets }
}
/// 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 = TextLabel::new("The graph's input frame is the rasterized artwork under the layer").widget_holder();
let layer_path = context.layer_path.to_vec();
let refresh_button = TextButton::new("Refresh Input")
.tooltip("Refresh the artwork under the layer")
.on_update(move |_| DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path: layer_path.clone() }.into())
.widget_holder();
vec![LayoutGroup::Row { widgets: vec![information] }, LayoutGroup::Row { widgets: vec![refresh_button] }]
}
pub fn levels_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let input_shadows = number_widget(document_node, node_id, 1, "Shadows", NumberInput::default().min(0.).max(100.).unit("%"), true);
let input_midtones = number_widget(document_node, node_id, 2, "Midtones", NumberInput::default().min(0.).max(100.).unit("%"), true);
@@ -1629,12 +1618,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
.tooltip("Generate with a new random seed")
.on_update({
let imaginate_node = imaginate_node.clone();
let layer_path = context.layer_path.to_vec();
let controller = controller.clone();
move |_| {
controller.trigger_regenerate();
DocumentMessage::ImaginateRandom {
layer_path: layer_path.clone(),
imaginate_node: imaginate_node.clone(),
then_generate: true,
}
@@ -1646,11 +1633,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
TextButton::new("Generate")
.tooltip("Fill layer frame by generating a new image")
.on_update({
let layer_path = context.layer_path.to_vec();
let controller = controller.clone();
move |_| {
controller.trigger_regenerate();
DocumentMessage::ImaginateGenerate { layer_path: layer_path.clone() }.into()
DocumentMessage::ImaginateGenerate.into()
}
})
.widget_holder(),
@@ -1659,11 +1645,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
.tooltip("Remove generated image from the layer frame")
.disabled(!matches!(imaginate_status, ImaginateStatus::ReadyDone))
.on_update({
let layer_path = context.layer_path.to_vec();
let controller = controller.clone();
move |_| {
controller.set_status(ImaginateStatus::Ready);
DocumentMessage::ImaginateClear { layer_path: layer_path.clone() }.into()
DocumentMessage::ImaginateGenerate.into()
}
})
.widget_holder(),
@@ -1687,10 +1672,8 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
.tooltip("Set a new random seed")
.on_update({
let imaginate_node = imaginate_node.clone();
let layer_path = context.layer_path.to_vec();
move |_| {
DocumentMessage::ImaginateRandom {
layer_path: layer_path.clone(),
imaginate_node: imaginate_node.clone(),
then_generate: false,
}
@@ -1701,8 +1684,8 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
Separator::new(SeparatorType::Unrelated).widget_holder(),
NumberInput::new(Some(seed))
.int()
.min(-((1u64 << f64::MANTISSA_DIGITS) as f64))
.max((1u64 << f64::MANTISSA_DIGITS) as f64)
.min(-((1_u64 << f64::MANTISSA_DIGITS) as f64))
.max((1_u64 << f64::MANTISSA_DIGITS) as f64)
.on_update(update_value(move |input: &NumberInput| TaggedValue::F64(input.value.unwrap()), node_id, seed_index))
.mode(NumberInputMode::Increment)
.widget_holder(),
@@ -37,7 +37,6 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
persistent_data,
responses,
nested_path: &node_graph_message_handler.network,
layer_path: &[],
executor,
network: document_network,
metadata: document_metadata,
@@ -107,8 +107,9 @@ impl DocumentMetadata {
layer_path
})
.collect::<Vec<_>>();
sorted_layers.sort();
// Sorting here creates groups of similar UUID paths
sorted_layers.sort();
sorted_layers.dedup_by(|a, b| a.starts_with(b));
sorted_layers
}
@@ -386,32 +387,27 @@ impl LayerNodeIdentifier {
u64::from(self.0) - 1
}
/// Convert layer to layer path
pub fn to_path(self) -> Vec<NodeId> {
vec![self.to_node()]
}
/// Access the parent layer if possible
pub fn parent(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> {
document_metadata.get_relations(self).and_then(|relations| relations.parent)
}
/// Access the previous sibling of this layer (up the layer tree)
/// Access the previous sibling of this layer (up the Layers panel)
pub fn previous_sibling(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> {
document_metadata.get_relations(self).and_then(|relations| relations.previous_sibling)
}
/// Access the next sibling of this layer (down the layer tree)
/// Access the next sibling of this layer (down the Layers panel)
pub fn next_sibling(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> {
document_metadata.get_relations(self).and_then(|relations| relations.next_sibling)
}
/// Access the first child of this layer (top most in layer tree)
/// Access the first child of this layer (top most in Layers panel)
pub fn first_child(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> {
document_metadata.get_relations(self).and_then(|relations| relations.first_child)
}
/// Access the last child of this layer (bottom most in layer tree)
/// Access the last child of this layer (bottom most in Layers panel)
pub fn last_child(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> {
document_metadata.get_relations(self).and_then(|relations| relations.last_child)
}
@@ -457,7 +453,7 @@ impl LayerNodeIdentifier {
}
}
/// Add a child towards the top of the layer tree
/// Add a child towards the top of the Layers panel
pub fn push_front_child(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) {
assert!(!document_metadata.structure.contains_key(&new), "Cannot add already existing layer");
let parent = document_metadata.get_structure_mut(self);
@@ -470,7 +466,7 @@ impl LayerNodeIdentifier {
document_metadata.get_structure_mut(new).parent = Some(self);
}
/// Add a child towards the bottom of the layer tree
/// Add a child towards the bottom of the Layers panel
pub fn push_child(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) {
assert!(!document_metadata.structure.contains_key(&new), "Cannot add already existing layer");
let parent = document_metadata.get_structure_mut(self);
@@ -483,7 +479,7 @@ impl LayerNodeIdentifier {
document_metadata.get_structure_mut(new).parent = Some(self);
}
/// Add sibling above in the layer tree
/// Add sibling above in the Layers panel
pub fn add_before(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) {
assert!(!document_metadata.structure.contains_key(&new), "Cannot add already existing layer");
document_metadata.get_structure_mut(new).next_sibling = Some(self);
@@ -501,7 +497,7 @@ impl LayerNodeIdentifier {
}
}
/// Add sibling below in the layer tree
/// Add sibling below in the Layers panel
pub fn add_after(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) {
assert!(!document_metadata.structure.contains_key(&new), "Cannot add already existing layer");
document_metadata.get_structure_mut(new).previous_sibling = Some(self);
@@ -1,4 +1,4 @@
use crate::messages::portfolio::document::utility_types::LayerId;
use graph_craft::document::NodeId;
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
@@ -45,6 +45,9 @@ pub struct LayerPanelEntry {
pub layer_classification: LayerClassification,
pub selected: bool,
pub expanded: bool,
pub path: Vec<LayerId>,
#[serde(rename = "parentId")]
pub parent_id: Option<NodeId>,
pub id: NodeId,
pub depth: usize,
pub thumbnail: String,
}
@@ -1,7 +1,4 @@
pub use super::layer_panel::LayerPanelEntry;
use crate::messages::portfolio::document::utility_types::LayerId;
use graphene_core::raster::color::Color;
use glam::DVec2;
use serde::{Deserialize, Serialize};
@@ -54,12 +51,6 @@ impl DocumentMode {
}
}
pub enum DocumentRenderMode<'a> {
Root,
OnlyBelowLayerInFolder(&'a [LayerId]),
LayerCutout(&'a [LayerId], Color),
}
#[derive(Clone, Debug)]
/// SnappingState determines the current individual snapping states
pub struct SnappingState {
@@ -4,8 +4,3 @@ pub mod error;
pub mod layer_panel;
pub mod misc;
pub mod transformation;
// TODO: Remove this entirely
/// A number that identifies a layer.
/// This does not technically need to be unique globally, only within a folder.
pub type LayerId = u64;
@@ -376,7 +376,7 @@ impl<'a> Selected<'a> {
let to = document_metadata.downstream_transform_to_viewport(layer);
let new = to.inverse() * transformation * to * original_transform;
responses.add(GraphOperationMessage::TransformSet {
layer: layer.to_path(),
layer,
transform: new,
transform_in: TransformIn::Local,
skip_rerender: false,
@@ -404,7 +404,7 @@ impl<'a> Selected<'a> {
let position = new_pos_viewport;
responses.add(GraphOperationMessage::Vector {
layer: layer.to_path(),
layer,
modification: VectorDataModification::SetManipulatorPosition { point, position },
});
}
@@ -438,17 +438,17 @@ impl<'a> Selected<'a> {
OriginalTransforms::Layer(hash) => {
let Some(matrix) = hash.get(&layer) else { continue };
self.responses.add(GraphOperationMessage::TransformSet {
layer: layer.to_path(),
layer,
transform: *matrix,
transform_in: TransformIn::Local,
skip_rerender: false,
});
}
OriginalTransforms::Path(path) => {
for (layer, points) in path {
for (&layer, points) in path {
for &(point, position) in points {
self.responses.add(GraphOperationMessage::Vector {
layer: layer.to_path(),
layer,
modification: VectorDataModification::SetManipulatorPosition { point, position },
});
}
@@ -1,8 +1,8 @@
use super::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::frontend::utility_types::{ExportBounds, FileType};
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
use crate::messages::portfolio::document::utility_types::LayerId;
use crate::messages::prelude::*;
use graphene_core::text::Font;
use serde::{Deserialize, Serialize};
@@ -22,21 +22,21 @@ pub enum PortfolioMessage {
// Messages
#[remain::unsorted]
DocumentPassMessage {
document_id: u64,
document_id: DocumentId,
message: DocumentMessage,
},
AutoSaveActiveDocument,
AutoSaveDocument {
document_id: u64,
document_id: DocumentId,
},
CloseActiveDocumentWithConfirmation,
CloseAllDocuments,
CloseAllDocumentsWithConfirmation,
CloseDocument {
document_id: u64,
document_id: DocumentId,
},
CloseDocumentWithConfirmation {
document_id: u64,
document_id: DocumentId,
},
Copy {
clipboard: Clipboard,
@@ -45,7 +45,7 @@ pub enum PortfolioMessage {
clipboard: Clipboard,
},
DeleteDocument {
document_id: u64,
document_id: DocumentId,
},
DestroyAllDocuments,
FontLoaded {
@@ -65,7 +65,7 @@ pub enum PortfolioMessage {
ImaginateServerHostname,
Import,
LoadDocumentResources {
document_id: u64,
document_id: DocumentId,
},
LoadFont {
font: Font,
@@ -81,7 +81,7 @@ pub enum PortfolioMessage {
document_serialized_content: String,
},
OpenDocumentFileWithId {
document_id: u64,
document_id: DocumentId,
document_name: String,
document_is_auto_saved: bool,
document_is_saved: bool,
@@ -97,10 +97,10 @@ pub enum PortfolioMessage {
},
PrevDocument,
SelectDocument {
document_id: u64,
document_id: DocumentId,
},
SetActiveDocument {
document_id: u64,
document_id: DocumentId,
},
SubmitDocumentExport {
file_name: String,
@@ -110,8 +110,7 @@ pub enum PortfolioMessage {
transparent_background: bool,
},
SubmitGraphRender {
document_id: u64,
layer_path: Vec<LayerId>,
document_id: DocumentId,
},
ToggleRulers,
UpdateDocumentWidgets,
@@ -19,9 +19,9 @@ use std::sync::Arc;
#[derive(Debug, Default)]
pub struct PortfolioMessageHandler {
menu_bar_message_handler: MenuBarMessageHandler,
documents: HashMap<u64, DocumentMessageHandler>,
document_ids: Vec<u64>,
active_document_id: Option<u64>,
documents: HashMap<DocumentId, DocumentMessageHandler>,
document_ids: Vec<DocumentId>,
active_document_id: Option<DocumentId>,
graph_view_overlay_open: bool,
copy_buffer: [Vec<CopyBufferEntry>; INTERNAL_CLIPBOARD_COUNT as usize],
pub persistent_data: PersistentData,
@@ -109,7 +109,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
// Clear relevant UI layouts if there are no documents
responses.add(PropertiesPanelMessage::Clear);
responses.add(DocumentMessage::ClearLayerTree);
responses.add(DocumentMessage::ClearLayersPanel);
let hint_data = HintData(vec![HintGroup(vec![])]);
responses.add(FrontendMessage::UpdateInputHints { hint_data });
}
@@ -133,7 +133,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
if self.documents.len() == 1 && self.document_ids[0] == document_id {
// Clear UI layouts that assume the existence of a document
responses.add(PropertiesPanelMessage::Clear);
responses.add(DocumentMessage::ClearLayerTree);
responses.add(DocumentMessage::ClearLayersPanel);
let hint_data = HintData(vec![HintGroup(vec![])]);
responses.add(FrontendMessage::UpdateInputHints { hint_data });
}
@@ -506,10 +506,9 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
});
}
}
PortfolioMessage::SubmitGraphRender { document_id, layer_path } => {
PortfolioMessage::SubmitGraphRender { document_id } => {
let result = self.executor.submit_node_graph_evaluation(
self.documents.get_mut(&document_id).expect("Tried to render no existent Document"),
layer_path,
ipp.viewport_bounds.size().as_uvec2(),
);
@@ -591,11 +590,11 @@ impl PortfolioMessageHandler {
self.executor.introspect_node(node_path)
}
pub fn document(&self, document_id: u64) -> Option<&DocumentMessageHandler> {
pub fn document(&self, document_id: DocumentId) -> Option<&DocumentMessageHandler> {
self.documents.get(&document_id)
}
pub fn document_mut(&mut self, document_id: u64) -> Option<&mut DocumentMessageHandler> {
pub fn document_mut(&mut self, document_id: DocumentId) -> Option<&mut DocumentMessageHandler> {
self.documents.get_mut(&document_id)
}
@@ -607,7 +606,7 @@ impl PortfolioMessageHandler {
self.active_document_id.and_then(|id| self.documents.get_mut(&id))
}
pub fn active_document_id(&self) -> Option<u64> {
pub fn active_document_id(&self) -> Option<DocumentId> {
self.active_document_id
}
@@ -637,7 +636,7 @@ impl PortfolioMessageHandler {
}
// TODO: Fix how this doesn't preserve tab order upon loading new document from *File > Load*
fn load_document(&mut self, new_document: DocumentMessageHandler, document_id: u64, responses: &mut VecDeque<Message>) {
fn load_document(&mut self, new_document: DocumentMessageHandler, document_id: DocumentId, responses: &mut VecDeque<Message>) {
self.document_ids.push(document_id);
new_document.update_layers_panel_options_bar_widgets(responses);
@@ -667,7 +666,7 @@ impl PortfolioMessageHandler {
self.document_ids.iter().map(|id| self.documents.get(id).expect("document id was not found in the document hashmap"))
}
fn document_index(&self, document_id: u64) -> usize {
fn document_index(&self, document_id: DocumentId) -> usize {
self.document_ids.iter().position(|id| id == &document_id).expect("Active document is missing from document ids")
}