mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 06:48:11 +08:00
Merge branch 'master' into lock-layer-feature
This commit is contained in:
@@ -460,7 +460,11 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
match ipp.keyboard.key(resize) {
|
match ipp.keyboard.key(resize) {
|
||||||
// Nudge translation
|
// Nudge translation
|
||||||
false => {
|
false => {
|
||||||
for layer in self.selected_nodes.selected_layers(self.metadata()) {
|
for layer in self
|
||||||
|
.selected_nodes
|
||||||
|
.selected_layers(self.metadata())
|
||||||
|
.filter(|&layer| self.selected_nodes.layer_visible(layer, self.metadata()))
|
||||||
|
{
|
||||||
responses.add(GraphOperationMessage::TransformChange {
|
responses.add(GraphOperationMessage::TransformChange {
|
||||||
layer,
|
layer,
|
||||||
transform: DAffine2::from_translation(delta),
|
transform: DAffine2::from_translation(delta),
|
||||||
@@ -491,7 +495,11 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
let pivot = DAffine2::from_translation(pivot);
|
let pivot = DAffine2::from_translation(pivot);
|
||||||
let transformation = pivot * scale * pivot.inverse();
|
let transformation = pivot * scale * pivot.inverse();
|
||||||
|
|
||||||
for layer in self.selected_nodes.selected_layers(self.metadata()) {
|
for layer in self
|
||||||
|
.selected_nodes
|
||||||
|
.selected_layers(self.metadata())
|
||||||
|
.filter(|&layer| self.selected_nodes.layer_visible(layer, self.metadata()))
|
||||||
|
{
|
||||||
let to = self.metadata().document_to_viewport.inverse() * self.metadata().downstream_transform_to_viewport(layer);
|
let to = self.metadata().document_to_viewport.inverse() * self.metadata().downstream_transform_to_viewport(layer);
|
||||||
let original_transform = self.metadata().upstream_transform(layer.to_node());
|
let original_transform = self.metadata().upstream_transform(layer.to_node());
|
||||||
let new = to.inverse() * transformation * to * original_transform;
|
let new = to.inverse() * transformation * to * original_transform;
|
||||||
@@ -614,11 +622,11 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
}
|
}
|
||||||
DocumentMessage::SelectAllLayers => {
|
DocumentMessage::SelectAllLayers => {
|
||||||
let metadata = self.metadata();
|
let metadata = self.metadata();
|
||||||
let all_layers_except_artboards_locked = metadata
|
let all_layers_except_artboards_and_invisible = metadata
|
||||||
.all_layers()
|
.all_layers()
|
||||||
.filter(move |&layer| !metadata.is_artboard(layer))
|
.filter(move |&layer| !metadata.is_artboard(layer))
|
||||||
.filter(|&layer| !self.selected_nodes.layer_locked(layer, metadata));
|
.filter(|&layer| self.selected_nodes.layer_visible(layer, metadata));
|
||||||
let nodes = all_layers_except_artboards_locked.map(|layer| layer.to_node()).collect();
|
let nodes = all_layers_except_artboards_and_invisible.map(|layer| layer.to_node()).collect();
|
||||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes });
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes });
|
||||||
}
|
}
|
||||||
DocumentMessage::SelectedLayersLower => {
|
DocumentMessage::SelectedLayersLower => {
|
||||||
|
|||||||
@@ -459,6 +459,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeGraphMessage::ToggleVisibility { node_id } => {
|
NodeGraphMessage::ToggleVisibility { node_id } => {
|
||||||
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let visible = document_metadata.node_is_visible(node_id);
|
let visible = document_metadata.node_is_visible(node_id);
|
||||||
let visible = !visible;
|
let visible = !visible;
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ fn get_closest_intersection(snap_to: DVec2, curves: &[SnappedCurve]) -> Option<S
|
|||||||
curves: [Some(close.document_curve), Some(far.document_curve)],
|
curves: [Some(close.document_curve), Some(far.document_curve)],
|
||||||
source: close.point.source,
|
source: close.point.source,
|
||||||
at_intersection: true,
|
at_intersection: true,
|
||||||
contrained: true,
|
constrained: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ fn get_grid_intersection(snap_to: DVec2, lines: &[SnappedLine]) -> Option<Snappe
|
|||||||
tolerance: line_i.point.tolerance,
|
tolerance: line_i.point.tolerance,
|
||||||
source: line_i.point.source,
|
source: line_i.point.source,
|
||||||
at_intersection: true,
|
at_intersection: true,
|
||||||
contrained: true,
|
constrained: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ impl SnapManager {
|
|||||||
self.update_indicator(snapped);
|
self.update_indicator(snapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_best_snap(snap_data: &mut SnapData, point: &SnapCandidatePoint, snap_results: SnapResults, contrained: bool, off_screen: bool, to_path: bool) -> SnappedPoint {
|
fn find_best_snap(snap_data: &mut SnapData, point: &SnapCandidatePoint, snap_results: SnapResults, constrained: bool, off_screen: bool, to_path: bool) -> SnappedPoint {
|
||||||
let mut snapped_points = Vec::new();
|
let mut snapped_points = Vec::new();
|
||||||
let document = snap_data.document;
|
let document = snap_data.document;
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ impl SnapManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !contrained {
|
if !constrained {
|
||||||
if document.snapping_state.target_enabled(SnapTarget::Geometry(GeometrySnapTarget::Intersection)) {
|
if document.snapping_state.target_enabled(SnapTarget::Geometry(GeometrySnapTarget::Intersection)) {
|
||||||
if let Some(closest_curves_intersection) = get_closest_intersection(point.document_point, &snap_results.curves) {
|
if let Some(closest_curves_intersection) = get_closest_intersection(point.document_point, &snap_results.curves) {
|
||||||
snapped_points.push(closest_curves_intersection);
|
snapped_points.push(closest_curves_intersection);
|
||||||
@@ -316,8 +316,8 @@ impl SnapManager {
|
|||||||
|
|
||||||
let mut snap_data = snap_data.clone();
|
let mut snap_data = snap_data.clone();
|
||||||
snap_data.candidates = Some(&*self.candidates.get_or_insert_with(|| Self::find_candidates(&snap_data, point, bbox)));
|
snap_data.candidates = Some(&*self.candidates.get_or_insert_with(|| Self::find_candidates(&snap_data, point, bbox)));
|
||||||
self.layer_snapper.contrained_snap(&mut snap_data, point, &mut snap_results, constraint);
|
self.layer_snapper.constrained_snap(&mut snap_data, point, &mut snap_results, constraint);
|
||||||
self.grid_snapper.contrained_snap(&mut snap_data, point, &mut snap_results, constraint);
|
self.grid_snapper.constrained_snap(&mut snap_data, point, &mut snap_results, constraint);
|
||||||
|
|
||||||
Self::find_best_snap(&mut snap_data, point, snap_results, true, false, false)
|
Self::find_best_snap(&mut snap_data, point, snap_results, true, false, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ impl GridSnapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contrained_snap(&mut self, snap_data: &mut SnapData, point: &SnapCandidatePoint, snap_results: &mut SnapResults, constraint: SnapConstraint) {
|
pub fn constrained_snap(&mut self, snap_data: &mut SnapData, point: &SnapCandidatePoint, snap_results: &mut SnapResults, constraint: SnapConstraint) {
|
||||||
let tolerance = snap_tolerance(snap_data.document);
|
let tolerance = snap_tolerance(snap_data.document);
|
||||||
let projected = constraint.projection(point.document_point);
|
let projected = constraint.projection(point.document_point);
|
||||||
let lines = self.get_snap_lines(projected, snap_data);
|
let lines = self.get_snap_lines(projected, snap_data);
|
||||||
@@ -170,7 +170,7 @@ impl GridSnapper {
|
|||||||
source: point.source,
|
source: point.source,
|
||||||
target: SnapTarget::Grid(GridSnapTarget::Line),
|
target: SnapTarget::Grid(GridSnapTarget::Line),
|
||||||
at_intersection: false,
|
at_intersection: false,
|
||||||
contrained: true,
|
constrained: true,
|
||||||
source_bounds: point.quad,
|
source_bounds: point.quad,
|
||||||
curves: [
|
curves: [
|
||||||
Some(Bezier::from_linear_dvec2(projected - constraint_direction * tolerance, projected + constraint_direction * tolerance)),
|
Some(Bezier::from_linear_dvec2(projected - constraint_direction * tolerance, projected + constraint_direction * tolerance)),
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ impl LayerSnapper {
|
|||||||
target: candidate.target,
|
target: candidate.target,
|
||||||
distance,
|
distance,
|
||||||
tolerance,
|
tolerance,
|
||||||
contrained: true,
|
constrained: true,
|
||||||
target_bounds: candidate.quad,
|
target_bounds: candidate.quad,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
@@ -242,7 +242,7 @@ impl LayerSnapper {
|
|||||||
self.free_snap_paths(snap_data, point, snap_results);
|
self.free_snap_paths(snap_data, point, snap_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contrained_snap(&mut self, snap_data: &mut SnapData, point: &SnapCandidatePoint, snap_results: &mut SnapResults, constraint: SnapConstraint) {
|
pub fn constrained_snap(&mut self, snap_data: &mut SnapData, point: &SnapCandidatePoint, snap_results: &mut SnapResults, constraint: SnapConstraint) {
|
||||||
self.snap_anchors(snap_data, point, snap_results, constraint, constraint.projection(point.document_point));
|
self.snap_anchors(snap_data, point, snap_results, constraint, constraint.projection(point.document_point));
|
||||||
self.snap_paths_constrained(snap_data, point, snap_results, constraint);
|
self.snap_paths_constrained(snap_data, point, snap_results, constraint);
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ fn normals_and_tangents(path: &SnapCandidatePath, normals: bool, tangents: bool,
|
|||||||
tolerance,
|
tolerance,
|
||||||
curves: [Some(path.document_curve), None],
|
curves: [Some(path.document_curve), None],
|
||||||
source: point.source,
|
source: point.source,
|
||||||
contrained: true,
|
constrained: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -285,7 +285,7 @@ fn normals_and_tangents(path: &SnapCandidatePath, normals: bool, tangents: bool,
|
|||||||
tolerance,
|
tolerance,
|
||||||
curves: [Some(path.document_curve), None],
|
curves: [Some(path.document_curve), None],
|
||||||
source: point.source,
|
source: point.source,
|
||||||
contrained: true,
|
constrained: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub struct SnappedPoint {
|
|||||||
pub source: SnapSource,
|
pub source: SnapSource,
|
||||||
pub target: SnapTarget,
|
pub target: SnapTarget,
|
||||||
pub at_intersection: bool,
|
pub at_intersection: bool,
|
||||||
pub contrained: bool, // Found when looking for contrained
|
pub constrained: bool, // Found when looking for constrained
|
||||||
pub target_bounds: Option<Quad>,
|
pub target_bounds: Option<Quad>,
|
||||||
pub source_bounds: Option<Quad>,
|
pub source_bounds: Option<Quad>,
|
||||||
pub curves: [Option<Bezier>; 2],
|
pub curves: [Option<Bezier>; 2],
|
||||||
@@ -56,16 +56,16 @@ impl SnappedPoint {
|
|||||||
// Prefer closest
|
// Prefer closest
|
||||||
let other_closer = other_dist < my_dist + bias;
|
let other_closer = other_dist < my_dist + bias;
|
||||||
|
|
||||||
// We should prefer the most contrained option (e.g. intersection > path)
|
// We should prefer the most constrained option (e.g. intersection > path)
|
||||||
let other_more_contrained = other.contrained && !self.contrained;
|
let other_more_constrained = other.constrained && !self.constrained;
|
||||||
let self_more_contrained = self.contrained && !other.contrained;
|
let self_more_constrained = self.constrained && !other.constrained;
|
||||||
|
|
||||||
// Prefer nodes to intersections if both are at the same position
|
// Prefer nodes to intersections if both are at the same position
|
||||||
let contrained_at_same_pos = other.contrained && self.contrained && self.snapped_point_document.abs_diff_eq(other.snapped_point_document, 1.);
|
let constrained_at_same_pos = other.constrained && self.constrained && self.snapped_point_document.abs_diff_eq(other.snapped_point_document, 1.);
|
||||||
let other_better_constraint = contrained_at_same_pos && self.at_intersection && !other.at_intersection;
|
let other_better_constraint = constrained_at_same_pos && self.at_intersection && !other.at_intersection;
|
||||||
let self_better_constraint = contrained_at_same_pos && other.at_intersection && !self.at_intersection;
|
let self_better_constraint = constrained_at_same_pos && other.at_intersection && !self.at_intersection;
|
||||||
|
|
||||||
(other_closer || other_more_contrained || other_better_constraint) && !self_more_contrained && !self_better_constraint
|
(other_closer || other_more_constrained || other_better_constraint) && !self_more_constrained && !self_better_constraint
|
||||||
}
|
}
|
||||||
pub fn is_snapped(&self) -> bool {
|
pub fn is_snapped(&self) -> bool {
|
||||||
self.distance.is_finite()
|
self.distance.is_finite()
|
||||||
|
|||||||
@@ -45,7 +45,11 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
|||||||
fn process_message(&mut self, message: TransformLayerMessage, responses: &mut VecDeque<Message>, (document, input, tool_data, shape_editor): TransformData) {
|
fn process_message(&mut self, message: TransformLayerMessage, responses: &mut VecDeque<Message>, (document, input, tool_data, shape_editor): TransformData) {
|
||||||
let using_path_tool = tool_data.active_tool_type == ToolType::Path;
|
let using_path_tool = tool_data.active_tool_type == ToolType::Path;
|
||||||
|
|
||||||
let selected_layers = document.selected_nodes.selected_layers(document.metadata()).collect::<Vec<_>>();
|
let selected_layers = document
|
||||||
|
.selected_nodes
|
||||||
|
.selected_layers(document.metadata())
|
||||||
|
.filter(|&layer| document.metadata().node_is_visible(layer.to_node()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut selected = Selected::new(
|
let mut selected = Selected::new(
|
||||||
&mut self.original_transforms,
|
&mut self.original_transforms,
|
||||||
|
|||||||
@@ -155,6 +155,7 @@
|
|||||||
// HELPER FUNCTIONS
|
// HELPER FUNCTIONS
|
||||||
// ================
|
// ================
|
||||||
|
|
||||||
|
// Calculates the string to display when the field is not being edited.
|
||||||
function displayText(displayValue: number | undefined): string {
|
function displayText(displayValue: number | undefined): string {
|
||||||
if (displayValue === undefined) return "-";
|
if (displayValue === undefined) return "-";
|
||||||
|
|
||||||
@@ -164,6 +165,7 @@
|
|||||||
return `${unitlessDisplayValue}${unPluralize(unit, displayValue)}`;
|
return `${unitlessDisplayValue}${unPluralize(unit, displayValue)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removes the trailing "s" from a unit if the quantity is 1.
|
||||||
function unPluralize(unit: string, quantity: number): string {
|
function unPluralize(unit: string, quantity: number): string {
|
||||||
if (quantity !== 1 || !unit.endsWith("s")) return unit;
|
if (quantity !== 1 || !unit.endsWith("s")) return unit;
|
||||||
return unit.slice(0, -1);
|
return unit.slice(0, -1);
|
||||||
@@ -174,9 +176,13 @@
|
|||||||
// ===========================
|
// ===========================
|
||||||
|
|
||||||
function onTextFocused() {
|
function onTextFocused() {
|
||||||
|
// The degree of precision allowed in the number that's shown when editing the number field, where additional precision is removed to round out floating point errors.
|
||||||
|
const MAX_PRECISION = 12;
|
||||||
|
const noFloatingImprecisionValue = value === undefined ? undefined : Number(value.toPrecision(MAX_PRECISION));
|
||||||
|
|
||||||
if (value === undefined) text = "";
|
if (value === undefined) text = "";
|
||||||
else if (unitIsHiddenWhenEditing) text = String(value);
|
else if (unitIsHiddenWhenEditing) text = `${noFloatingImprecisionValue}`;
|
||||||
else text = `${value}${unPluralize(unit, value)}`;
|
else text = `${noFloatingImprecisionValue}${unPluralize(unit, value)}`;
|
||||||
|
|
||||||
editing = true;
|
editing = true;
|
||||||
|
|
||||||
@@ -253,7 +259,7 @@
|
|||||||
|
|
||||||
function onDragPointerDown(e: PointerEvent) {
|
function onDragPointerDown(e: PointerEvent) {
|
||||||
// Only drag the number with left click (and when it's valid to do so)
|
// Only drag the number with left click (and when it's valid to do so)
|
||||||
if (e.button !== BUTTON_LEFT || mode !== "Increment" || value === undefined || disabled) return;
|
if (e.button !== BUTTON_LEFT || mode !== "Increment" || value === undefined || disabled || editing) return;
|
||||||
|
|
||||||
// Don't drag the text value from is input element
|
// Don't drag the text value from is input element
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
Reference in New Issue
Block a user