T04 window and shell: chrome, bars, rail, tabs, windows, dialogs, tray, badge, zoom
This commit is contained in:
37 files changed
+4516
-111
No files matched your search
@@ -0,0 +1,144 @@
|
||||
use ely_gpui_component::{
|
||||
buttons::{Button, ButtonVariant},
|
||||
shell::{TrayIcon, TrayItem, dock_badge, set_dock_badge},
|
||||
typography::Caption,
|
||||
};
|
||||
use gpui::{App, IntoElement, ParentElement, SharedString, Window};
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{blocked, row, section},
|
||||
};
|
||||
|
||||
const ITEMS: [&str; 3] = ["Open gallery", "Toggle theme", "Quit"];
|
||||
|
||||
pub fn tray(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let tray = window.use_keyed_state("tray", cx, |_, _| None::<TrayIcon>);
|
||||
let last = window.use_keyed_state("tray-last", cx, |_, _| SharedString::from("nothing yet"));
|
||||
let shown = tray.read(cx).is_some();
|
||||
let note = last.read(cx).clone();
|
||||
let (toggle, pick) = (tray.clone(), tray);
|
||||
section(
|
||||
"TrayIcon / TrayMenu",
|
||||
"An SF Symbol in the menu bar with a menu. macOS only.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
row()
|
||||
.child(probe(
|
||||
"tray-show",
|
||||
Button::new(
|
||||
"tray-show",
|
||||
if shown {
|
||||
"Remove tray icon"
|
||||
} else {
|
||||
"Show tray icon"
|
||||
},
|
||||
)
|
||||
.variant(ButtonVariant::Outline)
|
||||
.on_click(move |_, _, cx| {
|
||||
let last = last.clone();
|
||||
let next = match toggle.read(cx) {
|
||||
Some(_) => None,
|
||||
None => {
|
||||
let items = vec![
|
||||
TrayItem::Action(ITEMS[0].into()),
|
||||
TrayItem::Action(ITEMS[1].into()),
|
||||
TrayItem::Separator,
|
||||
TrayItem::Action(ITEMS[2].into()),
|
||||
];
|
||||
let made = TrayIcon::new(
|
||||
"circle.hexagongrid",
|
||||
items,
|
||||
move |index, cx| {
|
||||
let label = match index {
|
||||
0 => ITEMS[0],
|
||||
1 => ITEMS[1],
|
||||
3 => ITEMS[2],
|
||||
other => panic!("tray has no action at {other}"),
|
||||
};
|
||||
last.update(cx, |last, cx| {
|
||||
*last = label.into();
|
||||
cx.notify();
|
||||
})
|
||||
},
|
||||
cx,
|
||||
);
|
||||
match made {
|
||||
Ok(icon) => Some(icon),
|
||||
Err(error) => {
|
||||
log::error!("gallery: tray failed: {error:#}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
toggle.update(cx, |tray, cx| {
|
||||
*tray = next;
|
||||
cx.notify();
|
||||
})
|
||||
}),
|
||||
))
|
||||
.child(probe(
|
||||
"tray-pick",
|
||||
Button::new("tray-pick", "Pick “Open gallery”")
|
||||
.variant(ButtonVariant::Ghost)
|
||||
.disabled(!shown)
|
||||
.on_click(move |_, _, cx| {
|
||||
if let Some(icon) = pick.read(cx) {
|
||||
icon.pick(0);
|
||||
}
|
||||
}),
|
||||
))
|
||||
.child(Caption::new(format!("Last pick: {note}"))),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn dock(cx: &mut App) -> impl IntoElement + use<> {
|
||||
let reading = match dock_badge() {
|
||||
Ok(Some(label)) => format!("The Dock shows “{label}”."),
|
||||
Ok(None) => "The Dock shows no badge.".to_string(),
|
||||
Err(error) => format!("{error:#}"),
|
||||
};
|
||||
let badge = |label: Option<&'static str>| {
|
||||
move |_: &gpui::ClickEvent, window: &mut Window, _: &mut App| {
|
||||
if let Err(error) = set_dock_badge(label) {
|
||||
log::error!("gallery: badge failed: {error:#}");
|
||||
}
|
||||
window.refresh();
|
||||
}
|
||||
};
|
||||
section(
|
||||
"DockBadge",
|
||||
"A count on the app's Dock icon. macOS only.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
row()
|
||||
.child(probe(
|
||||
"badge-set",
|
||||
Button::new("badge-set", "Badge 3")
|
||||
.variant(ButtonVariant::Outline)
|
||||
.on_click(badge(Some("3"))),
|
||||
))
|
||||
.child(probe(
|
||||
"badge-clear",
|
||||
Button::new("badge-clear", "Clear")
|
||||
.variant(ButtonVariant::Ghost)
|
||||
.on_click(badge(None)),
|
||||
))
|
||||
.child(Caption::new(reading)),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn notification(cx: &App) -> impl IntoElement + use<> {
|
||||
section(
|
||||
"SystemNotification",
|
||||
"Notices from the system's own center.",
|
||||
cx,
|
||||
)
|
||||
.child(blocked(
|
||||
"Blocked: an unbundled app has no notification center, and gpui 0.2.2 has no notification API.",
|
||||
cx,
|
||||
))
|
||||
}
|
||||
Reference in new issue
Block a user