feat(gui): implement egui navigation tabs and control dashboard

This commit is contained in:
katR 2026-09-29 08:09:53 +05:30
parent c922851f91
commit 175b8772f4
3 changed files with 115 additions and 1 deletions

View 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!");
}
}
});
}
}

View file

@ -1,4 +1,19 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pub mod app;
use app::MolotovApp;
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()))),
);
}

View 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");
}