1mod input;
2mod output;
3mod renderer;
4mod textures;
5
6use std::collections::HashMap;
7
8use egui::{ClippedPrimitive, Context, TextureId, TexturesDelta, Ui};
9use raylib::prelude::*;
10
11use crate::textures::HandleTexturesErrors;
12
13#[derive(Debug)]
14pub enum EguiRaylibError {
15 HandleTexturesErrors(HandleTexturesErrors),
16}
17
18impl From<HandleTexturesErrors> for EguiRaylibError {
19 fn from(value: HandleTexturesErrors) -> Self {
20 EguiRaylibError::HandleTexturesErrors(value)
21 }
22}
23
24pub struct EguiRaylib {
25 ctx: egui::Context,
26 textures: HashMap<TextureId, Texture2D>,
27 pixels_per_point: f32,
28 last_textures_delta: Option<TexturesDelta>,
29 last_clipped_primitives: Option<Vec<ClippedPrimitive>>,
30}
31
32impl EguiRaylib {
33 pub fn new(ctx: egui::Context, pixels_per_point: f32) -> Self {
34 Self {
35 ctx,
36 textures: HashMap::new(),
37 last_textures_delta: None,
38 last_clipped_primitives: None,
39 pixels_per_point: pixels_per_point,
40 }
41 }
42
43 pub fn ctx(&self) -> &Context {
44 &self.ctx
45 }
46
47 pub fn run(&mut self, rl: &mut RaylibHandle, run_ui: impl FnMut(&mut Ui)) {
48 let raw_input: egui::RawInput = input::gather_input(rl, self.pixels_per_point);
49
50 let full_output = self.ctx.run_ui(raw_input, run_ui);
51
52 output::handle_platform_output(rl, full_output.platform_output);
53
54 self.pixels_per_point = full_output.pixels_per_point;
55 self.last_clipped_primitives = Some(
56 self.ctx
57 .tessellate(full_output.shapes, full_output.pixels_per_point),
58 );
59
60 self.last_textures_delta = Some(full_output.textures_delta);
61 }
62
63 pub fn draw(
64 &mut self,
65 d: &mut RaylibDrawHandle,
66 thread: &RaylibThread,
67 ) -> Result<(), EguiRaylibError> {
68 if let Some(textures_delta) = &self.last_textures_delta {
69 match textures::handle_textures(&mut self.textures, d, &thread, &textures_delta) {
70 Ok(()) => self.last_textures_delta = None,
71 Err(err) => return Err(err.into()),
72 }
73 }
74
75 if let Some(clipped_primitives) = self.last_clipped_primitives.take() {
76 renderer::render(
77 d,
78 self.pixels_per_point,
79 &clipped_primitives,
80 &self.textures,
81 );
82 }
83
84 Ok(())
85 }
86}
87
88impl Default for EguiRaylib {
89 fn default() -> Self {
90 Self::new(egui::Context::default(), 1.)
91 }
92}