Prevent rendering when transforming frame layer

Reduces confusion from rendering lag and lessens the opportunity to build up leaked memory from the present lack of node graph cache eviction
This commit is contained in:
Keavon Chambers
2023-04-06 16:59:10 -07:00
parent 0d6d498480
commit 05e5be3200
16 changed files with 205 additions and 119 deletions
@@ -34,35 +34,36 @@ impl Resize {
&mut self,
responses: &mut VecDeque<Message>,
document: &DocumentMessageHandler,
ipp: &InputPreprocessorMessageHandler,
center: Key,
lock_ratio: Key,
ipp: &InputPreprocessorMessageHandler,
skip_rerender: bool,
) -> Option<Message> {
if let Some(path) = &self.path {
let mut start = self.viewport_drag_start(document);
let Some(path) = &self.path else {
return None;
};
let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position);
let mut start = self.viewport_drag_start(document);
let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position);
let mut size = stop - start;
if ipp.keyboard.get(lock_ratio as usize) {
size = size.abs().max(size.abs().yx()) * size.signum();
}
if ipp.keyboard.get(center as usize) {
start -= size;
size *= 2.;
}
Some(
GraphOperationMessage::TransformSet {
layer: path.to_vec(),
transform: DAffine2::from_scale_angle_translation(size, 0., start),
transform_in: TransformIn::Viewport,
}
.into(),
)
} else {
None
let mut size = stop - start;
if ipp.keyboard.get(lock_ratio as usize) {
size = size.abs().max(size.abs().yx()) * size.signum();
}
if ipp.keyboard.get(center as usize) {
start -= size;
size *= 2.;
}
Some(
GraphOperationMessage::TransformSet {
layer: path.to_vec(),
transform: DAffine2::from_scale_angle_translation(size, 0., start),
transform_in: TransformIn::Viewport,
skip_rerender,
}
.into(),
)
}
pub fn cleanup(&mut self, responses: &mut VecDeque<Message>) {
@@ -151,7 +151,7 @@ impl Fsm for EllipseToolFsmState {
Drawing
}
(state, Resize { center, lock_ratio }) => {
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
responses.push_back(message);
}
@@ -113,39 +113,39 @@ impl Fsm for NodeGraphToolFsmState {
match (self, event) {
(Ready, DragStart) => {
shape_data.start(responses, document, input, render_data);
responses.push_back(DocumentMessage::StartTransaction.into());
responses.add(DocumentMessage::StartTransaction);
shape_data.path = Some(document.get_path_for_new_layer());
responses.push_back(DocumentMessage::DeselectAllLayers.into());
responses.add(DocumentMessage::DeselectAllLayers);
let network = node_graph::new_image_network(8, 0);
responses.push_back(
Operation::AddNodeGraphFrame {
path: shape_data.path.clone().unwrap(),
insert_index: -1,
transform: DAffine2::ZERO.to_cols_array(),
network,
}
.into(),
);
responses.add(Operation::AddNodeGraphFrame {
path: shape_data.path.clone().unwrap(),
insert_index: -1,
transform: DAffine2::ZERO.to_cols_array(),
network,
});
Drawing
}
(state, Resize { center, lock_ratio }) => {
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
responses.push_back(message);
}
let message = shape_data.calculate_transform(responses, document, input, center, lock_ratio, true);
responses.try_add(message);
state
}
(Drawing, DragStop) => {
if let Some(layer_path) = &shape_data.path {
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
}
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
shape_data.cleanup(responses);
Ready
}
(Drawing, Abort) => {
responses.push_back(DocumentMessage::AbortTransaction.into());
responses.add(DocumentMessage::AbortTransaction);
shape_data.cleanup(responses);
@@ -168,10 +168,10 @@ impl Fsm for NodeGraphToolFsmState {
NodeGraphToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
};
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
responses.add(FrontendMessage::UpdateInputHints { hint_data });
}
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
}
}
@@ -230,5 +230,6 @@ fn add_polyline(data: &FreehandToolData, tool_data: &DocumentToolData, responses
layer: layer_path,
transform: DAffine2::from_translation(position),
transform_in: TransformIn::Local,
skip_rerender: false,
});
}
@@ -113,9 +113,9 @@ impl Fsm for ImaginateToolFsmState {
match (self, event) {
(Ready, DragStart) => {
shape_data.start(responses, document, input, render_data);
responses.push_back(DocumentMessage::StartTransaction.into());
responses.add(DocumentMessage::StartTransaction);
shape_data.path = Some(document.get_path_for_new_layer());
responses.push_back(DocumentMessage::DeselectAllLayers.into());
responses.add(DocumentMessage::DeselectAllLayers);
use graph_craft::document::*;
@@ -149,34 +149,34 @@ impl Fsm for ImaginateToolFsmState {
);
// Add the node graph frame layer to the document
responses.push_back(
Operation::AddNodeGraphFrame {
path: shape_data.path.clone().unwrap(),
insert_index: -1,
transform: DAffine2::ZERO.to_cols_array(),
network,
}
.into(),
);
responses.push_back(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id }.into());
responses.add(Operation::AddNodeGraphFrame {
path: shape_data.path.clone().unwrap(),
insert_index: -1,
transform: DAffine2::ZERO.to_cols_array(),
network,
});
responses.add(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id });
Drawing
}
(state, Resize { center, lock_ratio }) => {
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
responses.push_back(message);
}
let message = shape_data.calculate_transform(responses, document, input, center, lock_ratio, true);
responses.try_add(message);
state
}
(Drawing, DragStop) => {
if let Some(layer_path) = &shape_data.path {
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
}
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
shape_data.cleanup(responses);
Ready
}
(Drawing, Abort) => {
responses.push_back(DocumentMessage::AbortTransaction.into());
responses.add(DocumentMessage::AbortTransaction);
shape_data.cleanup(responses);
@@ -199,10 +199,10 @@ impl Fsm for ImaginateToolFsmState {
ImaginateToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
};
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
responses.add(FrontendMessage::UpdateInputHints { hint_data });
}
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
}
}
@@ -256,6 +256,7 @@ fn generate_transform(tool_data: &mut LineToolData, lock_angle: bool, snap_angle
layer: tool_data.path.clone().unwrap(),
transform: glam::DAffine2::from_scale_angle_translation(DVec2::new(line_length, 1.), angle, start),
transform_in: TransformIn::Viewport,
skip_rerender: false,
}
.into()
}
@@ -133,7 +133,7 @@ impl Fsm for RectangleToolFsmState {
Drawing
}
(state, Resize { center, lock_ratio }) => {
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
responses.push_back(message);
}
@@ -338,6 +338,7 @@ impl SelectToolData {
fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
responses.push_back(DocumentMessage::DeselectAllLayers.into());
// Take the selected layers and store them in a separate list.
self.not_duplicated_layers = Some(self.layers_dragging.clone());
// Duplicate each previously selected layer and select the new ones.
@@ -348,6 +349,7 @@ impl SelectToolData {
layer: layer_path.clone(),
transform: DAffine2::from_translation(self.drag_start - self.drag_current),
transform_in: TransformIn::Viewport,
skip_rerender: true,
}
.into(),
);
@@ -365,26 +367,24 @@ impl SelectToolData {
let layer_metadata = *document.layer_metadata(layer_path);
*layer_path.last_mut().unwrap() = generate_uuid();
responses.push_back(
Operation::InsertLayer {
layer: Box::new(layer),
destination_path: layer_path.clone(),
insert_index: -1,
}
.into(),
);
responses.add(Operation::InsertLayer {
layer: Box::new(layer),
destination_path: layer_path.clone(),
insert_index: -1,
});
responses.add(DocumentMessage::UpdateLayerMetadata {
layer_path: layer_path.clone(),
layer_metadata,
});
}
responses.push_back(
DocumentMessage::UpdateLayerMetadata {
layer_path: layer_path.clone(),
layer_metadata,
}
.into(),
);
// Since the selected layers have now moved back to their original transforms before the drag began, we rerender them to be displayed as if they weren't touched.
for layer_path in self.not_duplicated_layers.iter().flatten() {
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
}
}
/// Removes the duplicated layers. Called when Alt is released and the layers have been duplicated.
/// Removes the duplicated layers. Called when Alt is released and the layers have previously been duplicated.
fn stop_duplicates(&mut self, responses: &mut VecDeque<Message>) {
let originals = match self.not_duplicated_layers.take() {
Some(x) => x,
@@ -405,6 +405,7 @@ impl SelectToolData {
layer: layer_path.clone(),
transform: DAffine2::from_translation(self.drag_current - self.drag_start),
transform_in: TransformIn::Viewport,
skip_rerender: true,
}
.into(),
);
@@ -624,6 +625,7 @@ impl Fsm for SelectToolFsmState {
layer: path.to_vec(),
transform: DAffine2::from_translation(mouse_delta + closest_move),
transform_in: TransformIn::Viewport,
skip_rerender: true,
}
.into(),
);
@@ -729,15 +731,20 @@ impl Fsm for SelectToolFsmState {
Ready
}
(Dragging, Enter) => {
rerender_selected_layers(tool_data, responses);
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
};
tool_data.snap_manager.cleanup(responses);
responses.push_front(response.into());
Ready
}
(Dragging, DragStop { remove_from_selection }) => {
rerender_selected_layers(tool_data, responses);
// Deselect layer if not snap dragging
if !tool_data.is_dragging && input.keyboard.get(remove_from_selection as usize) && tool_data.layer_selected_on_start.is_none() {
let quad = tool_data.selection_quad();
@@ -760,9 +767,12 @@ impl Fsm for SelectToolFsmState {
responses.push_back(DocumentMessage::CommitTransaction.into());
tool_data.snap_manager.cleanup(responses);
Ready
}
(ResizingBounds, DragStop { .. } | Enter) => {
rerender_selected_layers(tool_data, responses);
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
@@ -778,6 +788,8 @@ impl Fsm for SelectToolFsmState {
Ready
}
(RotatingBounds, DragStop { .. } | Enter) => {
rerender_selected_layers(tool_data, responses);
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
@@ -838,6 +850,8 @@ impl Fsm for SelectToolFsmState {
Ready
}
(Dragging, Abort) => {
rerender_selected_layers(tool_data, responses);
tool_data.snap_manager.cleanup(responses);
responses.push_back(DocumentMessage::Undo.into());
@@ -951,6 +965,18 @@ impl Fsm for SelectToolFsmState {
}
}
fn rerender_selected_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque<Message>) {
for layer_path in &tool_data.layers_dragging {
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
}
}
fn rerender_duplicated_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque<Message>) {
for layer_path in tool_data.not_duplicated_layers.iter().flatten() {
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
}
}
// TODO: Majorly clean up these next five functions
fn drag_shallowest_manipulation(
@@ -172,7 +172,7 @@ impl Fsm for ShapeToolFsmState {
Drawing
}
(state, Resize { center, lock_ratio }) => {
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
responses.push_back(message);
}
@@ -274,5 +274,6 @@ fn add_spline(tool_data: &SplineToolData, global_tool_data: &DocumentToolData, s
layer: layer_path,
transform: glam::DAffine2::from_translation(position),
transform_in: TransformIn::Local,
skip_rerender: false,
})
}
@@ -330,6 +330,7 @@ impl Fsm for TextToolFsmState {
layer: tool_data.layer_path.clone(),
transform,
transform_in: TransformIn::Viewport,
skip_rerender: false,
}
.into(),
);
@@ -72,6 +72,9 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
responses.add(ToolMessage::UpdateHints);
responses.add(BroadcastEvent::DocumentIsDirty);
for layer_path in document.selected_layers() {
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
}
}
BeginGrab => {
if let TransformOperation::Grabbing(_) = self.transform_operation {
@@ -194,10 +197,10 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
let layer_paths = document.selected_visible_layers().map(|layer_path| layer_path.to_vec()).collect();
shape_editor.set_selected_layers(layer_paths);
}
TypeBackspace => self.transform_operation.handle_typed(self.typing.type_backspace(), &mut selected, self.snap),
TypeDecimalPoint => self.transform_operation.handle_typed(self.typing.type_decimal_point(), &mut selected, self.snap),
TypeDigit { digit } => self.transform_operation.handle_typed(self.typing.type_number(digit), &mut selected, self.snap),
TypeNegate => self.transform_operation.handle_typed(self.typing.type_negate(), &mut selected, self.snap),
TypeBackspace => self.transform_operation.grs_typed(self.typing.type_backspace(), &mut selected, self.snap),
TypeDecimalPoint => self.transform_operation.grs_typed(self.typing.type_decimal_point(), &mut selected, self.snap),
TypeDigit { digit } => self.transform_operation.grs_typed(self.typing.type_number(digit), &mut selected, self.snap),
TypeNegate => self.transform_operation.grs_typed(self.typing.type_negate(), &mut selected, self.snap),
}
}