1+ //
2+ // SettingsView.swift
3+ // TrackWeight
4+ //
5+
6+ import OpenMultitouchSupport
7+ import SwiftUI
8+
9+ struct SettingsView : View {
10+ @StateObject private var viewModel = ContentViewModel ( )
11+ @State private var showDebugView = false
12+
13+ var body : some View {
14+ VStack ( spacing: 0 ) {
15+ // Minimal Header
16+ Text ( " Settings " )
17+ . font ( . title)
18+ . fontWeight ( . medium)
19+ . padding ( . top, 32 )
20+ . padding ( . bottom, 32 )
21+
22+ // Settings Cards
23+ VStack ( spacing: 20 ) {
24+ // Device Card
25+ SettingsCard {
26+ VStack ( spacing: 20 ) {
27+ // Status Row
28+ HStack {
29+ HStack ( spacing: 12 ) {
30+ Text ( " Trackpad " )
31+ . font ( . headline)
32+ . fontWeight ( . medium)
33+ }
34+
35+ Spacer ( )
36+
37+ if !viewModel. availableDevices. isEmpty {
38+ Text ( " \( viewModel. availableDevices. count) device \( viewModel. availableDevices. count == 1 ? " " : " s " ) " )
39+ . font ( . caption)
40+ . foregroundColor ( . secondary)
41+ }
42+ }
43+
44+ // Device Selector
45+ if !viewModel. availableDevices. isEmpty {
46+ HStack {
47+ Picker ( " " , selection: Binding (
48+ get: { viewModel. selectedDevice } ,
49+ set: { device in
50+ if let device = device {
51+ viewModel. selectDevice ( device)
52+ }
53+ }
54+ ) ) {
55+ ForEach ( viewModel. availableDevices, id: \. self) { device in
56+ Text ( device. deviceName)
57+ . tag ( device as OMSDeviceInfo ? )
58+ }
59+ }
60+ . pickerStyle ( MenuPickerStyle ( ) )
61+
62+ Spacer ( )
63+ }
64+ } else {
65+ HStack {
66+ Text ( " No devices available " )
67+ . foregroundColor ( . secondary)
68+ Spacer ( )
69+ }
70+ }
71+ }
72+ }
73+
74+ // Debug Card
75+ SettingsCard {
76+ Button ( action: { showDebugView = true } ) {
77+ HStack ( spacing: 16 ) {
78+ VStack ( alignment: . leading, spacing: 4 ) {
79+ Text ( " Debug Console " )
80+ . font ( . headline)
81+ . fontWeight ( . medium)
82+ . foregroundColor ( . primary)
83+
84+ Text ( " Raw touch data & diagnostics " )
85+ . font ( . caption)
86+ . foregroundColor ( . secondary)
87+ }
88+
89+ Spacer ( )
90+
91+ Image ( systemName: " chevron.right " )
92+ . font ( . caption)
93+ . fontWeight ( . medium)
94+ . foregroundColor ( . secondary. opacity ( 0.6 ) )
95+ }
96+ . contentShape ( Rectangle ( ) )
97+ }
98+ . buttonStyle ( CardButtonStyle ( ) )
99+ }
100+ }
101+ . frame ( maxWidth: 480 )
102+ . padding ( . horizontal, 40 )
103+
104+ Spacer ( )
105+ }
106+ . frame ( maxWidth: . infinity, maxHeight: . infinity)
107+ . background ( Color ( NSColor . windowBackgroundColor) )
108+ . sheet ( isPresented: $showDebugView) {
109+ DebugView ( )
110+ . frame ( minWidth: 700 , minHeight: 500 )
111+ }
112+ . onAppear {
113+ viewModel. loadDevices ( )
114+ }
115+ }
116+ }
117+
118+ struct SettingsCard < Content: View > : View {
119+ let content : Content
120+
121+ init ( @ViewBuilder content: ( ) -> Content ) {
122+ self . content = content ( )
123+ }
124+
125+ var body : some View {
126+ VStack {
127+ content
128+ }
129+ . padding ( 24 )
130+ . background ( Color ( NSColor . controlBackgroundColor) )
131+ . cornerRadius ( 16 )
132+ . shadow ( color: Color . black. opacity ( 0.03 ) , radius: 1 , x: 0 , y: 1 )
133+ . shadow ( color: Color . black. opacity ( 0.05 ) , radius: 8 , x: 0 , y: 4 )
134+ }
135+ }
136+
137+ struct CardButtonStyle : ButtonStyle {
138+ func makeBody( configuration: Configuration ) -> some View {
139+ configuration. label
140+ . scaleEffect ( configuration. isPressed ? 0.98 : 1.0 )
141+ . animation ( . easeInOut( duration: 0.1 ) , value: configuration. isPressed)
142+ }
143+ }
144+
145+ #Preview {
146+ SettingsView ( )
147+ }
0 commit comments