pub mod about;
pub mod agent_layer;
pub mod charts;
pub mod dock;
pub mod edge_layer;
pub mod export;
pub mod fault;
pub mod files;
pub mod mcs;
pub mod menu_bar;
pub mod model;
pub mod pacing;
pub mod painted;
pub mod params;
pub mod performance;
pub mod playback;
pub mod results;
pub mod stats;
pub mod sweep;
pub mod system;
pub mod viewport;
pub fn banner(ui: &mut egui::Ui, icon: &str, color: egui::Color32, title: &str, detail: &str) {
ui.horizontal_wrapped(|ui| {
ui.colored_label(color, icon);
ui.colored_label(color, title);
});
ui.label(detail);
ui.separator();
}
pub fn add_progress_bar(ui: &mut egui::Ui, bar: egui::ProgressBar, fill: egui::Color32) -> egui::Response {
ui.scope(|ui| {
ui.visuals_mut().override_text_color = Some(mcs::GRAY_50);
ui.add(bar.fill(fill))
})
.inner
}
pub(crate) fn plural(count: u64, noun: &str) -> String {
if count == 1 {
noun.to_owned()
} else {
format!("{noun}s")
}
}
const KV_GRID_SPACING: [f32; 2] = [16.0, 4.0];
const KV_STRIPE_OVERHANG: f32 = 2.0;
pub fn kv_grid(ui: &egui::Ui, id: &str) -> KvGrid {
let col_width = ((ui.available_width() - KV_GRID_SPACING[0]) / 2.0).max(0.0);
KvGrid {
grid: egui::Grid::new(id)
.num_columns(2)
.striped(false)
.spacing(KV_GRID_SPACING)
.min_col_width(col_width),
}
}
pub struct KvGrid {
grid: egui::Grid,
}
impl KvGrid {
pub fn show<R>(
self,
ui: &mut egui::Ui,
add_rows: impl FnOnce(&mut egui::Ui, &mut KvGridRows) -> R,
) -> egui::InnerResponse<R> {
self.grid.show(ui, |ui| {
let mut rows = KvGridRows::new(ui);
add_rows(ui, &mut rows)
})
}
}
pub struct KvGridRows {
count: usize,
stripe: egui::layers::ShapeIdx,
}
impl KvGridRows {
fn new(ui: &egui::Ui) -> Self {
Self {
count: 0,
stripe: ui.painter().add(egui::Shape::Noop),
}
}
pub fn end_row(&mut self, ui: &mut egui::Ui) {
if self.count % 2 == 1 {
let rect = egui::Rect::from_x_y_ranges(
ui.max_rect().left()..=ui.max_rect().right().max(ui.min_rect().right()),
ui.cursor().top()..=ui.min_rect().bottom(),
)
.expand2(egui::vec2(KV_STRIPE_OVERHANG, 0.5 * KV_GRID_SPACING[1]));
let stripe = egui::epaint::RectShape::filled(rect, egui::CornerRadius::ZERO, ui.visuals().faint_bg_color);
ui.painter().set(self.stripe, stripe);
}
ui.end_row();
self.count += 1;
self.stripe = ui.painter().add(egui::Shape::Noop);
}
}
pub fn show_plot<'a, R>(
ui: &mut egui::Ui,
plot: egui_plot::Plot<'a>,
build: impl FnOnce(&mut egui_plot::PlotUi<'a>) -> R + 'a,
) -> egui_plot::PlotResponse<R> {
let background = ui.painter().add(egui::Shape::Noop);
let response = plot.show_background(false).show(ui, build);
let visuals = ui.visuals();
ui.painter().set(
background,
egui::epaint::RectShape::new(
*response.transform.frame(),
egui::CornerRadius::ZERO,
visuals.extreme_bg_color,
visuals.widgets.noninteractive.bg_stroke,
egui::StrokeKind::Inside,
),
);
response
}