Theme · Platform: one platform for buttons and caps, icon themes, frosted panes

theme::Platform moves out of typography and shell's ControlsStyle folds
into it; the theme's platform starts as the system's. Window buttons Ely
draws, the title bar's layout and every key cap follow it, secondary
included, through typography::keys::keystroke; a title bar whose buttons
the OS draws follows the OS. primitives::IconTheme lays an owner's rules
by file name and extension over Ely's map, for every file icon.
shell::Vibrancy fills a pane with the palette's new glass, translucent
so a window opened Blurred shows its backdrop, solid under high contrast.
gpui 0.2.2 has no Mica; that line stays blocked.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-27 17:41:15 -04:00
1 parent 7f2205c811
commit d3cfc71ead
30 files changed
+593 -162

No files matched your search

+10 -5
View File
@@ -8,7 +8,7 @@ use gpui::{
use super::FileIcon;
use crate::{
lists::{Folder, Tree, TreeNode},
primitives::{IconName, file_icon},
primitives::{IconName, IconTheme, icon_theme},
theme::{ActiveTheme, IconSize, TextSize},
typography::{MiddleEllipsis, format},
};
@@ -32,14 +32,19 @@ pub(crate) fn saving(size: u64, packed: u64) -> u64 {
}
/// Nodes for `folder` under `prefix`, folders first, then files, each by name; and the bytes it holds.
fn nodes(folder: &Folder, prefix: &str, entries: &[ArchiveEntry]) -> (Vec<TreeNode>, u64) {
fn nodes(
folder: &Folder,
prefix: &str,
entries: &[ArchiveEntry],
icons: &IconTheme,
) -> (Vec<TreeNode>, u64) {
let mut out = Vec::new();
let mut held = 0;
let mut folders: Vec<_> = folder.folders.iter().collect();
folders.sort_by_key(|(name, _)| name.to_lowercase());
for (name, inner) in folders {
let path = format!("{prefix}{name}");
let (children, bytes) = nodes(inner, &format!("{path}/"), entries);
let (children, bytes) = nodes(inner, &format!("{path}/"), entries, icons);
held += bytes;
let node = TreeNode::new(path, name.clone())
.icon(IconName::Folder)
@@ -63,7 +68,7 @@ fn nodes(folder: &Folder, prefix: &str, entries: &[ArchiveEntry]) -> (Vec<TreeNo
);
out.push(
TreeNode::new(path, name.clone())
.icon(file_icon(name))
.icon(icons.file(name))
.note(note),
);
}
@@ -115,7 +120,7 @@ impl RenderOnce for ArchiveViewer {
let theme = cx.theme();
let colors = &theme.colors;
let folders = Folder::of(self.entries.iter().map(|entry| entry.path.as_ref()));
let (nodes, size) = nodes(&folders, "", &self.entries);
let (nodes, size) = nodes(&folders, "", &self.entries, icon_theme(cx));
let packed: u64 = self.entries.iter().map(|entry| entry.packed).sum();
let top: Vec<SharedString> = folders
.folders
+17 -7
View File
@@ -1,4 +1,4 @@
use gpui::{App, IntoElement, RenderOnce, Window};
use gpui::{App, IntoElement, RenderOnce, SharedString, Window};
use crate::{
lists::DirEntry,
@@ -6,28 +6,34 @@ use crate::{
theme::{ActiveTheme, IconSize},
};
/// A file's icon by its name's extension, or a folder's, open or shut.
/// A file's name, its icon found under the icon theme at render, or an icon itself.
enum Shown {
File(SharedString),
Icon(IconName),
}
/// A file's icon by its name under the owner's icon theme, or a folder's, open or shut.
#[derive(IntoElement)]
pub struct FileIcon {
icon: IconName,
shown: Shown,
size: IconSize,
}
impl FileIcon {
pub fn file(name: impl AsRef<str>) -> Self {
Self {
icon: file_icon(name.as_ref()),
shown: Shown::File(name.as_ref().to_string().into()),
size: IconSize::Md,
}
}
pub fn folder(open: bool) -> Self {
Self {
icon: if open {
shown: Shown::Icon(if open {
IconName::FolderOpen
} else {
IconName::Folder
},
}),
size: IconSize::Md,
}
}
@@ -48,7 +54,11 @@ impl FileIcon {
impl RenderOnce for FileIcon {
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
Icon::new(self.icon)
let icon = match self.shown {
Shown::File(name) => file_icon(&name, cx),
Shown::Icon(icon) => icon,
};
Icon::new(icon)
.size(self.size)
.color(cx.theme().colors.fg_muted)
}