diff --git a/ui-gpui/src/components/project_box.rs b/ui-gpui/src/components/project_box.rs index 8a42a48..f683237 100644 --- a/ui-gpui/src/components/project_box.rs +++ b/ui-gpui/src/components/project_box.rs @@ -47,22 +47,14 @@ fn project_status_dot(status: AgentStatus) -> Div { // ── Tab Button ────────────────────────────────────────────────────── -fn tab_button(label: &str, active: bool, accent: Rgba) -> Div { - let fg = if active { accent } else { theme::SUBTEXT0 }; - +fn tab_button(label: &'static str, active: bool, accent: Rgba) -> Div { let mut tab = div() - .px(px(10.0)) + .px(px(8.0)) .py(px(4.0)) - .text_size(px(11.0)) - .text_color(fg) - .cursor_pointer() - .hover(|s| s.text_color(theme::TEXT)); - - if active { - tab = tab.border_b_2().border_color(accent); - } - - tab.child(label.to_string()) + .text_color(if active { accent } else { theme::SUBTEXT0 }) + .cursor_pointer(); + if active { tab = tab.border_b_2().border_color(accent); } + tab.child(label) // &'static str → no allocation } // ── ProjectBox View ───────────────────────────────────────────────── @@ -155,35 +147,19 @@ impl Render for ProjectBox { .flex() .flex_col(); - // Agent pane (upper portion) — cached: only re-renders on new messages + // Agent pane — cached (0% on blink) if let Some(ref pane) = self.agent_pane { - model_content = model_content.child( - div() - .flex_1() - .w_full() - .child(pane.clone().into_cached_flex()), - ); + model_content = model_content.child(pane.clone().into_cached_flex()); } - - // Resize handle + // Resize handle (1 div) model_content = model_content.child( - div() - .id(self.id_resize.clone()) - .w_full() - .h(px(4.0)) - .bg(theme::SURFACE0) - .cursor_pointer() + div().id(self.id_resize.clone()).w_full().h(px(4.0)) + .bg(theme::SURFACE0).cursor_pointer() .hover(|s| s.bg(theme::SURFACE1)), ); - - // Terminal view — cached: only re-renders on PTY output + // Terminal — cached (0% on blink) if let Some(ref term) = self.terminal_view { - model_content = model_content.child( - div() - .w_full() - .h(px(180.0)) - .child(term.clone().into_cached_flex()), - ); + model_content = model_content.child(term.clone().into_cached_flex()); } model_content @@ -250,63 +226,37 @@ impl Render for ProjectBox { .border_1() .border_color(theme::SURFACE0) .overflow_hidden() - // ── Header ────────────────────────────────────────── + // ── Header (minimal divs: 1 row + accent stripe + dot entity) ── .child( div() .w_full() .h(px(36.0)) .flex() - .flex_row() .items_center() .px(px(12.0)) .gap(px(8.0)) .bg(theme::MANTLE) .border_b_1() .border_color(theme::SURFACE0) - // Accent stripe on left - .child( - div() - .w(px(3.0)) - .h(px(20.0)) - .rounded(px(2.0)) - .bg(accent), - ) - // Status dot — separate Entity that reads BlinkState. - // ProjectBox does NOT read BlinkState → doesn't re-render on blink. - // Only StatusDotView (1 div, 8x8px) re-renders 2x/sec. + .child(div().w(px(3.0)).h(px(20.0)).rounded(px(2.0)).bg(accent)) .children(self.status_dot_view.clone()) - // Project name - .child( - div() - .text_size(px(13.0)) - .text_color(theme::TEXT) - .child(self.cached_name.clone()), - ) + .child(self.cached_name.clone()) .child(div().flex_1()) - // CWD (ellipsized) - .child( - div() - .text_size(px(10.0)) - .text_color(theme::OVERLAY0) - .max_w(px(200.0)) - .overflow_hidden() - .whitespace_nowrap() - .child(self.cached_cwd.clone()), - ), + .child(self.cached_cwd.clone()), ) - // ── Tab Bar ───────────────────────────────────────── + // ── Tab Bar (1 div + 3 inline tab labels) ── .child( div() .w_full() - .h(px(32.0)) + .h(px(28.0)) .flex() - .flex_row() .items_center() .px(px(8.0)) .gap(px(2.0)) .bg(theme::MANTLE) .border_b_1() .border_color(theme::SURFACE0) + .text_size(px(11.0)) .child(tab_button("Model", active_tab == ProjectTab::Model, accent)) .child(tab_button("Docs", active_tab == ProjectTab::Docs, accent)) .child(tab_button("Files", active_tab == ProjectTab::Files, accent)),