Slight improvements to the demo (#5527)
This commit is contained in:
parent
820d42802a
commit
fa95351675
|
|
@ -14,6 +14,7 @@ impl crate::Demo for About {
|
||||||
.default_height(480.0)
|
.default_height(480.0)
|
||||||
.open(open)
|
.open(open)
|
||||||
.resizable([true, false])
|
.resizable([true, false])
|
||||||
|
.scroll(false)
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
use crate::View as _;
|
use crate::View as _;
|
||||||
self.ui(ui);
|
self.ui(ui);
|
||||||
|
|
@ -36,11 +37,13 @@ impl crate::View for About {
|
||||||
));
|
));
|
||||||
ui.label("egui is designed to be easy to use, portable, and fast.");
|
ui.label("egui is designed to be easy to use, portable, and fast.");
|
||||||
|
|
||||||
ui.add_space(12.0); // ui.separator();
|
ui.add_space(12.0);
|
||||||
|
|
||||||
ui.heading("Immediate mode");
|
ui.heading("Immediate mode");
|
||||||
about_immediate_mode(ui);
|
about_immediate_mode(ui);
|
||||||
|
|
||||||
ui.add_space(12.0); // ui.separator();
|
ui.add_space(12.0);
|
||||||
|
|
||||||
ui.heading("Links");
|
ui.heading("Links");
|
||||||
links(ui);
|
links(ui);
|
||||||
|
|
||||||
|
|
@ -50,7 +53,10 @@ impl crate::View for About {
|
||||||
ui.spacing_mut().item_spacing.x = 0.0;
|
ui.spacing_mut().item_spacing.x = 0.0;
|
||||||
ui.label("egui development is sponsored by ");
|
ui.label("egui development is sponsored by ");
|
||||||
ui.hyperlink_to("Rerun.io", "https://www.rerun.io/");
|
ui.hyperlink_to("Rerun.io", "https://www.rerun.io/");
|
||||||
ui.label(", a startup building an SDK for visualizing streams of multimodal data.");
|
ui.label(", a startup building an SDK for visualizing streams of multimodal data. ");
|
||||||
|
ui.label("For an example of a real-world egui app, see ");
|
||||||
|
ui.hyperlink_to("rerun.io/viewer", "https://www.rerun.io/viewer");
|
||||||
|
ui.label(" (runs in your browser).");
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.add_space(12.0);
|
ui.add_space(12.0);
|
||||||
|
|
@ -94,12 +100,12 @@ fn about_immediate_mode(ui: &mut egui::Ui) {
|
||||||
fn links(ui: &mut egui::Ui) {
|
fn links(ui: &mut egui::Ui) {
|
||||||
use egui::special_emojis::{GITHUB, TWITTER};
|
use egui::special_emojis::{GITHUB, TWITTER};
|
||||||
ui.hyperlink_to(
|
ui.hyperlink_to(
|
||||||
format!("{GITHUB} egui on GitHub"),
|
format!("{GITHUB} github.com/emilk/egui"),
|
||||||
"https://github.com/emilk/egui",
|
"https://github.com/emilk/egui",
|
||||||
);
|
);
|
||||||
ui.hyperlink_to(
|
ui.hyperlink_to(
|
||||||
format!("{TWITTER} @ernerfeldt"),
|
format!("{TWITTER} @ernerfeldt"),
|
||||||
"https://twitter.com/ernerfeldt",
|
"https://twitter.com/ernerfeldt",
|
||||||
);
|
);
|
||||||
ui.hyperlink_to("egui documentation", "https://docs.rs/egui/");
|
ui.hyperlink_to("📓 egui documentation", "https://docs.rs/egui/");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,9 +84,8 @@ impl CodeExample {
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let font_id = egui::TextStyle::Monospace.resolve(ui.style());
|
let font_id = egui::TextStyle::Monospace.resolve(ui.style());
|
||||||
let indentation = 8.0 * ui.fonts(|f| f.glyph_width(&font_id, ' '));
|
let indentation = 2.0 * 4.0 * ui.fonts(|f| f.glyph_width(&font_id, ' '));
|
||||||
let item_spacing = ui.spacing_mut().item_spacing;
|
ui.add_space(indentation);
|
||||||
ui.add_space(indentation - item_spacing.x);
|
|
||||||
|
|
||||||
egui::Grid::new("code_samples")
|
egui::Grid::new("code_samples")
|
||||||
.striped(true)
|
.striped(true)
|
||||||
|
|
@ -120,7 +119,7 @@ impl crate::Demo for CodeExample {
|
||||||
impl crate::View for CodeExample {
|
impl crate::View for CodeExample {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
ui.scope(|ui| {
|
ui.scope(|ui| {
|
||||||
ui.spacing_mut().item_spacing = egui::vec2(8.0, 8.0);
|
ui.spacing_mut().item_spacing = egui::vec2(8.0, 6.0);
|
||||||
self.code(ui);
|
self.code(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use egui::{Context, Modifiers, NumExt as _, ScrollArea, Ui};
|
use egui::{Context, Modifiers, ScrollArea, Ui};
|
||||||
|
|
||||||
use super::About;
|
use super::About;
|
||||||
use crate::is_mobile;
|
use crate::is_mobile;
|
||||||
|
|
@ -9,73 +9,17 @@ use crate::View;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
struct DemoGroup {
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
|
||||||
struct Demos {
|
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
|
||||||
demos: Vec<Box<dyn Demo>>,
|
demos: Vec<Box<dyn Demo>>,
|
||||||
|
|
||||||
open: BTreeSet<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Demos {
|
impl DemoGroup {
|
||||||
fn default() -> Self {
|
pub fn new(demos: Vec<Box<dyn Demo>>) -> Self {
|
||||||
Self::from_demos(vec![
|
Self { demos }
|
||||||
Box::<super::paint_bezier::PaintBezier>::default(),
|
|
||||||
Box::<super::code_editor::CodeEditor>::default(),
|
|
||||||
Box::<super::code_example::CodeExample>::default(),
|
|
||||||
Box::<super::context_menu::ContextMenus>::default(),
|
|
||||||
Box::<super::dancing_strings::DancingStrings>::default(),
|
|
||||||
Box::<super::drag_and_drop::DragAndDropDemo>::default(),
|
|
||||||
Box::<super::extra_viewport::ExtraViewport>::default(),
|
|
||||||
Box::<super::font_book::FontBook>::default(),
|
|
||||||
Box::<super::frame_demo::FrameDemo>::default(),
|
|
||||||
Box::<super::highlighting::Highlighting>::default(),
|
|
||||||
Box::<super::interactive_container::InteractiveContainerDemo>::default(),
|
|
||||||
Box::<super::MiscDemoWindow>::default(),
|
|
||||||
Box::<super::modals::Modals>::default(),
|
|
||||||
Box::<super::multi_touch::MultiTouch>::default(),
|
|
||||||
Box::<super::painting::Painting>::default(),
|
|
||||||
Box::<super::pan_zoom::PanZoom>::default(),
|
|
||||||
Box::<super::panels::Panels>::default(),
|
|
||||||
Box::<super::screenshot::Screenshot>::default(),
|
|
||||||
Box::<super::scrolling::Scrolling>::default(),
|
|
||||||
Box::<super::sliders::Sliders>::default(),
|
|
||||||
Box::<super::strip_demo::StripDemo>::default(),
|
|
||||||
Box::<super::table_demo::TableDemo>::default(),
|
|
||||||
Box::<super::text_edit::TextEditDemo>::default(),
|
|
||||||
Box::<super::text_layout::TextLayoutDemo>::default(),
|
|
||||||
Box::<super::tooltips::Tooltips>::default(),
|
|
||||||
Box::<super::undo_redo::UndoRedoDemo>::default(),
|
|
||||||
Box::<super::widget_gallery::WidgetGallery>::default(),
|
|
||||||
Box::<super::window_options::WindowOptions>::default(),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Demos {
|
|
||||||
pub fn from_demos(demos: Vec<Box<dyn Demo>>) -> Self {
|
|
||||||
let mut open = BTreeSet::new();
|
|
||||||
|
|
||||||
// Explains egui very well
|
|
||||||
open.insert(
|
|
||||||
super::code_example::CodeExample::default()
|
|
||||||
.name()
|
|
||||||
.to_owned(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Shows off the features
|
|
||||||
open.insert(
|
|
||||||
super::widget_gallery::WidgetGallery::default()
|
|
||||||
.name()
|
|
||||||
.to_owned(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Self { demos, open }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checkboxes(&mut self, ui: &mut Ui) {
|
pub fn checkboxes(&mut self, ui: &mut Ui, open: &mut BTreeSet<String>) {
|
||||||
let Self { demos, open } = self;
|
let Self { demos } = self;
|
||||||
for demo in demos {
|
for demo in demos {
|
||||||
if demo.is_enabled(ui.ctx()) {
|
if demo.is_enabled(ui.ctx()) {
|
||||||
let mut is_open = open.contains(demo.name());
|
let mut is_open = open.contains(demo.name());
|
||||||
|
|
@ -85,8 +29,8 @@ impl Demos {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn windows(&mut self, ctx: &Context) {
|
pub fn windows(&mut self, ctx: &Context, open: &mut BTreeSet<String>) {
|
||||||
let Self { demos, open } = self;
|
let Self { demos } = self;
|
||||||
for demo in demos {
|
for demo in demos {
|
||||||
let mut is_open = open.contains(demo.name());
|
let mut is_open = open.contains(demo.name());
|
||||||
demo.show(ctx, &mut is_open);
|
demo.show(ctx, &mut is_open);
|
||||||
|
|
@ -95,65 +39,6 @@ impl Demos {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
|
||||||
struct Tests {
|
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
|
||||||
demos: Vec<Box<dyn Demo>>,
|
|
||||||
|
|
||||||
open: BTreeSet<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Tests {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::from_demos(vec![
|
|
||||||
Box::<super::tests::CursorTest>::default(),
|
|
||||||
Box::<super::tests::GridTest>::default(),
|
|
||||||
Box::<super::tests::IdTest>::default(),
|
|
||||||
Box::<super::tests::InputEventHistory>::default(),
|
|
||||||
Box::<super::tests::InputTest>::default(),
|
|
||||||
Box::<super::tests::LayoutTest>::default(),
|
|
||||||
Box::<super::tests::ManualLayoutTest>::default(),
|
|
||||||
Box::<super::tests::WindowResizeTest>::default(),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Tests {
|
|
||||||
pub fn from_demos(demos: Vec<Box<dyn Demo>>) -> Self {
|
|
||||||
let mut open = BTreeSet::new();
|
|
||||||
open.insert(
|
|
||||||
super::widget_gallery::WidgetGallery::default()
|
|
||||||
.name()
|
|
||||||
.to_owned(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Self { demos, open }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn checkboxes(&mut self, ui: &mut Ui) {
|
|
||||||
let Self { demos, open } = self;
|
|
||||||
for demo in demos {
|
|
||||||
let mut is_open = open.contains(demo.name());
|
|
||||||
ui.toggle_value(&mut is_open, demo.name());
|
|
||||||
set_open(open, demo.name(), is_open);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn windows(&mut self, ctx: &Context) {
|
|
||||||
let Self { demos, open } = self;
|
|
||||||
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) {
|
fn set_open(open: &mut BTreeSet<String>, key: &'static str, is_open: bool) {
|
||||||
if is_open {
|
if is_open {
|
||||||
if !open.contains(key) {
|
if !open.contains(key) {
|
||||||
|
|
@ -166,23 +51,131 @@ fn set_open(open: &mut BTreeSet<String>, key: &'static str, is_open: bool) {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub struct DemoGroups {
|
||||||
|
about: About,
|
||||||
|
demos: DemoGroup,
|
||||||
|
tests: DemoGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DemoGroups {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
about: About::default(),
|
||||||
|
demos: DemoGroup::new(vec![
|
||||||
|
Box::<super::paint_bezier::PaintBezier>::default(),
|
||||||
|
Box::<super::code_editor::CodeEditor>::default(),
|
||||||
|
Box::<super::code_example::CodeExample>::default(),
|
||||||
|
Box::<super::context_menu::ContextMenus>::default(),
|
||||||
|
Box::<super::dancing_strings::DancingStrings>::default(),
|
||||||
|
Box::<super::drag_and_drop::DragAndDropDemo>::default(),
|
||||||
|
Box::<super::extra_viewport::ExtraViewport>::default(),
|
||||||
|
Box::<super::font_book::FontBook>::default(),
|
||||||
|
Box::<super::frame_demo::FrameDemo>::default(),
|
||||||
|
Box::<super::highlighting::Highlighting>::default(),
|
||||||
|
Box::<super::interactive_container::InteractiveContainerDemo>::default(),
|
||||||
|
Box::<super::MiscDemoWindow>::default(),
|
||||||
|
Box::<super::modals::Modals>::default(),
|
||||||
|
Box::<super::multi_touch::MultiTouch>::default(),
|
||||||
|
Box::<super::painting::Painting>::default(),
|
||||||
|
Box::<super::pan_zoom::PanZoom>::default(),
|
||||||
|
Box::<super::panels::Panels>::default(),
|
||||||
|
Box::<super::screenshot::Screenshot>::default(),
|
||||||
|
Box::<super::scrolling::Scrolling>::default(),
|
||||||
|
Box::<super::sliders::Sliders>::default(),
|
||||||
|
Box::<super::strip_demo::StripDemo>::default(),
|
||||||
|
Box::<super::table_demo::TableDemo>::default(),
|
||||||
|
Box::<super::text_edit::TextEditDemo>::default(),
|
||||||
|
Box::<super::text_layout::TextLayoutDemo>::default(),
|
||||||
|
Box::<super::tooltips::Tooltips>::default(),
|
||||||
|
Box::<super::undo_redo::UndoRedoDemo>::default(),
|
||||||
|
Box::<super::widget_gallery::WidgetGallery>::default(),
|
||||||
|
Box::<super::window_options::WindowOptions>::default(),
|
||||||
|
]),
|
||||||
|
tests: DemoGroup::new(vec![
|
||||||
|
Box::<super::tests::CursorTest>::default(),
|
||||||
|
Box::<super::tests::GridTest>::default(),
|
||||||
|
Box::<super::tests::IdTest>::default(),
|
||||||
|
Box::<super::tests::InputEventHistory>::default(),
|
||||||
|
Box::<super::tests::InputTest>::default(),
|
||||||
|
Box::<super::tests::LayoutTest>::default(),
|
||||||
|
Box::<super::tests::ManualLayoutTest>::default(),
|
||||||
|
Box::<super::tests::WindowResizeTest>::default(),
|
||||||
|
]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DemoGroups {
|
||||||
|
pub fn checkboxes(&mut self, ui: &mut Ui, open: &mut BTreeSet<String>) {
|
||||||
|
let Self {
|
||||||
|
about,
|
||||||
|
demos,
|
||||||
|
tests,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut is_open = open.contains(about.name());
|
||||||
|
ui.toggle_value(&mut is_open, about.name());
|
||||||
|
set_open(open, about.name(), is_open);
|
||||||
|
}
|
||||||
|
ui.separator();
|
||||||
|
demos.checkboxes(ui, open);
|
||||||
|
ui.separator();
|
||||||
|
tests.checkboxes(ui, open);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn windows(&mut self, ctx: &Context, open: &mut BTreeSet<String>) {
|
||||||
|
let Self {
|
||||||
|
about,
|
||||||
|
demos,
|
||||||
|
tests,
|
||||||
|
} = self;
|
||||||
|
{
|
||||||
|
let mut is_open = open.contains(about.name());
|
||||||
|
about.show(ctx, &mut is_open);
|
||||||
|
set_open(open, about.name(), is_open);
|
||||||
|
}
|
||||||
|
demos.windows(ctx, open);
|
||||||
|
tests.windows(ctx, open);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// A menu bar in which you can select different demo windows to show.
|
/// A menu bar in which you can select different demo windows to show.
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
#[cfg_attr(feature = "serde", serde(default))]
|
||||||
pub struct DemoWindows {
|
pub struct DemoWindows {
|
||||||
about_is_open: bool,
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
about: About,
|
groups: DemoGroups,
|
||||||
demos: Demos,
|
|
||||||
tests: Tests,
|
open: BTreeSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DemoWindows {
|
impl Default for DemoWindows {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let mut open = BTreeSet::new();
|
||||||
|
|
||||||
|
// Explains egui very well
|
||||||
|
set_open(&mut open, About::default().name(), true);
|
||||||
|
|
||||||
|
// Explains egui very well
|
||||||
|
set_open(
|
||||||
|
&mut open,
|
||||||
|
super::code_example::CodeExample::default().name(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Shows off the features
|
||||||
|
set_open(
|
||||||
|
&mut open,
|
||||||
|
super::widget_gallery::WidgetGallery::default().name(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
about_is_open: true,
|
groups: Default::default(),
|
||||||
about: Default::default(),
|
open,
|
||||||
demos: Default::default(),
|
|
||||||
tests: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,36 +190,35 @@ impl DemoWindows {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mobile_ui(&mut self, ctx: &Context) {
|
fn about_is_open(&self) -> bool {
|
||||||
if self.about_is_open {
|
self.open.contains(About::default().name())
|
||||||
let screen_size = ctx.input(|i| i.screen_rect.size());
|
}
|
||||||
let default_width = (screen_size.x - 32.0).at_most(400.0);
|
|
||||||
|
|
||||||
|
fn mobile_ui(&mut self, ctx: &Context) {
|
||||||
|
if self.about_is_open() {
|
||||||
let mut close = false;
|
let mut close = false;
|
||||||
egui::Window::new(self.about.name())
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
.anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
|
egui::ScrollArea::vertical()
|
||||||
.default_width(default_width)
|
.auto_shrink(false)
|
||||||
.default_height(ctx.available_rect().height() - 46.0)
|
.show(ui, |ui| {
|
||||||
.vscroll(true)
|
self.groups.about.ui(ui);
|
||||||
.open(&mut self.about_is_open)
|
ui.add_space(12.0);
|
||||||
.resizable(false)
|
ui.vertical_centered_justified(|ui| {
|
||||||
.collapsible(false)
|
if ui
|
||||||
.show(ctx, |ui| {
|
.button(egui::RichText::new("Continue to the demo!").size(20.0))
|
||||||
self.about.ui(ui);
|
.clicked()
|
||||||
ui.add_space(12.0);
|
{
|
||||||
ui.vertical_centered_justified(|ui| {
|
close = true;
|
||||||
if ui
|
}
|
||||||
.button(egui::RichText::new("Continue to the demo!").size(20.0))
|
});
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
close = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
self.about_is_open &= !close;
|
if close {
|
||||||
|
set_open(&mut self.open, About::default().name(), false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.mobile_top_bar(ctx);
|
self.mobile_top_bar(ctx);
|
||||||
self.show_windows(ctx);
|
self.groups.windows(ctx, &mut self.open);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,27 +284,14 @@ impl DemoWindows {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
self.show_windows(ctx);
|
self.groups.windows(ctx, &mut self.open);
|
||||||
}
|
|
||||||
|
|
||||||
/// Show the open windows.
|
|
||||||
fn show_windows(&mut self, ctx: &Context) {
|
|
||||||
self.about.show(ctx, &mut self.about_is_open);
|
|
||||||
self.demos.windows(ctx);
|
|
||||||
self.tests.windows(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn demo_list_ui(&mut self, ui: &mut egui::Ui) {
|
fn demo_list_ui(&mut self, ui: &mut egui::Ui) {
|
||||||
ScrollArea::vertical().show(ui, |ui| {
|
ScrollArea::vertical().show(ui, |ui| {
|
||||||
ui.with_layout(egui::Layout::top_down_justified(egui::Align::LEFT), |ui| {
|
ui.with_layout(egui::Layout::top_down_justified(egui::Align::LEFT), |ui| {
|
||||||
ui.toggle_value(&mut self.about_is_open, self.about.name());
|
self.groups.checkboxes(ui, &mut self.open);
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
self.demos.checkboxes(ui);
|
|
||||||
ui.separator();
|
|
||||||
self.tests.checkboxes(ui);
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
if ui.button("Organize windows").clicked() {
|
if ui.button("Organize windows").clicked() {
|
||||||
ui.ctx().memory_mut(|mem| mem.reset_areas());
|
ui.ctx().memory_mut(|mem| mem.reset_areas());
|
||||||
}
|
}
|
||||||
|
|
@ -382,29 +361,29 @@ fn file_menu_button(ui: &mut Ui) {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::demo::demo_app_windows::Demos;
|
use crate::{demo::demo_app_windows::DemoGroups, Demo};
|
||||||
use egui::Vec2;
|
use egui::Vec2;
|
||||||
use egui_kittest::kittest::Queryable;
|
use egui_kittest::kittest::Queryable;
|
||||||
use egui_kittest::{Harness, SnapshotOptions};
|
use egui_kittest::{Harness, SnapshotOptions};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn demos_should_match_snapshot() {
|
fn demos_should_match_snapshot() {
|
||||||
let demos = Demos::default();
|
let demos = DemoGroups::default().demos;
|
||||||
|
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
for mut demo in demos.demos {
|
for mut demo in demos.demos {
|
||||||
|
// Widget Gallery needs to be customized (to set a specific date) and has its own test
|
||||||
|
if demo.name() == crate::WidgetGallery::default().name() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the emoji from the demo name
|
// Remove the emoji from the demo name
|
||||||
let name = demo
|
let name = demo
|
||||||
.name()
|
.name()
|
||||||
.split_once(' ')
|
.split_once(' ')
|
||||||
.map_or(demo.name(), |(_, name)| name);
|
.map_or(demo.name(), |(_, name)| name);
|
||||||
|
|
||||||
// Widget Gallery needs to be customized (to set a specific date) and has its own test
|
|
||||||
if name == "Widget Gallery" {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut harness = Harness::new(|ctx| {
|
let mut harness = Harness::new(|ctx| {
|
||||||
demo.show(ctx, &mut true);
|
demo.show(ctx, &mut true);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ impl crate::View for FontBook {
|
||||||
ui.horizontal_wrapped(|ui| {
|
ui.horizontal_wrapped(|ui| {
|
||||||
ui.spacing_mut().item_spacing = egui::Vec2::splat(2.0);
|
ui.spacing_mut().item_spacing = egui::Vec2::splat(2.0);
|
||||||
|
|
||||||
for (&chr, glyph_info) in available_glyphs {
|
for (&chr, glyph_info) in available_glyphs.iter() {
|
||||||
if filter.is_empty()
|
if filter.is_empty()
|
||||||
|| glyph_info.name.contains(filter)
|
|| glyph_info.name.contains(filter)
|
||||||
|| *filter == chr.to_string()
|
|| *filter == chr.to_string()
|
||||||
|
|
@ -96,13 +96,9 @@ impl crate::View for FontBook {
|
||||||
.frame(false);
|
.frame(false);
|
||||||
|
|
||||||
let tooltip_ui = |ui: &mut egui::Ui| {
|
let tooltip_ui = |ui: &mut egui::Ui| {
|
||||||
ui.label(
|
let font_id = self.font_id.clone();
|
||||||
egui::RichText::new(chr.to_string()).font(self.font_id.clone()),
|
|
||||||
);
|
char_info_ui(ui, chr, glyph_info, font_id);
|
||||||
ui.label(format!(
|
|
||||||
"{}\nU+{:X}\n\nFound in: {:?}\n\nClick to copy",
|
|
||||||
glyph_info.name, chr as u32, glyph_info.fonts
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if ui.add(button).on_hover_ui(tooltip_ui).clicked() {
|
if ui.add(button).on_hover_ui(tooltip_ui).clicked() {
|
||||||
|
|
@ -115,6 +111,35 @@ impl crate::View for FontBook {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn char_info_ui(ui: &mut egui::Ui, chr: char, glyph_info: &GlyphInfo, font_id: egui::FontId) {
|
||||||
|
let resp = ui.label(egui::RichText::new(chr.to_string()).font(font_id));
|
||||||
|
|
||||||
|
egui::Grid::new("char_info")
|
||||||
|
.num_columns(2)
|
||||||
|
.striped(true)
|
||||||
|
.show(ui, |ui| {
|
||||||
|
ui.label("Name");
|
||||||
|
ui.label(glyph_info.name.clone());
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("Hex");
|
||||||
|
ui.label(format!("{:X}", chr as u32));
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("Width");
|
||||||
|
ui.label(format!("{:.1} pts", resp.rect.width()));
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("Fonts");
|
||||||
|
ui.label(
|
||||||
|
format!("{:?}", glyph_info.fonts)
|
||||||
|
.trim_start_matches('[')
|
||||||
|
.trim_end_matches(']'),
|
||||||
|
);
|
||||||
|
ui.end_row();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn available_characters(ui: &egui::Ui, family: egui::FontFamily) -> BTreeMap<char, GlyphInfo> {
|
fn available_characters(ui: &egui::Ui, family: egui::FontFamily) -> BTreeMap<char, GlyphInfo> {
|
||||||
ui.fonts(|f| {
|
ui.fonts(|f| {
|
||||||
f.lock()
|
f.lock()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e640606207265b4f040f793b0ffb989504b6a98b89e95e77a9a9d3e3abc9327a
|
oid sha256:37ba383a2ba7f00f8064d21203c22f9de2f688ea4fbd45d400c979187686cf33
|
||||||
size 80933
|
size 80861
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue