use egui::{self, Color32, ScrollArea, TextEdit, TextFormat, Vec2, text::LayoutSection};
use crate::parser::{get_duckyscript_tokens, DuckyScriptTokens};
#[derive(Default)]
pub struct DuckyScriptCodeView {
syntax_highlight: egui::text::LayoutJob,
}
impl DuckyScriptCodeView {
pub fn ui(&mut self, ui: &mut egui::Ui, code: &mut String) {
ScrollArea::vertical().show(ui, |ui| {
let mut layouter = |ui: &egui::Ui, code: &str, wrap_width: f32| {
let mut s = egui::text::LayoutJob::simple(
code.into(),
egui::FontId::monospace(12.0),
egui::Color32::DARK_GRAY
,
f32::INFINITY,
);
s.sections = self.syntax_highlight.sections.clone();
return ui.fonts().layout_job(s);
};
ui.add_sized(
ui.available_size(),
egui::TextEdit::multiline(code)
.code_editor()
.desired_width(f32::INFINITY)
.font(egui::TextStyle::Monospace) .layouter(&mut layouter),
)
});
}
pub fn update_syntax_highlight(&mut self, code: &str, tokens: DuckyScriptTokens, egui_style: &egui::Style) {
self.syntax_highlight = highlight_duckyscript(code, tokens, egui_style);
}
}
fn highlight_duckyscript(
code: &str,
tokens: DuckyScriptTokens,
egui_style: &egui::Style,
) -> egui::text::LayoutJob {
let mut job = egui::text::LayoutJob{
text: code.into(),
..Default::default()
};
return job;
highlight_tokens(&mut job, tokens, egui_style);
job
}
fn highlight_tokens(
job: &mut egui::text::LayoutJob,
tokens: DuckyScriptTokens,
egui_style: &egui::Style,
) {
use crate::parser::ducky::Rule;
for token in tokens.into_inner() {
let span = token.as_span();
match token.as_rule() {
Rule::builtin_fn => {
}
Rule::variable_def => {
job.sections.push(LayoutSection {
leading_space: 0.0,
byte_range: span.start()..span.start()+5,
format: TextFormat {
font_id: egui::FontId::monospace(12.0),
color: Color32::from_rgb(255, 100, 100),
..Default::default()
},
});
}
Rule::while_block => {
job.sections.push(LayoutSection {
leading_space: 0.0,
byte_range: span.start()..span.start()+5,
format: TextFormat {
font_id: egui::FontId::monospace(12.0),
color: Color32::from_rgb(255, 100, 100),
..Default::default()
},
});
}
Rule::EOI => break,
_ => {
break
},
};
highlight_tokens(job, token, egui_style);
}
}