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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,15 @@ fn generate_layout(introspected_data: &Arc<dyn std::any::Any + Send + Sync + 'st
Table<Raster<GPU>>,
Table<Color>,
Table<GradientStops>,
Table<String>,
Table<NodeId>,
Table<f64>,
Table<u8>,
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
GradientStops,
f64,
u32,
u64,
bool,
Vec<String>,
String,
Option<f64>,
DVec2,
Expand Down Expand Up @@ -214,46 +217,6 @@ trait TableRowLayout {
}
}

impl<T: TableRowLayout> TableRowLayout for Vec<T> {
fn type_name() -> &'static str {
"Vec"
}
fn identifier(&self) -> String {
format!("Vec<{}> ({} element{})", T::type_name(), self.len(), if self.len() == 1 { "" } else { "s" })
}
fn element_page(&self, data: &mut LayoutData) -> Vec<LayoutGroup> {
if let Some(step) = data.desired_path.get(data.current_depth).cloned() {
match step {
PathStep::Element(index) => {
if let Some(row) = self.get(index) {
data.current_depth += 1;
let result = row.layout_with_breadcrumb(data);
data.current_depth -= 1;
return result;
} else {
warn!("Desired path truncated");
data.desired_path.truncate(data.current_depth);
}
}
PathStep::Attribute { .. } => {
warn!("Attribute path step inside a Vec is unsupported");
data.desired_path.truncate(data.current_depth);
}
}
}

let mut rows = self
.iter()
.enumerate()
.map(|(index, row)| vec![TextLabel::new(format!("{index}")).narrow(true).widget_instance(), row.cell_widget(PathStep::Element(index))])
.collect::<Vec<_>>();

rows.insert(0, column_headings(&["", "element"]));

vec![LayoutGroup::table(rows, false)]
}
}

impl<T: TableRowLayout> TableRowLayout for Table<T> {
fn type_name() -> &'static str {
"Table"
Expand Down Expand Up @@ -616,6 +579,21 @@ impl TableRowLayout for f64 {
}
}

impl TableRowLayout for u8 {
fn type_name() -> &'static str {
"Byte"
}
fn identifier(&self) -> String {
format!("{self:02X}")
}
fn cell_widget(&self, _target: PathStep) -> WidgetInstance {
TextLabel::new(self.identifier()).narrow(true).widget_instance()
}
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
vec![LayoutGroup::row(vec![self.cell_widget(PathStep::Element(0))])]
}
}

impl TableRowLayout for u32 {
fn type_name() -> &'static str {
"Number (u32)"
Expand Down Expand Up @@ -774,6 +752,26 @@ impl TableRowLayout for AlphaBlending {
}
}

impl TableRowLayout for NodeId {
fn type_name() -> &'static str {
"NodeId"
}
fn identifier(&self) -> String {
format!("Node {self}")
}
fn cell_widget(&self, _target: PathStep) -> WidgetInstance {
let node_id = *self;
TextButton::new("Go to Node")
.tooltip_description("Click to select the node with this ID in the graph.")
.on_update(move |_| NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] }.into())
.narrow(true)
.widget_instance()
}
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
vec![LayoutGroup::row(vec![self.cell_widget(PathStep::Element(0))])]
}
}

impl TableRowLayout for Option<NodeId> {
fn type_name() -> &'static str {
"NodeId"
Expand Down Expand Up @@ -812,8 +810,13 @@ macro_rules! known_table_row_types {
Table<Raster<GPU>>,
Table<Color>,
Table<GradientStops>,
Table<String>,
Table<NodeId>,
Table<f64>,
Table<u8>,
GradientStops,
Color,
NodeId,
Option<NodeId>,
AlphaBlending,
DAffine2,
Expand All @@ -822,11 +825,11 @@ macro_rules! known_table_row_types {
Vec2,
Option<f64>,
f64,
u8,
u32,
u64,
bool,
String,
Vec<String>,
Vector,
Raster<CPU>,
Raster<GPU>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,9 @@ impl<'a> ModifyInputsContext<'a> {
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.join_miter_limit), false), false);
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::PaintOrderInput::INDEX);
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::PaintOrder(stroke.paint_order), false), false);
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashLengthsInput::<Vec<f64>>::INDEX);
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::VecF64(stroke.dash_lengths), false), true);
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashLengthsInput::<graphene_std::table::Table<f64>>::INDEX);
let dash_lengths_table = stroke.dash_lengths.into_iter().map(graphene_std::table::TableRow::new_from_element).collect();
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64Table(dash_lengths_table), false), true);
let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashOffsetInput::INDEX);
self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.dash_offset), false), true);
}
Expand Down Expand Up @@ -579,7 +580,8 @@ impl<'a> ModifyInputsContext<'a> {
let Some(brush_node_id) = self.existing_network_node_id("Brush", true) else {
return;
};
self.set_input_with_refresh(InputConnector::node(brush_node_id, 1), NodeInput::value(TaggedValue::BrushStrokes(strokes), false), false);
let strokes_table = strokes.into_iter().map(graphene_std::table::TableRow::new_from_element).collect();
self.set_input_with_refresh(InputConnector::node(brush_node_id, 1), NodeInput::value(TaggedValue::BrushStrokeTable(strokes_table), false), false);
}

pub fn resize_artboard(&mut self, location: IVec2, dimensions: IVec2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
}),
inputs: vec![
NodeInput::value(TaggedValue::Raster(Default::default()), true),
NodeInput::value(TaggedValue::BrushStrokes(Vec::new()), false),
NodeInput::value(TaggedValue::BrushStrokeTable(Default::default()), false),
NodeInput::value(TaggedValue::BrushCache(BrushCache::default()), false),
],
..Default::default()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,10 @@ pub(crate) fn property_from_type(
Some(x) if x == TypeId::of::<String>() => text_widget(default_info).into(),
Some(x) if x == TypeId::of::<DVec2>() => vec2_widget(default_info, "X", "Y", "", None, false),
Some(x) if x == TypeId::of::<DAffine2>() => transform_widget(default_info, &mut extra_widgets),
// ==========================
// PRIMITIVE COLLECTION TYPES
// ==========================
Some(x) if x == TypeId::of::<Vec<f64>>() => array_of_number_widget(default_info, TextInput::default()).into(),
Some(x) if x == TypeId::of::<Vec<DVec2>>() => array_of_vec2_widget(default_info, TextInput::default()).into(),
// ===========
// TABLE TYPES
// ===========
Some(x) if x == TypeId::of::<Table<f64>>() => array_of_number_widget(default_info, TextInput::default()).into(),
Some(x) if x == TypeId::of::<Table<Color>>() => color_widget(default_info, ColorInput::default().allow_none(true)),
Some(x) if x == TypeId::of::<Table<GradientStops>>() => color_widget(default_info, ColorInput::default().allow_none(false)),
// ============
Expand Down Expand Up @@ -776,51 +772,19 @@ pub fn array_of_number_widget(parameter_widgets_info: ParameterWidgetsInfo, text
.map(str::parse::<f64>)
.collect::<Result<Vec<_>, _>>()
.ok()
.map(TaggedValue::VecF64)
.map(|values| TaggedValue::F64Table(values.into_iter().map(graphene_std::table::TableRow::new_from_element).collect()))
};

let Some(document_node) = document_node else { return Vec::new() };
let Some(input) = document_node.inputs.get(index) else {
log::warn!("A widget failed to be built because its node's input index is invalid.");
return vec![];
};
if let Some(TaggedValue::VecF64(x)) = &input.as_non_exposed_value() {
if let Some(TaggedValue::F64Table(table)) = &input.as_non_exposed_value() {
widgets.extend_from_slice(&[
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
text_input
.value(x.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
.on_update(optionally_update_value(move |x: &TextInput| from_string(&x.value), node_id, index))
.widget_instance(),
])
}
widgets
}

pub fn array_of_vec2_widget(parameter_widgets_info: ParameterWidgetsInfo, text_props: TextInput) -> Vec<WidgetInstance> {
let ParameterWidgetsInfo { document_node, node_id, index, .. } = parameter_widgets_info;

let mut widgets = start_widgets(parameter_widgets_info);

let from_string = |string: &str| {
string
.split(|c: char| !c.is_alphanumeric() && !matches!(c, '.' | '+' | '-'))
.filter(|x| !x.is_empty())
.map(|x| x.parse::<f64>().ok())
.collect::<Option<Vec<_>>>()
.map(|numbers| numbers.chunks_exact(2).map(|values| DVec2::new(values[0], values[1])).collect())
.map(TaggedValue::VecDVec2)
};

let Some(document_node) = document_node else { return Vec::new() };
let Some(input) = document_node.inputs.get(index) else {
log::warn!("A widget failed to be built because its node's input index is invalid.");
return vec![];
};
if let Some(TaggedValue::VecDVec2(x)) = &input.as_non_exposed_value() {
widgets.extend_from_slice(&[
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
text_props
.value(x.iter().map(|v| format!("({}, {})", v.x, v.y)).collect::<Vec<_>>().join(", "))
.value(table.iter_element_values().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
.on_update(optionally_update_value(move |x: &TextInput| from_string(&x.value), node_id, index))
.widget_instance(),
])
Expand Down Expand Up @@ -1839,13 +1803,13 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
};
let uniform_val = match input.as_non_exposed_value() {
Some(TaggedValue::F64(x)) => *x,
Some(TaggedValue::F64Array4(x)) => x[0],
Some(TaggedValue::F64Table(table)) => table.iter_element_values().copied().next().unwrap_or(0.),
_ => 0.,
};
let individual_val = match input.as_non_exposed_value() {
Some(&TaggedValue::F64Array4(x)) => x,
Some(&TaggedValue::F64(x)) => [x; 4],
_ => [0.; 4],
Some(&TaggedValue::F64(x)) => vec![x; 4],
Some(TaggedValue::F64Table(table)) => table.iter_element_values().copied().collect(),
_ => vec![0.; 4],
};
Comment thread
Keavon marked this conversation as resolved.

// Uniform/individual radio input widget
Expand All @@ -1868,6 +1832,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
]),
})
.on_commit(commit_value);
let individual_val_for_switch = individual_val.clone();
let individual = RadioEntryData::new("Individual")
.label("Individual")
.on_update(move |_| Message::Batched {
Expand All @@ -1881,7 +1846,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
NodeGraphMessage::SetInputValue {
node_id,
input_index: CornerRadiusInput::<f64>::INDEX,
value: TaggedValue::F64Array4(individual_val),
value: TaggedValue::F64Table(individual_val_for_switch.iter().copied().map(graphene_std::table::TableRow::new_from_element).collect()),
}
.into(),
]),
Expand All @@ -1899,11 +1864,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
.map(str::parse::<f64>)
.collect::<Result<Vec<f64>, _>>()
.ok()
.map(|v| {
let arr: Box<[f64; 4]> = v.into_boxed_slice().try_into().unwrap_or_default();
*arr
})
.map(TaggedValue::F64Array4)
.map(|values| TaggedValue::F64Table(values.into_iter().take(4).map(graphene_std::table::TableRow::new_from_element).collect()))
};
TextInput::default()
.value(individual_val.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
Expand Down Expand Up @@ -2296,11 +2257,10 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
_ => &StrokeJoin::Miter,
};

let dash_lengths_val = match &document_node.inputs[DashLengthsInput::<Vec<f64>>::INDEX].as_value() {
Some(TaggedValue::VecF64(x)) => x,
_ => &vec![],
let has_dash_lengths = match &document_node.inputs[DashLengthsInput::<Table<f64>>::INDEX].as_value() {
Some(TaggedValue::F64Table(table)) => table.is_empty(),
_ => true,
};
let has_dash_lengths = dash_lengths_val.is_empty();
let miter_limit_disabled = join_value != &StrokeJoin::Miter;

let color = color_widget(
Expand All @@ -2325,7 +2285,7 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
.property_row();
let disabled_number_input = NumberInput::default().unit(" px").disabled(has_dash_lengths);
let dash_lengths = array_of_number_widget(
ParameterWidgetsInfo::new(node_id, DashLengthsInput::<Vec<f64>>::INDEX, true, context),
ParameterWidgetsInfo::new(node_id, DashLengthsInput::<Table<f64>>::INDEX, true, context),
TextInput::default().centered(true),
);
let number_input = disabled_number_input;
Expand Down
12 changes: 2 additions & 10 deletions editor/src/messages/portfolio/document/node_graph/utility_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,14 @@ pub enum FrontendGraphDataType {
impl FrontendGraphDataType {
pub fn from_type(input: &Type) -> Self {
match TaggedValue::from_type_or_none(input) {
TaggedValue::U32(_)
| TaggedValue::U64(_)
| TaggedValue::F32(_)
| TaggedValue::F64(_)
| TaggedValue::DVec2(_)
| TaggedValue::F64Array4(_)
| TaggedValue::VecF64(_)
| TaggedValue::VecDVec2(_)
| TaggedValue::DAffine2(_) => Self::Number,
TaggedValue::U32(_) | TaggedValue::U64(_) | TaggedValue::F32(_) | TaggedValue::F64(_) | TaggedValue::DVec2(_) | TaggedValue::F64Table(_) | TaggedValue::DAffine2(_) => Self::Number,
TaggedValue::Artboard(_) => Self::Artboard,
TaggedValue::Graphic(_) => Self::Graphic,
TaggedValue::Raster(_) => Self::Raster,
TaggedValue::Vector(_) => Self::Vector,
TaggedValue::Color(_) => Self::Color,
TaggedValue::Gradient(_) | TaggedValue::GradientTable(_) => Self::Gradient,
TaggedValue::String(_) | TaggedValue::VecString(_) => Self::Typography,
TaggedValue::String(_) | TaggedValue::StringTable(_) => Self::Typography,
_ => Self::General,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,9 @@ impl TypeSource {
};
match self.compiled_nested_type() {
Some(nested_type) => match TaggedValue::from_type_or_none(nested_type) {
TaggedValue::U32(_)
| TaggedValue::U64(_)
| TaggedValue::F32(_)
| TaggedValue::F64(_)
| TaggedValue::DVec2(_)
| TaggedValue::F64Array4(_)
| TaggedValue::VecF64(_)
| TaggedValue::VecDVec2(_)
| TaggedValue::DAffine2(_) => FrontendGraphDataType::Number,
TaggedValue::U32(_) | TaggedValue::U64(_) | TaggedValue::F32(_) | TaggedValue::F64(_) | TaggedValue::DVec2(_) | TaggedValue::F64Table(_) | TaggedValue::DAffine2(_) => {
FrontendGraphDataType::Number
}
TaggedValue::Artboard(_) => FrontendGraphDataType::Artboard,
TaggedValue::Graphic(_) => FrontendGraphDataType::Graphic,
TaggedValue::Raster(_) => FrontendGraphDataType::Raster,
Expand Down
Loading
Loading