@@ -3,195 +3,111 @@ import Kingfisher
33import SwiftUI
44
55enum Cheatsheet {
6- private static let iconSize = NSSize ( width: 24 , height: 24 )
6+ static func createWindow( for userState: UserState ) -> NSWindow {
7+ let view = CheatsheetView ( ) . environmentObject ( userState)
8+ let controller = NSHostingController ( rootView: view)
9+ controller. sizingOptions = . preferredContentSize
10+ let cheatsheet = PanelWindow (
11+ contentRect: NSRect ( x: 0 , y: 0 , width: 700 , height: 640 )
12+ )
13+ cheatsheet. contentViewController = controller
14+ return cheatsheet
15+ }
16+ }
717
8- struct KeyBadge : SwiftUI . View {
9- let key : String
18+ struct CheatsheetView : SwiftUI . View {
19+ @EnvironmentObject var userState : UserState
20+ @Default ( . cheatsheetStyle) var cheatsheetStyle
21+ @State private var contentHeight : CGFloat = 0
1022
11- var body : some SwiftUI . View {
12- Text ( KeyMaps . glyph ( for: key) ?? key)
13- . font ( . system( . body, design: . rounded) )
14- . multilineTextAlignment ( . center)
15- . fontWeight ( . bold)
16- . padding ( . vertical, 4 )
17- . frame ( width: 24 )
18- . background ( . white. opacity ( 0.1 ) )
19- . clipShape ( RoundedRectangle ( cornerRadius: 5.0 , style: . continuous) )
23+ var maxHeight : CGFloat {
24+ if let screen = NSScreen . main {
25+ return screen. visibleFrame. height - 40
2026 }
27+ return 640
2128 }
2229
23- struct ActionRow : SwiftUI . View {
24- let action : Action
25- let indent : Int
26- @Default ( . showDetailsInCheatsheet) var showDetails
27- @Default ( . showAppIconsInCheatsheet) var showIcons
28-
29- var body : some SwiftUI . View {
30- HStack {
31- HStack {
32- ForEach ( 0 ..< indent, id: \. self) { _ in
33- Text ( " " )
34- }
35- KeyBadge ( key: action. key ?? " ● " )
36-
37- if showIcons {
38- actionIcon ( item: ActionOrGroup . action ( action) , iconSize: iconSize)
39- }
40-
41- Text ( action. displayName)
42- . lineLimit ( 1 )
43- . truncationMode ( . middle)
44- }
45- Spacer ( )
46- if showDetails {
47- Text ( action. value)
48- . foregroundStyle ( . secondary)
49- . lineLimit ( 1 )
50- . truncationMode ( . middle)
51- }
52- }
30+ // Constrain to edge of screen
31+ static var preferredWidth : CGFloat {
32+ if let screen = NSScreen . main {
33+ let screenHalf = screen. visibleFrame. width / 2
34+ let desiredWidth : CGFloat = 700
35+ let margin : CGFloat = 20
36+ return desiredWidth > screenHalf ? screenHalf - margin : desiredWidth
5337 }
38+ return 700
5439 }
5540
56- struct GroupRow : SwiftUI . View {
57- @ Default ( . expandGroupsInCheatsheet ) var expand
58- @ Default ( . showDetailsInCheatsheet ) var showDetails
59- @ Default ( . showAppIconsInCheatsheet ) var showIcons
41+ var actions : [ ActionOrGroup ] {
42+ ( userState . currentGroup != nil )
43+ ? userState . currentGroup! . actions : userState . userConfig . root . actions
44+ }
6045
61- let group : Group
62- let indent : Int
46+ var body : some SwiftUI . View {
47+ switch cheatsheetStyle {
48+ case . list:
49+ listView
50+ case . keyboard:
51+ KeyboardCheatsheetView ( )
52+ . fixedSize ( )
53+ . clipShape ( RoundedRectangle ( cornerRadius: 12 , style: . continuous) )
54+ }
55+ }
6356
64- var body : some SwiftUI . View {
57+ var listView : some View {
58+ ScrollView {
6559 VStack ( alignment: . leading, spacing: 4 ) {
66- HStack {
67- ForEach ( 0 ..< indent, id: \. self) { _ in
68- Text ( " " )
69- }
70- KeyBadge ( key: group. key ?? " " )
71-
72- if showIcons {
73- actionIcon ( item: ActionOrGroup . group ( group) , iconSize: iconSize)
74- }
75-
76- Image ( systemName: " chevron.right " )
77- . foregroundStyle ( . secondary)
78-
79- Text ( group. displayName)
80-
81- Spacer ( )
82- if showDetails {
83- Text ( " \( group. actions. count. description) item(s) " )
60+ if let group = userState. currentGroup {
61+ HStack {
62+ KeyBadge ( key: group. key ?? " • " )
63+ Text ( group. key == nil ? " Leader Key " : group. displayName)
8464 . foregroundStyle ( . secondary)
85- . lineLimit ( 1 )
86- . truncationMode ( . middle)
8765 }
88- }
89- if expand {
90- ForEach ( Array ( group. actions. enumerated ( ) ) , id: \. offset) { _, item in
91- switch item {
92- case . action( let action) :
93- Cheatsheet . ActionRow ( action: action, indent: indent + 1 )
94- case . group( let group) :
95- Cheatsheet . GroupRow ( group: group, indent: indent + 1 )
96- }
97- }
98- }
99- }
100- }
101- }
102-
103- struct CheatsheetView : SwiftUI . View {
104- @EnvironmentObject var userState : UserState
105- @State private var contentHeight : CGFloat = 0
106-
107- var maxHeight : CGFloat {
108- if let screen = NSScreen . main {
109- return screen. visibleFrame. height - 40 // Leave some margin
110- }
111- return 640
112- }
113-
114- // Constrain to edge of screen
115- static var preferredWidth : CGFloat {
116- if let screen = NSScreen . main {
117- let screenHalf = screen. visibleFrame. width / 2
118- let desiredWidth : CGFloat = 580
119- let margin : CGFloat = 20
120- return desiredWidth > screenHalf ? screenHalf - margin : desiredWidth
121- }
122- return 580
123- }
124-
125- var actions : [ ActionOrGroup ] {
126- ( userState. currentGroup != nil )
127- ? userState. currentGroup!. actions : userState. userConfig. root. actions
128- }
129-
130- var body : some SwiftUI . View {
131- ScrollView {
132- SwiftUI . VStack ( alignment: . leading, spacing: 4 ) {
133- if let group = userState. currentGroup {
134- HStack {
135- KeyBadge ( key: group. key ?? " • " )
136- Text ( group. key == nil ? " Leader Key " : group. displayName)
137- . foregroundStyle ( . secondary)
138- }
66+ . padding ( . bottom, 8 )
67+ Divider ( )
13968 . padding ( . bottom, 8 )
140- Divider ( )
141- . padding ( . bottom, 8 )
142- }
69+ }
14370
144- ForEach ( Array ( actions. enumerated ( ) ) , id: \. offset) { _, item in
145- switch item {
146- case . action( let action) :
147- Cheatsheet . ActionRow ( action: action, indent: 0 )
148- case . group( let group) :
149- Cheatsheet . GroupRow ( group: group, indent: 0 )
150- }
71+ ForEach ( Array ( actions. enumerated ( ) ) , id: \. offset) { _, item in
72+ switch item {
73+ case . action( let action) :
74+ ActionRow ( action: action, indent: 0 )
75+ case . group( let group) :
76+ GroupRow ( group: group, indent: 0 )
15177 }
15278 }
153- . padding ( )
154- . overlay (
155- GeometryReader { geo in
156- Color . clear. preference (
157- key: HeightPreferenceKey . self,
158- value: geo. size. height
159- )
160- }
161- )
16279 }
163- . frame ( width: Cheatsheet . CheatsheetView. preferredWidth)
164- . frame ( height: min ( contentHeight, maxHeight) )
165- . background (
166- VisualEffectView ( material: . hudWindow, blendingMode: . behindWindow)
80+ . padding ( )
81+ . overlay (
82+ GeometryReader { geo in
83+ Color . clear. preference (
84+ key: HeightPreferenceKey . self,
85+ value: geo. size. height
86+ )
87+ }
16788 )
168- . onPreferenceChange ( HeightPreferenceKey . self) { height in
169- self . contentHeight = height
170- }
17189 }
172- }
173-
174- struct HeightPreferenceKey : PreferenceKey {
175- static var defaultValue : CGFloat = 0
176- static func reduce( value: inout CGFloat , nextValue: ( ) -> CGFloat ) {
177- value = nextValue ( )
90+ . frame ( width: CheatsheetView . preferredWidth)
91+ . frame ( height: min ( contentHeight, maxHeight) )
92+ . background (
93+ VisualEffectView ( material: . hudWindow, blendingMode: . behindWindow)
94+ )
95+ . onPreferenceChange ( HeightPreferenceKey . self) { height in
96+ self . contentHeight = height
17897 }
17998 }
99+ }
180100
181- static func createWindow( for userState: UserState ) -> NSWindow {
182- let view = CheatsheetView ( ) . environmentObject ( userState)
183- let controller = NSHostingController ( rootView: view)
184- let cheatsheet = PanelWindow (
185- contentRect: NSRect ( x: 0 , y: 0 , width: 580 , height: 640 )
186- )
187- cheatsheet. contentViewController = controller
188- return cheatsheet
101+ struct HeightPreferenceKey : PreferenceKey {
102+ static var defaultValue : CGFloat = 0
103+ static func reduce( value: inout CGFloat , nextValue: ( ) -> CGFloat ) {
104+ value = nextValue ( )
189105 }
190106}
191107
192108struct CheatsheetView_Previews : PreviewProvider {
193109 static var previews : some View {
194- Cheatsheet . CheatsheetView ( )
110+ CheatsheetView ( )
195111 . environmentObject ( UserState ( userConfig: UserConfig ( ) ) )
196112 }
197- }
113+ }
0 commit comments