settings/ui: add consistent config and settings window. add toggleable single instance option

This commit is contained in:
2023-10-24 03:14:19 +02:00
parent 54cac634e8
commit 23e127e908
6 changed files with 184 additions and 19 deletions
+6 -2
View File
@@ -23,7 +23,11 @@ fn send_args_to_existing_instance(pipe_path: PathBuf, args_paths: Vec<PathBuf>)
.expect("Failed to send arguments");
}
pub fn init(lock_file: &File, args_paths: Vec<PathBuf>) -> Receiver<Vec<PathBuf>> {
pub fn init(lock_file: &File, args_paths: Vec<PathBuf>, one_instance: bool) -> Option<Receiver<Vec<PathBuf>>> {
if !one_instance {
return None;
}
let pipe_name = "3dobs_pipe";
let pipe_path = std::env::temp_dir().join(pipe_name);
@@ -61,5 +65,5 @@ pub fn init(lock_file: &File, args_paths: Vec<PathBuf>) -> Receiver<Vec<PathBuf>
}
});
ipc_rx
Some(ipc_rx)
}
+20 -12
View File
@@ -8,6 +8,8 @@ use std::path::PathBuf;
use threedobs::{shader, ui::ui, utils, ipc};
fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
let settings: ui::Settings = confy::load("3dobs", "settings")?;
let args: Vec<String> = env::args().collect();
let args_paths: Vec<PathBuf> = args
.iter()
@@ -18,7 +20,7 @@ fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
let lock_file_name = "3dobs.lock";
let lock_file_path = std::env::temp_dir().join(lock_file_name);
let lock_file = File::create(&lock_file_path)?;
let ipc_rx = ipc::init(&lock_file, args_paths.clone());
let ipc_rx = ipc::init(&lock_file, args_paths.clone(), settings.one_instance);
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS)?;
@@ -32,7 +34,10 @@ fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
window.set_cursor_mode(glfw::CursorMode::Disabled);
window.make_current();
let mut state = ui::State::default();
let mut state = ui::State{
settings,
..Default::default()
};
glfw.set_swap_interval(glfw::SwapInterval::Sync(1));
@@ -128,20 +133,23 @@ fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
let view_mat = glm::ext::look_at(state.camera.position, state.camera.position + state.camera.front, state.camera.up);
let projection_mat = glm::ext::perspective(glm::radians(state.camera.fov), state.viewport_size[0] / state.viewport_size[1], 0.01, 200.0);
match ipc_rx.try_recv() {
Ok(paths) => {
window.focus();
utils::import_models_from_paths(&paths, &mut state);
},
Err(e) => {
match e {
std::sync::mpsc::TryRecvError::Empty => {},
std::sync::mpsc::TryRecvError::Disconnected => {
panic!("Error: IPC thread channel disconnected");
if let Some(rx) = &ipc_rx {
match rx.try_recv() {
Ok(paths) => {
window.focus();
utils::import_models_from_paths(&paths, &mut state);
},
Err(e) => {
match e {
std::sync::mpsc::TryRecvError::Empty => {},
std::sync::mpsc::TryRecvError::Disconnected => {
panic!("Error: IPC thread channel disconnected");
}
}
}
}
}
for (_, event) in glfw::flush_messages(&events) {
// order of handling events is important here
+34 -2
View File
@@ -1,13 +1,20 @@
use std::time::{SystemTime, UNIX_EPOCH};
use glad_gl::gl;
use serde::{Serialize, Deserialize};
use crate::{camera::Camera, model, imgui_glfw_support, imgui_opengl_renderer, mesh, ui, log, utils};
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct Settings {
pub one_instance: bool,
}
pub struct State {
pub active_model: Option<u32>,
pub show_console: bool,
pub show_help_menu_about: bool,
pub show_settings: bool,
pub is_cursor_captured: bool,
pub can_capture_cursor: bool,
pub draw_grid: bool,
@@ -20,6 +27,7 @@ pub struct State {
pub objects: Vec<model::Model>,
pub viewport_size: [f32; 2],
pub logger: log::Log,
pub settings: Settings,
}
impl Default for State {
@@ -27,6 +35,8 @@ impl Default for State {
Self {
active_model: None,
show_console: false,
show_help_menu_about: false,
show_settings: false,
first_frame_drawn: false,
is_cursor_captured: false,
can_capture_cursor: false,
@@ -34,12 +44,12 @@ impl Default for State {
draw_aabb: false,
fov_zoom: true,
rotation_speed: 1.0,
show_help_menu_about: false,
wireframe: false,
camera: Camera::new(),
objects: vec![],
viewport_size: [0.0, 0.0],
logger: log::Log::default(),
settings: Settings::default(),
}
}
}
@@ -102,6 +112,9 @@ pub fn draw_main_menu_bar(ui: &imgui::Ui, state: &mut State, window: &mut glfw::
if ui.menu_item_config("Import Model(s)").shortcut("Ctrl+O").build() {
import_model(state);
}
if ui.menu_item_config("Settings").build() {
state.show_settings = !state.show_settings;
}
if ui.menu_item_config("Quit").shortcut("Ctrl+Q").build() {
window.set_should_close(true);
}
@@ -124,6 +137,24 @@ pub fn draw_main_menu_bar(ui: &imgui::Ui, state: &mut State, window: &mut glfw::
});
}
pub fn draw_settings_window(ui: &imgui::Ui, state: &mut State) {
if !state.show_settings {
return;
}
let display_size = ui.io().display_size;
ui.window("Settings")
.size([500.0, 100.0], imgui::Condition::FirstUseEver)
.opened(&mut state.show_settings)
.position([display_size[0] / 2.0, display_size[1] / 2.0], imgui::Condition::FirstUseEver)
.position_pivot([0.5, 0.5])
.build(|| {
if ui.checkbox("Only allow one program instance (Reboot required when enabling)", &mut state.settings.one_instance) {
confy::store("3dobs", "settings", state.settings.clone()).unwrap();
}
});
}
fn draw_transformations(ui: &imgui::Ui, mesh: &mut mesh::Mesh) {
imgui::Drag::new("###XPos")
.range(f32::NEG_INFINITY, f32::INFINITY)
@@ -428,6 +459,7 @@ pub fn draw_ui(
draw_viewport(ui, state, scene_fb_texture);
draw_objects_window(ui, state);
draw_console(ui, state);
draw_settings_window(ui, state);
ui.end_frame_early();