Back to Blog

Rust egui Settings Dashboard — Tabbed Panels & Persistence | Ep31

Celest KimCelest Kim

Video: Rust egui Settings Dashboard — Tabbed Panels & Persistence | Ep31 by Taught by Celeste AI - AI Coding Coach

Watch full page →

Rust egui Settings Dashboard — Tabbed Panels & Persistence

Learn how to build a feature-rich settings dashboard in Rust using the egui GUI library. This example demonstrates creating tabbed navigation with SidePanel, persisting user settings with serde and eframe storage, and adding interactive controls like sliders, radio buttons, and checkboxes for a customizable user experience.

Code

use eframe::{egui, epi};
use serde::{Deserialize, Serialize};

const APP_KEY: &str = "my_app_settings";

#[derive(PartialEq, Copy, Clone)]
enum Tab {
  General,
  Appearance,
  Audio,
}

#[derive(Serialize, Deserialize, Clone)]
struct Settings {
  theme: Theme,
  font_size: f32,
  volume: u32,
  tab_size: u8,
  show_grid: bool,
  notifications: bool,
  sound_effects: bool,
  word_wrap: bool,
  line_numbers: bool,
  auto_save: bool,
}

impl Default for Settings {
  fn default() -> Self {
    Self {
      theme: Theme::System,
      font_size: 14.0,
      volume: 50,
      tab_size: 4,
      show_grid: true,
      notifications: true,
      sound_effects: true,
      word_wrap: true,
      line_numbers: true,
      auto_save: false,
    }
  }
}

#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
enum Theme {
  Dark,
  Light,
  System,
}

struct MyApp {
  current_tab: Tab,
  settings: Settings,
}

impl Default for MyApp {
  fn default() -> Self {
    Self {
      current_tab: Tab::General,
      settings: Settings::default(),
    }
  }
}

impl epi::App for MyApp {
  fn name(&self) -> &str {
    "Settings Dashboard"
  }

  fn setup(
    &mut self,
    _ctx: &egui::Context,
    frame: &epi::Frame,
    storage: Option<&dyn epi::Storage>,
  ) {
    if let Some(storage) = storage {
      if let Some(saved) = epi::get_value(storage, APP_KEY) {
        self.settings = saved;
      }
    }
  }

  fn save(&mut self, storage: &mut dyn epi::Storage) {
    epi::set_value(storage, APP_KEY, &self.settings);
  }

  fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
    use egui::*;

    TopBottomPanel::top("header").show(ctx, |ui| {
      ui.with_layout(Layout::right_to_left(), |ui| {
        if ui.button("Reset All").clicked() {
          self.settings = Settings::default();
        }
      });
      ui.label("Settings Dashboard");
    });

    SidePanel::left("tabs").show(ctx, |ui| {
      ui.selectable_value(&mut self.current_tab, Tab::General, "General");
      ui.selectable_value(&mut self.current_tab, Tab::Appearance, "Appearance");
      ui.selectable_value(&mut self.current_tab, Tab::Audio, "Audio");
    });

    CentralPanel::default().show(ctx, |ui| {
      match self.current_tab {
        Tab::General => {
          ui.checkbox(&mut self.settings.show_grid, "Show Grid");
          ui.checkbox(&mut self.settings.notifications, "Enable Notifications");
          ui.checkbox(&mut self.settings.auto_save, "Auto Save");
        }
        Tab::Appearance => {
          ui.label("Theme:");
          ui.radio_value(&mut self.settings.theme, Theme::Dark, "Dark");
          ui.radio_value(&mut self.settings.theme, Theme::Light, "Light");
          ui.radio_value(&mut self.settings.theme, Theme::System, "System");

          ui.add(Slider::new(&mut self.settings.font_size, 10.0..=32.0).text("Font Size"));
          ui.add(Slider::new(&mut self.settings.tab_size, 2..=8).text("Tab Size"));
          ui.checkbox(&mut self.settings.word_wrap, "Word Wrap");
          ui.checkbox(&mut self.settings.line_numbers, "Show Line Numbers");
        }
        Tab::Audio => {
          ui.add(Slider::new(&mut self.settings.volume, 0..=100).suffix("%").text("Volume"));
          ui.checkbox(&mut self.settings.sound_effects, "Sound Effects");
        }
      }
    });
  }
}

Key Points

  • Use SidePanel with selectable_value to create tabbed navigation for different settings categories.
  • Define a Settings struct with Serialize, Deserialize, and Default traits for easy state management and resetting.
  • Persist settings using eframe's Storage API with get_value and set_value keyed by a constant APP_KEY.
  • Implement interactive UI controls like radio buttons, sliders, and checkboxes for user customization.
  • Place a Reset All button in a TopBottomPanel with right-to-left layout to restore default settings instantly.