Newer
Older
use crate::color::{set_alpha_in_place, set_style_alpha};
use eframe::egui::{Align2, Color32, Context, Frame, Vec2, Widget, Window};
#[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,
/// 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),
}
}
}
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)))
.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
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())
.code_editor()
.lock_focus(true)
.desired_width(f32::INFINITY)
.layouter(&mut layouter)
.ui(ui);
/// 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", "")