diff --git a/src/app.rs b/src/app.rs index cbb5672..47ee048 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,13 +11,13 @@ pub struct TemplateApp { counter: i32, name_input: String, x: i32, - show_popup_panel1: bool, first_frame: bool, language: String, code: String, show_area1: bool, show_area2: bool, show_area3: bool, + side_panel_state: side_panel::SidePanelState, // This is how you opt-out of serialization of a field #[serde(skip)] @@ -35,13 +35,13 @@ impl Default for TemplateApp { counter: 0, name_input: String::new(), x: 5, - show_popup_panel1: false, first_frame: true, language: "rs".into(), code: String::new(), show_area1: false, show_area2: false, show_area3: false, + side_panel_state: side_panel::SidePanelState::new(), } } } @@ -79,7 +79,7 @@ impl eframe::App for TemplateApp { top_panel::top_panel_ui(ctx); - side_panel::side_panel_ui(ctx, &mut self.show_popup_panel1, &mut self.language); + side_panel::side_panel_ui(ctx, &mut self.side_panel_state); central_panel::central_panel_ui( ctx, diff --git a/src/central_panel.rs b/src/central_panel.rs index eb2fe28..b886e6a 100644 --- a/src/central_panel.rs +++ b/src/central_panel.rs @@ -55,10 +55,8 @@ pub fn central_panel_ui( ui.horizontal(|ui| { - ui.add(egui::github_link_file!( - "https://github.com/emilk/eframe_template/blob/main/", - "Source code." - )); + + ui.hyperlink_to("eframe source code.", "https://github.com/emilk/eframe_template"); if ui.button("Toggle Area 1").clicked() { *show_area1 = !*show_area1; } diff --git a/src/side_panel.rs b/src/side_panel.rs index 07fd5a0..596d9e5 100644 --- a/src/side_panel.rs +++ b/src/side_panel.rs @@ -1,29 +1,95 @@ use crate::rustbook_code_blocks::{self}; use eframe::egui; -pub fn side_panel_ui(ctx: &egui::Context, spp1: &mut bool, language: &mut String) { +/// We derive Deserialize/Serialize so we can persist app state on shutdown. +#[derive(serde::Deserialize, serde::Serialize)] +pub struct SidePanelState { + pub spp1: bool, // spp = side_panel_popup + pub spp2: bool, + pub language: String, +} + +impl SidePanelState { + pub fn new() -> Self { + Self { + spp1: false, + spp2: false, + language: "rs".into() + } + } +} + +pub fn side_panel_ui(ctx: &egui::Context, state: &mut SidePanelState) { egui::SidePanel::left("side_nav") - .exact_width(250.0) + .default_width(100.0) + // .exact_width(250.0) .show(ctx, |ui| { - ui.heading("Sidebar"); + ui.heading("Common Rust Concepts"); if ui.button("📦 Variables, Mutability & DataTypes").clicked() { - *spp1 = true; + if state.spp1 { + state.spp1 = false; + } else { + state.spp1 = true; + } + } + if ui.button("📦 Functions").clicked() { + if state.spp2 { + state.spp2 = false; + } else { + state.spp2 = true; + } } }); - if *spp1 { + if state.spp1 { egui::Window::new("📦 Variables, Mutability & DataTypes").show(ctx, |ui| { ui.label("📦 Variables, Mutability & DataTypes"); let theme = egui_extras::syntax_highlighting::CodeTheme::from_memory(ui.ctx(), ui.style()); let code = rustbook_code_blocks::VARIABLES_MUTABILITY_DATATYPES; + let mut layouter = |ui: &egui::Ui, text: &str, wrap_width: f32| { + let mut layout_job = egui_extras::syntax_highlighting::highlight( + ui.ctx(), + ui.style(), + &theme, + text, + &state.language, + ); + layout_job.wrap.max_width = wrap_width; + ui.fonts(|f| f.layout_job(layout_job)) + }; + + egui::ScrollArea::vertical() + .max_height(600.0) // Limit height for scrollability + .show(ui, |ui| { + ui.add_sized( + [ui.available_width(), 800.0], // Large height to simulate overflow + egui::TextEdit::multiline(&mut code.to_string()) + .font(egui::TextStyle::Monospace) // Use monospaced font + .code_editor() // Enables code styling + .desired_rows(13) + .lock_focus(true) + .desired_width(f32::INFINITY) + .layouter(&mut layouter), + ); + }); + if ui.button("❌ Close").clicked() { + state.spp1 = false; + } + }); + } + if state.spp2 { + egui::Window::new("📦 Functions").show(ctx, |ui| { + ui.label("📦 Functions"); + let theme = egui_extras::syntax_highlighting::CodeTheme::from_memory(ui.ctx(), ui.style()); + let code = rustbook_code_blocks::FUNCTIONS; let mut layouter = |ui: &egui::Ui, text: &str, wrap_width: f32| { let mut layout_job = egui_extras::syntax_highlighting::highlight( ui.ctx(), ui.style(), &theme, text, - language, + &state.language, ); layout_job.wrap.max_width = wrap_width; ui.fonts(|f| f.layout_job(layout_job)) @@ -44,7 +110,7 @@ pub fn side_panel_ui(ctx: &egui::Context, spp1: &mut bool, language: &mut String ); }); if ui.button("❌ Close").clicked() { - *spp1 = false; + state.spp2 = false; } }); }