Skip to content

FIX: Show local-axis grab measurement as a single tilted component#4326

Open
Chetansahney wants to merge 1 commit into
GraphiteEditor:masterfrom
Chetansahney:fix/local-grab-dashed-line
Open

FIX: Show local-axis grab measurement as a single tilted component#4326
Chetansahney wants to merge 1 commit into
GraphiteEditor:masterfrom
Chetansahney:fix/local-grab-dashed-line

Conversation

@Chetansahney

Copy link
Copy Markdown

Closes #3341

When grabbing (G) and pressing X/Y a second time to switch from a global-axis to a local-axis constraint, the on-canvas measurement overlay was drawn incorrectly. It showed an axis-aligned box with both the X and Y screen-space components, and when typing a value it printed that number on both axes, instead of a single line along the tilted local axis.

This implements the change requested in #3527 (comment).

Change

In the Grabbing overlay branch, when the transform is constrained to a single axis in local space, draw one dashed line from the pivot along the (already correctly tilted) translation_viewport vector, with a single measurement label — instead of the screen-aligned translation_box.

The unconstrained and global-axis cases are untouched and still use translation_box. The equivalent overlay for Scale (S) already behaved this way, so this brings Grab in line with it.

When grabbing (G) and pressing X/Y a second time to constrain to a local
axis, the measurement overlay drew an axis-aligned box showing both the X
and Y screen components (and printed a typed value on both axes) instead
of a single line along the tilted local axis.

In the Grabbing overlay branch, when constrained to a single axis in local
space, draw one dashed line along the (already tilted) translation vector
with a single measurement label, mirroring how Scale (S) already behaves.
The unconstrained and global-axis cases are unchanged.

Closes GraphiteEditor#3341
@Chetansahney Chetansahney changed the title Show local-axis grab measurement as a single tilted component FIX: Show local-axis grab measurement as a single tilted component Jul 10, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the grab transform operation overlay. When translating a layer constrained to a single axis in local space, it now draws a single dashed line with a measurement label along that axis instead of an axis-aligned box. The reviewer suggested reusing the existing format_rounded helper to format the measurement label to maintain consistency and reduce code duplication.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +254 to +257
let label = match typed_string {
Some(typed_string) => typed_string,
None => format!("{length:.2}").trim_end_matches('0').trim_end_matches('.').to_string(),
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of manually matching on typed_string and duplicating the formatting logic, you can reuse the existing format_rounded helper closure defined at the beginning of the Overlays handler (line 218). This keeps the code concise and consistent with other transform operations (like scaling and rotating).

                            let label = format_rounded(length, 2);

// axis-aligned box, which would incorrectly show both the X and Y screen-space components.
if self.state.is_transforming_in_local_space && axis_constraint != Axis::Both {
let end_point = pivot + translation_viewport;
overlay_context.dashed_line(pivot, end_point, None, None, Some(2.), Some(2.), Some(0.5));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect the drawing of the overlays to be implemented in the fn translation_box code.

let end_point = pivot + translation_viewport;
overlay_context.dashed_line(pivot, end_point, None, None, Some(2.), Some(2.), Some(0.5));

let axis_direction = self.state.constraint_axis(axis_constraint).unwrap_or(DVec2::X).normalize_or(DVec2::X);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just make this the overall condition e.g.

if let Some(axis_contraint) = self.state.constraint_axis(axis_constraint)
         && self.state.is_transforming_in_local_space {
    // Logic for constraint in local space
}

overlay_context.dashed_line(pivot, end_point, None, None, Some(2.), Some(2.), Some(0.5));

let axis_direction = self.state.constraint_axis(axis_constraint).unwrap_or(DVec2::X).normalize_or(DVec2::X);
let length = translation_viewport.dot(axis_direction) / document_to_viewport.matrix2.y_axis.length();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't really make any sense to me? Why take the length of a column of the document to viewport matrix?

I guess it works given that you only rotate and scale in a uniform fashion the viewport.

I would suggest you do something like document_to_viewport.transform_vector2(translation_viewport)

Comment on lines +258 to +260
let text_position = pivot.midpoint(end_point) + translation_viewport.perp().normalize_or(DVec2::X) * 24.;
let transform = DAffine2::from_translation(text_position);
overlay_context.text(&label, COLOR_OVERLAY_BLUE, None, transform, 16., [Pivot::Middle, Pivot::Middle]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic constants 16 and 24 should be given names since I don't know what they do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local-axis grab (G key) dashed line should show only the X or Y component, tilted

2 participants