2021-02-07 13:46:53 +00:00
|
|
|
use egui::{CtxRef, ScrollArea, Ui, Window};
|
2021-02-20 08:18:23 +00:00
|
|
|
use std::collections::BTreeSet;
|
2020-10-19 21:06:11 +00:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2021-01-04 00:44:02 +00:00
|
|
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
|
|
|
#[cfg_attr(feature = "persistence", serde(default))]
|
2020-11-02 16:53:28 +00:00
|
|
|
struct Demos {
|
2021-01-10 19:57:33 +00:00
|
|
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
|
|
|
demos: Vec<Box<dyn super::Demo>>,
|
2021-02-20 08:18:23 +00:00
|
|
|
|
|
|
|
open: BTreeSet<String>,
|
2020-11-02 16:53:28 +00:00
|
|
|
}
|
|
|
|
impl Default for Demos {
|
|
|
|
fn default() -> Self {
|
2021-01-10 19:57:33 +00:00
|
|
|
let demos: Vec<Box<dyn super::Demo>> = vec![
|
2021-01-25 19:43:41 +00:00
|
|
|
Box::new(super::dancing_strings::DancingStrings::default()),
|
|
|
|
Box::new(super::drag_and_drop::DragAndDropDemo::default()),
|
2021-01-27 19:14:53 +00:00
|
|
|
Box::new(super::font_book::FontBook::default()),
|
2021-02-07 13:46:53 +00:00
|
|
|
Box::new(super::DemoWindow::default()),
|
2021-05-09 08:09:05 +00:00
|
|
|
Box::new(super::multi_touch::MultiTouch::default()),
|
2021-01-27 19:14:53 +00:00
|
|
|
Box::new(super::painting::Painting::default()),
|
2021-02-14 20:39:04 +00:00
|
|
|
Box::new(super::plot_demo::PlotDemo::default()),
|
2021-01-25 19:43:41 +00:00
|
|
|
Box::new(super::scrolling::Scrolling::default()),
|
2021-01-27 19:14:53 +00:00
|
|
|
Box::new(super::sliders::Sliders::default()),
|
|
|
|
Box::new(super::widget_gallery::WidgetGallery::default()),
|
|
|
|
Box::new(super::window_options::WindowOptions::default()),
|
2021-02-07 13:46:53 +00:00
|
|
|
Box::new(super::tests::WindowResizeTest::default()),
|
2021-01-27 19:14:53 +00:00
|
|
|
// Tests:
|
2021-03-13 11:38:03 +00:00
|
|
|
Box::new(super::tests::CursorTest::default()),
|
2021-01-27 19:14:53 +00:00
|
|
|
Box::new(super::tests::IdTest::default()),
|
2021-02-06 15:54:38 +00:00
|
|
|
Box::new(super::tests::InputTest::default()),
|
2021-02-07 12:48:55 +00:00
|
|
|
Box::new(super::layout_test::LayoutTest::default()),
|
|
|
|
Box::new(super::tests::ManualLayoutTest::default()),
|
|
|
|
Box::new(super::tests::TableTest::default()),
|
2021-01-10 19:57:33 +00:00
|
|
|
];
|
2021-02-20 08:18:23 +00:00
|
|
|
|
|
|
|
use crate::apps::demo::Demo;
|
|
|
|
let mut open = BTreeSet::new();
|
|
|
|
open.insert(
|
|
|
|
super::widget_gallery::WidgetGallery::default()
|
|
|
|
.name()
|
|
|
|
.to_owned(),
|
|
|
|
);
|
|
|
|
|
2021-05-06 18:49:22 +00:00
|
|
|
Self { demos, open }
|
2020-11-02 16:53:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
impl Demos {
|
|
|
|
pub fn checkboxes(&mut self, ui: &mut Ui) {
|
2021-05-06 18:49:22 +00:00
|
|
|
let Self { demos, open } = self;
|
2021-02-20 08:18:23 +00:00
|
|
|
for demo in demos {
|
|
|
|
let mut is_open = open.contains(demo.name());
|
|
|
|
ui.checkbox(&mut is_open, demo.name());
|
|
|
|
set_open(open, demo.name(), is_open);
|
2020-11-02 16:53:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-19 13:48:04 +00:00
|
|
|
pub fn show(&mut self, ctx: &CtxRef) {
|
2021-05-06 18:49:22 +00:00
|
|
|
let Self { demos, open } = self;
|
2021-02-20 08:18:23 +00:00
|
|
|
for demo in demos {
|
|
|
|
let mut is_open = open.contains(demo.name());
|
|
|
|
demo.show(ctx, &mut is_open);
|
|
|
|
set_open(open, demo.name(), is_open);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_open(open: &mut BTreeSet<String>, key: &'static str, is_open: bool) {
|
|
|
|
if is_open {
|
|
|
|
if !open.contains(key) {
|
|
|
|
open.insert(key.to_owned());
|
2020-11-02 16:53:28 +00:00
|
|
|
}
|
2021-02-20 08:18:23 +00:00
|
|
|
} else {
|
|
|
|
open.remove(key);
|
2020-11-02 16:53:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2020-10-19 21:06:11 +00:00
|
|
|
/// A menu bar in which you can select different demo windows to show.
|
2021-01-04 00:44:02 +00:00
|
|
|
#[derive(Default)]
|
|
|
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
|
|
|
#[cfg_attr(feature = "persistence", serde(default))]
|
2020-10-19 21:06:11 +00:00
|
|
|
pub struct DemoWindows {
|
|
|
|
open_windows: OpenWindows,
|
2020-11-02 16:53:28 +00:00
|
|
|
demos: Demos,
|
2020-10-19 21:06:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl DemoWindows {
|
|
|
|
/// Show the app ui (menu bar and windows).
|
2020-12-12 23:30:54 +00:00
|
|
|
/// `sidebar_ui` can be used to optionally show some things in the sidebar
|
2021-01-02 00:01:01 +00:00
|
|
|
pub fn ui(&mut self, ctx: &CtxRef) {
|
2021-03-07 18:51:07 +00:00
|
|
|
egui::SidePanel::left("side_panel", 190.0).show(ctx, |ui| {
|
2021-01-17 13:48:59 +00:00
|
|
|
ui.heading("✒ egui demos");
|
2020-12-12 18:43:12 +00:00
|
|
|
|
2020-10-21 16:05:36 +00:00
|
|
|
ui.separator();
|
|
|
|
|
2020-12-16 20:57:13 +00:00
|
|
|
ScrollArea::auto_sized().show(ui, |ui| {
|
2021-02-20 15:07:42 +00:00
|
|
|
use egui::special_emojis::{GITHUB, OS_APPLE, OS_LINUX, OS_WINDOWS};
|
2020-12-16 20:57:13 +00:00
|
|
|
|
2021-02-20 15:07:42 +00:00
|
|
|
ui.label("egui is an immediate mode GUI library written in Rust.");
|
|
|
|
ui.hyperlink_to(
|
|
|
|
format!("{} egui home page", GITHUB),
|
|
|
|
"https://github.com/emilk/egui",
|
|
|
|
);
|
|
|
|
|
|
|
|
ui.label(format!(
|
|
|
|
"egui can be run on the web, or natively on {}{}{}",
|
|
|
|
OS_APPLE, OS_LINUX, OS_WINDOWS,
|
|
|
|
));
|
2020-12-12 23:30:54 +00:00
|
|
|
|
2020-12-16 20:57:13 +00:00
|
|
|
ui.separator();
|
|
|
|
|
|
|
|
ui.heading("Windows:");
|
2021-02-07 13:46:53 +00:00
|
|
|
self.demos.checkboxes(ui);
|
2021-03-31 21:12:42 +00:00
|
|
|
|
|
|
|
ui.separator();
|
|
|
|
|
|
|
|
ui.label("egui:");
|
2021-02-07 13:46:53 +00:00
|
|
|
self.open_windows.checkboxes(ui);
|
2020-12-16 20:57:13 +00:00
|
|
|
|
|
|
|
ui.separator();
|
|
|
|
|
2021-01-25 17:50:19 +00:00
|
|
|
if ui.button("Organize windows").clicked() {
|
2020-12-16 20:57:13 +00:00
|
|
|
ui.ctx().memory().reset_areas();
|
|
|
|
}
|
|
|
|
});
|
2020-10-21 16:05:36 +00:00
|
|
|
});
|
2020-10-21 20:10:55 +00:00
|
|
|
|
2020-12-29 12:40:11 +00:00
|
|
|
egui::TopPanel::top("menu_bar").show(ctx, |ui| {
|
2021-01-01 20:27:10 +00:00
|
|
|
show_menu_bar(ui);
|
2020-10-21 16:05:36 +00:00
|
|
|
});
|
|
|
|
|
2021-03-31 18:53:13 +00:00
|
|
|
{
|
|
|
|
let mut fill = ctx.style().visuals.extreme_bg_color;
|
|
|
|
if !cfg!(target_arch = "wasm32") {
|
|
|
|
// Native: WrapApp uses a transparent window, so let's show that off:
|
|
|
|
// NOTE: the OS compositor assumes "normal" blending, so we need to hack it:
|
|
|
|
let [r, g, b, _] = fill.to_array();
|
|
|
|
fill = egui::Color32::from_rgba_premultiplied(r, g, b, 180);
|
|
|
|
}
|
|
|
|
let frame = egui::Frame::none().fill(fill);
|
|
|
|
egui::CentralPanel::default().frame(frame).show(ctx, |_| {});
|
|
|
|
}
|
2021-02-03 00:08:23 +00:00
|
|
|
|
2021-01-01 23:13:34 +00:00
|
|
|
self.windows(ctx);
|
2020-10-19 21:06:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Show the open windows.
|
2021-01-01 23:13:34 +00:00
|
|
|
fn windows(&mut self, ctx: &CtxRef) {
|
2020-10-19 21:06:11 +00:00
|
|
|
let Self {
|
|
|
|
open_windows,
|
2020-11-02 16:53:28 +00:00
|
|
|
demos,
|
2020-10-19 21:06:11 +00:00
|
|
|
..
|
|
|
|
} = self;
|
|
|
|
|
2020-12-12 18:43:12 +00:00
|
|
|
Window::new("🔧 Settings")
|
2020-10-19 21:06:11 +00:00
|
|
|
.open(&mut open_windows.settings)
|
2021-01-02 11:00:14 +00:00
|
|
|
.scroll(true)
|
2020-10-19 21:06:11 +00:00
|
|
|
.show(ctx, |ui| {
|
|
|
|
ctx.settings_ui(ui);
|
|
|
|
});
|
|
|
|
|
2020-12-12 18:43:12 +00:00
|
|
|
Window::new("🔍 Inspection")
|
2020-10-19 21:06:11 +00:00
|
|
|
.open(&mut open_windows.inspection)
|
|
|
|
.scroll(true)
|
|
|
|
.show(ctx, |ui| {
|
|
|
|
ctx.inspection_ui(ui);
|
|
|
|
});
|
|
|
|
|
2020-12-12 18:43:12 +00:00
|
|
|
Window::new("📝 Memory")
|
2020-10-19 21:06:11 +00:00
|
|
|
.open(&mut open_windows.memory)
|
|
|
|
.resizable(false)
|
|
|
|
.show(ctx, |ui| {
|
|
|
|
ctx.memory_ui(ui);
|
|
|
|
});
|
|
|
|
|
2020-11-02 16:53:28 +00:00
|
|
|
demos.show(ctx);
|
2020-10-19 21:06:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2021-01-04 00:44:02 +00:00
|
|
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
2020-10-19 21:06:11 +00:00
|
|
|
struct OpenWindows {
|
|
|
|
// egui stuff:
|
|
|
|
settings: bool,
|
|
|
|
inspection: bool,
|
|
|
|
memory: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for OpenWindows {
|
|
|
|
fn default() -> Self {
|
2021-02-07 13:46:53 +00:00
|
|
|
OpenWindows::none()
|
2020-10-19 21:06:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl OpenWindows {
|
|
|
|
fn none() -> Self {
|
|
|
|
Self {
|
|
|
|
settings: false,
|
|
|
|
inspection: false,
|
|
|
|
memory: false,
|
|
|
|
}
|
|
|
|
}
|
2020-10-21 16:05:36 +00:00
|
|
|
|
2020-11-02 16:53:28 +00:00
|
|
|
fn checkboxes(&mut self, ui: &mut Ui) {
|
2020-10-21 16:05:36 +00:00
|
|
|
let Self {
|
|
|
|
settings,
|
|
|
|
inspection,
|
|
|
|
memory,
|
|
|
|
} = self;
|
2021-02-07 13:46:53 +00:00
|
|
|
|
2020-12-12 18:43:12 +00:00
|
|
|
ui.checkbox(settings, "🔧 Settings");
|
|
|
|
ui.checkbox(inspection, "🔍 Inspection");
|
|
|
|
ui.checkbox(memory, "📝 Memory");
|
2020-10-21 16:05:36 +00:00
|
|
|
}
|
2020-10-19 21:06:11 +00:00
|
|
|
}
|
|
|
|
|
2021-01-01 20:27:10 +00:00
|
|
|
fn show_menu_bar(ui: &mut Ui) {
|
2020-12-29 12:40:11 +00:00
|
|
|
use egui::*;
|
2020-10-19 21:06:11 +00:00
|
|
|
|
|
|
|
menu::bar(ui, |ui| {
|
|
|
|
menu::menu(ui, "File", |ui| {
|
2021-01-25 17:50:19 +00:00
|
|
|
if ui.button("Organize windows").clicked() {
|
2020-10-19 21:06:11 +00:00
|
|
|
ui.ctx().memory().reset_areas();
|
|
|
|
}
|
|
|
|
if ui
|
2021-01-17 13:48:59 +00:00
|
|
|
.button("Clear egui memory")
|
2020-11-03 21:00:56 +00:00
|
|
|
.on_hover_text("Forget scroll, collapsing headers etc")
|
2021-01-25 17:50:19 +00:00
|
|
|
.clicked()
|
2020-10-19 21:06:11 +00:00
|
|
|
{
|
|
|
|
*ui.ctx().memory() = Default::default();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|