Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify interaction with Gui #1301

Merged
merged 12 commits into from
Nov 2, 2022
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/fj-host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl Host {
/// Create a new instance of `Host`
///
/// This is only useful, if you want to continuously watch the model for
/// changes. If you don't just keep using `Model`.
/// changes. If you don't, just keep using `Model`.
pub fn from_model(model: Model) -> Result<Self, Error> {
let watch_path = model.watch_path();
let evaluator = Evaluator::from_model(model);
Expand Down
1 change: 0 additions & 1 deletion crates/fj-interop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ keywords.workspace = true
categories.workspace = true

[dependencies]
chrono = "0.4.22"
fj-math.workspace = true
1 change: 0 additions & 1 deletion crates/fj-interop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ pub mod debug;
pub mod ext;
pub mod mesh;
pub mod processed_shape;
pub mod status_report;
1 change: 1 addition & 0 deletions crates/fj-viewer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ categories.workspace = true

[dependencies]
bytemuck = "1.12.2"
chrono = "0.4.22"
crossbeam-channel = "0.5.6"
egui = "0.19.0"
egui-wgpu = "0.19.0"
Expand Down
11 changes: 3 additions & 8 deletions crates/fj-viewer/src/graphics/renderer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{io, mem::size_of, path::PathBuf};
use std::{io, mem::size_of};

use crossbeam_channel::{Receiver, Sender};
use thiserror::Error;
use tracing::debug;
use wgpu::util::DeviceExt as _;
Expand Down Expand Up @@ -172,12 +171,8 @@ impl Renderer {
})
}

pub(crate) fn init_gui(
&self,
event_rx: Receiver<()>,
event_tx: Sender<PathBuf>,
) -> Gui {
Gui::new(&self.device, self.surface_config.format, event_rx, event_tx)
pub(crate) fn init_gui(&self) -> Gui {
Gui::new(&self.device, self.surface_config.format)
}

/// Updates the geometry of the model being rendered.
Expand Down
79 changes: 25 additions & 54 deletions crates/fj-viewer/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,24 @@ use std::path::PathBuf;
#[cfg(not(target_arch = "wasm32"))]
use std::env::current_dir;

use crossbeam_channel::{Receiver, Sender};

#[cfg(not(target_arch = "wasm32"))]
use rfd::FileDialog;

use fj_interop::status_report::StatusReport;
use fj_math::{Aabb, Scalar};

use crate::graphics::DrawConfig;

struct GuiState {
has_model: bool,
}

impl Default for GuiState {
fn default() -> Self {
Self { has_model: true }
}
}
use crate::{graphics::DrawConfig, StatusReport};

/// The GUI
pub struct Gui {
context: egui::Context,
render_pass: egui_wgpu::renderer::RenderPass,
options: Options,
event_rx: Receiver<()>,
event_tx: Sender<PathBuf>,
state: GuiState,
}

impl Gui {
pub(crate) fn new(
device: &wgpu::Device,
texture_format: wgpu::TextureFormat,
event_rx: Receiver<()>,
event_tx: Sender<PathBuf>,
) -> Self {
// The implementation of the integration with `egui` is likely to need
// to change "significantly" depending on what architecture approach is
Expand Down Expand Up @@ -94,9 +76,6 @@ impl Gui {
context,
render_pass,
options: Default::default(),
event_rx,
event_tx,
state: Default::default(),
}
}

Expand All @@ -111,26 +90,9 @@ impl Gui {
egui_input: egui::RawInput,
config: &mut DrawConfig,
aabb: &Aabb<3>,
status: &StatusReport,
line_drawing_available: bool,
) {
loop {
let gui_event = self
.event_rx
.try_recv()
.map_err(|err| {
if err.is_disconnected() {
panic!("Expected channel to never disconnect");
}
})
.ok();

match gui_event {
Some(_) => self.state.has_model = false,
None => break,
};
}

state: GuiState,
) -> Option<PathBuf> {
self.context.set_pixels_per_point(pixels_per_point);
self.context.begin_frame(egui_input);

Expand Down Expand Up @@ -281,15 +243,20 @@ impl Gui {
egui::Area::new("fj-status-message").show(&self.context, |ui| {
ui.group(|ui| {
ui.add(egui::Label::new(
egui::RichText::new(format!("Status:{}", status.status()))
.monospace()
.color(egui::Color32::BLACK)
.background_color(egui::Color32::WHITE),
egui::RichText::new(format!(
"Status:{}",
state.status.status()
))
.monospace()
.color(egui::Color32::BLACK)
.background_color(egui::Color32::WHITE),
))
})
});

if !self.state.has_model {
let mut new_model_path = None;

if !state.model_available {
egui::Area::new("ask-model")
.anchor(egui::Align2::CENTER_CENTER, [0_f32, -5_f32])
.show(&self.context, |ui| {
Expand All @@ -302,18 +269,13 @@ impl Gui {
.button(egui::RichText::new("Pick a model"))
.clicked()
{
let model_dir = show_file_dialog();
if let Some(model_dir) = model_dir {
self.event_tx
.send(model_dir)
.expect("Channel is disconnected");

self.state.has_model = true;
}
new_model_path = show_file_dialog();
}
})
});
}

new_model_path
}

pub(crate) fn draw(
Expand Down Expand Up @@ -376,3 +338,12 @@ pub struct Options {
pub show_settings_ui: bool,
pub show_inspection_ui: bool,
}

/// The current status of the GUI
pub struct GuiState<'a> {
/// Reference to the status messages
pub status: &'a StatusReport,

/// Indicates whether a model is currently available
pub model_available: bool,
}
4 changes: 3 additions & 1 deletion crates/fj-viewer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ mod graphics;
mod gui;
mod input;
mod screen;
mod status_report;
mod viewer;

pub use self::{
camera::Camera,
graphics::{DrawConfig, Renderer, RendererInitError},
gui::Gui,
gui::{Gui, GuiState},
input::{InputEvent, InputHandler},
screen::{NormalizedScreenPosition, Screen, ScreenSize},
status_report::StatusReport,
viewer::Viewer,
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct StatusReport {
}

impl StatusReport {
/// Create a new ``StatusReport`` instance with a blank status
/// Create a new `StatusReport` instance with a blank status
pub fn new() -> Self {
Self::default()
}
Expand Down
29 changes: 12 additions & 17 deletions crates/fj-viewer/src/viewer.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use std::path::PathBuf;

use fj_interop::{
processed_shape::ProcessedShape, status_report::StatusReport,
};
use fj_interop::processed_shape::ProcessedShape;
use fj_math::Aabb;
use tracing::warn;

use crossbeam_channel::{Receiver, Sender};

use crate::{
camera::FocusPoint, gui::Gui, Camera, DrawConfig, InputEvent, InputHandler,
NormalizedScreenPosition, Renderer, RendererInitError, Screen, ScreenSize,
camera::FocusPoint, gui::Gui, Camera, DrawConfig, GuiState, InputEvent,
InputHandler, NormalizedScreenPosition, Renderer, RendererInitError,
Screen, ScreenSize,
};

/// The Fornjot model viewer
Expand Down Expand Up @@ -42,13 +39,9 @@ pub struct Viewer {

impl Viewer {
/// Construct a new instance of `Viewer`
pub async fn new(
screen: &impl Screen,
event_rx: Receiver<()>,
event_tx: Sender<PathBuf>,
) -> Result<Self, RendererInitError> {
pub async fn new(screen: &impl Screen) -> Result<Self, RendererInitError> {
let renderer = Renderer::new(screen).await?;
let gui = renderer.init_gui(event_rx, event_tx);
let gui = renderer.init_gui();

Ok(Self {
camera: Camera::default(),
Expand Down Expand Up @@ -128,9 +121,9 @@ impl Viewer {
pub fn draw(
&mut self,
pixels_per_point: f32,
status: &mut StatusReport,
egui_input: egui::RawInput,
) {
gui_state: GuiState,
) -> Option<PathBuf> {
let aabb = self
.shape
.as_ref()
Expand All @@ -139,13 +132,13 @@ impl Viewer {

self.camera.update_planes(&aabb);

self.gui.update(
let new_model_path = self.gui.update(
pixels_per_point,
egui_input,
&mut self.draw_config,
&aabb,
status,
self.renderer.is_line_drawing_available(),
gui_state,
);

if let Err(err) = self.renderer.draw(
Expand All @@ -156,5 +149,7 @@ impl Viewer {
) {
warn!("Draw error: {}", err);
}

new_model_path
}
}
Loading