Data display · DescriptionList::text rows speak their label and value; Git · commit rows speak their refs; shorter comments

This commit is contained in:
ZacharyZhang-NY committed 2026-10-07 01:52:19 -04:00
1 parent 3fc5a46a13
commit d9cbe996a5
4 files changed
+45 -23

No files matched your search

+24 -7
View File
@@ -1,6 +1,6 @@
use gpui::{
AnyElement, App, ElementId, FontWeight, InteractiveElement, IntoElement, ParentElement,
RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div, prelude::*,
RenderOnce, Role, SharedString, StatefulInteractiveElement, Styled, Window, div, prelude::*,
};
use crate::{
@@ -9,10 +9,11 @@ use crate::{
theme::{ActiveTheme, ControlSize, TextSize},
};
/// Labels and their values, one pair a row with the labels in a quiet column, or stacked with each label above its value. A value short of room drops under its label.
/// Labels and their values, side by side or stacked.
#[derive(IntoElement, Default)]
pub struct DescriptionList {
items: Vec<(SharedString, AnyElement)>,
/// Label, value, and the value as words when text.
items: Vec<(SharedString, AnyElement, Option<SharedString>)>,
stacked: bool,
lined: bool,
}
@@ -22,9 +23,18 @@ impl DescriptionList {
Self::default()
}
/// A label, and its value: text, or any element such as a badge.
/// A label and its value, any element.
pub fn item(mut self, label: impl Into<SharedString>, value: impl IntoElement) -> Self {
self.items.push((label.into(), value.into_any_element()));
self.items
.push((label.into(), value.into_any_element(), None));
self
}
/// A label and its text, both spoken.
pub fn text(mut self, label: impl Into<SharedString>, value: impl Into<SharedString>) -> Self {
let value = value.into();
self.items
.push((label.into(), value.clone().into_any_element(), Some(value)));
self
}
@@ -54,9 +64,16 @@ impl RenderOnce for DescriptionList {
self.items
.into_iter()
.enumerate()
.map(|(ix, (label, value))| {
.map(|(ix, (label, value, spoken))| {
let said =
spoken.map(|spoken| SharedString::from(format!("{label}: {spoken}")));
let label = div().text_color(colors.fg_muted).child(label);
div()
.id(ElementId::Name(
said.clone()
.unwrap_or_else(|| format!("description-{ix}").into()),
))
.when_some(said, |row, said| row.role(Role::Label).aria_label(said))
.flex()
.when(stacked, |row| row.flex_col().gap_0p5())
.when(!stacked, |row| {
@@ -114,7 +131,7 @@ impl PropertyGroup {
}
}
/// An inspector's table: groups that fold, each row a name and its editor. The owner supplies the editors and keeps the values.
/// An inspector's table of folding groups of named editors.
#[derive(IntoElement)]
pub struct PropertyGrid {
id: ElementId,
+5 -5
View File
@@ -14,7 +14,7 @@ use crate::{
typography::{Ellipsis, LEADING},
};
/// Who last changed lines: the commit, its author, when and its subject, and its age from 0, newest, to 1, oldest.
/// Who last changed lines; age 0 newest, 1 oldest.
#[derive(Clone, Debug, PartialEq)]
pub struct Blame {
pub commit: SharedString,
@@ -24,7 +24,7 @@ pub struct Blame {
pub age: f32,
}
/// Consecutive lines from one change, as the change's index and the lines.
/// Consecutive lines from one change, with that change's index.
pub(crate) fn runs(owners: &[Option<usize>]) -> Vec<(Option<usize>, Range<usize>)> {
let mut out: Vec<(Option<usize>, Range<usize>)> = Vec::new();
for (line, owner) in owners.iter().enumerate() {
@@ -36,7 +36,7 @@ pub(crate) fn runs(owners: &[Option<usize>]) -> Vec<(Option<usize>, Range<usize>
out
}
/// Who last changed a line, set after its code in quiet words: the author, when, and the subject.
/// Who last changed a line, quietly after its code.
#[derive(IntoElement)]
pub struct GitBlameAnnotation {
blame: Blame,
@@ -65,7 +65,7 @@ impl RenderOnce for GitBlameAnnotation {
type OnCommit = Rc<dyn Fn(&SharedString, &mut Window, &mut App)>;
/// Code with who last changed each run of lines beside it: author, when and subject on a run's first line, a bar that fades with age. The current line shows its annotation; a press on a run picks its commit.
/// Code beside each run's last author; a press picks it.
#[derive(IntoElement)]
pub struct BlameView {
id: ElementId,
@@ -77,7 +77,7 @@ pub struct BlameView {
}
impl BlameView {
/// `owners` holds, for each line of `code`, its entry in `blames`.
/// `owners`: each line's entry in `blames`.
pub fn new(
id: impl Into<ElementId>,
code: impl Into<SharedString>,
+7 -7
View File
@@ -16,7 +16,7 @@ use crate::{
typography::{Ellipsis, tabular},
};
/// A changed file: its path, its status, and the lines it added and removed.
/// A changed file: path, status, and lines changed.
#[derive(Clone, Debug, PartialEq)]
pub struct Changed {
pub path: SharedString,
@@ -37,7 +37,7 @@ pub enum ChangeAction {
type OnAction = Rc<dyn Fn(&SharedString, ChangeSection, ChangeAction, &mut Window, &mut App)>;
type OnAll = Rc<dyn Fn(bool, &mut Window, &mut App)>;
/// Which part of the work tree a file is listed in.
/// The part of the work tree listing a file.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChangeSection {
Conflicted,
@@ -59,7 +59,7 @@ impl ChangeSection {
}
}
/// Files changed in the work tree, kept apart as conflicted, staged, changed, untracked and ignored: each with its status, its folder and what it changed; open, discard, stage or unstage it, or all at once.
/// Work tree files in five sections, each with its actions.
#[derive(IntoElement)]
pub struct ChangesList {
id: ElementId,
@@ -98,7 +98,7 @@ impl ChangesList {
self
}
/// Files Git does not track yet; staged or discarded one by one.
/// Untracked files, staged one by one.
pub fn untracked(mut self, files: impl IntoIterator<Item = Changed>) -> Self {
self.untracked = files.into_iter().collect();
self
@@ -124,7 +124,7 @@ impl ChangesList {
self
}
/// Called with true to stage every change, false to unstage every staged one.
/// True stages every change; false unstages every staged one.
pub fn on_all(mut self, handler: impl Fn(bool, &mut Window, &mut App) + 'static) -> Self {
self.on_all = Some(Rc::new(handler));
self
@@ -330,12 +330,12 @@ impl RenderOnce for ChangesList {
}
}
/// Characters a subject reads well within, and the most it should take.
/// A subject's comfortable length, and its most.
const SUBJECT: (usize, usize) = (50, 72);
type Run = Rc<dyn Fn(&mut Window, &mut App)>;
/// A commit message: its subject counted against fifty, a body, and the commit button, which waits for a subject and something staged. Cmd-Enter commits; amend takes the last commit's place.
/// A commit message, its counted subject, body, and button.
#[derive(IntoElement)]
pub struct CommitInput {
id: ElementId,
+9 -4
View File
@@ -14,7 +14,7 @@ use crate::{
typography::Ellipsis,
};
/// A commit as lists show it: id, parents first-parent first, subject, author, when, and the refs on it.
/// A commit as lists show it; first parent first.
#[derive(Clone, Debug, PartialEq)]
pub struct Commit {
pub id: SharedString,
@@ -27,7 +27,7 @@ pub struct Commit {
type OnPick = Rc<dyn Fn(&SharedString, &mut Window, &mut App)>;
/// One commit in a row: its author's initials, its subject and the refs on it, its short id, and when.
/// One commit in a row: author, subject, refs, id, when.
#[derive(IntoElement)]
pub struct CommitItem {
id: ElementId,
@@ -67,10 +67,15 @@ impl RenderOnce for CommitItem {
let commit = self.commit;
let short: String = commit.id.chars().take(7).collect();
let (pick, picked) = (self.on_pick, commit.id.clone());
// Refs are tags drawn only; the name carries them.
let spoken: SharedString = match commit.refs.is_empty() {
true => commit.subject.clone(),
false => format!("{} ({})", commit.subject, commit.refs.join(", ")).into(),
};
div()
.id(self.id.clone())
.role(Role::ListItem)
.aria_label(commit.subject.clone())
.aria_label(spoken)
.aria_selected(self.selected)
.tab_index(0)
.focus_ring(cx)
@@ -185,7 +190,7 @@ impl CommitList {
/// Rows from the end that ask for more.
const NEAR_END: usize = 20;
/// Paints one row's lanes, `span` lanes wide so every row lines up: strokes into and out of its commit, lanes passing it, and the commit's dot.
/// Paints one row's lanes, `span` wide so rows line up.
fn lanes_cell(
row: GraphRow,
span: usize,