use crate::stage::Stage;
use ::uxn::{Backend, Uxn};
use eframe::egui;
use varvara::Varvara;
pub struct UxnPanel<'a> {
pub stage: Stage<'a>,
focused: bool,
last_response_id: Option<egui::Id>,
}
impl<'a> UxnPanel<'a> {
pub fn last_response_id(&self) -> egui::Id {
self.last_response_id
.unwrap_or_else(|| egui::Id::new("uxn_panel_default"))
}
pub fn set_rom_bytes(&mut self, data: &[u8]) {
self.stage.load_rom(data);
}
pub fn set_sym_bytes(&mut self, data: &[u8]) {
self.stage.load_symbols(data);
}
pub fn set_rom_path<P: AsRef<std::path::Path>>(&mut self, path: P) {
self.stage.load_rom_with_path(path);
}
pub fn new(
ctx: &egui::Context,
rom: Option<&[u8]>,
size: (u16, u16),
texture_name: String,
) -> Self {
let ram = Box::new([0u8; 65536]);
let ram_for_leak = ram.clone();
let ram_static: &'static mut [u8; 65536] = Box::leak(ram_for_leak);
let vm = Uxn::new(ram_static, Backend::Interpreter);
let dev = Varvara::default();
let (_tx, rx) = std::sync::mpsc::channel();
let mut stage = Stage::new(vm, dev, size, 1.0, rx, ctx, texture_name);
if let Some(rom) = rom {
stage.load_rom(rom);
}
Self {
stage,
focused: false,
last_response_id: None,
}
}
pub fn is_focused(&self) -> bool {
self.focused
}
pub fn handle_input(
&mut self,
input: &egui::InputState,
response: &egui::Response,
rect: egui::Rect,
) {
self.stage.handle_input(input, response, rect);
}
pub fn show(&mut self, ui: &mut egui::Ui) -> egui::Response {
let panel_size =
egui::Vec2::new(self.stage.size.0 as f32, self.stage.size.1 as f32) * self.stage.scale;
let (rect_id, rect) = ui.allocate_space(panel_size);
let response = ui.interact(rect, rect_id, egui::Sense::click_and_drag());
if response.clicked() {
response.request_focus();
}
let input = ui.ctx().input(|i| i.clone());
if response.hovered() {
self.stage.handle_mouse_input(&input, &response, rect);
}
self.focused = response.has_focus();
if self.focused {
self.stage.handle_input(&input, &response, rect);
self.stage.handle_usb_input();
}
self.stage.step();
self.stage.update_texture();
self.stage.draw_at(ui, rect);
self.last_response_id = Some(response.id);
response
}
}