feat(gui): implement egui navigation tabs and control dashboard
This commit is contained in:
parent
c922851f91
commit
175b8772f4
3 changed files with 115 additions and 1 deletions
91
crates/molotov-gui/src/app.rs
Normal file
91
crates/molotov-gui/src/app.rs
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
use eframe::egui;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Tab {
|
||||||
|
Play,
|
||||||
|
FastFlags,
|
||||||
|
Mods,
|
||||||
|
Audio,
|
||||||
|
MultiInstance,
|
||||||
|
Maintenance,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MolotovApp {
|
||||||
|
current_tab: Tab,
|
||||||
|
pub safe_mode: bool,
|
||||||
|
pub fps_cap: i64,
|
||||||
|
pub vram_skip_mips: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MolotovApp {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
current_tab: Tab::Play,
|
||||||
|
safe_mode: false,
|
||||||
|
fps_cap: 144,
|
||||||
|
vram_skip_mips: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MolotovApp {
|
||||||
|
pub fn active_tab_name(&self) -> &'static str {
|
||||||
|
match self.current_tab {
|
||||||
|
Tab::Play => "Play",
|
||||||
|
Tab::FastFlags => "FastFlags",
|
||||||
|
Tab::Mods => "Mods",
|
||||||
|
Tab::Audio => "Audio & Voice",
|
||||||
|
Tab::MultiInstance => "Instances",
|
||||||
|
Tab::Maintenance => "Maintenance",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl eframe::App for MolotovApp {
|
||||||
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
|
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.selectable_value(&mut self.current_tab, Tab::Play, "🎮 Play");
|
||||||
|
ui.selectable_value(&mut self.current_tab, Tab::FastFlags, "⚙️ FastFlags");
|
||||||
|
ui.selectable_value(&mut self.current_tab, Tab::Mods, "🎨 Mods");
|
||||||
|
ui.selectable_value(&mut self.current_tab, Tab::Audio, "🎙️ Audio");
|
||||||
|
ui.selectable_value(&mut self.current_tab, Tab::MultiInstance, "👥 Instances");
|
||||||
|
ui.selectable_value(&mut self.current_tab, Tab::Maintenance, "🧹 Maintenance");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| match self.current_tab {
|
||||||
|
Tab::Play => {
|
||||||
|
ui.heading("Molotov Roblox Runtime");
|
||||||
|
ui.checkbox(&mut self.safe_mode, "Safe Mode (Minimal Flags)");
|
||||||
|
if ui.button("🚀 Launch Roblox").clicked() {
|
||||||
|
println!("Launch clicked!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tab::FastFlags => {
|
||||||
|
ui.heading("Performance & FastFlags");
|
||||||
|
ui.add(egui::Slider::new(&mut self.fps_cap, 30..=360).text("Target FPS"));
|
||||||
|
ui.checkbox(&mut self.vram_skip_mips, "Reduce VRAM Texture Mipmaps (NVIDIA fix)");
|
||||||
|
}
|
||||||
|
Tab::Mods => {
|
||||||
|
ui.heading("Asset Mods (In-Memory)");
|
||||||
|
ui.label("Drop custom ouch.ogg or cursors into ~/.config/molotov/mods/");
|
||||||
|
}
|
||||||
|
Tab::Audio => {
|
||||||
|
ui.heading("PipeWire Voice Chat");
|
||||||
|
ui.label("Microphone active stream is destroyed on pause to prevent indicator leaks.");
|
||||||
|
}
|
||||||
|
Tab::MultiInstance => {
|
||||||
|
ui.heading("Multi-Instance Sandboxing (bubblewrap)");
|
||||||
|
ui.label("Launch isolated accounts in independent namespaces.");
|
||||||
|
}
|
||||||
|
Tab::Maintenance => {
|
||||||
|
ui.heading("Maintenance & Cleaning");
|
||||||
|
if ui.button("Clean Stale Versions").clicked() {
|
||||||
|
println!("Clean clicked!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,19 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
pub mod app;
|
||||||
|
use app::MolotovApp;
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
println!("Molotov GUI placeholder");
|
let native_options = eframe::NativeOptions {
|
||||||
|
viewport: eframe::egui::ViewportBuilder::default()
|
||||||
|
.with_inner_size([720.0, 480.0])
|
||||||
|
.with_min_inner_size([600.0, 400.0])
|
||||||
|
.with_title("Molotov - Roblox Runtime for Linux"),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = eframe::run_native(
|
||||||
|
"Molotov",
|
||||||
|
native_options,
|
||||||
|
Box::new(|_cc| Ok(Box::new(MolotovApp::default()))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
crates/molotov-gui/tests/gui_test.rs
Normal file
8
crates/molotov-gui/tests/gui_test.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
use molotov_gui::app::MolotovApp;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gui_default_tab_is_play() {
|
||||||
|
let app = MolotovApp::default();
|
||||||
|
assert_eq!(app.active_tab_name(), "Play");
|
||||||
|
}
|
||||||
Reference in a new issue