use std::{collections::HashMap, f32::consts::TAU}; use ggez::{ContextBuilder, event::{EventHandler, self}, graphics::{*, self}, context::Has, Context, GameError}; use ggez_egui::{egui, EguiBackend}; #[derive(Clone)] struct Element { pos: [f32; 2], size: [f32; 2], angle: f32, mesh: Mesh } impl Element { fn new(ctx: &mut Context) -> Element { Element { pos: [300.0, 500.0], size: [100.0, 50.0], angle: 0.0, mesh: Mesh::new_rectangle( ctx, DrawMode::fill(), Rect::new(-1.0, -1.0, 1.0, 1.0), Color::WHITE ).unwrap() } } } impl Drawable for Element { fn draw(&self, canvas: &mut Canvas, _param: impl Into) { canvas.draw( &self.mesh, DrawParam::default() .dest(self.pos) .offset([-0.5, -0.5]) .scale(self.size) .rotation(self.angle) ) } fn dimensions(&self, _gfx: &impl Has) -> Option { None } } fn main() { let (ctx, event_loop) = ContextBuilder::new("game_id", "author") .build() .expect("FATAL - Failed to create the window.s"); let my_game = MyGame::default(); event::run(ctx, event_loop, my_game); } #[derive(Default)] struct MyGame { egui_backend: EguiBackend, elements: HashMap, curret_element: String, } impl EventHandler for MyGame { fn update(&mut self, ctx: &mut ggez::Context) -> ggez::GameResult { let egui_ctx = self.egui_backend.ctx(); egui::Window::new("Editor").show(&egui_ctx, |ui| { ui.add( egui::TextEdit::singleline(&mut self.curret_element).hint_text("put an id here") ); let selected = self.elements.get(&self.curret_element).is_some() && !self.curret_element.is_empty(); if ui.add_enabled(!selected, egui::Button::new("add element")).clicked() { self.elements.insert(self.curret_element.clone(), Element::new(ctx)); self.curret_element = String::new(); } if self.elements.len() > 0 { let elements = self.elements.clone(); for (id, _element) in &elements.clone() { ui.horizontal(|ui| { let selected = self.curret_element == *id; if ui.add_enabled(!selected, egui::Button::new("select")).clicked() { self.curret_element = (*id).clone(); } if ui.button("remove").clicked() { self.elements.remove(id); } ui.label(id.to_string()); }); } } if selected { ui.group(|ui| { if let Some(element) = self.elements.get_mut(&self.curret_element) { ui.label("config"); ui.group(|ui| { ui.label("position"); ui.horizontal(|ui| { ui.add(egui::DragValue::new(&mut element.pos[0]).prefix("x: ")); ui.add(egui::DragValue::new(&mut element.pos[1]).prefix("y: ")); }); }); ui.group(|ui| { ui.label("size"); ui.horizontal(|ui| { ui.add(egui::DragValue::new(&mut element.size[0]).prefix("w: ")); ui.add(egui::DragValue::new(&mut element.size[1]).prefix("h: ")); }); }); ui.group(|ui| { ui.label("angle"); ui.add(egui::Slider::new(&mut element.angle, 0.0..=TAU).prefix("angle: ")); }); } }); } }); self.egui_backend.update(ctx); Ok(()) } fn draw(&mut self, ctx: &mut ggez::Context) -> ggez::GameResult { let mut canvas = graphics::Canvas::from_frame(ctx, Color::BLACK); for (_, element) in &self.elements { canvas.draw(element, DrawParam::default()); } canvas.draw(&self.egui_backend, DrawParam::default()); canvas.finish(ctx) } fn text_input_event(&mut self, _ctx: &mut ggez::Context, character: char) -> Result<(), GameError> { self.egui_backend.input.text_input_event(character); Ok(()) } }