mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 06:08:11 +08:00
Add artboard displayed names in the viewport (#1795)
* possible location of the change is decided. * fix for issue #1774 * possible location of the change is decided. * fix for issue #1774 * fix for #1706 * fix for #1706, code reformatted * fix for #1706, Label input removed from Properties * fix for #1706 * deleted the comment
This commit is contained in:
+1
@@ -709,6 +709,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
|
|||||||
responses.add(DocumentMessage::RenderRulers);
|
responses.add(DocumentMessage::RenderRulers);
|
||||||
responses.add(DocumentMessage::RenderScrollbars);
|
responses.add(DocumentMessage::RenderScrollbars);
|
||||||
responses.add(NodeGraphMessage::SendGraph);
|
responses.add(NodeGraphMessage::SendGraph);
|
||||||
|
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GraphOperationMessage::SetNodeInput { node_id, input_index, input } => {
|
GraphOperationMessage::SetNodeInput { node_id, input_index, input } => {
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ impl<'a> ModifyInputsContext<'a> {
|
|||||||
|
|
||||||
ModifyInputsContext::insert_node_as_primary_export(node_graph, document_network, new_id, artboard_node)
|
ModifyInputsContext::insert_node_as_primary_export(node_graph, document_network, new_id, artboard_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_vector_data(&mut self, subpaths: Vec<Subpath<ManipulatorGroupId>>, layer: NodeId) {
|
pub fn insert_vector_data(&mut self, subpaths: Vec<Subpath<ManipulatorGroupId>>, layer: NodeId) {
|
||||||
let shape = {
|
let shape = {
|
||||||
let node_type: &crate::messages::portfolio::document::node_graph::document_node_types::DocumentNodeDefinition = resolve_document_node_type("Shape").expect("Shape node does not exist");
|
let node_type: &crate::messages::portfolio::document::node_graph::document_node_types::DocumentNodeDefinition = resolve_document_node_type("Shape").expect("Shape node does not exist");
|
||||||
|
|||||||
@@ -266,13 +266,14 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
name: "To Artboard".to_string(),
|
name: "To Artboard".to_string(),
|
||||||
manual_composition: Some(concrete!(Footprint)),
|
manual_composition: Some(concrete!(Footprint)),
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
NodeInput::network(concrete!(graphene_core::GraphicGroup), 1),
|
NodeInput::network(concrete!(TaggedValue), 1),
|
||||||
|
NodeInput::value(TaggedValue::String(String::from("Artboard")), false),
|
||||||
NodeInput::network(concrete!(TaggedValue), 2),
|
NodeInput::network(concrete!(TaggedValue), 2),
|
||||||
NodeInput::network(concrete!(TaggedValue), 3),
|
NodeInput::network(concrete!(TaggedValue), 3),
|
||||||
NodeInput::network(concrete!(TaggedValue), 4),
|
NodeInput::network(concrete!(TaggedValue), 4),
|
||||||
NodeInput::network(concrete!(TaggedValue), 5),
|
NodeInput::network(concrete!(TaggedValue), 5),
|
||||||
],
|
],
|
||||||
implementation: DocumentNodeImplementation::proto("graphene_core::ConstructArtboardNode<_, _, _, _, _>"),
|
implementation: DocumentNodeImplementation::proto("graphene_core::ConstructArtboardNode<_, _, _, _, _, _>"),
|
||||||
metadata: DocumentNodeMetadata { position: glam::IVec2::new(-10, -3) }, // To Artboard
|
metadata: DocumentNodeMetadata { position: glam::IVec2::new(-10, -3) }, // To Artboard
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -309,7 +310,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
}),
|
}),
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
DocumentInputType::value("Artboards", TaggedValue::ArtboardGroup(ArtboardGroup::EMPTY), true),
|
DocumentInputType::value("Artboards", TaggedValue::ArtboardGroup(ArtboardGroup::EMPTY), true),
|
||||||
DocumentInputType::value("Over", TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
DocumentInputType::value("Contents", TaggedValue::GraphicGroup(GraphicGroup::EMPTY), true),
|
||||||
DocumentInputType::value("Location", TaggedValue::IVec2(glam::IVec2::ZERO), false),
|
DocumentInputType::value("Location", TaggedValue::IVec2(glam::IVec2::ZERO), false),
|
||||||
DocumentInputType::value("Dimensions", TaggedValue::IVec2(glam::IVec2::new(1920, 1080)), false),
|
DocumentInputType::value("Dimensions", TaggedValue::IVec2(glam::IVec2::new(1920, 1080)), false),
|
||||||
DocumentInputType::value("Background", TaggedValue::Color(Color::WHITE), false),
|
DocumentInputType::value("Background", TaggedValue::Color(Color::WHITE), false),
|
||||||
|
|||||||
@@ -1408,7 +1408,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
self.update_click_target(node_id, document_network, self.network.clone());
|
self.update_click_target(node_id, document_network, self.network.clone());
|
||||||
responses.add(DocumentMessage::RenderRulers);
|
responses.add(DocumentMessage::RenderRulers);
|
||||||
responses.add(DocumentMessage::RenderScrollbars);
|
responses.add(DocumentMessage::RenderScrollbars);
|
||||||
self.send_graph(document_network, document_metadata, collapsed, graph_view_overlay_open, responses);
|
responses.add(NodeGraphMessage::SendGraph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeGraphMessage::StartPreviewingWithoutRestore { node_id } => {
|
NodeGraphMessage::StartPreviewingWithoutRestore { node_id } => {
|
||||||
|
|||||||
@@ -2448,8 +2448,10 @@ pub fn artboard_properties(document_node: &DocumentNode, node_id: NodeId, _conte
|
|||||||
let dimensions = vec2_widget(document_node, node_id, 3, "Dimensions", "W", "H", " px", None, add_blank_assist);
|
let dimensions = vec2_widget(document_node, node_id, 3, "Dimensions", "W", "H", " px", None, add_blank_assist);
|
||||||
let background = color_widget(document_node, node_id, 4, "Background", ColorButton::default().allow_none(false), true);
|
let background = color_widget(document_node, node_id, 4, "Background", ColorButton::default().allow_none(false), true);
|
||||||
let clip = bool_widget(document_node, node_id, 5, "Clip", true);
|
let clip = bool_widget(document_node, node_id, 5, "Clip", true);
|
||||||
let clip = LayoutGroup::Row { widgets: clip };
|
|
||||||
vec![location, dimensions, background, clip]
|
let clip_row = LayoutGroup::Row { widgets: clip };
|
||||||
|
|
||||||
|
vec![location, dimensions, background, clip_row]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn color_fill_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
pub fn color_fill_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
id,
|
id,
|
||||||
artboard: graphene_core::Artboard {
|
artboard: graphene_core::Artboard {
|
||||||
graphic_group: graphene_core::GraphicGroup::EMPTY,
|
graphic_group: graphene_core::GraphicGroup::EMPTY,
|
||||||
|
label: String::from("Artboard"),
|
||||||
location: start.round().as_ivec2(),
|
location: start.round().as_ivec2(),
|
||||||
dimensions: IVec2::splat(1),
|
dimensions: IVec2::splat(1),
|
||||||
background: graphene_core::Color::WHITE,
|
background: graphene_core::Color::WHITE,
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ impl Default for GraphicElement {
|
|||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub struct Artboard {
|
pub struct Artboard {
|
||||||
pub graphic_group: GraphicGroup,
|
pub graphic_group: GraphicGroup,
|
||||||
|
pub label: String,
|
||||||
pub location: IVec2,
|
pub location: IVec2,
|
||||||
pub dimensions: IVec2,
|
pub dimensions: IVec2,
|
||||||
pub background: Color,
|
pub background: Color,
|
||||||
@@ -98,6 +99,7 @@ impl Artboard {
|
|||||||
pub fn new(location: IVec2, dimensions: IVec2) -> Self {
|
pub fn new(location: IVec2, dimensions: IVec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
graphic_group: GraphicGroup::EMPTY,
|
graphic_group: GraphicGroup::EMPTY,
|
||||||
|
label: String::from("Artboard"),
|
||||||
location: location.min(location + dimensions),
|
location: location.min(location + dimensions),
|
||||||
dimensions: dimensions.abs(),
|
dimensions: dimensions.abs(),
|
||||||
background: Color::WHITE,
|
background: Color::WHITE,
|
||||||
@@ -165,8 +167,9 @@ fn to_graphic_group<Data: Into<GraphicGroup>>(data: Data) -> GraphicGroup {
|
|||||||
data.into()
|
data.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConstructArtboardNode<Contents, Location, Dimensions, Background, Clip> {
|
pub struct ConstructArtboardNode<Contents, Label, Location, Dimensions, Background, Clip> {
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
|
label: Label,
|
||||||
location: Location,
|
location: Location,
|
||||||
dimensions: Dimensions,
|
dimensions: Dimensions,
|
||||||
background: Background,
|
background: Background,
|
||||||
@@ -177,6 +180,7 @@ pub struct ConstructArtboardNode<Contents, Location, Dimensions, Background, Cli
|
|||||||
async fn construct_artboard<Fut: Future<Output = GraphicGroup>>(
|
async fn construct_artboard<Fut: Future<Output = GraphicGroup>>(
|
||||||
mut footprint: Footprint,
|
mut footprint: Footprint,
|
||||||
contents: impl Node<Footprint, Output = Fut>,
|
contents: impl Node<Footprint, Output = Fut>,
|
||||||
|
label: String,
|
||||||
location: IVec2,
|
location: IVec2,
|
||||||
dimensions: IVec2,
|
dimensions: IVec2,
|
||||||
background: Color,
|
background: Color,
|
||||||
@@ -184,8 +188,10 @@ async fn construct_artboard<Fut: Future<Output = GraphicGroup>>(
|
|||||||
) -> Artboard {
|
) -> Artboard {
|
||||||
footprint.transform *= DAffine2::from_translation(location.as_dvec2());
|
footprint.transform *= DAffine2::from_translation(location.as_dvec2());
|
||||||
let graphic_group = self.contents.eval(footprint).await;
|
let graphic_group = self.contents.eval(footprint).await;
|
||||||
|
|
||||||
Artboard {
|
Artboard {
|
||||||
graphic_group,
|
graphic_group,
|
||||||
|
label,
|
||||||
location: location.min(location + dimensions),
|
location: location.min(location + dimensions),
|
||||||
dimensions: dimensions.abs(),
|
dimensions: dimensions.abs(),
|
||||||
background,
|
background,
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ impl GraphicElementRendered for Artboard {
|
|||||||
},
|
},
|
||||||
|render| {
|
|render| {
|
||||||
// TODO: Use the artboard's layer name
|
// TODO: Use the artboard's layer name
|
||||||
render.svg.push("Artboard".into());
|
render.svg.push(self.label.to_string().into());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -475,6 +475,7 @@ impl GraphicElementRendered for crate::ArtboardGroup {
|
|||||||
self.artboards.len() > 0
|
self.artboards.len() > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicElementRendered for ImageFrame<Color> {
|
impl GraphicElementRendered for ImageFrame<Color> {
|
||||||
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
|
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
|
||||||
let transform: String = format_transform_matrix(self.transform * render.transform);
|
let transform: String = format_transform_matrix(self.transform * render.transform);
|
||||||
|
|||||||
@@ -1110,14 +1110,14 @@ impl NodeNetwork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Remove all nodes that contain [`DocumentNodeImplementation::Network`] by moving the nested nodes into the parent network.
|
/// Remove all nodes that contain [`DocumentNodeImplementation::Network`] by moving the nested nodes into the parent network.
|
||||||
pub fn flatten(&mut self, node: NodeId) {
|
pub fn flatten(&mut self, node_id: NodeId) {
|
||||||
self.flatten_with_fns(node, merge_ids, || NodeId(generate_uuid()))
|
self.flatten_with_fns(node_id, merge_ids, || NodeId(generate_uuid()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove all nodes that contain [`DocumentNodeImplementation::Network`] by moving the nested nodes into the parent network.
|
/// Remove all nodes that contain [`DocumentNodeImplementation::Network`] by moving the nested nodes into the parent network.
|
||||||
pub fn flatten_with_fns(&mut self, node: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
|
pub fn flatten_with_fns(&mut self, node_id: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
|
||||||
let Some((id, mut node)) = self.nodes.remove_entry(&node) else {
|
let Some((id, mut node)) = self.nodes.remove_entry(&node_id) else {
|
||||||
warn!("The node which was supposed to be flattened does not exist in the network, id {node} network {self:#?}");
|
warn!("The node which was supposed to be flattened does not exist in the network, id {node_id} network {self:#?}");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1166,6 +1166,7 @@ impl NodeNetwork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace value inputs with value nodes, added to flattened network
|
// Replace value inputs with value nodes, added to flattened network
|
||||||
for input in node.inputs.iter_mut() {
|
for input in node.inputs.iter_mut() {
|
||||||
let previous_input = std::mem::replace(input, NodeInput::network(concrete!(()), 0));
|
let previous_input = std::mem::replace(input, NodeInput::network(concrete!(()), 0));
|
||||||
@@ -1201,8 +1202,16 @@ impl NodeNetwork {
|
|||||||
// Connect all network inputs to either the parent network nodes, or newly created value nodes for the parent node.
|
// Connect all network inputs to either the parent network nodes, or newly created value nodes for the parent node.
|
||||||
inner_network.map_ids(|inner_id| map_ids(id, inner_id));
|
inner_network.map_ids(|inner_id| map_ids(id, inner_id));
|
||||||
let new_nodes = inner_network.nodes.keys().cloned().collect::<Vec<_>>();
|
let new_nodes = inner_network.nodes.keys().cloned().collect::<Vec<_>>();
|
||||||
|
|
||||||
// Match the document node input and the inputs of the inner network
|
// Match the document node input and the inputs of the inner network
|
||||||
for (nested_node_id, mut nested_node) in inner_network.nodes.into_iter() {
|
for (nested_node_id, mut nested_node) in inner_network.nodes.into_iter() {
|
||||||
|
if nested_node.name == "To Artboard" {
|
||||||
|
let label_index = 1;
|
||||||
|
let label = if !node.alias.is_empty() { node.alias.clone() } else { node.name.clone() };
|
||||||
|
let label_input = NodeInput::value(TaggedValue::String(label), false);
|
||||||
|
nested_node.inputs[label_index] = label_input;
|
||||||
|
}
|
||||||
|
|
||||||
for (nested_input_index, nested_input) in nested_node.clone().inputs.iter().enumerate() {
|
for (nested_input_index, nested_input) in nested_node.clone().inputs.iter().enumerate() {
|
||||||
if let NodeInput::Network { import_index, .. } = nested_input {
|
if let NodeInput::Network { import_index, .. } = nested_input {
|
||||||
let parent_input = node.inputs.get(*import_index).expect("Import index should always exist");
|
let parent_input = node.inputs.get(*import_index).expect("Import index should always exist");
|
||||||
|
|||||||
@@ -238,6 +238,17 @@ impl<'a> TaggedValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
TaggedValue::String(x) => x.to_string(),
|
||||||
|
TaggedValue::U32(x) => x.to_string(),
|
||||||
|
TaggedValue::U64(x) => x.to_string(),
|
||||||
|
TaggedValue::F64(x) => x.to_string(),
|
||||||
|
TaggedValue::Bool(x) => x.to_string(),
|
||||||
|
_ => panic!("Cannot convert to string"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_primitive_string(&self) -> String {
|
pub fn to_primitive_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
TaggedValue::None => "()".to_string(),
|
TaggedValue::None => "()".to_string(),
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ macro_rules! async_node {
|
|||||||
ProtoNodeIdentifier::new(stringify!($path)),
|
ProtoNodeIdentifier::new(stringify!($path)),
|
||||||
|mut args| {
|
|mut args| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.reverse();
|
args.reverse();
|
||||||
let node = <$path>::new($(graphene_std::any::downcast_node::<$arg, $type>(args.pop().expect("Not enough arguments provided to construct node"))),*);
|
let node = <$path>::new($(graphene_std::any::downcast_node::<$arg, $type>(args.pop().expect("Not enough arguments provided to construct node"))),*);
|
||||||
let any: DynAnyNode<$input, _, _> = graphene_std::any::DynAnyNode::new(node);
|
let any: DynAnyNode<$input, _, _> = graphene_std::any::DynAnyNode::new(node);
|
||||||
Box::new(any) as TypeErasedBox
|
Box::new(any) as TypeErasedBox
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -104,7 +104,7 @@ macro_rules! async_node {
|
|||||||
let params = vec![$(fn_type!($arg, $type)),*];
|
let params = vec![$(fn_type!($arg, $type)),*];
|
||||||
let mut node_io = NodeIO::<'_, $input>::to_node_io(&node, params);
|
let mut node_io = NodeIO::<'_, $input>::to_node_io(&node, params);
|
||||||
node_io.input = concrete!(<$input as StaticType>::Static);
|
node_io.input = concrete!(<$input as StaticType>::Static);
|
||||||
node_io.input = concrete!(<$input as StaticType>::Static);
|
node_io.input = concrete!(<$input as StaticType>::Static); // Why are there 2 of them?
|
||||||
node_io.output = concrete!(<$output as StaticType>::Static);
|
node_io.output = concrete!(<$output as StaticType>::Static);
|
||||||
node_io
|
node_io
|
||||||
},
|
},
|
||||||
@@ -811,7 +811,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||||||
register_node!(graphene_core::ToGraphicGroupNode, input: ImageFrame<Color>, params: []),
|
register_node!(graphene_core::ToGraphicGroupNode, input: ImageFrame<Color>, params: []),
|
||||||
register_node!(graphene_core::ToGraphicGroupNode, input: GraphicGroup, params: []),
|
register_node!(graphene_core::ToGraphicGroupNode, input: GraphicGroup, params: []),
|
||||||
register_node!(graphene_core::ToGraphicGroupNode, input: Artboard, params: []),
|
register_node!(graphene_core::ToGraphicGroupNode, input: Artboard, params: []),
|
||||||
async_node!(graphene_core::ConstructArtboardNode<_, _, _, _, _>, input: Footprint, output: Artboard, fn_params: [Footprint => GraphicGroup, () => glam::IVec2, () => glam::IVec2, () => Color, () => bool]),
|
async_node!(graphene_core::ConstructArtboardNode<_, _, _, _, _, _>, input: Footprint, output: Artboard, fn_params: [Footprint => GraphicGroup, () => String, () => glam::IVec2, () => glam::IVec2, () => Color, () => bool]),
|
||||||
async_node!(graphene_core::AddArtboardNode<_, _>, input: Footprint, output: ArtboardGroup, fn_params: [Footprint => ArtboardGroup, Footprint => Artboard]),
|
async_node!(graphene_core::AddArtboardNode<_, _>, input: Footprint, output: ArtboardGroup, fn_params: [Footprint => ArtboardGroup, Footprint => Artboard]),
|
||||||
];
|
];
|
||||||
let mut map: HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> = HashMap::new();
|
let mut map: HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> = HashMap::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user