mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 07:18:04 +08:00
Implement the Brush without relying on a stamp texture
Test Plan: Test the BrushNode in the editor Reviewers: Keavon Reviewed By: Keavon Pull Request: https://github.com/GraphiteEditor/Graphite/pull/1184
This commit is contained in:
@@ -24,7 +24,7 @@ struct ModifyInputsContext<'a> {
|
||||
impl<'a> ModifyInputsContext<'a> {
|
||||
/// Get the node network from the document
|
||||
fn new(layer: &'a [LayerId], document: &'a mut Document, node_graph: &'a mut NodeGraphMessageHandler, responses: &'a mut VecDeque<Message>) -> Option<Self> {
|
||||
document.layer_mut(&layer).ok().and_then(|layer| layer.as_node_graph_mut().ok()).map(|network| Self {
|
||||
document.layer_mut(layer).ok().and_then(|layer| layer.as_node_graph_mut().ok()).map(|network| Self {
|
||||
network,
|
||||
node_graph,
|
||||
responses,
|
||||
|
||||
@@ -1048,19 +1048,19 @@ pub fn wrap_network_in_scope(network: NodeNetwork) -> NodeNetwork {
|
||||
let nodes = vec![
|
||||
resolve_document_node_type("Begin Scope")
|
||||
.expect("Begin Scope node type not found")
|
||||
.to_document_node(vec![input_type.clone()], DocumentNodeMetadata::default()),
|
||||
.to_document_node(vec![input_type], DocumentNodeMetadata::default()),
|
||||
inner_network,
|
||||
resolve_document_node_type("End Scope")
|
||||
.expect("End Scope node type not found")
|
||||
.to_document_node(vec![NodeInput::node(0, 0), NodeInput::node(1, 0)], DocumentNodeMetadata::default()),
|
||||
];
|
||||
let network = NodeNetwork {
|
||||
|
||||
NodeNetwork {
|
||||
inputs: vec![0],
|
||||
outputs: vec![NodeOutput::new(2, 0)],
|
||||
nodes: nodes.into_iter().enumerate().map(|(id, node)| (id as NodeId, node)).collect(),
|
||||
..Default::default()
|
||||
};
|
||||
network
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_image_network(output_offset: i32, output_node_id: NodeId) -> NodeNetwork {
|
||||
@@ -1121,8 +1121,8 @@ pub fn new_text_network(text: String, font: Font, size: f64) -> NodeNetwork {
|
||||
text_generator.to_document_node(
|
||||
[
|
||||
NodeInput::Network(concrete!(graphene_core::EditorApi)),
|
||||
NodeInput::value(TaggedValue::String(text.clone()), false),
|
||||
NodeInput::value(TaggedValue::Font(font.clone()), false),
|
||||
NodeInput::value(TaggedValue::String(text), false),
|
||||
NodeInput::value(TaggedValue::Font(font), false),
|
||||
NodeInput::value(TaggedValue::F64(size), false),
|
||||
],
|
||||
DocumentNodeMetadata::position((0, 4)),
|
||||
|
||||
@@ -149,10 +149,10 @@ impl ShapeState {
|
||||
/// Move the selected points by dragging the mouse.
|
||||
pub fn move_selected_points(&self, document: &Document, delta: DVec2, mirror_distance: bool, responses: &mut VecDeque<Message>) {
|
||||
for (layer_path, state) in &self.selected_shape_state {
|
||||
let Ok(layer) = document.layer(&layer_path) else { continue };
|
||||
let Ok(layer) = document.layer(layer_path) else { continue };
|
||||
let Some(vector_data) = layer.as_vector_data() else { continue };
|
||||
|
||||
let transform = document.multiply_transforms(&layer_path).unwrap_or_default();
|
||||
let transform = document.multiply_transforms(layer_path).unwrap_or_default();
|
||||
let delta = transform.inverse().transform_vector2(delta);
|
||||
|
||||
for &point in state.selected_points.iter() {
|
||||
|
||||
@@ -315,7 +315,7 @@ fn add_brush_render(data: &BrushToolData, tool_data: &DocumentToolData, response
|
||||
};
|
||||
let mut network = NodeNetwork::value_network(brush_node);
|
||||
network.push_output_node();
|
||||
graph_modification_utils::new_custom_layer(network, layer_path.clone(), responses);
|
||||
graph_modification_utils::new_custom_layer(network, layer_path, responses);
|
||||
}
|
||||
|
||||
fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerId>, Vec<DVec2>)> {
|
||||
|
||||
@@ -223,7 +223,7 @@ fn add_polyline(data: &FreehandToolData, tool_data: &DocumentToolData, responses
|
||||
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
||||
|
||||
responses.add(GraphOperationMessage::StrokeSet {
|
||||
layer: layer_path.clone(),
|
||||
layer: layer_path,
|
||||
stroke: Stroke::new(tool_data.primary_color, data.weight),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ impl Fsm for LineToolFsmState {
|
||||
tool_data.path = Some(layer_path.clone());
|
||||
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
||||
responses.add(GraphOperationMessage::StrokeSet {
|
||||
layer: layer_path.clone(),
|
||||
layer: layer_path,
|
||||
stroke: Stroke::new(global_tool_data.primary_color, tool_options.line_weight),
|
||||
});
|
||||
|
||||
|
||||
@@ -273,11 +273,9 @@ impl Fsm for PathToolFsmState {
|
||||
if tool_data.opposing_handle_lengths.is_none() {
|
||||
tool_data.opposing_handle_lengths = Some(shape_editor.opposing_handle_lengths(&document.document_legacy));
|
||||
}
|
||||
} else {
|
||||
if let Some(opposing_handle_lengths) = &tool_data.opposing_handle_lengths {
|
||||
shape_editor.reset_opposing_handle_lengths(&document.document_legacy, opposing_handle_lengths, responses);
|
||||
tool_data.opposing_handle_lengths = None;
|
||||
}
|
||||
} else if let Some(opposing_handle_lengths) = &tool_data.opposing_handle_lengths {
|
||||
shape_editor.reset_opposing_handle_lengths(&document.document_legacy, opposing_handle_lengths, responses);
|
||||
tool_data.opposing_handle_lengths = None;
|
||||
}
|
||||
|
||||
// Move the selected points by the mouse position
|
||||
@@ -291,8 +289,7 @@ impl Fsm for PathToolFsmState {
|
||||
(_, PathToolMessage::DragStop { shift_mirror_distance }) => {
|
||||
let nearest_point = shape_editor
|
||||
.find_nearest_point_indices(&document.document_legacy, input.mouse.position, SELECTION_THRESHOLD)
|
||||
.map(|(_, nearest_point)| nearest_point)
|
||||
.clone();
|
||||
.map(|(_, nearest_point)| nearest_point);
|
||||
let shift_pressed = input.keyboard.get(shift_mirror_distance as usize);
|
||||
|
||||
if tool_data.drag_start_pos.distance(input.mouse.position) <= DRAG_THRESHOLD && !shift_pressed {
|
||||
|
||||
@@ -475,7 +475,7 @@ impl PenToolData {
|
||||
modification: VectorDataModification::SetManipulatorPosition { point, position },
|
||||
});
|
||||
|
||||
return Some(DocumentMessage::CommitTransaction);
|
||||
Some(DocumentMessage::CommitTransaction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -762,7 +762,7 @@ impl Fsm for SelectToolFsmState {
|
||||
if let Some(path) = intersection.last() {
|
||||
// let folders: Vec<_> = (1..path.len() + 1).map(|i| &path[0..i]).collect();
|
||||
// let replacement_selected_layers: Vec<_> = document.selected_layers().filter(|&layer| !folders.contains(&layer)).map(|path| path.to_vec()).collect();
|
||||
let replacement_selected_layers: Vec<_> = document.selected_layers().filter(|&layer| !path.starts_with(&layer)).map(|path| path.to_vec()).collect();
|
||||
let replacement_selected_layers: Vec<_> = document.selected_layers().filter(|&layer| !path.starts_with(layer)).map(|path| path.to_vec()).collect();
|
||||
|
||||
tool_data.layers_dragging.clear();
|
||||
tool_data.layers_dragging.append(replacement_selected_layers.clone().as_mut());
|
||||
@@ -999,7 +999,7 @@ fn drag_shallowest_manipulation(
|
||||
// Checks if the incoming layer's root parent is already selected
|
||||
// If so we need to update the selected layer to the deeper of the two
|
||||
let mut layers_without_incoming_parent: Vec<Vec<u64>> = document.selected_layers().filter(|&layer| layer != [incoming_parent].as_slice()).map(|path| path.to_vec()).collect();
|
||||
if layers.contains(&&[incoming_parent].as_slice()) {
|
||||
if layers.contains(&[incoming_parent].as_slice()) {
|
||||
// Add incoming layer
|
||||
tool_data.layers_dragging.clear();
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
@@ -1028,7 +1028,7 @@ fn drag_shallowest_manipulation(
|
||||
|
||||
// Check if the intersected layer path is already selected
|
||||
let previous_parents: Vec<_> = (0..layers.len()).map(|i| &layers.get(i).unwrap()[..1]).collect();
|
||||
let already_selected_parent = previous_parents.contains(&&[incoming_parent].as_slice());
|
||||
let already_selected_parent = previous_parents.contains(&[incoming_parent].as_slice());
|
||||
|
||||
let selected_layers: Vec<_> = document.selected_layers().collect();
|
||||
let mut search = previous_layer_path.to_vec();
|
||||
@@ -1042,7 +1042,7 @@ fn drag_shallowest_manipulation(
|
||||
selected_layer_path_parent = selected_layer_path_parent[..selected_layer_path_parent.len() - 1].to_vec();
|
||||
}
|
||||
|
||||
while selected_layer_path_parent.len() > 0 && !is_parent && !recursive_found {
|
||||
while !selected_layer_path_parent.is_empty() && !is_parent && !recursive_found {
|
||||
let selected_children_layer_paths = document.document_legacy.folder_children_paths(&selected_layer_path_parent);
|
||||
for child in selected_children_layer_paths {
|
||||
if child == *incoming_layer_path_vector {
|
||||
@@ -1062,7 +1062,7 @@ fn drag_shallowest_manipulation(
|
||||
|
||||
// Check if new layer is already selected
|
||||
let mut already_selected = false;
|
||||
if selected_layers.contains(&search.clone().as_slice()) {
|
||||
if selected_layers.contains(&search.as_slice()) {
|
||||
already_selected = true;
|
||||
}
|
||||
|
||||
@@ -1086,7 +1086,7 @@ fn drag_shallowest_manipulation(
|
||||
} else {
|
||||
// Previous selected layers with the intersect layer path appended to it
|
||||
let mut combined_layers = selected_layers.clone();
|
||||
let intersection_temp = intersection.clone();
|
||||
let intersection_temp = intersection;
|
||||
let intersection_temp_slice = intersection_temp.as_slice();
|
||||
combined_layers.push(intersection_temp_slice);
|
||||
let layers_iter = combined_layers.into_iter();
|
||||
@@ -1162,7 +1162,7 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, interse
|
||||
let incoming_parent = *intersect_layer_path.first().unwrap();
|
||||
let previous_parents: Vec<_> = (0..selected_layers.len()).map(|i| &selected_layers.get(i).unwrap()[..1]).collect();
|
||||
let mut incoming_parent_selected = false;
|
||||
if previous_parents.contains(&&[incoming_parent].as_slice()) {
|
||||
if previous_parents.contains(&[incoming_parent].as_slice()) {
|
||||
incoming_parent_selected = true;
|
||||
}
|
||||
if incoming_parent_selected {
|
||||
@@ -1225,11 +1225,9 @@ fn recursive_search(document: &DocumentMessageHandler, layer_path: &Vec<u64>, in
|
||||
for path in layer_paths {
|
||||
if path == *incoming_layer_path_vector {
|
||||
return true;
|
||||
} else if document.document_legacy.is_folder(path.clone()) {
|
||||
if recursive_search(document, &path, incoming_layer_path_vector) {
|
||||
return true;
|
||||
}
|
||||
} else if document.document_legacy.is_folder(path.clone()) && recursive_search(document, &path, incoming_layer_path_vector) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
false
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ impl TextToolData {
|
||||
else if let Some(editing_text) = self.editing_text.as_ref().filter(|_| state == TextToolFsmState::Ready) {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
|
||||
let network = new_text_network(String::new(), editing_text.font.clone(), editing_text.font_size as f64);
|
||||
let network = new_text_network(String::new(), editing_text.font.clone(), editing_text.font_size);
|
||||
|
||||
responses.add(Operation::AddFrame {
|
||||
path: self.layer_path.clone(),
|
||||
@@ -320,7 +320,7 @@ impl TextToolData {
|
||||
resize_overlays(&mut self.overlays, responses, 1);
|
||||
|
||||
let editing_text = self.editing_text.as_ref()?;
|
||||
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(&data));
|
||||
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(data));
|
||||
let far = graphene_core::text::bounding_box(&self.new_text, buzz_face, editing_text.font_size, None);
|
||||
let quad = Quad::from_box([DVec2::ZERO, far]);
|
||||
|
||||
@@ -337,8 +337,8 @@ impl TextToolData {
|
||||
|
||||
fn get_bounds(&self, text: &str, render_data: &RenderData) -> Option<[DVec2; 2]> {
|
||||
let editing_text = self.editing_text.as_ref()?;
|
||||
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(&data));
|
||||
let subpaths = graphene_core::text::to_path(&text, buzz_face, editing_text.font_size, None);
|
||||
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(data));
|
||||
let subpaths = graphene_core::text::to_path(text, buzz_face, editing_text.font_size, None);
|
||||
let bounds = subpaths.iter().filter_map(|subpath| subpath.bounding_box());
|
||||
let combined_bounds = bounds.reduce(|a, b| [a[0].min(b[0]), a[1].max(b[1])]).unwrap_or_default();
|
||||
Some(combined_bounds)
|
||||
@@ -383,8 +383,8 @@ fn update_overlays(document: &DocumentMessageHandler, tool_data: &mut TextToolDa
|
||||
let node_id = get_text_node_id(node_graph)?;
|
||||
let document_node = node_graph.nodes.get(&node_id)?;
|
||||
let (text, font, font_size) = TextToolData::extract_text_node_inputs(document_node)?;
|
||||
let buzz_face = render_data.font_cache.get(font).map(|data| load_face(&data));
|
||||
let far = graphene_core::text::bounding_box(&text, buzz_face, font_size, None);
|
||||
let buzz_face = render_data.font_cache.get(font).map(|data| load_face(data));
|
||||
let far = graphene_core::text::bounding_box(text, buzz_face, font_size, None);
|
||||
let quad = Quad::from_box([DVec2::ZERO, far]);
|
||||
let multiplied = document.document_legacy.multiply_transforms(path).ok()? * quad;
|
||||
Some(multiplied.bounding_box())
|
||||
@@ -474,7 +474,7 @@ impl Fsm for TextToolFsmState {
|
||||
tool_data.new_text = String::new();
|
||||
tool_data.layer_path = document.get_path_for_new_layer();
|
||||
|
||||
tool_data.interact(state, input.mouse.position, document, &render_data, responses)
|
||||
tool_data.interact(state, input.mouse.position, document, render_data, responses)
|
||||
}
|
||||
(state, TextToolMessage::EditSelected) => {
|
||||
if let Some(layer_path) = can_edit_selected(document) {
|
||||
|
||||
@@ -65,10 +65,10 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
||||
}
|
||||
|
||||
if using_path_tool {
|
||||
if let Ok(layer) = document.document_legacy.layer(&selected_layers[0]) {
|
||||
if let Ok(layer) = document.document_legacy.layer(selected_layers[0]) {
|
||||
if let Some(vector_data) = layer.as_vector_data() {
|
||||
*selected.original_transforms = OriginalTransforms::default();
|
||||
let viewspace = &mut document.document_legacy.generate_transform_relative_to_viewport(&selected_layers[0]).ok().unwrap_or_default();
|
||||
let viewspace = &mut document.document_legacy.generate_transform_relative_to_viewport(selected_layers[0]).ok().unwrap_or_default();
|
||||
|
||||
let mut point_count: usize = 0;
|
||||
let count_point = |position| {
|
||||
|
||||
Reference in New Issue
Block a user