Skip to content
Snippets Groups Projects
code.rs 2.92 KiB
Newer Older
use crate::color::{set_alpha_in_place, set_style_alpha};
use eframe::egui;
use eframe::egui::{Align2, Color32, Context, Frame, Vec2, Widget, Window};
Finn Bear's avatar
Finn Bear committed

#[derive(Clone)]
pub struct Code {
    /// Must be unique.
    pub name: &'static str,
    /// Horizontal offset from middle.
    pub offset_x: f32,
    /// Vertical offset from middle.
    pub offset_y: f32,
    /// How tall and wide.
    pub size_pixels: f32,
    /// Background color. Transparent disables background.
    pub background: Color32,
    /// Alpha (how opaque) entire widget is.
    pub alpha: f32,
Finn Bear's avatar
Finn Bear committed
    /// Code.
    pub code: String,
}

impl Default for Code {
    fn default() -> Self {
        Self {
            name: "grid",
            offset_x: 0.0,
            offset_y: 0.0,
            size_pixels: 400.0,
            background: Color32::from_rgb(230, 230, 230),
            alpha: 1.0,
Finn Bear's avatar
Finn Bear committed
            code: String::from(r#"println("Hello world!");"#),
Finn Bear's avatar
Finn Bear committed
        }
    }
}

impl Code {
    /// Render to UI.
    pub fn show(&self, ctx: &Context) {
        Window::new(self.name)
            .title_bar(false)
            .frame(Frame::window(&set_style_alpha(&ctx.style(), self.alpha)))
Finn Bear's avatar
Finn Bear committed
            .anchor(
                Align2::CENTER_CENTER,
                Vec2::new(self.offset_x, self.offset_y),
            )
            .fixed_size(Vec2::splat(self.size_pixels))
            .show(ctx, |ui| {
                // Syntax coloring code adapted from: https://github.com/emilk/egui/blob/master/egui_demo_lib/src/apps/demo/code_editor.rs
Finn Bear's avatar
Finn Bear committed
                let theme = egui_demo_lib::syntax_highlighting::CodeTheme::light();
                let mut layouter = |ui: &egui::Ui, string: &str, wrap_width: f32| {
                    let mut layout_job = egui_demo_lib::syntax_highlighting::highlight(
                        ui.ctx(),
                        &theme,
                        string,
                        "rs",
                    );
                    for section in &mut layout_job.sections {
                        set_alpha_in_place(&mut section.format.color, self.alpha);
                    }
                    layout_job.wrap_width = wrap_width;
                    ui.fonts().layout_job(layout_job)
                };

                egui::TextEdit::multiline(&mut self.code.as_str())
Finn Bear's avatar
Finn Bear committed
                    .font(egui::TextStyle::Monospace) // Only affects cursor.
                    .code_editor()
                    .lock_focus(true)
                    .desired_width(f32::INFINITY)
                    .layouter(&mut layouter)
                    .ui(ui);
Finn Bear's avatar
Finn Bear committed
            });
    }
}

/// Converts Rust code to pseudocode.
///
/// Note: Must use non-idiomatic `return x;` instead of just `x`.
pub fn pseudocode(code: &str) -> String {
    code.replace("pub ", "")
        .replace("fn ", "function ")
        .replace("let ", "")
        .replace("mut ", "")
        .replace(": f32", "")
        .replace(" -> bool", "")
Finn Bear's avatar
Finn Bear committed
        .replace("println!", "println")
        .replace(";\n", "\n")
}