nightshade 0.8.0

A cross-platform data-oriented game engine.
Documentation
use crate::prelude::*;

pub struct StatusBarSection {
    pub label: String,
    pub tooltip: Option<String>,
    pub color: Option<egui::Color32>,
}

pub struct StatusBar {
    left_sections: Vec<StatusBarSection>,
    right_sections: Vec<StatusBarSection>,
}

impl StatusBar {
    pub fn new() -> Self {
        Self {
            left_sections: Vec::new(),
            right_sections: Vec::new(),
        }
    }

    pub fn clear(&mut self) {
        self.left_sections.clear();
        self.right_sections.clear();
    }

    pub fn add_left(&mut self, label: impl Into<String>) {
        self.left_sections.push(StatusBarSection {
            label: label.into(),
            tooltip: None,
            color: None,
        });
    }

    pub fn add_left_colored(&mut self, label: impl Into<String>, color: egui::Color32) {
        self.left_sections.push(StatusBarSection {
            label: label.into(),
            tooltip: None,
            color: Some(color),
        });
    }

    pub fn add_left_with_tooltip(&mut self, label: impl Into<String>, tooltip: impl Into<String>) {
        self.left_sections.push(StatusBarSection {
            label: label.into(),
            tooltip: Some(tooltip.into()),
            color: None,
        });
    }

    pub fn add_right(&mut self, label: impl Into<String>) {
        self.right_sections.push(StatusBarSection {
            label: label.into(),
            tooltip: None,
            color: None,
        });
    }

    pub fn add_right_colored(&mut self, label: impl Into<String>, color: egui::Color32) {
        self.right_sections.push(StatusBarSection {
            label: label.into(),
            tooltip: None,
            color: Some(color),
        });
    }

    pub fn add_right_with_tooltip(&mut self, label: impl Into<String>, tooltip: impl Into<String>) {
        self.right_sections.push(StatusBarSection {
            label: label.into(),
            tooltip: Some(tooltip.into()),
            color: None,
        });
    }

    pub fn render(&self, ui_context: &egui::Context) {
        egui::TopBottomPanel::bottom("status_bar").show(ui_context, |ui| {
            ui.horizontal(|ui| {
                for section in &self.left_sections {
                    render_section(ui, section);
                    ui.separator();
                }

                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                    for section in self.right_sections.iter().rev() {
                        render_section(ui, section);
                        ui.separator();
                    }
                });
            });
        });
    }
}

impl Default for StatusBar {
    fn default() -> Self {
        Self::new()
    }
}

fn render_section(ui: &mut egui::Ui, section: &StatusBarSection) {
    let text = if let Some(color) = section.color {
        egui::RichText::new(&section.label).color(color).small()
    } else {
        egui::RichText::new(&section.label).small()
    };

    let response = ui.label(text);

    if let Some(tooltip) = &section.tooltip {
        response.on_hover_text(tooltip);
    }
}