Data display · DescriptionList::text rows speak their label and value; Git · commit rows speak their refs; shorter comments
This commit is contained in:
4 files changed
+45
-23
No files matched your search
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user