nandi/jolt-nativepublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Bring vidya in cfd3e36 · on main · nandi · 19d ago
lib.rs · 133 lines · 4.8 KBRust Blame HistoryRaw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! **Vidya** — theme layer on top of [egui].
//!
//! Palette and spacing track GNOME HIG / libadwaita *feel* without linking GTK
//! or using that name in the public API. Dark is the default.
//!
//! On Android (edge-to-edge), call [`reserve_system_chrome`] once per frame
//! **before** other panels, or use [`top_header`] so content cannot sit under
//! the system status / navigation bars.
//!
//! Layout composition: prefer [`page_body`] / [`card`] / [`compact_card`] /
//! [`pack`] / [`vstack`] / [`lead_trail`] / [`two_col`] / [`grid_cols`] /
//! [`metric_bps`] so apps avoid width overflow, justified-gap stretch, and
//! metric “waterfall” columns.
//!
//! **Top-level application UI is grid-only:** [`central_page`] / [`page_body`]
//! take a [`GridCtx`] callback (not a free-stack `Ui`). Compose with
//! [`GridCtx::section`] / `g.row`; nest cards and nested grids inside cells.
//!
//! ```ignore
//! vidya::central_page(ctx, &th, "main", |g| {
//!     g.section(|ui| { /* … */ });
//!     g.section(|ui| { /* … */ });
//! });
//! ```
//!
//! Nested / table Grid DSL:
//! ```ignore
//! vidya::grid_cols(ui, &th, "procs", &[ColSpec::Flex, ColSpec::MetricBps], |g| {
//!     g.row(|r| { r.heading("Name"); r.heading("Write"); });
//!     g.row(|r| { r.text(name); r.metric_bps(rate); });
//! });
//! ```
//!
//! Window icon (embed a PNG with `include_bytes!`):
//! ```ignore
//! use egui::ViewportBuilder;
//! use vidya::with_app_icon_id;
//!
//! let viewport = with_app_icon_id(
//!     ViewportBuilder::default().with_title("usage"),
//!     "usage", // Wayland app_id ↔ .desktop StartupWMClass
//!     include_bytes!("../assets/usage-256.png"),
//! );
//! ```
//!
//! ```ignore
//! use vidya::{apply_dark, Theme};
//!
//! apply_dark(ctx);
//! if vidya::primary_button(ui, &Theme::dark(), "Open").clicked() { /* … */ }
//! ```

mod app_icon;
mod chrome;
mod fonts;
mod hotkeys;
mod icons;
mod layout;
mod theme;
mod video;

pub use app_icon::{
    icon_data_from_png, try_with_app_icon, try_with_app_icon_id, with_app_icon, with_app_icon_id,
    AppIconError,
};
#[cfg(target_os = "android")]
pub use chrome::sync_system_chrome_from_android;
pub use chrome::{
    dialog, reserve_system_chrome, set_system_chrome, system_chrome, top_header, SystemChrome,
};
pub use fonts::install_symbol_font;
pub use hotkeys::{
    command_glyph, command_pressed, command_shift_shortcut_label, command_shortcut_label,
    consume_command, consume_command_shift, consume_escape, escape_label, is_macos,
};
pub use icons::{
    emoji_icon, emoji_icon_colored, emoji_pack_len, has_emoji_icon, icon, icon_colored,
    icon_for_emoji, normalize_emoji, paint_emoji_in, paint_icon, paint_icon_in, reaction_chip,
    reaction_chip_sized, twemoji_key, Icon,
};
pub use layout::{
    card, card_frame_chrome_x, central_page, central_page_cols, compact_card, data_table,
    default_min_col, distribute_col_max, fill_width, fit_width, format_bps, format_rate, grid,
    grid_cols, grid_cols_with, hflow, inset_row, lead_trail, measure_mono_caption, metric_bps,
    metric_cell, metric_cell_px, metric_rate, pack, pad_metric, page_body, page_body_cols,
    page_scroll, side_by_side, table_metric, table_text, table_text_capped, two_col, vstack, Col,
    ColKind, ColSpec, GridCtx, GridOpts, RowDsl, FLEX_COL_MIN_PX, METRIC_BPS_CHARS,
    METRIC_RATE_CHARS,
};
pub use theme::{
    body, button, checkbox, destructive_button, dim_label, icon_button, primary_button, status_dot,
    text_field_multiline, text_field_singleline, title, title_2, Mode, Palette, Spacing, Theme,
    TypeScale,
};
pub use video::{video_player, VideoPlayerAction, VideoPlayerOpts, VideoPlayerState};

use egui::{Context, FontFamily, FontId, Style, TextStyle};

/// Install palette + spacing + text styles on the egui context.
///
/// Also registers a small symbol-font fallback so punctuation like `→` / `●` /
/// `▾` / `▴` and block/box art (`█▄▀░`) do not render as hollow boxes on Android.
pub fn apply(ctx: &Context, theme: &Theme) {
    install_symbol_font(ctx);
    ctx.set_visuals(theme.visuals());
    ctx.set_style(theme.style());
}

/// Dark shell (default).
pub fn apply_dark(ctx: &Context) {
    apply(ctx, &Theme::dark());
}

/// Light shell.
pub fn apply_light(ctx: &Context) {
    apply(ctx, &Theme::light());
}

/// Map type scale onto egui text styles.
pub fn install_text_styles(style: &mut Style, scale: &TypeScale) {
    use FontFamily::Proportional;
    style.text_styles = [
        (TextStyle::Small, FontId::new(scale.caption, Proportional)),
        (TextStyle::Body, FontId::new(scale.body, Proportional)),
        (TextStyle::Button, FontId::new(scale.body, Proportional)),
        (TextStyle::Heading, FontId::new(scale.title, Proportional)),
        (
            TextStyle::Monospace,
            FontId::new(scale.body, FontFamily::Monospace),
        ),
    ]
    .into();
}