Improve select tool click targets (#1976)

* Improve select tool click targets

* Improve spellings
This commit is contained in:
James Lindsay 2024-09-15 01:02:48 +01:00 committed by GitHub
parent 6c8a4fe5b3
commit 2fa8773092
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 10 deletions

View File

@ -295,25 +295,37 @@ impl BoundingBoxManager {
} }
} }
/// Compute the threshold in viewport space. This only works with affine transforms as it assumes lines remain parallel.
fn compute_viewport_threshold(&self, scalar: f64) -> [f64; 2] {
let inverse = self.transform.inverse();
let viewport_x = self.transform.transform_vector2(DVec2::X).normalize_or_zero() * scalar;
let viewport_y = self.transform.transform_vector2(DVec2::Y).normalize_or_zero() * scalar;
let threshold_x = inverse.transform_vector2(viewport_x).length();
let threshold_y = inverse.transform_vector2(viewport_y).length();
[threshold_x, threshold_y]
}
/// Check if the user has selected the edge for dragging (returns which edge in order top, bottom, left, right) /// Check if the user has selected the edge for dragging (returns which edge in order top, bottom, left, right)
pub fn check_selected_edges(&self, cursor: DVec2) -> Option<(bool, bool, bool, bool)> { pub fn check_selected_edges(&self, cursor: DVec2) -> Option<(bool, bool, bool, bool)> {
let cursor = self.transform.inverse().transform_point2(cursor); let cursor = self.transform.inverse().transform_point2(cursor);
let select_threshold = self.transform.inverse().transform_vector2(DVec2::new(0., BOUNDS_SELECT_THRESHOLD)).length();
let min = self.bounds[0].min(self.bounds[1]); let min = self.bounds[0].min(self.bounds[1]);
let max = self.bounds[0].max(self.bounds[1]); let max = self.bounds[0].max(self.bounds[1]);
if min.x - cursor.x < select_threshold && min.y - cursor.y < select_threshold && cursor.x - max.x < select_threshold && cursor.y - max.y < select_threshold { let [threshold_x, threshold_y] = self.compute_viewport_threshold(BOUNDS_SELECT_THRESHOLD);
let mut top = (cursor.y - min.y).abs() < select_threshold;
let mut bottom = (max.y - cursor.y).abs() < select_threshold; if min.x - cursor.x < threshold_x && min.y - cursor.y < threshold_y && cursor.x - max.x < threshold_x && cursor.y - max.y < threshold_y {
let mut left = (cursor.x - min.x).abs() < select_threshold; let mut top = (cursor.y - min.y).abs() < threshold_y;
let mut right = (max.x - cursor.x).abs() < select_threshold; let mut bottom = (max.y - cursor.y).abs() < threshold_y;
let mut left = (cursor.x - min.x).abs() < threshold_x;
let mut right = (max.x - cursor.x).abs() < threshold_x;
// Prioritise single axis transformations on very small bounds // Prioritise single axis transformations on very small bounds
if cursor.y - min.y + max.y - cursor.y < select_threshold * 2. && (left || right) { if cursor.y - min.y + max.y - cursor.y < threshold_y * 2. && (left || right) {
top = false; top = false;
bottom = false; bottom = false;
} }
if cursor.x - min.x + max.x - cursor.x < select_threshold * 2. && (top || bottom) { if cursor.x - min.x + max.x - cursor.x < threshold_x * 2. && (top || bottom) {
left = false; left = false;
right = false; right = false;
} }
@ -339,13 +351,13 @@ impl BoundingBoxManager {
/// Check if the user is rotating with the bounds /// Check if the user is rotating with the bounds
pub fn check_rotate(&self, cursor: DVec2) -> bool { pub fn check_rotate(&self, cursor: DVec2) -> bool {
let cursor = self.transform.inverse().transform_point2(cursor); let cursor = self.transform.inverse().transform_point2(cursor);
let rotate_threshold = self.transform.inverse().transform_vector2(DVec2::new(0., BOUNDS_ROTATE_THRESHOLD)).length(); let [threshold_x, threshold_y] = self.compute_viewport_threshold(BOUNDS_ROTATE_THRESHOLD);
let min = self.bounds[0].min(self.bounds[1]); let min = self.bounds[0].min(self.bounds[1]);
let max = self.bounds[0].max(self.bounds[1]); let max = self.bounds[0].max(self.bounds[1]);
let outside_bounds = (min.x > cursor.x || cursor.x > max.x) || (min.y > cursor.y || cursor.y > max.y); let outside_bounds = (min.x > cursor.x || cursor.x > max.x) || (min.y > cursor.y || cursor.y > max.y);
let inside_extended_bounds = min.x - cursor.x < rotate_threshold && min.y - cursor.y < rotate_threshold && cursor.x - max.x < rotate_threshold && cursor.y - max.y < rotate_threshold; let inside_extended_bounds = min.x - cursor.x < threshold_x && min.y - cursor.y < threshold_y && cursor.x - max.x < threshold_x && cursor.y - max.y < threshold_y;
outside_bounds & inside_extended_bounds outside_bounds & inside_extended_bounds
} }