Skip to content

Commit 4640512

Browse files
author
Tom
committed
get dragging dimension references working
1 parent fe53395 commit 4640512

File tree

3 files changed

+113
-32
lines changed

3 files changed

+113
-32
lines changed

drawing/src/constraints.rs

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,33 @@ impl Constraint {
4646
hp: egui::Pos2,
4747
vp: &crate::Viewport,
4848
) -> Option<f32> {
49-
None
49+
use Constraint::{Fixed, LineLength};
50+
match self {
51+
Fixed(..) => None,
52+
LineLength(_, fk, _, (ref_x, ref_y)) => {
53+
if let Some(Feature::LineSegment(_, f1, f2)) = drawing.features.get(*fk) {
54+
let (a, b) = match (
55+
drawing.features.get(*f1).unwrap(),
56+
drawing.features.get(*f2).unwrap(),
57+
) {
58+
(Feature::Point(_, x1, y1), Feature::Point(_, x2, y2)) => {
59+
(egui::Pos2 { x: *x1, y: *y1 }, egui::Pos2 { x: *x2, y: *y2 })
60+
}
61+
_ => panic!("unexpected subkey types: {:?} & {:?}", f1, f2),
62+
};
63+
64+
let reference = egui::Vec2::new(*ref_x, *ref_y);
65+
let t = (a - b).angle() + reference.angle();
66+
let text_center = vp.translate_point(a.lerp(b, 0.5))
67+
+ egui::Vec2::angled(t) * reference.length();
68+
69+
let bounds = egui::Rect::from_center_size(text_center, (60., 15.).into());
70+
Some(bounds.distance_sq_to_pos(hp))
71+
} else {
72+
None
73+
}
74+
}
75+
}
5076
}
5177

5278
pub fn paint(
@@ -60,12 +86,6 @@ impl Constraint {
6086
match self {
6187
Fixed(_, k, _, _) => {
6288
if let Some(Feature::Point(_, x, y)) = drawing.features.get(*k) {
63-
let layout = painter.layout_no_wrap(
64-
"( )".to_string(),
65-
egui::FontId::monospace(12.),
66-
params.colors.text,
67-
);
68-
6989
let c = params.vp.translate_point(egui::Pos2 { x: *x, y: *y });
7090
painter.circle_stroke(
7191
c,
@@ -95,8 +115,10 @@ impl Constraint {
95115
b,
96116
val: d,
97117
reference: egui::Vec2::new(*ref_x, *ref_y),
118+
hovered: params.hovered,
119+
selected: params.selected,
98120
}
99-
.draw(painter, &params.vp);
121+
.draw(painter, params);
100122
}
101123
}
102124
}
@@ -109,26 +131,37 @@ struct DimensionLengthOverlay<'a> {
109131
a: egui::Pos2,
110132
b: egui::Pos2,
111133
reference: egui::Vec2,
134+
hovered: bool,
135+
selected: bool,
112136
}
113137

114138
impl<'a> DimensionLengthOverlay<'a> {
115139
const LINE_STOP_OFFSET: f32 = 5.5;
116140

117-
pub fn draw(&self, painter: &egui::Painter, vp: &crate::Viewport) {
141+
pub fn draw(&self, painter: &egui::Painter, params: &crate::PaintParams) {
142+
let vp = &params.vp;
118143
let t = (self.a - self.b).angle() + self.reference.angle();
119144
let (sa, sb) = (vp.translate_point(self.a), vp.translate_point(self.b));
120145

121-
self.draw_stop_lines(t, sa, sb, painter, vp);
146+
self.draw_stop_lines(t, sa, sb, painter);
147+
148+
let color = if self.selected {
149+
params.colors.selected
150+
} else if self.hovered {
151+
params.colors.hover
152+
} else {
153+
egui::Color32::LIGHT_BLUE
154+
};
122155

123156
let layout = painter.layout_no_wrap(
124157
format!("{:.3}", self.val).into(),
125158
egui::FontId::monospace(10.),
126-
egui::Color32::LIGHT_BLUE,
159+
color,
127160
);
128161
let text_pos = vp.translate_point(self.a.lerp(self.b, 0.5))
129162
+ egui::Vec2::angled(t) * self.reference.length();
130163

131-
self.draw_parallel_arrows(t, sa, sb, text_pos, &layout.rect, painter, vp);
164+
self.draw_parallel_arrows(t, sa, sb, text_pos, &layout.rect, color, painter);
132165
painter.galley(
133166
text_pos
134167
- egui::Vec2 {
@@ -146,8 +179,8 @@ impl<'a> DimensionLengthOverlay<'a> {
146179
sb: egui::Pos2,
147180
text_pos: egui::Pos2,
148181
text_bounds: &egui::Rect,
182+
color: egui::Color32,
149183
painter: &egui::Painter,
150-
vp: &crate::Viewport,
151184
) {
152185
let v = egui::Vec2::angled(t) * self.reference.length();
153186
let text_offset = text_pos.to_vec2()
@@ -163,14 +196,11 @@ impl<'a> DimensionLengthOverlay<'a> {
163196
if let Some(end) = arrow_line_1
164197
.intersection_rect(&text_bounds.expand2((12., 2.).into()).translate(text_offset))
165198
{
166-
if sa.distance_sq(end) > 1890. {
199+
if sa.distance_sq(end) > 1950. {
167200
painter.arrow(
168201
end,
169202
egui::Vec2::angled((sa - sb).angle()) * 20.,
170-
egui::Stroke {
171-
width: 1.,
172-
color: egui::Color32::LIGHT_BLUE,
173-
},
203+
egui::Stroke { width: 1., color },
174204
);
175205
}
176206
}
@@ -182,27 +212,17 @@ impl<'a> DimensionLengthOverlay<'a> {
182212
if let Some(end) = arrow_line_2
183213
.intersection_rect(&text_bounds.expand2((12., 2.).into()).translate(text_offset))
184214
{
185-
if sb.distance_sq(end) > 1890. {
215+
if sb.distance_sq(end) > 1950. {
186216
painter.arrow(
187217
end,
188218
egui::Vec2::angled((sb - sa).angle()) * 20.,
189-
egui::Stroke {
190-
width: 1.,
191-
color: egui::Color32::LIGHT_BLUE,
192-
},
219+
egui::Stroke { width: 1., color },
193220
);
194221
}
195222
}
196223
}
197224

198-
fn draw_stop_lines(
199-
&self,
200-
t: f32,
201-
sa: egui::Pos2,
202-
sb: egui::Pos2,
203-
painter: &egui::Painter,
204-
vp: &crate::Viewport,
205-
) {
225+
fn draw_stop_lines(&self, t: f32, sa: egui::Pos2, sb: egui::Pos2, painter: &egui::Painter) {
206226
let l = self.reference.length();
207227

208228
painter.line_segment(

drawing/src/data/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,37 @@ impl Data {
117117
self.solve_and_apply();
118118
}
119119

120+
pub fn move_constraint(&mut self, k: ConstraintKey, pos: egui::Pos2) {
121+
if let Some(Constraint::LineLength(_, fk, _, _)) = self.constraints.get(k) {
122+
let (a, b) = match self.features.get(*fk) {
123+
Some(Feature::LineSegment(_, f1, f2)) => {
124+
let (a, b) = match (
125+
self.features.get(*f1).unwrap(),
126+
self.features.get(*f2).unwrap(),
127+
) {
128+
(Feature::Point(_, x1, y1), Feature::Point(_, x2, y2)) => {
129+
(egui::Pos2 { x: *x1, y: *y1 }, egui::Pos2 { x: *x2, y: *y2 })
130+
}
131+
_ => panic!("unexpected subkey types: {:?} & {:?}", f1, f2),
132+
};
133+
134+
(self.vp.translate_point(a), self.vp.translate_point(b))
135+
}
136+
_ => {
137+
panic!("feature referenced in LineLength constraint was missing or not a line")
138+
}
139+
};
140+
141+
if let Some(Constraint::LineLength(_, fk, _, (ref_x, ref_y))) = self.constraint_mut(k) {
142+
let c = a.lerp(b, 0.5);
143+
let mut v = c.to_vec2() - pos.to_vec2();
144+
let reference = egui::Vec2::angled((a - b).angle() - v.angle()) * v.length();
145+
*ref_x = -reference.x;
146+
*ref_y = reference.y;
147+
};
148+
}
149+
}
150+
120151
/// Returns the feature key of the point exactly at the given position.
121152
pub fn find_point_at(&self, p: egui::Pos2) -> Option<FeatureKey> {
122153
for (k, v) in self.features.iter() {

drawing/src/lib.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ pub struct PaintParams {
3737
enum DragState {
3838
SelectBox(egui::Pos2),
3939
Feature(FeatureKey, egui::Vec2),
40+
Constraint(ConstraintKey, egui::Vec2),
4041
}
4142

4243
#[derive(Clone, Debug, Copy)]
4344
enum Input {
4445
Selection(egui::Rect),
4546
FeatureDrag(FeatureKey, egui::Pos2),
47+
ConstraintDrag(ConstraintKey, egui::Pos2),
4648
}
4749

4850
/// Widget implements the egui drawing widget.
@@ -134,6 +136,15 @@ impl<'a> Widget<'a> {
134136
k: _,
135137
feature: Feature::LineSegment(..),
136138
} => None,
139+
Hover::Constraint {
140+
k,
141+
constraint: Constraint::LineLength(_, _, _, (x, y)),
142+
} => {
143+
let offset = self.drawing.vp.screen_to_point(hp) - egui::Pos2::new(*x, *y);
144+
let state = DragState::Constraint(*k, offset);
145+
ui.memory_mut(|mem| mem.data.insert_temp(select_id, state));
146+
Some(state)
147+
}
137148
Hover::Constraint { .. } => None,
138149
}
139150
} else {
@@ -174,6 +185,14 @@ impl<'a> Widget<'a> {
174185
Some(Input::FeatureDrag(fk, new_pos))
175186
}
176187

188+
(Some(DragState::Constraint(ck, offset)), _) => {
189+
if released {
190+
ui.memory_mut(|mem| mem.data.remove::<DragState>(select_id));
191+
}
192+
self.drawing.move_constraint(ck, hp);
193+
Some(Input::ConstraintDrag(ck, hp))
194+
}
195+
177196
(None, _) => None,
178197
}
179198
} else {
@@ -265,7 +284,18 @@ impl<'a> Widget<'a> {
265284

266285
// Draw constraints
267286
for (k, v) in self.drawing.constraints_iter() {
268-
v.paint(self.drawing, k, &base_params, painter);
287+
let hovered = match hover {
288+
Hover::Constraint { k: hk, .. } => hk == k,
289+
_ => false,
290+
};
291+
let selected = false;
292+
293+
let pp = PaintParams {
294+
hovered,
295+
selected,
296+
..base_params.clone()
297+
};
298+
v.paint(self.drawing, k, &pp, painter);
269299
}
270300

271301
if let Some(Input::Selection(current_drag)) = current_input {

0 commit comments

Comments
 (0)