fixed picture's aspect ratio

This commit is contained in:
Nickiel12 2024-04-27 22:35:43 -07:00
parent f706157354
commit 3cb560093c
2 changed files with 57 additions and 20 deletions

View file

@ -72,6 +72,7 @@ impl<'a> CoordState<'a> {
to_gui: Sender<GuiUpdate>, to_gui: Sender<GuiUpdate>,
rt: Handle, rt: Handle,
identity_boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>>, identity_boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>>,
tracker_state: Arc<Mutex<TrackerState>>,
) -> Self { ) -> Self {
let this = CoordState { let this = CoordState {
sck_outbound: None, sck_outbound: None,
@ -91,11 +92,7 @@ impl<'a> CoordState<'a> {
pipeline: gstreamer_pipeline::WebcamPipeline::new(), pipeline: gstreamer_pipeline::WebcamPipeline::new(),
keep_windows_pipe_alive: Arc::new(AtomicBool::new(true)), keep_windows_pipe_alive: Arc::new(AtomicBool::new(true)),
tracker_state: Arc::new(Mutex::new(TrackerState { tracker_state,
tracking_id: 0,
last_detect: Instant::now(),
has_active_connection: false,
}))
}; };
this.rt.spawn(crate::remote_sources::shared_video_pipe::create_outbound_pipe( this.rt.spawn(crate::remote_sources::shared_video_pipe::create_outbound_pipe(
this.pipeline.sink_frame.clone(), this.pipeline.sink_frame.clone(),
@ -202,12 +199,13 @@ pub async fn start_coordinator(
to_gui: Sender<GuiUpdate>, to_gui: Sender<GuiUpdate>,
runtime: Handle, runtime: Handle,
identity_boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>>, identity_boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>>,
tracker_state: Arc<Mutex<TrackerState>>,
) { ) {
info!("Starting coordinator!"); info!("Starting coordinator!");
let mec = pin!(mec); let mec = pin!(mec);
let mut state = CoordState::new(mec, to_mec, to_gui, runtime, identity_boxes); let mut state = CoordState::new(mec, to_mec, to_gui, runtime, identity_boxes, tracker_state);
state.pipeline state.pipeline
.pipeline .pipeline

View file

@ -1,16 +1,19 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Instant;
use gtk::cairo::Context; use gtk::cairo::Context;
use gtk::ffi::gtk_picture_set_keep_aspect_ratio;
use gtk::gdk::Paintable; use gtk::gdk::Paintable;
use gtk::{glib, prelude::*, Box, Entry, Label, ListBox}; use gtk::{glib, prelude::*, AspectFrame, Box, Entry, Label, ListBox};
use gtk::{Application, ApplicationWindow, Button}; use gtk::{Application, ApplicationWindow, Button};
use log::error; use log::{info, error};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::runtime::Handle; use tokio::runtime::Handle;
use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::tungstenite::Message;
use crate::config::{load_config, save_config}; use crate::config::{load_config, save_config};
use crate::coordinator::{start_coordinator, ApplicationEvent, MoveEvent}; use crate::coordinator::{start_coordinator, ApplicationEvent, MoveEvent};
use crate::remote_sources::TrackerState;
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AppState { pub struct AppState {
@ -70,8 +73,8 @@ pub fn build_ui(app: &Application, runtime: Handle) {
let window = ApplicationWindow::builder() let window = ApplicationWindow::builder()
.application(app) .application(app)
.title("VCC Camera Controller") .title("VCC Camera Controller")
.default_width(840) // .default_width(840)
.default_height(480) // .default_height(480)
.child(&main_box) .child(&main_box)
.build(); .build();
@ -79,6 +82,12 @@ pub fn build_ui(app: &Application, runtime: Handle) {
let (to_mec, mec) = async_channel::unbounded::<ApplicationEvent>(); let (to_mec, mec) = async_channel::unbounded::<ApplicationEvent>();
let (to_gui, gui_recv) = async_channel::bounded::<GuiUpdate>(10); let (to_gui, gui_recv) = async_channel::bounded::<GuiUpdate>(10);
let identity_boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>> = Arc::new(Mutex::new(vec![])); let identity_boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>> = Arc::new(Mutex::new(vec![]));
let tracker_state = Arc::new(Mutex::new(TrackerState {
tracking_id: 0,
last_detect: Instant::now(),
has_active_connection: false,
}));
runtime.spawn(start_coordinator( runtime.spawn(start_coordinator(
mec, mec,
@ -86,6 +95,7 @@ pub fn build_ui(app: &Application, runtime: Handle) {
to_gui, to_gui,
runtime.clone(), runtime.clone(),
identity_boxes.clone(), identity_boxes.clone(),
tracker_state.clone(),
)); ));
// let conn_status_label = Label::new(Some(&"No Connection".to_string())); // let conn_status_label = Label::new(Some(&"No Connection".to_string()));
@ -134,22 +144,30 @@ pub fn build_ui(app: &Application, runtime: Handle) {
main_box.append(&left_box); main_box.append(&left_box);
let webcam_picture = gtk::Picture::builder() let webcam_picture = gtk::Picture::builder()
.height_request(480) // .height_request(270)
.width_request(640) .width_request(640)
.can_focus(false) .can_focus(false)
.build(); .build();
let overlay_box = gtk::Overlay::new(); let overlay_box = gtk::Overlay::builder()
main_box.append(&overlay_box); .build();
let aspect = AspectFrame::builder()
.ratio(16.0/9.0)
.obey_child(false)
.child(&overlay_box)
.build();
main_box.append(&aspect);
let drawable = gtk::DrawingArea::builder() let drawable = gtk::DrawingArea::builder()
.content_height(480) // .content_height(480)
.content_width(640) // .content_width(640)
.build(); .build();
drawable.set_draw_func(move |_, ctx, width, height| { drawable.set_draw_func(move |_, ctx, width, height| {
draw_boxes(width, height,&ctx, identity_boxes.clone()); draw_boxes(width, height, &ctx, identity_boxes.clone(), tracker_state.clone());
}); });
overlay_box.set_child(Some(&webcam_picture)); overlay_box.set_child(Some(&webcam_picture));
overlay_box.add_overlay(&drawable); overlay_box.add_overlay(&drawable);
@ -186,8 +204,9 @@ pub fn build_ui(app: &Application, runtime: Handle) {
})); }));
glib::spawn_future_local( glib::spawn_future_local(
glib::clone!(@weak axis_label, @weak button, @weak conn_status_label, @weak ip_entry, @weak port_entry, @strong gui_recv => async move { glib::clone!(@weak axis_label, @weak button, @weak conn_status_label, @weak ip_entry, @weak port_entry, @strong gui_recv, @weak drawable => async move {
while let Ok(d) = gui_recv.recv().await { while let Ok(d) = gui_recv.recv().await {
drawable.queue_draw();
match d { match d {
GuiUpdate::MoveEvent(msg) => { GuiUpdate::MoveEvent(msg) => {
axis_label.set_text( axis_label.set_text(
@ -233,12 +252,25 @@ pub fn build_ui(app: &Application, runtime: Handle) {
window.present(); window.present();
} }
fn draw_boxes(width: i32, height: i32, ctx: &Context, boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>>) { fn draw_boxes(width: i32, height: i32, ctx: &Context, boxes: Arc<Mutex<Vec<NormalizedBoxCoords>>>, tracker_state: Arc<Mutex<TrackerState>>) {
ctx.set_line_width(2.0); ctx.set_line_width(5.0);
ctx.set_source_rgb(0.0, 1.0, 0.0); ctx.select_font_face("Arial", gtk::cairo::FontSlant::Normal, gtk::cairo::FontWeight::Bold);
ctx.set_font_size(24.0);
let active: u32 = match tracker_state.lock() {
Ok(e) => e.tracking_id,
Err(_) => 0
};
if let Ok(bxs) = boxes.lock() { if let Ok(bxs) = boxes.lock() {
for nb in bxs.iter() { for nb in bxs.iter() {
if nb.id == active {
ctx.set_source_rgb(1.0, 0.0, 0.0);
} else {
ctx.set_source_rgb(0.0, 0.0, 1.0);
}
let b = nb.into_relative(width, height); let b = nb.into_relative(width, height);
ctx.rectangle( ctx.rectangle(
b.x1 as f64, b.x1 as f64,
@ -251,6 +283,13 @@ fn draw_boxes(width: i32, height: i32, ctx: &Context, boxes: Arc<Mutex<Vec<Norma
} }
ctx.stroke() ctx.stroke()
.expect("GTK Cario context did not have a stroke!"); .expect("GTK Cario context did not have a stroke!");
ctx.move_to(b.x1 as f64 + 5.0, b.y1 as f64 + 18.0);
ctx.set_source_rgb(0.0, 0.0, 0.0);
ctx.show_text(&format!("[{}]", b.id)).expect("Couldn't show text!");
ctx.stroke()
.expect("GTK Cario context did not have a stroke!");
} }
} else { } else {
error!("Could not get lock on boxes for drawing on the draw area!"); error!("Could not get lock on boxes for drawing on the draw area!");