Rename 'Image Value' node to 'Image' and have its input value be an image not a raster table (#4037)
* Rename 'Image Value' node to 'Image' and have its input value be Image<Color> not Table<Raster<CPU>> * Add a Properties panel widget labeling "width x height" for images in the Image node * Add Image<Color> node registry entry for MonitorNode * Code review
This commit is contained in:
parent
c2e1208d82
commit
d3f36a95cf
|
|
@ -497,7 +497,7 @@ impl TableRowLayout for Raster<CPU> {
|
|||
"Raster"
|
||||
}
|
||||
fn identifier(&self) -> String {
|
||||
format!("Raster ({}x{})", self.width, self.height)
|
||||
format!("Raster ({} x {})", self.width, self.height)
|
||||
}
|
||||
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
||||
let raster = self.data();
|
||||
|
|
@ -528,7 +528,7 @@ impl TableRowLayout for Raster<GPU> {
|
|||
"Raster"
|
||||
}
|
||||
fn identifier(&self) -> String {
|
||||
format!("Raster ({}x{})", self.data().width(), self.data().height())
|
||||
format!("Raster ({} x {})", self.data().width(), self.data().height())
|
||||
}
|
||||
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
||||
let widgets = vec![TextLabel::new("Raster is a texture on the GPU and cannot currently be displayed here").widget_instance()];
|
||||
|
|
|
|||
|
|
@ -34,10 +34,8 @@ use graph_craft::document::{NodeId, NodeInput, NodeNetwork, OldNodeNetwork};
|
|||
use graphene_std::math::quad::Quad;
|
||||
use graphene_std::path_bool_nodes::boolean_intersect;
|
||||
use graphene_std::raster::BlendMode;
|
||||
use graphene_std::raster_types::Raster;
|
||||
use graphene_std::render_node::wgpu_available;
|
||||
use graphene_std::subpath::Subpath;
|
||||
use graphene_std::table::Table;
|
||||
use graphene_std::vector::PointId;
|
||||
use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
|
||||
use graphene_std::vector::misc::dvec2_to_point;
|
||||
|
|
@ -696,7 +694,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
|
|||
|
||||
responses.add(DocumentMessage::AddTransaction);
|
||||
|
||||
let layer = graph_modification_utils::new_image_layer(Table::new_from_element(Raster::new_cpu(image)), layer_node_id, layer_parent, responses);
|
||||
let layer = graph_modification_utils::new_image_layer(image, layer_node_id, layer_parent, responses);
|
||||
|
||||
if let Some(name) = name {
|
||||
responses.add(NodeGraphMessage::SetDisplayName {
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ use crate::messages::portfolio::document::utility_types::network_interface::Node
|
|||
use crate::messages::prelude::*;
|
||||
use glam::{DAffine2, IVec2};
|
||||
use graph_craft::document::NodeId;
|
||||
use graphene_std::Artboard;
|
||||
use graphene_std::brush::brush_stroke::BrushStroke;
|
||||
use graphene_std::color::Color;
|
||||
use graphene_std::raster::BlendMode;
|
||||
use graphene_std::raster_types::{CPU, Raster};
|
||||
use graphene_std::raster_types::Image;
|
||||
use graphene_std::subpath::Subpath;
|
||||
use graphene_std::table::Table;
|
||||
use graphene_std::text::{Font, TypesettingConfig};
|
||||
use graphene_std::vector::PointId;
|
||||
use graphene_std::vector::VectorModificationType;
|
||||
use graphene_std::vector::style::{Fill, Stroke};
|
||||
use graphene_std::{Artboard, Color};
|
||||
|
||||
#[impl_message(Message, DocumentMessage, GraphOperation)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
|
|
@ -70,7 +70,7 @@ pub enum GraphOperationMessage {
|
|||
},
|
||||
NewBitmapLayer {
|
||||
id: NodeId,
|
||||
image_frame: Table<Raster<CPU>>,
|
||||
image: Image<Color>,
|
||||
parent: LayerNodeIdentifier,
|
||||
insert_index: usize,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -160,15 +160,10 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for
|
|||
responses.add_front(NodeGraphMessage::SelectedNodesSet { nodes: vec![id] });
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
}
|
||||
GraphOperationMessage::NewBitmapLayer {
|
||||
id,
|
||||
image_frame,
|
||||
parent,
|
||||
insert_index,
|
||||
} => {
|
||||
GraphOperationMessage::NewBitmapLayer { id, image, parent, insert_index } => {
|
||||
let mut modify_inputs = ModifyInputsContext::new(network_interface, responses);
|
||||
let layer = modify_inputs.create_layer(id);
|
||||
modify_inputs.insert_image_data(image_frame, layer);
|
||||
modify_inputs.insert_image_data(image, layer);
|
||||
network_interface.move_layer_to_stack(layer, parent, insert_index, &[]);
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use graph_craft::document::{NodeId, NodeInput};
|
|||
use graph_craft::{ProtoNodeIdentifier, concrete};
|
||||
use graphene_std::brush::brush_stroke::BrushStroke;
|
||||
use graphene_std::raster::BlendMode;
|
||||
use graphene_std::raster_types::{CPU, Raster};
|
||||
use graphene_std::raster_types::Image;
|
||||
use graphene_std::subpath::Subpath;
|
||||
use graphene_std::table::Table;
|
||||
use graphene_std::text::{Font, TypesettingConfig};
|
||||
|
|
@ -303,14 +303,14 @@ impl<'a> ModifyInputsContext<'a> {
|
|||
self.network_interface.move_node_to_chain_start(&color_value_id, layer, &[], self.import);
|
||||
}
|
||||
|
||||
pub fn insert_image_data(&mut self, image_frame: Table<Raster<CPU>>, layer: LayerNodeIdentifier) {
|
||||
pub fn insert_image_data(&mut self, image: Image<Color>, layer: LayerNodeIdentifier) {
|
||||
let transform = resolve_network_node_type("Transform").expect("Transform node does not exist").default_node_template();
|
||||
let image = resolve_proto_node_type(graphene_std::raster_nodes::std_nodes::image_value::IDENTIFIER)
|
||||
.expect("ImageValue node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::value(TaggedValue::None, false)), Some(NodeInput::value(TaggedValue::Raster(image_frame), false))]);
|
||||
let image_node = resolve_proto_node_type(graphene_std::raster_nodes::std_nodes::image::IDENTIFIER)
|
||||
.expect("Image node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::value(TaggedValue::None, false)), Some(NodeInput::value(TaggedValue::ImageData(image), false))]);
|
||||
|
||||
let image_id = NodeId::new();
|
||||
self.network_interface.insert_node(image_id, image, &[]);
|
||||
self.network_interface.insert_node(image_id, image_node, &[]);
|
||||
self.network_interface.move_node_to_chain_start(&image_id, layer, &[], self.import);
|
||||
|
||||
let transform_id = NodeId::new();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use graphene_std::raster::{
|
|||
BlendMode, CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, LuminanceCalculation, NoiseType, RedGreenBlue, RedGreenBlueAlpha, RelativeAbsolute,
|
||||
SelectiveColorChoice,
|
||||
};
|
||||
use graphene_std::raster_types::Image;
|
||||
use graphene_std::table::{Table, TableRow};
|
||||
use graphene_std::text::{Font, TextAlign};
|
||||
use graphene_std::transform::{Footprint, ReferencePoint, ScaleType, Transform};
|
||||
|
|
@ -231,6 +232,7 @@ pub(crate) fn property_from_type(
|
|||
Some(x) if x == TypeId::of::<Curve>() => curve_widget(default_info),
|
||||
Some(x) if x == TypeId::of::<Footprint>() => footprint_widget(default_info, &mut extra_widgets),
|
||||
Some(x) if x == TypeId::of::<Box<VectorModification>>() => vector_modification_widget(default_info).into(),
|
||||
Some(x) if x == TypeId::of::<Image<Color>>() => image_data_widget(default_info).into(),
|
||||
// ===============================
|
||||
// MANUALLY IMPLEMENTED ENUM TYPES
|
||||
// ===============================
|
||||
|
|
@ -420,6 +422,23 @@ pub fn vector_modification_widget(parameter_widgets_info: ParameterWidgetsInfo)
|
|||
widgets
|
||||
}
|
||||
|
||||
pub fn image_data_widget(parameter_widgets_info: ParameterWidgetsInfo) -> Vec<WidgetInstance> {
|
||||
let ParameterWidgetsInfo { document_node, node_id: _, index, .. } = parameter_widgets_info;
|
||||
|
||||
let mut widgets = start_widgets(parameter_widgets_info);
|
||||
|
||||
let Some(document_node) = document_node else { return widgets };
|
||||
let Some(input) = document_node.inputs.get(index) else { return widgets };
|
||||
|
||||
if let Some(TaggedValue::ImageData(image)) = input.as_non_exposed_value() {
|
||||
let label = format!("{} x {}", image.width, image.height);
|
||||
|
||||
widgets.extend_from_slice(&[Separator::new(SeparatorStyle::Unrelated).widget_instance(), TextLabel::new(label).widget_instance()]);
|
||||
}
|
||||
|
||||
widgets
|
||||
}
|
||||
|
||||
pub fn footprint_widget(parameter_widgets_info: ParameterWidgetsInfo, extra_widgets: &mut Vec<LayoutGroup>) -> LayoutGroup {
|
||||
let ParameterWidgetsInfo { document_node, node_id, index, .. } = parameter_widgets_info;
|
||||
|
||||
|
|
|
|||
|
|
@ -584,8 +584,9 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
|||
],
|
||||
},
|
||||
NodeReplacement {
|
||||
node: graphene_std::raster_nodes::std_nodes::image_value::IDENTIFIER,
|
||||
node: graphene_std::raster_nodes::std_nodes::image::IDENTIFIER,
|
||||
aliases: &[
|
||||
"raster_nodes::std_nodes::ImageValueNode",
|
||||
"graphene_raster_nodes::std_nodes::ImageValueNode",
|
||||
"graphene_std::raster::ImageValueNode",
|
||||
"graphene_std::raster::ImageNode",
|
||||
|
|
@ -1384,7 +1385,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
|||
.set_input(&InputConnector::node(NodeId(0), 1), NodeInput::value(TaggedValue::String(label), false), &[*node_id]);
|
||||
}
|
||||
|
||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::raster_nodes::std_nodes::image_value::IDENTIFIER) && inputs_count == 1 {
|
||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::raster_nodes::std_nodes::image::IDENTIFIER) && inputs_count == 1 {
|
||||
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
|
||||
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
|
||||
|
||||
|
|
@ -1972,6 +1973,19 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
|||
}
|
||||
}
|
||||
|
||||
// Migrate Image nodes that stored a Table<Raster<CPU>> in input 1 to instead use bare Image<Color> via TaggedValue::ImageData
|
||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::raster_nodes::std_nodes::image::IDENTIFIER)
|
||||
&& let Some(NodeInput::Value { tagged_value, .. }) = node.inputs.get(1)
|
||||
&& let TaggedValue::Raster(raster_table) = &**tagged_value
|
||||
&& let Some(row) = raster_table.iter().next()
|
||||
{
|
||||
let image = row.element.data().clone();
|
||||
|
||||
document
|
||||
.network_interface
|
||||
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::ImageData(image), false), network_path);
|
||||
}
|
||||
|
||||
// ==================================
|
||||
// PUT ALL MIGRATIONS ABOVE THIS LINE
|
||||
// ==================================
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use graph_craft::{ProtoNodeIdentifier, concrete};
|
|||
use graphene_std::Color;
|
||||
use graphene_std::NodeInputDecleration;
|
||||
use graphene_std::raster::BlendMode;
|
||||
use graphene_std::raster_types::{CPU, GPU, Raster};
|
||||
use graphene_std::raster_types::{CPU, GPU, Image, Raster};
|
||||
use graphene_std::subpath::Subpath;
|
||||
use graphene_std::table::Table;
|
||||
use graphene_std::text::{Font, TypesettingConfig};
|
||||
|
|
@ -218,14 +218,9 @@ pub fn new_vector_layer(subpaths: Vec<Subpath<PointId>>, id: NodeId, parent: Lay
|
|||
}
|
||||
|
||||
/// Create a new bitmap layer.
|
||||
pub fn new_image_layer(image_frame: Table<Raster<CPU>>, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
|
||||
pub fn new_image_layer(image: Image<Color>, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
|
||||
let insert_index = 0;
|
||||
responses.add(GraphOperationMessage::NewBitmapLayer {
|
||||
id,
|
||||
image_frame,
|
||||
parent,
|
||||
insert_index,
|
||||
});
|
||||
responses.add(GraphOperationMessage::NewBitmapLayer { id, image, parent, insert_index });
|
||||
LayerNodeIdentifier::new_unchecked(id)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ tagged_value! {
|
|||
Curve(raster_nodes::curve::Curve),
|
||||
Footprint(core_types::transform::Footprint),
|
||||
VectorModification(Box<vector::VectorModification>),
|
||||
ImageData(Image<Color>),
|
||||
// ==========
|
||||
// ENUM TYPES
|
||||
// ==========
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Table<Raster<GPU>>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Table<Color>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Table<GradientStops>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Image<Color>]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => String]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => IVec2]),
|
||||
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => DVec2]),
|
||||
|
|
|
|||
|
|
@ -297,8 +297,8 @@ pub fn empty_image(_: impl Ctx, transform: DAffine2, color: Table<Color>) -> Tab
|
|||
}
|
||||
|
||||
#[node_macro::node(category(""))]
|
||||
pub fn image_value(_: impl Ctx, _primary: (), image: Table<Raster<CPU>>) -> Table<Raster<CPU>> {
|
||||
image
|
||||
pub fn image(_: impl Ctx, _primary: (), image: Image<Color>) -> Table<Raster<CPU>> {
|
||||
Table::new_from_element(Raster::new_cpu(image))
|
||||
}
|
||||
|
||||
#[node_macro::node(category("Raster: Pattern"))]
|
||||
|
|
|
|||
Loading…
Reference in New Issue