111 lines
3.9 KiB
Swift
111 lines
3.9 KiB
Swift
import SwiftUI
|
||
|
||
struct ProcessListView: View {
|
||
let processes: [SystemInfo.ProcessInfo]
|
||
let title: String
|
||
let icon: String
|
||
let isMemory: Bool // true = 显示内存,false = 显示 CPU%
|
||
let fontSize: Double
|
||
|
||
@ObservedObject private var config = Configuration.shared
|
||
|
||
/// 高亮模式下标题/图标/表头的主题色(Top 进程典型为橙色)
|
||
private var headerColor: Color {
|
||
config.highlightMode ? .orange : .secondary
|
||
}
|
||
|
||
var body: some View {
|
||
VStack(alignment: .leading, spacing: 4) {
|
||
// 标题
|
||
HStack(spacing: 5) {
|
||
Image(systemName: icon)
|
||
.font(.system(size: fontSize))
|
||
.foregroundColor(headerColor)
|
||
Text(title)
|
||
.font(.system(size: fontSize, weight: .medium))
|
||
.foregroundColor(headerColor)
|
||
Spacer()
|
||
}
|
||
|
||
// 表头
|
||
HStack(spacing: 0) {
|
||
Text("进程")
|
||
.font(.system(size: fontSize - 2))
|
||
.foregroundColor(headerColor.opacity(0.6))
|
||
.frame(maxWidth: .infinity, alignment: .leading)
|
||
Text(isMemory ? "内存" : "CPU")
|
||
.font(.system(size: fontSize - 2))
|
||
.foregroundColor(headerColor.opacity(0.6))
|
||
.frame(width: 52, alignment: .trailing)
|
||
}
|
||
.padding(.horizontal, 4)
|
||
|
||
Divider()
|
||
.background(Color.white.opacity(0.1))
|
||
|
||
// 进程列表
|
||
ForEach(processes.prefix(5)) { proc in
|
||
processRow(proc)
|
||
}
|
||
}
|
||
}
|
||
|
||
private func processRow(_ proc: SystemInfo.ProcessInfo) -> some View {
|
||
HStack(spacing: 4) {
|
||
// 进程名
|
||
Text(proc.name.components(separatedBy: "/").last ?? proc.name)
|
||
.font(.system(size: fontSize - 1, design: .monospaced))
|
||
.foregroundColor(config.highlightMode
|
||
? (isMemory ? memoryColor(proc.memoryBytes) : cpuColor(proc.cpuPercent)).opacity(0.7)
|
||
: .primary.opacity(0.85))
|
||
.lineLimit(1)
|
||
.truncationMode(.tail)
|
||
|
||
Spacer()
|
||
|
||
// 数值
|
||
if isMemory {
|
||
Text(formatBytes(proc.memoryBytes))
|
||
.font(.system(size: fontSize - 1, weight: .medium, design: .monospaced))
|
||
.foregroundColor(memoryColor(proc.memoryBytes))
|
||
.frame(width: 52, alignment: .trailing)
|
||
} else {
|
||
Text(String(format: "%.1f%%", proc.cpuPercent))
|
||
.font(.system(size: fontSize - 1, weight: .medium, design: .monospaced))
|
||
.foregroundColor(cpuColor(proc.cpuPercent))
|
||
.frame(width: 52, alignment: .trailing)
|
||
}
|
||
}
|
||
.padding(.horizontal, 4)
|
||
.padding(.vertical, 2)
|
||
.contentShape(Rectangle())
|
||
}
|
||
|
||
private func formatBytes(_ bytes: UInt64) -> String {
|
||
if bytes >= 1_073_741_824 {
|
||
String(format: "%.1f GB", Double(bytes) / 1_073_741_824)
|
||
} else if bytes >= 1_048_576 {
|
||
String(format: "%.0f MB", Double(bytes) / 1_048_576)
|
||
} else if bytes >= 1_024 {
|
||
String(format: "%.0f KB", Double(bytes) / 1_024)
|
||
} else {
|
||
"\(bytes) B"
|
||
}
|
||
}
|
||
|
||
private func cpuColor(_ value: Double) -> Color {
|
||
if value < 20 { return .green.opacity(0.8) }
|
||
if value < 50 { return .yellow.opacity(0.8) }
|
||
if value < 80 { return .orange.opacity(0.8) }
|
||
return .red.opacity(0.8)
|
||
}
|
||
|
||
private func memoryColor(_ bytes: UInt64) -> Color {
|
||
let mb = Double(bytes) / 1_048_576
|
||
if mb < 200 { return .green.opacity(0.8) }
|
||
if mb < 500 { return .yellow.opacity(0.8) }
|
||
if mb < 1000 { return .orange.opacity(0.8) }
|
||
return .red.opacity(0.8)
|
||
}
|
||
}
|