From 11ac0ea84b3631b876ea329b7441054ba7e6fafb Mon Sep 17 00:00:00 2001 From: ardocrat Date: Fri, 3 May 2024 23:34:28 +0300 Subject: [PATCH] camera: desktop support, switch camera, fix image crop --- .../java/mw/gri/android/MainActivity.java | 2 +- src/gui/platform/android/mod.rs | 20 +++++----- src/gui/platform/desktop/mod.rs | 23 ++++------- src/gui/platform/mod.rs | 4 +- src/gui/views/camera.rs | 39 ++++++++++++++----- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/android/app/src/main/java/mw/gri/android/MainActivity.java b/android/app/src/main/java/mw/gri/android/MainActivity.java index 976b51d..f78e91c 100644 --- a/android/app/src/main/java/mw/gri/android/MainActivity.java +++ b/android/app/src/main/java/mw/gri/android/MainActivity.java @@ -325,7 +325,7 @@ public class MainActivity extends GameActivity { // Called from native code to switch camera. public void switchCamera() { - mUseBackCamera = true; + mUseBackCamera = !mUseBackCamera; stopCamera(); startCamera(); } diff --git a/src/gui/platform/android/mod.rs b/src/gui/platform/android/mod.rs index a10a4b4..ca2d230 100644 --- a/src/gui/platform/android/mod.rs +++ b/src/gui/platform/android/mod.rs @@ -82,16 +82,6 @@ impl PlatformCallbacks for Android { paste_data } - fn cameras_amount(&self) -> u32 { - let result = self.call_java_method("camerasAmount", "()I", &[]).unwrap(); - let amount = unsafe { result.i }; - amount as u32 - } - - fn switch_camera(&self) { - self.call_java_method("switchCamera", "()V", &[]).unwrap(); - } - fn start_camera(&self) { // Clear image. let mut w_image = LAST_CAMERA_IMAGE.write().unwrap(); @@ -115,6 +105,16 @@ impl PlatformCallbacks for Android { } None } + + fn can_switch_camera(&self) -> bool { + let result = self.call_java_method("camerasAmount", "()I", &[]).unwrap(); + let amount = unsafe { result.i }; + amount > 1 + } + + fn switch_camera(&self) { + self.call_java_method("switchCamera", "()V", &[]).unwrap(); + } } lazy_static! { diff --git a/src/gui/platform/desktop/mod.rs b/src/gui/platform/desktop/mod.rs index fc9e1c2..8005c40 100644 --- a/src/gui/platform/desktop/mod.rs +++ b/src/gui/platform/desktop/mod.rs @@ -53,21 +53,6 @@ impl PlatformCallbacks for Desktop { clipboard.get_text().unwrap_or("".to_string()) } - fn cameras_amount(&self) -> u32 { - let devices = PlatformContext::default().devices(); - if devices.is_ok() { - return devices.unwrap().len() as u32; - } - 0 - } - - fn switch_camera(&self) { - let amount = self.cameras_amount(); - if amount < 2 { - return; - } - } - fn start_camera(&self) { // Clear image. { @@ -157,6 +142,14 @@ impl PlatformCallbacks for Desktop { } None } + + fn can_switch_camera(&self) -> bool { + false + } + + fn switch_camera(&self) { + return; + } } /// Last captured image from started camera. diff --git a/src/gui/platform/mod.rs b/src/gui/platform/mod.rs index 8f5172f..253fb50 100644 --- a/src/gui/platform/mod.rs +++ b/src/gui/platform/mod.rs @@ -26,9 +26,9 @@ pub trait PlatformCallbacks { fn hide_keyboard(&self); fn copy_string_to_buffer(&self, data: String); fn get_string_from_buffer(&self) -> String; - fn cameras_amount(&self) -> u32; - fn switch_camera(&self); fn start_camera(&self); fn stop_camera(&self); fn camera_image(&self) -> Option<(Vec, u32)>; + fn can_switch_camera(&self) -> bool; + fn switch_camera(&self); } \ No newline at end of file diff --git a/src/gui/views/camera.rs b/src/gui/views/camera.rs index 1b5000c..4dd29e2 100644 --- a/src/gui/views/camera.rs +++ b/src/gui/views/camera.rs @@ -13,9 +13,12 @@ // limitations under the License. use std::sync::{Arc, RwLock}; +use eframe::emath::Align; use egui::load::SizedTexture; -use egui::{Pos2, Rect, TextureOptions, Widget}; +use egui::{Layout, Pos2, Rect, TextureOptions, Widget}; use image::{DynamicImage, EncodableLayout, ImageFormat}; +use crate::gui::Colors; +use crate::gui::icons::CAMERA_ROTATE; use crate::gui::platform::PlatformCallbacks; use crate::gui::views::types::QrScanState; @@ -52,7 +55,7 @@ impl CameraContent { _ => img }; // Convert to ColorImage to add at content. - let color_image = match &img { + let color_img = match &img { DynamicImage::ImageRgb8(image) => { egui::ColorImage::from_rgb( [image.width() as usize, image.height() as usize], @@ -69,21 +72,37 @@ impl CameraContent { }; // Create image texture. let texture = ui.ctx().load_texture("camera_image", - color_image.clone(), + color_img.clone(), TextureOptions::default()); - let image_size = egui::emath::vec2(color_image.width() as f32, - color_image.height() as f32); - let sized_image = SizedTexture::new(texture.id(), image_size); + let img_size = egui::emath::vec2(color_img.width() as f32, + color_img.height() as f32); + let sized_img = SizedTexture::new(texture.id(), img_size); // Add image to content. ui.vertical_centered(|ui| { - egui::Image::from_texture(sized_image) - // Setup to make image cropped at center of square. - .uv(Rect::from([Pos2::new(0.25, 0.0), Pos2::new(1.0, 1.0)])) + egui::Image::from_texture(sized_img) + // Setup to crop image at square. + .uv(Rect::from([ + Pos2::new(1.0 - (img_size.y / img_size.x), 0.0), + Pos2::new(1.0, 1.0) + ])) .max_height(ui.available_width()) .maintain_aspect_ratio(false) .shrink_to_fit() .ui(ui); }); + + // Show button to switch cameras. + if cb.can_switch_camera() { + ui.add_space(-52.0); + let mut size = ui.available_size(); + size.y = 48.0; + ui.allocate_ui_with_layout(size, Layout::right_to_left(Align::Max), |ui| { + ui.add_space(4.0); + View::button(ui, CAMERA_ROTATE.to_string(), Colors::WHITE, || { + cb.switch_camera(); + }); + }); + } } else { self.loading_content_ui(ui); } @@ -137,7 +156,7 @@ impl CameraContent { for g in grids { if let Ok((meta, text)) = g.decode() { println!("12345 ecc: {}, text: {}", meta.ecc_level, text.clone()); - if !text.is_empty() { + if !text.trim().is_empty() { let mut w_scan = self.qr_scan_state.write().unwrap(); w_scan.qr_scan_result = Some(text); }