Skip to main content

ui_widgets/
ui_widgets.rs

1//! # Modern UI Widgets Showcase
2//!
3//! Demonstrates every UI primitive and interactive widget with the modern UGUI system.
4
5use jengine::engine::{Color, Game, jEngine, KeyCode};
6use jengine::renderer::text::Font;
7use jengine::ui::{BorderStyle, Padding};
8use jengine::ui::modern::Panel;
9use jengine::ui::widgets::{Dropdown, InputBox, ToggleSelector};
10use jengine::{DEFAULT_FONT_METADATA, DEFAULT_TILE_H, DEFAULT_TILE_W, DEFAULT_TILESET};
11
12const BG:     Color = Color([0.04, 0.06, 0.06, 1.0]);
13const BORDER: Color = Color([0.25, 0.65, 0.50, 1.0]);
14const HEAD:   Color = Color([1.00, 0.95, 0.20, 1.0]);
15const BODY:   Color = Color([0.75, 0.85, 0.80, 1.0]);
16const DIM:    Color = Color([0.40, 0.50, 0.48, 1.0]);
17
18struct ModernWidgetsDemo {
19    font_loaded: bool,
20    dropdown:    Dropdown,
21    toggle:      ToggleSelector,
22    input:       InputBox,
23    hp_pct:      f32,
24    tick:        u32,
25}
26
27impl ModernWidgetsDemo {
28    fn new() -> Self {
29        Self {
30            font_loaded: false,
31            dropdown: Dropdown::new(["Modern Panel", "SDF Borders", "Smooth Corners", "Glassmorphism"]),
32            toggle: ToggleSelector::new(["Dark Theme", "Light Theme", "High Contrast"]),
33            input: InputBox::new(24),
34            hp_pct: 0.75,
35            tick: 0,
36        }
37    }
38}
39
40impl Game for ModernWidgetsDemo {
41    fn update(&mut self, engine: &mut jEngine) {
42        if engine.is_key_pressed(KeyCode::Escape) { engine.request_quit(); }
43        self.tick += 1;
44        self.hp_pct = (self.tick as f32 * 0.01).sin() * 0.5 + 0.5;
45    }
46
47    fn render(&mut self, engine: &mut jEngine) {
48        if !self.font_loaded {
49            if let Ok(font) = Font::from_mtsdf_json(DEFAULT_FONT_METADATA) {
50                engine.ui.text.set_font(font);
51            }
52            self.font_loaded = true;
53        }
54
55        engine.clear();
56        let tw = engine.tile_width() as f32;
57        let th = engine.tile_height() as f32;
58        let sw = engine.grid_width() as f32 * tw;
59        let sh = engine.grid_height() as f32 * th;
60
61        engine.ui.ui_rect(0.0, 0.0, sw, sh, BG);
62
63        // ── Title ──
64        Panel::new(0.0, 0.0, sw, 50.0).with_color(Color([0.08, 0.12, 0.12, 1.0])).with_border(BORDER, 1.0).draw(engine);
65        engine.ui.ui_text(20.0, 15.0, "JENGINE — Modern UGUI Showcase", HEAD, Color::TRANSPARENT, Some(24.0));
66
67        let col_w = sw * 0.5;
68        let start_y = 70.0;
69
70        // ── Left: Primitives ──
71        let lx = 20.0;
72        engine.ui.ui_text(lx, start_y, "MODERN PRIMITIVES", HEAD, Color::TRANSPARENT, Some(18.0));
73        
74        // Rounded Box
75        engine.ui.ui_text(lx, start_y + 40.0, "Panel with 12px corners:", DIM, Color::TRANSPARENT, Some(14.0));
76        Panel::new(lx, start_y + 60.0, col_w - 40.0, 80.0)
77            .with_color(Color([0.1, 0.15, 0.15, 1.0]))
78            .with_border(BORDER, 1.0)
79            .with_radius(12.0)
80            .draw(engine);
81        engine.ui.ui_text(lx + 20.0, start_y + 90.0, "Smooth SDF edges at any resolution.", BODY, Color::TRANSPARENT, Some(14.0));
82
83        // Progress Bar
84        engine.ui.ui_text(lx, start_y + 160.0, "Procedural Progress Bar:", DIM, Color::TRANSPARENT, Some(14.0));
85        Panel::new(lx, start_y + 180.0, col_w - 40.0, 25.0).with_color(Color([0.05, 0.1, 0.05, 1.0])).with_radius(12.5).draw(engine);
86        Panel::new(lx, start_y + 180.0, (col_w - 40.0) * self.hp_pct, 25.0).with_color(Color([0.2, 0.8, 0.3, 1.0])).with_radius(12.5).draw(engine);
87
88        // Pattern
89        engine.ui.ui_text(lx, start_y + 220.0, "Procedural Pattern (Crosshatch):", DIM, Color::TRANSPARENT, Some(14.0));
90        Panel::new(lx, start_y + 240.0, col_w - 40.0, 60.0)
91            .with_color(Color([0.1, 0.1, 0.2, 0.5]))
92            .with_border(Color::CYAN, 1.0)
93            .with_pattern(1, 4.0)
94            .with_radius(8.0)
95            .draw(engine);
96
97        // ── Right: Interactive ──
98        let rx = col_w + 20.0;
99        let ctrl_w = col_w - 40.0;
100        engine.ui.ui_text(rx, start_y, "INTERACTIVE WIDGETS", HEAD, Color::TRANSPARENT, Some(18.0));
101
102        engine.ui.ui_text(rx, start_y + 40.0, "Dropdown:", DIM, Color::TRANSPARENT, Some(14.0));
103        self.dropdown.draw(engine, rx, start_y + 60.0, ctrl_w);
104
105        engine.ui.ui_text(rx, start_y + 120.0, "ToggleSelector:", DIM, Color::TRANSPARENT, Some(14.0));
106        self.toggle.draw(engine, rx, start_y + 140.0, ctrl_w);
107
108        engine.ui.ui_text(rx, start_y + 200.0, "InputBox:", DIM, Color::TRANSPARENT, Some(14.0));
109        self.input.draw(engine, rx, start_y + 220.0, ctrl_w);
110    }
111}
112
113fn main() {
114    jEngine::builder()
115        .with_title("jengine — Modern Widgets")
116        .with_size(1280, 720)
117        .with_tileset(DEFAULT_TILESET, DEFAULT_TILE_W, DEFAULT_TILE_H)
118        .run(ModernWidgetsDemo::new());
119}