build: macos camera fix, update dependencies, initial cargo-bundle setup, update icons
This commit is contained in:
parent
1c13eb370b
commit
2196fbefa6
6 changed files with 785 additions and 290 deletions
930
Cargo.lock
generated
930
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
24
Cargo.toml
24
Cargo.toml
|
@ -9,6 +9,20 @@ keywords = [ "crypto", "grin", "mimblewimble" ]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
build = "src/build/build.rs"
|
build = "src/build/build.rs"
|
||||||
|
|
||||||
|
[package.metadata.bundle]
|
||||||
|
name = "Grim"
|
||||||
|
identifier = "mw.gri"
|
||||||
|
icon = ["img/icon.png", "img/128x128.png", "img/128x128@2x.png"]
|
||||||
|
version = "0.1.0"
|
||||||
|
resources = ["img"]
|
||||||
|
copyright = "Copyright (c) Grim 2024. All rights reserved."
|
||||||
|
category = "public.app-category.finance"
|
||||||
|
short_description = "Cross-platform GUI for Grin."
|
||||||
|
long_description = """
|
||||||
|
Cross-platform GUI for Grin on Rust with focus on usability and availability to be used by anyone, anywhere.
|
||||||
|
"""
|
||||||
|
deb_depends = ["libssl-dev", "pkg-config"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name="grim"
|
name="grim"
|
||||||
crate_type=["cdylib", "rlib"]
|
crate_type=["cdylib", "rlib"]
|
||||||
|
@ -94,7 +108,13 @@ tokio-util = { version = "0.7.8", features = ["codec"] }
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
built = { version = "0.7.0", features = ["git2"]}
|
built = { version = "0.7.0", features = ["git2"]}
|
||||||
|
|
||||||
[target.'cfg(target_vendor = "apple")'.dependencies]
|
[target.'cfg(all(not(target_os = "windows"), not(target_os = "android")))'.dependencies]
|
||||||
|
eye = { version = "0.5.0", default-features = false }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
nokhwa = { version = "0.10.4", default-features = false, features = ["input-msmf"] }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
tls-api-openssl = "0.9.0"
|
tls-api-openssl = "0.9.0"
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||||
|
@ -104,8 +124,6 @@ eframe = { version = "0.27.2", features = ["wgpu", "glow"] }
|
||||||
arboard = "3.2.0"
|
arboard = "3.2.0"
|
||||||
rfd = "0.14.1"
|
rfd = "0.14.1"
|
||||||
dark-light = "1.1.1"
|
dark-light = "1.1.1"
|
||||||
# camera
|
|
||||||
nokhwa = { git = "https://github.com/l1npengtul/nokhwa", branch = "0.10", features = ["input-native", "output-threaded"] }
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
android_logger = "0.13.1"
|
android_logger = "0.13.1"
|
||||||
|
|
BIN
img/128x128.png
Normal file
BIN
img/128x128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
img/128x128@2.png
Normal file
BIN
img/128x128@2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
BIN
img/icon.png
BIN
img/icon.png
Binary file not shown.
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 88 KiB |
|
@ -19,9 +19,6 @@ use parking_lot::RwLock;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use nokhwa::Camera;
|
|
||||||
use nokhwa::pixel_format::RgbFormat;
|
|
||||||
use nokhwa::utils::{CameraIndex, RequestedFormat, RequestedFormatType};
|
|
||||||
use rfd::FileDialog;
|
use rfd::FileDialog;
|
||||||
|
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
@ -69,48 +66,13 @@ impl PlatformCallbacks for Desktop {
|
||||||
|
|
||||||
// Capture images at separate thread.
|
// Capture images at separate thread.
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
Self::start_camera_capture(stop_camera);
|
||||||
.enable_all()
|
|
||||||
.build()
|
|
||||||
.unwrap()
|
|
||||||
.block_on(async {
|
|
||||||
let index = CameraIndex::Index(0);
|
|
||||||
let requested = RequestedFormat::new::<RgbFormat>(
|
|
||||||
RequestedFormatType::AbsoluteHighestFrameRate
|
|
||||||
);
|
|
||||||
// Create and open camera.
|
|
||||||
let mut camera = Camera::new(index, requested).unwrap();
|
|
||||||
if let Ok(_) = camera.open_stream() {
|
|
||||||
loop {
|
|
||||||
// Stop if camera was stopped.
|
|
||||||
if stop_camera.load(Ordering::Relaxed) {
|
|
||||||
stop_camera.store(false, Ordering::Relaxed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Get a frame.
|
|
||||||
if let Ok(frame) = camera.frame() {
|
|
||||||
// Save image.
|
|
||||||
let mut w_image = LAST_CAMERA_IMAGE.write();
|
|
||||||
*w_image = Some((frame.buffer().to_vec(), 0));
|
|
||||||
} else {
|
|
||||||
// Clear image.
|
|
||||||
let mut w_image = LAST_CAMERA_IMAGE.write();
|
|
||||||
*w_image = None;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
camera.stop_stream().unwrap();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_camera(&self) {
|
fn stop_camera(&self) {
|
||||||
// Stop camera.
|
// Stop camera.
|
||||||
self.stop_camera.store(true, Ordering::Relaxed);
|
self.stop_camera.store(true, Ordering::Relaxed);
|
||||||
// Clear image.
|
|
||||||
let mut w_image = LAST_CAMERA_IMAGE.write();
|
|
||||||
*w_image = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn camera_image(&self) -> Option<(Vec<u8>, u32)> {
|
fn camera_image(&self) -> Option<(Vec<u8>, u32)> {
|
||||||
|
@ -159,6 +121,87 @@ impl PlatformCallbacks for Desktop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Desktop {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn start_camera_capture(stop_camera: Arc<AtomicBool>) {
|
||||||
|
use nokhwa::Camera;
|
||||||
|
use nokhwa::pixel_format::RgbFormat;
|
||||||
|
use nokhwa::utils::{CameraIndex, RequestedFormat, RequestedFormatType};
|
||||||
|
let index = CameraIndex::Index(0);
|
||||||
|
let requested = RequestedFormat::new::<RgbFormat>(
|
||||||
|
RequestedFormatType::AbsoluteHighestFrameRate
|
||||||
|
);
|
||||||
|
// Create and open camera.
|
||||||
|
let mut camera = Camera::new(index, requested).unwrap();
|
||||||
|
if let Ok(_) = camera.open_stream() {
|
||||||
|
loop {
|
||||||
|
// Stop if camera was stopped.
|
||||||
|
if stop_camera.load(Ordering::Relaxed) {
|
||||||
|
stop_camera.store(false, Ordering::Relaxed);
|
||||||
|
// Clear image.
|
||||||
|
let mut w_image = LAST_CAMERA_IMAGE.write();
|
||||||
|
*w_image = None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Get a frame.
|
||||||
|
if let Ok(frame) = camera.frame() {
|
||||||
|
// Save image.
|
||||||
|
let mut w_image = LAST_CAMERA_IMAGE.write();
|
||||||
|
*w_image = Some((frame.buffer().to_vec(), 0));
|
||||||
|
} else {
|
||||||
|
// Clear image.
|
||||||
|
let mut w_image = LAST_CAMERA_IMAGE.write();
|
||||||
|
*w_image = None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
camera.stop_stream().unwrap();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
fn start_camera_capture(stop_camera: Arc<AtomicBool>) {
|
||||||
|
use eye::hal::{traits::{Context, Device, Stream}, PlatformContext};
|
||||||
|
use image::ImageEncoder;
|
||||||
|
|
||||||
|
let ctx = PlatformContext::default();
|
||||||
|
let devices = ctx.devices().unwrap();
|
||||||
|
let dev = ctx.open_device(&devices[0].uri).unwrap();
|
||||||
|
|
||||||
|
let streams = dev.streams().unwrap();
|
||||||
|
let stream_desc = streams[0].clone();
|
||||||
|
let w = stream_desc.width;
|
||||||
|
let h = stream_desc.height;
|
||||||
|
|
||||||
|
let mut stream = dev.start_stream(&stream_desc).unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Stop if camera was stopped.
|
||||||
|
if stop_camera.load(Ordering::Relaxed) {
|
||||||
|
stop_camera.store(false, Ordering::Relaxed);
|
||||||
|
// Clear image.
|
||||||
|
let mut w_image = LAST_CAMERA_IMAGE.write();
|
||||||
|
*w_image = None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Get a frame.
|
||||||
|
let frame = stream.next().expect("Stream is dead").expect("Failed to capture a frame");
|
||||||
|
let mut out = vec![];
|
||||||
|
if let Some(buf) = image::ImageBuffer::<image::Rgb<u8>, &[u8]>::from_raw(w, h, &frame) {
|
||||||
|
image::codecs::jpeg::JpegEncoder::new(&mut out)
|
||||||
|
.write_image(buf.as_raw(), w, h, image::ExtendedColorType::Rgb8).unwrap();
|
||||||
|
} else {
|
||||||
|
out = frame.to_vec();
|
||||||
|
}
|
||||||
|
// Save image.
|
||||||
|
let mut w_image = LAST_CAMERA_IMAGE.write();
|
||||||
|
*w_image = Some((out, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Last captured image from started camera.
|
/// Last captured image from started camera.
|
||||||
static ref LAST_CAMERA_IMAGE: Arc<RwLock<Option<(Vec<u8>, u32)>>> = Arc::new(RwLock::new(None));
|
static ref LAST_CAMERA_IMAGE: Arc<RwLock<Option<(Vec<u8>, u32)>>> = Arc::new(RwLock::new(None));
|
||||||
|
|
Loading…
Reference in a new issue