mirror of
https://github.com/IllusionMan1212/3dobs.git
synced 2026-10-24 10:12:35 +00:00
settings/ui: add consistent config and settings window. add toggleable single instance option
This commit is contained in:
+6
-2
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user