mirror of
https://github.com/obhq/obliteration.git
synced 2025-04-02 11:02:08 -04:00
Initializes global graphics settings (#1308)
This commit is contained in:
parent
9de6e3237b
commit
45c447737a
12 changed files with 162 additions and 121 deletions
|
@ -1,4 +1,4 @@
|
|||
<p align="center"><img alt="Logo" src="logo.png"></p>
|
||||
<p align="center"><img alt="Logo" src="gui/ui/assets/logo.png"></p>
|
||||
|
||||
## About
|
||||
[](https://github.com/obhq/obliteration/actions/workflows/main.yml)
|
||||
|
|
|
@ -10,7 +10,7 @@ fn main() {
|
|||
.with_style(String::from("fluent-dark"))
|
||||
.with_library_paths(HashMap::from([("root".into(), root.join("ui"))]));
|
||||
|
||||
slint_build::compile_with_config(PathBuf::from_iter(["ui", "main.slint"]), config).unwrap();
|
||||
slint_build::compile_with_config(PathBuf::from_iter(["ui", "lib.slint"]), config).unwrap();
|
||||
|
||||
// Compile resources.rc.
|
||||
#[cfg(windows)]
|
||||
|
|
224
gui/src/main.rs
224
gui/src/main.rs
|
@ -60,6 +60,114 @@ struct MainProgram {
|
|||
}
|
||||
|
||||
impl MainProgram {
|
||||
async fn run_launcher(
|
||||
graphics: &impl EngineBuilder,
|
||||
data: &Arc<DataMgr>,
|
||||
profiles: Vec<Profile>,
|
||||
) -> Result<Option<(Profile, ExitAction)>, ProgramError> {
|
||||
// Create window and register callback handlers.
|
||||
let win = MainWindow::new().map_err(ProgramError::CreateMainWindow)?;
|
||||
let resolutions = Rc::new(ResolutionModel::default());
|
||||
let profiles = Rc::new(ProfileModel::new(profiles, resolutions.clone()));
|
||||
let exit = Rc::new(Cell::new(None));
|
||||
|
||||
win.on_settings({
|
||||
let win = win.as_weak();
|
||||
|
||||
move || spawn_handler(&win, |w| MainProgram::settings(w))
|
||||
});
|
||||
|
||||
win.on_report_issue({
|
||||
let win = win.as_weak();
|
||||
|
||||
move || spawn_handler(&win, |w| MainProgram::report_issue(w))
|
||||
});
|
||||
|
||||
win.on_about({
|
||||
let win = win.as_weak();
|
||||
|
||||
move || spawn_handler(&win, |w| MainProgram::about(w))
|
||||
});
|
||||
|
||||
win.on_profile_selected({
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
|
||||
move || {
|
||||
// TODO: Check if previous profile has unsaved data before switch the profile.
|
||||
let win = win.unwrap();
|
||||
let row: usize = win.get_selected_profile().try_into().unwrap();
|
||||
|
||||
profiles.select(row, &win);
|
||||
}
|
||||
});
|
||||
|
||||
win.on_save_profile({
|
||||
let data = data.clone();
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
|
||||
move || spawn_handler(&win, |w| save_profile(w, data.clone(), profiles.clone()))
|
||||
});
|
||||
|
||||
win.on_start_vmm({
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
let exit = exit.clone();
|
||||
let ty = ExitAction::Run;
|
||||
|
||||
move || spawn_handler(&win, |w| start_vmm(w, profiles.clone(), exit.clone(), ty))
|
||||
});
|
||||
|
||||
win.on_start_debug({
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
let exit = exit.clone();
|
||||
let ty = ExitAction::Debug;
|
||||
|
||||
move || spawn_handler(&win, |w| start_vmm(w, profiles.clone(), exit.clone(), ty))
|
||||
});
|
||||
|
||||
// Set window properties.
|
||||
let physical_devices = ModelRc::new(VecModel::from_iter(
|
||||
graphics
|
||||
.physical_devices()
|
||||
.iter()
|
||||
.map(|p| SharedString::from(p.name())),
|
||||
));
|
||||
|
||||
win.set_devices(physical_devices);
|
||||
win.set_resolutions(resolutions.into());
|
||||
win.set_profiles(profiles.clone().into());
|
||||
|
||||
// Load selected profile.
|
||||
let row: usize = win.get_selected_profile().try_into().unwrap();
|
||||
|
||||
profiles.select(row, &win);
|
||||
|
||||
// Run the window.
|
||||
win.show().map_err(ProgramError::ShowMainWindow)?;
|
||||
win.set_center().map_err(ProgramError::CenterMainWindow)?;
|
||||
win.wait().await;
|
||||
|
||||
// Extract window states.
|
||||
let profile = win.get_selected_profile();
|
||||
|
||||
drop(win);
|
||||
|
||||
// Check how we exit.
|
||||
let exit = match Rc::into_inner(exit).unwrap().into_inner() {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
// Get selected profile.
|
||||
let mut profiles = Rc::into_inner(profiles).unwrap().into_inner();
|
||||
let profile = profiles.remove(profile.try_into().unwrap());
|
||||
|
||||
Ok(Some((profile, exit)))
|
||||
}
|
||||
|
||||
async fn settings(main: MainWindow) {
|
||||
// Setup window.
|
||||
let win = match SettingsWindow::new() {
|
||||
|
@ -71,6 +179,12 @@ impl MainProgram {
|
|||
}
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
win.set_graphics_debug_layer_name("MTL_DEBUG_LAYER".into());
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
win.set_graphics_debug_layer_name("VK_LAYER_KHRONOS_validation".into());
|
||||
|
||||
// Run the window.
|
||||
if let Err(e) = win.show() {
|
||||
let m = slint::format!("Failed to show settings window: {}.", e.display());
|
||||
|
@ -237,7 +351,7 @@ impl App for MainProgram {
|
|||
// TODO: Select last used profile.
|
||||
(profiles.pop().unwrap(), Some(v))
|
||||
} else {
|
||||
let (profile, exit) = match run_launcher(&graphics, &data, profiles).await? {
|
||||
let (profile, exit) = match Self::run_launcher(&graphics, &data, profiles).await? {
|
||||
Some(v) => v,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
@ -318,114 +432,6 @@ impl App for MainProgram {
|
|||
}
|
||||
}
|
||||
|
||||
async fn run_launcher(
|
||||
graphics: &impl EngineBuilder,
|
||||
data: &Arc<DataMgr>,
|
||||
profiles: Vec<Profile>,
|
||||
) -> Result<Option<(Profile, ExitAction)>, ProgramError> {
|
||||
// Create window and register callback handlers.
|
||||
let win = MainWindow::new().map_err(ProgramError::CreateMainWindow)?;
|
||||
let resolutions = Rc::new(ResolutionModel::default());
|
||||
let profiles = Rc::new(ProfileModel::new(profiles, resolutions.clone()));
|
||||
let exit = Rc::new(Cell::new(None));
|
||||
|
||||
win.on_settings({
|
||||
let win = win.as_weak();
|
||||
|
||||
move || spawn_handler(&win, |w| MainProgram::settings(w))
|
||||
});
|
||||
|
||||
win.on_report_issue({
|
||||
let win = win.as_weak();
|
||||
|
||||
move || spawn_handler(&win, |w| MainProgram::report_issue(w))
|
||||
});
|
||||
|
||||
win.on_about({
|
||||
let win = win.as_weak();
|
||||
|
||||
move || spawn_handler(&win, |w| MainProgram::about(w))
|
||||
});
|
||||
|
||||
win.on_profile_selected({
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
|
||||
move || {
|
||||
// TODO: Check if previous profile has unsaved data before switch the profile.
|
||||
let win = win.unwrap();
|
||||
let row: usize = win.get_selected_profile().try_into().unwrap();
|
||||
|
||||
profiles.select(row, &win);
|
||||
}
|
||||
});
|
||||
|
||||
win.on_save_profile({
|
||||
let data = data.clone();
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
|
||||
move || spawn_handler(&win, |w| save_profile(w, data.clone(), profiles.clone()))
|
||||
});
|
||||
|
||||
win.on_start_vmm({
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
let exit = exit.clone();
|
||||
let ty = ExitAction::Run;
|
||||
|
||||
move || spawn_handler(&win, |w| start_vmm(w, profiles.clone(), exit.clone(), ty))
|
||||
});
|
||||
|
||||
win.on_start_debug({
|
||||
let win = win.as_weak();
|
||||
let profiles = profiles.clone();
|
||||
let exit = exit.clone();
|
||||
let ty = ExitAction::Debug;
|
||||
|
||||
move || spawn_handler(&win, |w| start_vmm(w, profiles.clone(), exit.clone(), ty))
|
||||
});
|
||||
|
||||
// Set window properties.
|
||||
let physical_devices = ModelRc::new(VecModel::from_iter(
|
||||
graphics
|
||||
.physical_devices()
|
||||
.iter()
|
||||
.map(|p| SharedString::from(p.name())),
|
||||
));
|
||||
|
||||
win.set_devices(physical_devices);
|
||||
win.set_resolutions(resolutions.into());
|
||||
win.set_profiles(profiles.clone().into());
|
||||
|
||||
// Load selected profile.
|
||||
let row: usize = win.get_selected_profile().try_into().unwrap();
|
||||
|
||||
profiles.select(row, &win);
|
||||
|
||||
// Run the window.
|
||||
win.show().map_err(ProgramError::ShowMainWindow)?;
|
||||
win.set_center().map_err(ProgramError::CenterMainWindow)?;
|
||||
win.wait().await;
|
||||
|
||||
// Extract window states.
|
||||
let profile = win.get_selected_profile();
|
||||
|
||||
drop(win);
|
||||
|
||||
// Check how we exit.
|
||||
let exit = match Rc::into_inner(exit).unwrap().into_inner() {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
// Get selected profile.
|
||||
let mut profiles = Rc::into_inner(profiles).unwrap().into_inner();
|
||||
let profile = profiles.remove(profile.try_into().unwrap());
|
||||
|
||||
Ok(Some((profile, exit)))
|
||||
}
|
||||
|
||||
async fn wait_for_debugger(addr: SocketAddr) -> Result<Option<TcpStream>, ProgramError> {
|
||||
// Start server.
|
||||
let server = TcpListener::bind(addr)
|
||||
|
|
|
@ -3,7 +3,7 @@ import { AboutSlint, VerticalBox, TabWidget } from "std-widgets.slint";
|
|||
component Obliteration {
|
||||
VerticalBox {
|
||||
Image {
|
||||
source: @image-url("about/logo.png");
|
||||
source: @image-url("@root/assets/logo.png");
|
||||
}
|
||||
|
||||
Text {
|
||||
|
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 200 B |
6
gui/ui/lib.slint
Normal file
6
gui/ui/lib.slint
Normal file
|
@ -0,0 +1,6 @@
|
|||
export { AboutWindow } from "about.slint";
|
||||
export { WaitForDebugger } from "debug.slint";
|
||||
export { ErrorWindow } from "error.slint";
|
||||
export { MainWindow } from "main.slint";
|
||||
export { SettingsWindow } from "settings.slint";
|
||||
export { InstallFirmware, SetupWizard } from "setup.slint";
|
|
@ -1,13 +1,7 @@
|
|||
import { VerticalBox, HorizontalBox, Button, ComboBox } from "std-widgets.slint";
|
||||
import { TabBar, TabContainer } from "@root/widgets/tab.slint";
|
||||
import { DisplayTab } from "main/display.slint";
|
||||
import { CpuTab } from "main/cpu.slint";
|
||||
import { TabBar, TabContainer } from "main/tab.slint";
|
||||
|
||||
export { AboutWindow } from "about.slint";
|
||||
export { WaitForDebugger } from "debug.slint";
|
||||
export { ErrorWindow } from "error.slint";
|
||||
export { SettingsWindow } from "settings.slint";
|
||||
export { InstallFirmware, SetupWizard } from "setup.slint";
|
||||
|
||||
export component MainWindow inherits Window {
|
||||
in property <[string]> devices;
|
||||
|
@ -72,7 +66,7 @@ export component MainWindow inherits Window {
|
|||
|
||||
tab := TabBar {
|
||||
tabs: [
|
||||
{ text: "Display", icon: @image-url("main/monitor.svg") },
|
||||
{ text: "Display", icon: @image-url("@root/assets/monitor.svg") },
|
||||
{ text: "CPU", icon: @image-url("main/cpu-64-bit.svg") }
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
export component SettingsWindow inherits Window {
|
||||
import { StandardButton } from "std-widgets.slint";
|
||||
import { TabBar, TabContainer } from "@root/widgets/tab.slint";
|
||||
import { GraphicsTab } from "settings/graphics.slint";
|
||||
|
||||
export component SettingsWindow inherits Dialog {
|
||||
in property <string> graphics-debug-layer-name: "VK_LAYER_KHRONOS_validation";
|
||||
|
||||
title: "Settings";
|
||||
|
||||
TabContainer {
|
||||
tab := TabBar {
|
||||
tabs: [{ text: "Graphics", icon: @image-url("@root/assets/monitor.svg") }];
|
||||
}
|
||||
|
||||
if tab.current-page == 0: GraphicsTab {
|
||||
debug-layer-name: root.graphics-debug-layer-name;
|
||||
}
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
kind: ok;
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
kind: cancel;
|
||||
}
|
||||
}
|
||||
|
|
11
gui/ui/settings/graphics.slint
Normal file
11
gui/ui/settings/graphics.slint
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { CheckBox, VerticalBox } from "std-widgets.slint";
|
||||
|
||||
export component GraphicsTab {
|
||||
in property <string> debug-layer-name;
|
||||
|
||||
VerticalBox {
|
||||
CheckBox {
|
||||
text: "Enable \{debug-layer-name}";
|
||||
}
|
||||
}
|
||||
}
|
BIN
logo.png
BIN
logo.png
Binary file not shown.
Before Width: | Height: | Size: 256 KiB |
Loading…
Add table
Reference in a new issue