Skip to content

Commit

Permalink
improve hover, tool hotkeys, misc
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom committed Nov 5, 2023
1 parent 5b6cdd2 commit 0898eed
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 11 deletions.
2 changes: 1 addition & 1 deletion drawing/src/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl LineSegment {
}
}

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, PartialEq)]
pub enum Feature {
Point(f32, f32),
LineSegment(K, K),
Expand Down
18 changes: 17 additions & 1 deletion drawing/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ impl super::CommandHandler<Feature, ToolResponse> for Handler {
ToolResponse::Handled => {}
ToolResponse::NewPoint(pos) => {
let pos = drawing.vp.screen_to_point(pos);
drawing.features.insert(Feature::Point(pos.x, pos.y));
let p = Feature::Point(pos.x, pos.y);

// Make sure it doesnt already exist
for v in drawing.features.values() {
if v == &p {
return;
}
}

drawing.features.insert(p);
}

ToolResponse::NewLineSegment(p1, p2) => {
Expand All @@ -20,6 +29,13 @@ impl super::CommandHandler<Feature, ToolResponse> for Handler {
drawing.find_point_at(p2).unwrap(),
);

// Make sure it doesnt already exist
for v in drawing.features.values() {
if v == &Feature::LineSegment(f1, f2) || v == &Feature::LineSegment(f2, f1) {
return;
}
}

drawing.features.insert(Feature::LineSegment(f1, f2));
}
}
Expand Down
27 changes: 20 additions & 7 deletions drawing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod handler;
pub use handler::Handler;
pub mod tools;

const MAX_HOVER_DISTANCE: f32 = 90.0;
const MAX_HOVER_DISTANCE: f32 = 160.0;

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct Viewport {
Expand Down Expand Up @@ -83,36 +83,49 @@ impl<F: DrawingFeature> Default for Data<F> {
impl<F: DrawingFeature> Data<F> {
pub fn find_point_at(&self, p: egui::Pos2) -> Option<slotmap::DefaultKey> {
for (k, v) in self.features.iter() {
if v.bb(self).center().distance_sq(p) < 1. {
if v.bb(self).center().distance_sq(p) < 0.0001 {
return Some(k);
}
}
None
}

pub fn find_screen_feature(&self, hp: egui::Pos2) -> Option<(slotmap::DefaultKey, F)> {
let mut closest: Option<(slotmap::DefaultKey, f32)> = None;
let mut closest: Option<(slotmap::DefaultKey, f32, bool)> = None;
for (k, v) in self.features.iter() {
let dist = v.screen_dist(self, hp, &self.vp);
let is_point = v.is_point();

if dist < MAX_HOVER_DISTANCE {
closest = Some(
closest
.map(|c| if c.1 > dist { (k, dist) } else { c })
.unwrap_or((k, dist)),
.map(|c| {
// Distance to a line segment and one of its defining points will
// read equal. If that happens, prefer the point.
if is_point && !c.2 && dist - (MAX_HOVER_DISTANCE / 2.) < c.1 {

Check failure on line 105 in drawing/src/lib.rs

View workflow job for this annotation

GitHub Actions / Clippy

this `if` has identical blocks
(k, dist, is_point)
} else if !is_point && c.2 && dist < c.1 - (MAX_HOVER_DISTANCE / 2.) {

Check failure on line 107 in drawing/src/lib.rs

View workflow job for this annotation

GitHub Actions / Clippy

this `if` has identical blocks
(k, dist, is_point)
} else if dist < c.1 {
(k, dist, is_point)
} else {
c
}
})
.unwrap_or((k, dist, is_point)),
);
}
}

match closest {

Check failure on line 120 in drawing/src/lib.rs

View workflow job for this annotation

GitHub Actions / Clippy

manual implementation of `Option::map`
Some((k, _dist)) => Some((k, self.features.get(k).unwrap().clone())),
Some((k, _dist, _is_point)) => Some((k, self.features.get(k).unwrap().clone())),
None => None,
}
}

pub fn delete_feature(&mut self, k: slotmap::DefaultKey) -> bool {
match self.features.remove(k) {
Some(v) => {
Some(_v) => {
// Find and also remove any features dependent on what we just removed.
let to_delete: std::collections::HashSet<slotmap::DefaultKey> = self
.features
Expand Down
20 changes: 18 additions & 2 deletions drawing/src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl Tool {
// Has first point, clicked on a point
(Some((_, crate::Feature::Point(x2, y2))), Some(starting_point), true) => {
let starting_point = starting_point.clone();

Check failure on line 136 in drawing/src/tools.rs

View workflow job for this annotation

GitHub Actions / Clippy

using `clone` on type `Pos2` which implements the `Copy` trait
*p1 = None;
*p1 = Some(egui::Pos2 { x: *x2, y: *y2 });
Some(ToolResponse::NewLineSegment(
starting_point,
egui::Pos2 { x: *x2, y: *y2 },
Expand Down Expand Up @@ -252,11 +252,28 @@ impl super::ToolController for Toolbar {
hf: &Option<(slotmap::DefaultKey, Self::Features)>,
response: &egui::Response,
) -> Option<ToolResponse> {
// Escape to exit use of a tool
if self.current.is_some() && ui.input(|i| i.key_pressed(egui::Key::Escape)) {
self.current = None;
return Some(ToolResponse::Handled);
}

// Hotkeys for switching tools
if hp.is_some() && !response.dragged() {
let (l, p) = ui.input(|i| (i.key_pressed(egui::Key::L), i.key_pressed(egui::Key::P)));
match (l, p) {
(true, _) => {
self.current = Some(Tool::Line(None));
return Some(ToolResponse::Handled);
}
(_, true) => {
self.current = Some(Tool::Point);
return Some(ToolResponse::Handled);
}
_ => {}
}
}

if let (Some(hp), true) = (
hp,
response.clicked()
Expand All @@ -278,7 +295,6 @@ impl super::ToolController for Toolbar {
return current.handle_input(ui, hp, hf, response);
}
}

None
}

Expand Down

0 comments on commit 0898eed

Please sign in to comment.