1use std::sync::atomic::{AtomicU64, Ordering};
13use swiftui_native::prelude::*;
14use swiftui_native::{state, views};
15
16static LOAD: [AtomicU64; 3] = [AtomicU64::new(34), AtomicU64::new(71), AtomicU64::new(12)];
19
20const LABELS: [&str; 3] = ["CPU", "Memory", "Disk"];
21const TINTS: [SystemColor; 3] = [SystemColor::Blue, SystemColor::Orange, SystemColor::Green];
22
23fn reading(i: usize) -> f64 {
24 LOAD[i].load(Ordering::Relaxed) as f64 / 100.0
25}
26
27fn tile(i: usize) -> View {
29 let value = reading(i);
30 vstack_spacing(
31 &[
32 zstack![
33 circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34 circle_shape()
38 .trim(0.0, value)
39 .stroke_system(TINTS[i], 6.0)
40 .rotate(-90.0),
41 text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42 ]
43 .frame(72.0, 72.0),
44 text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45 ],
46 8.0,
47 )
48 .padding(12.0)
49 .a11y_element(AccessibilityChildBehavior::Combine)
50 .a11y_label(LABELS[i])
51 .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
53
54fn body() -> View {
55 vstack_aligned_spacing(
56 &[
57 text("System").text_style(TextStyle::LargeTitle).bold(),
58 grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59 divider(),
60 vstack_aligned(
63 &[
64 text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65 gauge(reading(1), 0.0, 1.0, text("Memory"))
66 .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67 .tint_system(SystemColor::Orange),
68 ],
69 HorizontalAlignment::Leading,
70 ),
71 spacer(),
72 button("Refresh", refresh)
73 .button_style(views::ButtonStyle::BorderedProminent)
74 .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75 ],
76 HorizontalAlignment::Leading,
77 Some(16.0),
78 )
79 .padding(20.0)
80 .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
83
84fn refresh() {
86 static SEED: AtomicU64 = AtomicU64::new(0x9E37_79B9);
87 for slot in &LOAD {
88 let mut x = SEED.load(Ordering::Relaxed);
89 x ^= x << 13;
90 x ^= x >> 7;
91 x ^= x << 17;
92 SEED.store(x, Ordering::Relaxed);
93 slot.store(x % 101, Ordering::Relaxed);
94 }
95 state::refresh_animated(state::ease_in_out(0.6));
96}
97
98fn content_view() -> swiftui_native::ViewHandle {
99 state::root_view(|_| body().into_handle())
100}
101
102#[cfg(target_os = "macos")]
103#[path = "common/simulator.rs"]
104mod simulator;
105
106#[cfg(target_os = "macos")]
107fn main() {
108 if std::env::args().any(|a| a == "--sim" || a == "device") {
109 return simulator::main(&simulator::Bundle {
110 example: "dashboard",
111 bundle_id: "dev.rswift.Dashboard",
112 executable: "Dashboard",
113 display_name: "Dashboard",
114 launch_args: &[],
115 });
116 }
117 if std::env::args().any(|a| a == "--render") {
118 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/dashboard.png");
119 swiftui_native::render::render(&content_view(), 420, 480).write_png(out);
120 eprintln!("wrote {out}");
121 return;
122 }
123 show_window(&content_view(), "Dashboard", 420.0, 480.0);
124}
125
126#[cfg(not(target_os = "macos"))]
127fn main() {
128 swiftui_native::app::run(content_view)
129}