ferravex_render/
ui.rs

1//! Quiet, readable overlay helpers shared by the examples.
2use crate::prelude::*;
3
4pub const BACKGROUND: Color = Color::from_rgba(14, 22, 35, 255);
5pub const PANEL: Color = Color::from_rgba(20, 31, 47, 242);
6pub const LINE: Color = Color::from_rgba(43, 59, 77, 255);
7pub const INK: Color = Color::from_rgba(228, 238, 242, 255);
8pub const MUTED: Color = Color::from_rgba(139, 160, 177, 255);
9pub const AMBER: Color = Color::from_rgba(247, 181, 83, 255);
10pub const CYAN: Color = Color::from_rgba(91, 213, 216, 255);
11
12/// Glyph geometry is static and needs no texture atlas or DPI prewarming.
13pub fn warm_up_font() {}
14pub fn warm_up_font_sizes(_sizes: &[u16]) {}
15
16/// Compact lab title and controls; dimensions/backend details live in the host.
17pub fn header(_section: &str, title: &str, subtitle: &str) {
18    draw_rectangle(0.0, 0.0, screen_width(), 104.0, PANEL);
19    fitted_text(title, 24.0, 45.0, screen_width() - 48.0, 28.0, INK);
20    fitted_text(subtitle, 25.0, 78.0, screen_width() - 49.0, 16.0, MUTED);
21    draw_line(24.0, 103.0, screen_width() - 24.0, 103.0, 1.0, LINE);
22}
23
24pub fn panel(rect: Rect) {
25    draw_rectangle(rect.x, rect.y, rect.w, rect.h, PANEL);
26    draw_rectangle_lines(rect.x, rect.y, rect.w, rect.h, 1.0, LINE);
27}
28
29/// Click on press; the platform host maps the primary touch to the pointer.
30pub fn button(rect: Rect, text: &str, selected: bool) -> bool {
31    let hovered = rect.contains(Vec2::from(mouse_position()));
32    draw_rectangle(
33        rect.x,
34        rect.y,
35        rect.w,
36        rect.h,
37        if selected {
38            AMBER
39        } else if hovered {
40            LINE
41        } else {
42            PANEL
43        },
44    );
45    draw_rectangle_lines(
46        rect.x,
47        rect.y,
48        rect.w,
49        rect.h,
50        1.0,
51        if selected { AMBER } else { LINE },
52    );
53    // Keep one rasterized size across responsive layouts. Scaling existing
54    // glyphs avoids atlas growth midway through a frame after a resize.
55    let font_scale =
56        ((rect.w - 12.0) / measure_text(text, None, 17, 1.0).width.max(1.0)).clamp(0.1, 1.0);
57    let dimensions = measure_text(text, None, 17, font_scale);
58    draw_text_ex(
59        text,
60        rect.x + (rect.w - dimensions.width) * 0.5,
61        rect.y + rect.h * 0.5 + 6.0,
62        TextParams {
63            font_size: 17,
64            font_scale,
65            color: if selected { BACKGROUND } else { INK },
66        },
67    );
68    hovered && is_mouse_button_pressed(MouseButton::Left)
69}
70
71fn fitted_text(text: &str, x: f32, y: f32, width: f32, size: f32, color: Color) {
72    let measured = measure_text(text, None, size as u16, 1.0).width;
73    draw_text_ex(
74        text,
75        x,
76        y,
77        TextParams {
78            font_size: size as u16,
79            font_scale: (width.max(1.0) / measured.max(1.0)).min(1.0),
80            color,
81        },
82    );
83}
84
85pub fn stat(x: f32, y: f32, label: &str, value: &str) {
86    draw_text(label, x, y, 14.0, MUTED);
87    draw_text(value, x, y + 24.0, 25.0, INK);
88}