Skip to main content

oxide_gui_core/
backend.rs

1//! `Backend` — the single trait that every platform must implement.
2//!
3//! A backend owns the framebuffer (or window) and provides three core
4//! operations: draw into the buffer, flush the buffer to the screen, and
5//! return the next pending input event.
6//!
7//! Default implementations of `draw_char` and `draw_text` are provided using
8//! the embedded bitmap font in `font.rs`.  A backend can override these for
9//! hardware-accelerated text.
10//!
11//! ## Implementing a new backend
12//!
13//! ```rust,ignore
14//! struct MyBackend { /* framebuffer pointer, width, height */ }
15//!
16//! impl Backend for MyBackend {
17//!     fn width(&self)  -> u32 { … }
18//!     fn height(&self) -> u32 { … }
19//!
20//!     fn fill_rect(&mut self, x: u32, y: u32, w: u32, h: u32, color: Color) {
21//!         // write pixels into your framebuffer
22//!     }
23//!
24//!     fn present(&mut self) {
25//!         // flush back-buffer to screen (or no-op for direct FB)
26//!     }
27//!
28//!     fn poll_event(&mut self) -> Option<Event> {
29//!         // translate native input into oxide-gui Event
30//!         None
31//!     }
32//! }
33//! ```
34
35use crate::color::Color;
36use crate::event::Event;
37use crate::font;
38
39pub trait Backend {
40    // ── Required ───────────────────────────────────────────────────────────
41
42    /// Framebuffer width in pixels.
43    fn width(&self) -> u32;
44
45    /// Framebuffer height in pixels.
46    fn height(&self) -> u32;
47
48    /// Fill a rectangle with a solid color.
49    /// Out-of-bounds coordinates should be clipped silently.
50    fn fill_rect(&mut self, x: u32, y: u32, w: u32, h: u32, color: Color);
51
52    /// Flush the back-buffer to the physical display.
53    fn present(&mut self);
54
55    /// Return the next pending input event, or `None` if the queue is empty.
56    fn poll_event(&mut self) -> Option<Event>;
57
58    // ── Provided (override for hardware acceleration) ──────────────────────
59
60    /// Draw a single character at `(x, y)` using the embedded bitmap font.
61    fn draw_char(&mut self, x: u32, y: u32, ch: char, color: Color) {
62        font::render_char(self, x, y, ch, color);
63    }
64
65    /// Draw a string at `(x, y)` advancing by `font::CHAR_W` per glyph.
66    fn draw_text(&mut self, x: u32, y: u32, text: &str, color: Color) {
67        let mut cx = x;
68        for ch in text.chars() {
69            if cx + font::CHAR_W > self.width() { break; }
70            self.draw_char(cx, y, ch, color);
71            cx += font::CHAR_W;
72        }
73    }
74
75    /// Draw a 1-pixel horizontal rule.
76    fn hline(&mut self, x: u32, y: u32, w: u32, color: Color) {
77        self.fill_rect(x, y, w, 1, color);
78    }
79
80    /// Draw a 1-pixel vertical rule.
81    fn vline(&mut self, x: u32, y: u32, h: u32, color: Color) {
82        self.fill_rect(x, y, 1, h, color);
83    }
84
85    /// Draw a hollow rectangle (border only, 1-pixel thick).
86    fn draw_rect(&mut self, x: u32, y: u32, w: u32, h: u32, color: Color) {
87        self.hline(x, y,           w, color);
88        self.hline(x, y + h - 1,   w, color);
89        self.vline(x,           y, h, color);
90        self.vline(x + w - 1,   y, h, color);
91    }
92
93    /// Clear the entire framebuffer to `color`.
94    fn clear(&mut self, color: Color) {
95        let (w, h) = (self.width(), self.height());
96        self.fill_rect(0, 0, w, h, color);
97    }
98
99    /// Return `(width, height)` as a tuple.
100    fn size(&self) -> (u32, u32) { (self.width(), self.height()) }
101}