working highlight and click selection for tracker

This commit is contained in:
Nickiel12 2024-05-28 20:57:25 -05:00
parent 8924d2ab8f
commit bc5d2bc84e
4 changed files with 101 additions and 5 deletions

View file

@ -184,7 +184,11 @@ async fn listen_to_messages(
}
}
}
Ok(None) => info!("Recieved an empty message from the remote computer"),
Ok(None) => {
info!("Recieved an empty message from the remote computer: Aborting");
break;
}
Err(e) => {
error!("Got an error on while recieving from remote computer: {e}");
}

View file

@ -28,6 +28,7 @@ use crate::{
#[derive(Debug)]
pub struct TrackerState {
pub tracking_id: u32,
pub highlighted_id: Option<u32>,
pub last_detect: Instant,
pub enabled: bool,

View file

@ -1,7 +1,15 @@
use std::sync::{Arc, Mutex};
use gtk::{
gdk::Paintable, prelude::BoxExt, AspectFrame, Box, DrawingArea, Label, Overlay, Picture,
gdk::Paintable,
prelude::{BoxExt, GestureExt, WidgetExt},
AspectFrame, Box, DrawingArea, EventControllerMotion, GestureClick, Label, Overlay, Picture,
};
use tracing::info;
use crate::remote_sources::TrackerState;
pub struct LiveViewPanel {
top_level: gtk::Box,
@ -13,7 +21,7 @@ pub struct LiveViewPanel {
}
impl LiveViewPanel {
pub fn new() -> Self {
pub fn new(tracker_state: Arc<Mutex<TrackerState>>) -> Self {
let right_box = gtk::Box::builder()
.orientation(gtk::Orientation::Vertical)
.hexpand(true)
@ -26,7 +34,6 @@ impl LiveViewPanel {
.css_classes(vec!["large-label", "NoConnection"])
.build();
// let conn_status_label = Label::new(Some(&"No Connection".to_string()));
let cam_status_label = Label::builder()
.label("No Connection".to_string())
.css_classes(vec!["NoConnection"])
@ -44,6 +51,32 @@ impl LiveViewPanel {
let overlay_box = gtk::Overlay::builder().build();
overlay_box.set_child(Some(&webcam_picture));
let click_handler = GestureClick::builder()
.button(gtk::gdk::ffi::GDK_BUTTON_PRIMARY as u32)
.propagation_limit(gtk::PropagationLimit::SameNative)
.build();
let move_handler = EventControllerMotion::builder()
.propagation_limit(gtk::PropagationLimit::SameNative)
.build();
let tracker_state_2 = tracker_state.clone();
let handler_picture = webcam_picture.clone();
move_handler.connect_motion(move |_motion_handler, x, y| {
LiveViewPanel::motion_callback(&handler_picture, &tracker_state_2, x, y);
});
let handler_picture = webcam_picture.clone();
click_handler.connect_pressed(move |gesture, _id, x, y| {
gesture.set_state(gtk::EventSequenceState::Claimed);
LiveViewPanel::gesture_callback(&handler_picture, &tracker_state, x, y)
});
overlay_box.add_controller(click_handler);
overlay_box.add_controller(move_handler);
let aspect = AspectFrame::builder()
.ratio(16.0 / 9.0)
.obey_child(false)
@ -65,6 +98,60 @@ impl LiveViewPanel {
}
}
fn gesture_callback(
overlay: &Picture,
tracker_state: &Arc<Mutex<TrackerState>>,
x_coord: f64,
y_coord: f64,
) {
let x_size = overlay.size(gtk::Orientation::Horizontal);
let y_size = overlay.size(gtk::Orientation::Vertical);
let x_coord = x_coord as f32 / x_size as f32;
let y_coord = y_coord as f32 / y_size as f32;
if let Ok(mut ts) = tracker_state.lock() {
let mut select: Option<u32> = None;
for nb in ts.identity_boxes.iter() {
if nb.x1 < x_coord as f32
&& nb.y1 < y_coord as f32
&& nb.x2 > x_coord as f32
&& nb.y2 > y_coord as f32
{
select = Some(nb.id);
}
}
if let Some(new_id) = select {
ts.tracking_id = new_id;
}
}
}
fn motion_callback(
overlay: &Picture,
tracker_state: &Arc<Mutex<TrackerState>>,
x_coord: f64,
y_coord: f64,
) {
let x_size = overlay.size(gtk::Orientation::Horizontal);
let y_size = overlay.size(gtk::Orientation::Vertical);
let x_coord = x_coord as f32 / x_size as f32;
let y_coord = y_coord as f32 / y_size as f32;
if let Ok(mut ts) = tracker_state.lock() {
let mut highlighted_id: Option<u32> = None;
for nb in ts.identity_boxes.iter() {
if nb.x1 < x_coord as f32
&& nb.y1 < y_coord as f32
&& nb.x2 > x_coord as f32
&& nb.y2 > y_coord as f32
{
highlighted_id = Some(nb.id);
}
}
ts.highlighted_id = highlighted_id;
}
}
pub fn get_top_level(&self) -> &Box {
&self.top_level
}

View file

@ -144,6 +144,7 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
let (to_gui, gui_recv) = async_channel::bounded::<GuiUpdate>(10);
let tracker_state = Arc::new(Mutex::new(TrackerState {
tracking_id: 0,
highlighted_id: None,
last_detect: Instant::now(),
enabled: true,
@ -173,7 +174,7 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
main_box.append(&left_box);
let liveview_panel = LiveViewPanel::new();
let liveview_panel = LiveViewPanel::new(tracker_state.clone());
main_box.append(liveview_panel.get_top_level());
let drawable = gtk::DrawingArea::builder().build();
@ -314,9 +315,12 @@ fn draw_boxes(width: i32, height: i32, ctx: &Context, tracker_state: &Arc<Mutex<
debug!("Getting tracker state for drawing boxes");
if let Ok(ts) = tracker_state.lock() {
let active = ts.tracking_id;
let highlighted_id = ts.highlighted_id.unwrap_or(0);
for nb in ts.identity_boxes.iter() {
if nb.id == active {
ctx.set_source_rgb(1.0, 0.0, 0.0);
} else if nb.id == highlighted_id {
ctx.set_source_rgb(0.0, 1.0, 1.0);
} else {
ctx.set_source_rgb(0.0, 0.0, 1.0);
}