cyb/prysm/molecules/rs/table.rs

use bevy::prelude::*;
use tape::{Chunk, sigil, render, decode_nested};
use crate::theme;

#[derive(Component)]
pub struct TableRoot;

pub fn spawn(commands: &mut Commands, parent: Entity, chunk: &Chunk) -> Entity {
    let rows = decode_nested(&chunk.payload);
    let mut headers: Vec<String>       = Vec::new();
    let mut data_rows: Vec<Vec<String>> = Vec::new();

    for row in &rows {
        if row.sigil == sigil::FAS && row.render == render::STRUCT {
            for h in decode_nested(&row.payload) {
                headers.push(String::from_utf8_lossy(&h.payload).into_owned());
            }
        } else if row.sigil == sigil::COL && row.render == render::STRUCT {
            let cells = decode_nested(&row.payload);
            data_rows.push(cells.iter()
                .map(|c| String::from_utf8_lossy(&c.payload).into_owned())
                .collect());
        }
    }

    let root = commands.spawn((
        TableRoot,
        Node {
            flex_direction: FlexDirection::Column,
            width: Val::Percent(100.0),
            margin: UiRect::vertical(Val::Px(4.0)),
            ..default()
        },
        ChildOf(parent),
    )).id();

    if !headers.is_empty() {
        let header_row = commands.spawn((
            Node {
                flex_direction: FlexDirection::Row,
                width: Val::Percent(100.0),
                padding: UiRect::axes(Val::Px(4.0), Val::Px(3.0)),
                border: UiRect::bottom(Val::Px(1.0)),
                ..default()
            },
            BackgroundColor(Color::srgba(1.0, 1.0, 1.0, 0.06)),
            BorderColor::all(Color::srgba(1.0, 1.0, 1.0, 0.12)),
            ChildOf(root),
        )).id();

        for h in &headers {
            spawn_cell(commands, header_row, h, true);
        }
    }

    for (i, row) in data_rows.iter().enumerate() {
        let bg = if i % 2 == 0 { Color::NONE } else { Color::srgba(1.0, 1.0, 1.0, 0.03) };
        let data_row = commands.spawn((
            Node {
                flex_direction: FlexDirection::Row,
                width: Val::Percent(100.0),
                padding: UiRect::axes(Val::Px(4.0), Val::Px(2.0)),
                ..default()
            },
            BackgroundColor(bg),
            ChildOf(root),
        )).id();

        for cell in row {
            spawn_cell(commands, data_row, cell, false);
        }
    }

    root
}

fn spawn_cell(commands: &mut Commands, row: Entity, text: &str, is_header: bool) {
    let (size, color) = if is_header {
        (theme::CAPTION, Color::srgba(0.75, 0.75, 0.80, 1.0))
    } else {
        (theme::BODY, theme::TEXT_PRIMARY)
    };
    commands.spawn((
        Text::new(text.to_string()),
        TextFont { font_size: size, ..default() },
        TextColor(color),
        Node {
            flex_grow: 1.0,
            overflow: Overflow::clip(),
            ..default()
        },
        ChildOf(row),
    ));
}

Homonyms

cyberia/src/components/table.rs
cyb/wysm/crates/c_api/src/table.rs
cyb/wysm/crates/c_api/src/types/table.rs

Graph