From f025513998a04c0805a006f422de15d38c59e843 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 20 Oct 2021 12:34:27 +0200 Subject: [PATCH] Code example demo (#823) --- egui_demo_lib/src/apps/demo/code_example.rs | 159 ++++++++++++++++++ .../src/apps/demo/demo_app_windows.rs | 1 + egui_demo_lib/src/apps/demo/mod.rs | 1 + 3 files changed, 161 insertions(+) create mode 100644 egui_demo_lib/src/apps/demo/code_example.rs diff --git a/egui_demo_lib/src/apps/demo/code_example.rs b/egui_demo_lib/src/apps/demo/code_example.rs new file mode 100644 index 00000000..ef371a5e --- /dev/null +++ b/egui_demo_lib/src/apps/demo/code_example.rs @@ -0,0 +1,159 @@ +#[derive(Debug)] +pub struct CodeExample { + name: String, + age: u32, +} + +impl Default for CodeExample { + fn default() -> Self { + Self { + name: "Arthur".to_owned(), + age: 42, + } + } +} + +impl CodeExample { + fn samples_in_grid(&mut self, ui: &mut egui::Ui) { + show_code(ui, r#"ui.heading("Code samples");"#); + ui.heading("Code samples"); + ui.end_row(); + + show_code( + ui, + r#" + // Putting things on the same line using ui.horizontal: + ui.horizontal(|ui| { + ui.label("Your name: "); + ui.text_edit_singleline(&mut self.name); + });"#, + ); + // Putting things on the same line using ui.horizontal: + ui.horizontal(|ui| { + ui.label("Your name: "); + ui.text_edit_singleline(&mut self.name); + }); + ui.end_row(); + + show_code( + ui, + r#"egui::Slider::new(&mut self.age, 0..=120).text("age")"#, + ); + ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age")); + ui.end_row(); + + show_code( + ui, + r#" + if ui.button("Click each year").clicked() { + self.age += 1; + }"#, + ); + if ui.button("Click each year").clicked() { + self.age += 1; + } + ui.end_row(); + + show_code( + ui, + r#"ui.label(format!("Hello '{}', age {}", self.name, self.age));"#, + ); + ui.label(format!("Hello '{}', age {}", self.name, self.age)); + ui.end_row(); + } +} + +impl super::Demo for CodeExample { + fn name(&self) -> &'static str { + "🖮 Code Example" + } + + fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) { + use super::View; + egui::Window::new(self.name()) + .open(open) + .default_size([800.0, 400.0]) + .vscroll(false) + .hscroll(true) + .show(ctx, |ui| self.ui(ui)); + } +} + +impl super::View for CodeExample { + fn ui(&mut self, ui: &mut egui::Ui) { + use crate::syntax_highlighting::code_view_ui; + + code_view_ui( + ui, + r" +pub struct CodeExample { + name: String, + age: u32, +} + +impl CodeExample { + fn ui(&mut self, ui: &mut egui::Ui) { +" + .trim(), + ); + + egui::ScrollArea::vertical().show(ui, |ui| { + ui.horizontal(|ui| { + let indentation = 8.0 * ui.fonts()[egui::TextStyle::Monospace].glyph_width(' '); + let item_spacing = ui.spacing_mut().item_spacing; + ui.add_space(indentation - item_spacing.x); + + egui::Grid::new("code_samples") + .striped(true) + .num_columns(2) + .min_col_width(16.0) + .spacing([16.0, 8.0]) + .show(ui, |ui| { + self.samples_in_grid(ui); + }); + }); + }); + + code_view_ui(ui, " }\n}"); + + ui.separator(); + + code_view_ui(ui, &format!("{:#?}", self)); + + ui.separator(); + + let mut theme = crate::syntax_highlighting::CodeTheme::from_memory(ui.ctx()); + ui.collapsing("Theme", |ui| { + theme.ui(ui); + theme.store_in_memory(ui.ctx()); + }); + } +} + +fn show_code(ui: &mut egui::Ui, code: &str) { + let code = remove_leading_indentation(code.trim_start_matches('\n')); + crate::syntax_highlighting::code_view_ui(ui, &code); +} + +fn remove_leading_indentation(code: &str) -> String { + fn is_indent(c: &u8) -> bool { + matches!(*c, b' ' | b'\t') + } + + let first_line_indent = code.bytes().take_while(is_indent).count(); + + let mut out = String::new(); + + let mut code = code; + while !code.is_empty() { + let indent = code.bytes().take_while(is_indent).count(); + let start = first_line_indent.min(indent); + let end = code + .find('\n') + .map(|endline| endline + 1) + .unwrap_or_else(|| code.len()); + out += &code[start..end]; + code = &code[end..]; + } + out +} diff --git a/egui_demo_lib/src/apps/demo/demo_app_windows.rs b/egui_demo_lib/src/apps/demo/demo_app_windows.rs index 3fefb810..31f380d7 100644 --- a/egui_demo_lib/src/apps/demo/demo_app_windows.rs +++ b/egui_demo_lib/src/apps/demo/demo_app_windows.rs @@ -17,6 +17,7 @@ impl Default for Demos { fn default() -> Self { Self::from_demos(vec![ Box::new(super::code_editor::CodeEditor::default()), + Box::new(super::code_example::CodeExample::default()), Box::new(super::dancing_strings::DancingStrings::default()), Box::new(super::drag_and_drop::DragAndDropDemo::default()), Box::new(super::font_book::FontBook::default()), diff --git a/egui_demo_lib/src/apps/demo/mod.rs b/egui_demo_lib/src/apps/demo/mod.rs index 08c0caee..f519aeec 100644 --- a/egui_demo_lib/src/apps/demo/mod.rs +++ b/egui_demo_lib/src/apps/demo/mod.rs @@ -6,6 +6,7 @@ mod app; pub mod code_editor; +pub mod code_example; pub mod dancing_strings; pub mod demo_app_windows; pub mod drag_and_drop;