Skip to content

Commit 48b6e62

Browse files
author
Ubuntu
committed
Revert "feat(viewer): click-to-engage overlay, movable HUD (#18)"
This reverts commit 92be9ed.
1 parent 7f9c157 commit 48b6e62

File tree

1 file changed

+21
-85
lines changed

1 file changed

+21
-85
lines changed

dimos/src/interaction/keyboard.rs

Lines changed: 21 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const BASE_ANGULAR_SPEED: f64 = 0.8; // rad/s
1919
const FAST_MULTIPLIER: f64 = 2.0; // Shift modifier
2020

2121
/// Overlay styling
22+
const OVERLAY_MARGIN: f32 = 12.0;
2223
const OVERLAY_PADDING: f32 = 10.0;
2324
const OVERLAY_ROUNDING: f32 = 8.0;
2425
const OVERLAY_BG: egui::Color32 = egui::Color32::from_rgba_premultiplied(20, 20, 30, 220);
@@ -65,13 +66,11 @@ impl KeyState {
6566
}
6667

6768
/// Handles keyboard input and publishes Twist via LCM.
68-
/// Must be activated by clicking the overlay before keys are captured.
6969
pub struct KeyboardHandler {
7070
publisher: LcmPublisher,
7171
state: KeyState,
7272
was_active: bool,
7373
estop_flash: bool, // true briefly after space pressed
74-
engaged: bool, // true when user has clicked the overlay to activate
7574
}
7675

7776
impl KeyboardHandler {
@@ -83,30 +82,29 @@ impl KeyboardHandler {
8382
state: KeyState::new(),
8483
was_active: false,
8584
estop_flash: false,
86-
engaged: false,
8785
})
8886
}
8987

9088
/// Process keyboard input from egui and publish Twist if keys are held.
9189
/// Called once per frame from DimosApp.ui().
92-
/// Only captures keys when the overlay has been clicked (engaged).
9390
///
9491
/// Returns true if any movement key is active (for UI overlay).
9592
pub fn process(&mut self, ctx: &egui::Context) -> bool {
9693
self.estop_flash = false;
9794

98-
// If not engaged, don't capture any keys
99-
if !self.engaged {
95+
// Check if any text widget has focus - if so, skip keyboard capture
96+
let text_has_focus = ctx.memory(|m| m.focused().is_some());
97+
if text_has_focus {
10098
if self.was_active {
10199
if let Err(e) = self.publish_stop() {
102-
re_log::warn!("Failed to send stop on disengage: {e:?}");
100+
re_log::warn!("Failed to send stop command on focus change: {e:?}");
103101
}
104102
self.was_active = false;
105103
}
106104
return false;
107105
}
108106

109-
// Update key state from egui input (engaged flag is the only gate)
107+
// Update key state from egui input
110108
self.update_key_state(ctx);
111109

112110
// Check for emergency stop (Space key pressed - one-shot action)
@@ -136,85 +134,33 @@ impl KeyboardHandler {
136134
self.state.any_active()
137135
}
138136

139-
/// Draw keyboard overlay HUD at bottom-right of the 3D viewport area.
140-
/// Clickable: clicking the overlay toggles engaged state.
141-
pub fn draw_overlay(&mut self, ctx: &egui::Context) {
142-
let screen_rect = ctx.content_rect();
143-
// Default position: bottom-left, just above the timeline bar
144-
let overlay_height = 160.0;
145-
let left_margin = 12.0;
146-
let bottom_timeline_offset = 120.0;
147-
let default_pos = egui::pos2(
148-
screen_rect.min.x + left_margin,
149-
screen_rect.max.y - overlay_height - bottom_timeline_offset,
150-
);
151-
152-
let area_response = egui::Area::new("keyboard_hud".into())
153-
.pivot(egui::Align2::LEFT_BOTTOM)
154-
.default_pos(default_pos)
155-
.movable(true)
137+
/// Draw keyboard overlay HUD. Always shown (dim when idle, bright when active).
138+
pub fn draw_overlay(&self, ctx: &egui::Context) {
139+
egui::Area::new("keyboard_hud".into())
140+
.fixed_pos(egui::pos2(OVERLAY_MARGIN, OVERLAY_MARGIN))
156141
.order(egui::Order::Foreground)
157-
.interactable(true)
142+
.interactable(false)
158143
.show(ctx, |ui| {
159-
let border_color = if self.engaged {
160-
egui::Color32::from_rgb(60, 180, 75) // green border when active
161-
} else {
162-
egui::Color32::from_rgb(80, 80, 100) // dim border when inactive
163-
};
164-
165-
let response = egui::Frame::new()
144+
egui::Frame::new()
166145
.fill(OVERLAY_BG)
167146
.corner_radius(egui::CornerRadius::same(OVERLAY_ROUNDING as u8))
168147
.inner_margin(egui::Margin::same(OVERLAY_PADDING as i8))
169-
.stroke(egui::Stroke::new(2.0, border_color))
170148
.show(ui, |ui| {
171149
self.draw_hud_content(ui);
172150
});
173-
174-
// Make the frame rect clickable (Frame doesn't have click sense by default)
175-
let click_response = ui.interact(
176-
response.response.rect,
177-
ui.id().with("wasd_click"),
178-
egui::Sense::click(),
179-
);
180-
181-
// Force arrow cursor over the entire overlay (overrides label I-beam)
182-
if click_response.hovered() {
183-
ctx.set_cursor_icon(egui::CursorIcon::Default);
184-
}
185-
186-
// Toggle engaged state on click
187-
if click_response.clicked() {
188-
self.engaged = !self.engaged;
189-
if !self.engaged {
190-
// Send stop when disengaging
191-
if let Err(e) = self.publish_stop() {
192-
re_log::warn!("Failed to send stop on disengage: {e:?}");
193-
}
194-
self.state.reset();
195-
self.was_active = false;
196-
}
197-
}
198-
})
199-
.response;
200-
201-
// Disengage when clicking anywhere outside the overlay
202-
if self.engaged
203-
&& !ctx.rect_contains_pointer(area_response.layer_id, area_response.interact_rect)
204-
&& ctx.input(|i| i.pointer.primary_clicked())
205-
{
206-
self.engaged = false;
207-
if let Err(e) = self.publish_stop() {
208-
re_log::warn!("Failed to send stop on outside click: {e:?}");
209-
}
210-
self.state.reset();
211-
self.was_active = false;
212-
}
151+
});
213152
}
214153

215154
fn draw_hud_content(&self, ui: &mut egui::Ui) {
155+
let active = self.state.any_active() || self.estop_flash;
156+
216157
// Title
217-
ui.label(egui::RichText::new("Keyboard Teleop").color(LABEL_COLOR).size(13.0));
158+
let title_color = if active {
159+
egui::Color32::WHITE
160+
} else {
161+
egui::Color32::from_rgb(120, 120, 140)
162+
};
163+
ui.label(egui::RichText::new("🎮 Keyboard Teleop").color(title_color).size(13.0));
218164
ui.add_space(4.0);
219165

220166
// Key grid: [Q] [W] [E]
@@ -406,7 +352,6 @@ mod tests {
406352
state,
407353
was_active: false,
408354
estop_flash: false,
409-
engaged: true,
410355
};
411356
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
412357
assert_eq!(lin_x, BASE_LINEAR_SPEED);
@@ -423,7 +368,6 @@ mod tests {
423368
state,
424369
was_active: false,
425370
estop_flash: false,
426-
engaged: true,
427371
};
428372
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
429373
assert_eq!(lin_x, 0.0);
@@ -437,7 +381,6 @@ mod tests {
437381
state,
438382
was_active: false,
439383
estop_flash: false,
440-
engaged: true,
441384
};
442385
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
443386
assert_eq!(lin_x, 0.0);
@@ -454,7 +397,6 @@ mod tests {
454397
state,
455398
was_active: false,
456399
estop_flash: false,
457-
engaged: true,
458400
};
459401
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
460402
assert_eq!(lin_x, 0.0);
@@ -468,7 +410,6 @@ mod tests {
468410
state,
469411
was_active: false,
470412
estop_flash: false,
471-
engaged: true,
472413
};
473414
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
474415
assert_eq!(lin_x, 0.0);
@@ -486,7 +427,6 @@ mod tests {
486427
state,
487428
was_active: false,
488429
estop_flash: false,
489-
engaged: true,
490430
};
491431
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
492432
assert_eq!(lin_x, BASE_LINEAR_SPEED * FAST_MULTIPLIER);
@@ -504,7 +444,6 @@ mod tests {
504444
state,
505445
was_active: false,
506446
estop_flash: false,
507-
engaged: true,
508447
};
509448
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
510449
assert_eq!(lin_x, BASE_LINEAR_SPEED);
@@ -532,7 +471,6 @@ mod tests {
532471
assert!(handler.is_ok());
533472
let handler = handler.unwrap();
534473
assert!(!handler.was_active);
535-
assert!(!handler.engaged);
536474
assert!(!handler.state.any_active());
537475
}
538476

@@ -546,7 +484,6 @@ mod tests {
546484
state,
547485
was_active: false,
548486
estop_flash: false,
549-
engaged: true,
550487
};
551488
let (lin_x, lin_y, _, _, _, ang_z) = handler.compute_twist();
552489
assert_eq!(lin_x, 0.0);
@@ -561,7 +498,6 @@ mod tests {
561498
state: KeyState::new(),
562499
was_active: false,
563500
estop_flash: false,
564-
engaged: true,
565501
};
566502
let (lin_x, lin_y, lin_z, ang_x, ang_y, ang_z) = handler.compute_twist();
567503
assert_eq!(lin_x, 0.0);

0 commit comments

Comments
 (0)