feat: add Dioxus and GPUI UI prototypes for framework comparison
Dioxus (ui-dioxus/): 2,169 lines, WebView mode (same wry as Tauri), Catppuccin theme, 12 components, agor-core integration, compiles clean. Evolution path — keeps xterm.js, gradual migration from Tauri. GPUI (ui-gpui/): 2,490 lines, GPU-accelerated rendering, alacritty_terminal for native terminal, 17 files, Catppuccin palette, demo data. Revolution path — pure Rust UI, 120fps target, no WebView. Both are standalone (not in workspace), share agor-core backend. Created for side-by-side comparison to inform framework decision.
This commit is contained in:
parent
90c7315336
commit
f3d2ca78ba
34 changed files with 17467 additions and 0 deletions
80
ui-gpui/src/components/project_grid.rs
Normal file
80
ui-gpui/src/components/project_grid.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//! ProjectGrid: flex-wrap grid of ProjectBox cards.
|
||||
//!
|
||||
//! Lays out projects in a responsive grid that wraps when the window is wide
|
||||
//! enough for multiple columns.
|
||||
|
||||
use gpui::*;
|
||||
|
||||
use crate::components::project_box::ProjectBox;
|
||||
use crate::state::AppState;
|
||||
use crate::theme;
|
||||
|
||||
// ── ProjectGrid View ────────────────────────────────────────────────
|
||||
|
||||
pub struct ProjectGrid {
|
||||
app_state: Entity<AppState>,
|
||||
/// One ProjectBox entity per project.
|
||||
project_boxes: Vec<Entity<ProjectBox>>,
|
||||
}
|
||||
|
||||
impl ProjectGrid {
|
||||
pub fn new(app_state: Entity<AppState>, cx: &mut Context<Self>) -> Self {
|
||||
// Clone projects out of state to avoid borrowing cx through app_state
|
||||
let projects: Vec<_> = {
|
||||
let state = app_state.read(cx);
|
||||
state.projects.clone()
|
||||
};
|
||||
|
||||
let project_boxes: Vec<Entity<ProjectBox>> = projects
|
||||
.into_iter()
|
||||
.map(|proj| {
|
||||
cx.new(|cx| {
|
||||
let mut pb = ProjectBox::new(proj);
|
||||
pb.init_subviews(cx);
|
||||
pb
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
app_state,
|
||||
project_boxes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ProjectGrid {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let mut grid = div()
|
||||
.id("project-grid")
|
||||
.flex_1()
|
||||
.w_full()
|
||||
.h_full()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.flex_wrap()
|
||||
.gap(px(8.0))
|
||||
.p(px(8.0))
|
||||
.bg(theme::CRUST)
|
||||
.overflow_y_scroll();
|
||||
|
||||
for pb in &self.project_boxes {
|
||||
grid = grid.child(pb.clone());
|
||||
}
|
||||
|
||||
if self.project_boxes.is_empty() {
|
||||
grid = grid.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.text_size(px(16.0))
|
||||
.text_color(theme::OVERLAY0)
|
||||
.child("No projects. Press Ctrl+N to add one."),
|
||||
);
|
||||
}
|
||||
|
||||
grid
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue