diff --git a/src/main.rs b/src/main.rs index 1aac47f..5d4345b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,12 @@ + +mod tools; + use eframe::egui; -use egui_extras::syntax_highlighting; +use tools::Demo; + fn main() -> Result<(), eframe::Error> { + tools::code_editor::linked(); env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() @@ -16,45 +21,21 @@ fn main() -> Result<(), eframe::Error> { ) } -struct CodeEditor { - language: String, - code: String, -} - -impl Default for CodeEditor { - fn default() -> Self { - Self { - language: "rs".into(), - code: "// A very simple example\n\ - fn main() {\n\ - \tprintln!(\"Hello world!\");\n\ - }\n\ - " - .into(), - } - } -} - -impl CodeEditor { - fn ui(&mut self, ui: &mut egui::Ui) { - // The contents of the ui method from your reference go here - // ... - - // You can also replace `self.code` with `&mut self.code` in the method - // to directly modify the code in the CodeEditor instance. - } - - fn show(&mut self, ctx: &egui::Context, ui: &mut egui::Ui) { - // The contents of the show method from your reference go here - // ... - self.ui(ui); - } -} - -#[derive(Default)] +//#[derive(Default)] struct MyApp { picked_path: Option, - code: String, + code_editor: tools::code_editor::CodeEditor, + code_open: bool, +} + +impl Default for MyApp { + fn default() -> Self { + Self { + picked_path: None, + code_editor: tools::code_editor::CodeEditor::default(), // Initialize CodeEditor + code_open: true, + } + } } impl eframe::App for MyApp { @@ -79,11 +60,13 @@ impl eframe::App for MyApp { }); } - let mut code_editor = CodeEditor::default(); - code_editor.code = self.code.clone(); // Initialize code editor with MyApp's code - code_editor.show(ctx, ui); - }); - + //~ let mut code_editor = CodeEditor::default(); + //~ code_editor.code = self.code.clone(); // Initialize code editor with MyApp's code + //~ code_editor.language = self.language.clone(); + //~ code_editor.show(ctx, ui); + //~ + self.code_editor.show(ctx, &mut self.code_open); + }); egui::TopBottomPanel::bottom("terminal").show(ctx, |ui| { ui.label("Terminal ?"); }); diff --git a/src/tools/code_editor.rs b/src/tools/code_editor.rs new file mode 100644 index 0000000..0db90d5 --- /dev/null +++ b/src/tools/code_editor.rs @@ -0,0 +1,101 @@ +use eframe::egui; + +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[cfg_attr(feature = "serde", serde(default))] +pub struct CodeEditor { + language: String, + code: String, +} + +impl Default for CodeEditor { + fn default() -> Self { + Self { + language: "rs".into(), + code: "// A very simple example\n\ +fn main() {\n\ +\tprintln!(\"Hello world!\");\n\ +}\n\ +" + .into(), + } + } +} + +impl super::Demo for CodeEditor { + fn name(&self) -> &'static str { + "🖮 Code Editor" + } + + fn show(&mut self, ctx: &egui::Context, open: &mut bool) { + use super::View as _; + egui::Window::new(self.name()) + .open(open) + .default_height(500.0) + .show(ctx, |ui| self.ui(ui)); + } +} + +impl super::View for CodeEditor { + fn ui(&mut self, ui: &mut egui::Ui) { + let Self { language, code } = self; + + ui.horizontal(|ui| { + ui.set_height(0.0); + ui.label("An example of syntax highlighting in a TextEdit."); + //ui.add(crate::egui_github_link_file!()); + }); + + if cfg!(feature = "syntect") { + ui.horizontal(|ui| { + ui.label("Language:"); + ui.text_edit_singleline(language); + }); + ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("Syntax highlighting powered by "); + ui.hyperlink_to("syntect", "https://github.com/trishume/syntect"); + ui.label("."); + }); + } else { + ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("Compile the demo with the "); + ui.code("syntax_highlighting"); + ui.label(" feature to enable more accurate syntax highlighting using "); + ui.hyperlink_to("syntect", "https://github.com/trishume/syntect"); + ui.label("."); + }); + } + + let mut theme = egui_extras::syntax_highlighting::CodeTheme::from_memory(ui.ctx()); + ui.collapsing("Theme", |ui| { + ui.group(|ui| { + theme.ui(ui); + theme.clone().store_in_memory(ui.ctx()); + }); + }); + + let mut layouter = |ui: &egui::Ui, string: &str, wrap_width: f32| { + let mut layout_job = + egui_extras::syntax_highlighting::highlight(ui.ctx(), &theme, string, language); + layout_job.wrap.max_width = wrap_width; + ui.fonts(|f| f.layout_job(layout_job)) + }; + + egui::ScrollArea::vertical().show(ui, |ui| { + ui.add( + egui::TextEdit::multiline(code) + .font(egui::TextStyle::Monospace) // for cursor height + .code_editor() + .desired_rows(10) + .lock_focus(true) + .desired_width(f32::INFINITY) + .layouter(&mut layouter), + ); + }); + } +} + +pub fn linked() { + println!("Code Editor Linked"); +} diff --git a/src/tools/mod.rs b/src/tools/mod.rs new file mode 100644 index 0000000..6a7234a --- /dev/null +++ b/src/tools/mod.rs @@ -0,0 +1,25 @@ +use eframe::egui; + +pub mod code_editor; + + +// ---------------------------------------------------------------------------- + +/// Something to view in the demo windows +pub trait View { + fn ui(&mut self, ui: &mut egui::Ui); +} + +/// Something to view +pub trait Demo { + /// Is the demo enabled for this integraton? + fn is_enabled(&self, _ctx: &egui::Context) -> bool { + true + } + + /// `&'static` so we can also use it as a key to store open/close state. + fn name(&self) -> &'static str; + + /// Show windows, etc + fn show(&mut self, ctx: &egui::Context, open: &mut bool); +}