@@ -35,30 +35,34 @@ class InstrumentSFZConductor: ObservableObject, HasAudioEngine {
35
35
struct InstrumentSFZView : View {
36
36
@StateObject var conductor = InstrumentSFZConductor ( )
37
37
@Environment ( \. colorScheme) var colorScheme
38
+ @Environment ( \. horizontalSizeClass) var horizontalSizeClass
38
39
39
40
var body : some View {
40
- HStack {
41
- ForEach ( 0 ... 7 , id: \. self) {
42
- ParameterRow ( param: conductor. instrument. parameters [ $0] )
43
- }
44
- } . padding ( 5 )
45
- HStack {
46
- ForEach ( 8 ... 15 , id: \. self) {
47
- ParameterRow ( param: conductor. instrument. parameters [ $0] )
48
- }
49
- } . padding ( 5 )
50
- HStack {
51
- ForEach ( 16 ... 23 , id: \. self) {
52
- ParameterRow ( param: conductor. instrument. parameters [ $0] )
53
- }
54
- } . padding ( 5 )
55
- HStack {
56
- ForEach ( 24 ... 30 , id: \. self) {
57
- ParameterRow ( param: conductor. instrument. parameters [ $0] )
41
+ let instrumentParams = conductor. instrument. parameters
42
+ let paramsPerLine = horizontalSizeClass == . compact ? 6 : 8
43
+ let instrumentParamsChunked = instrumentParams. chunked ( into: paramsPerLine)
44
+
45
+ GeometryReader { geoProxy in
46
+ VStack {
47
+ let paramRows = ForEach ( 0 ..< instrumentParamsChunked. count, id: \. self) { chunkIndex in
48
+ HStack {
49
+ ForEach ( instrumentParamsChunked [ chunkIndex] , id: \. self) { param in
50
+ ParameterRow ( param: param)
51
+ }
52
+ } . padding ( 5 )
53
+ }
54
+ // i wanted to do it with verticalSizeClass, but couldn't work it out
55
+ if horizontalSizeClass == . compact {
56
+ ScrollView {
57
+ paramRows
58
+ }
59
+ } else {
60
+ paramRows
61
+ }
62
+ CookbookKeyboard ( noteOn: conductor. noteOn,
63
+ noteOff: conductor. noteOff) . frame ( height: geoProxy. size. height / 5 )
58
64
}
59
- } . padding ( 5 )
60
- CookbookKeyboard ( noteOn: conductor. noteOn,
61
- noteOff: conductor. noteOff)
65
+ }
62
66
. cookbookNavBarTitle ( " Instrument SFZ " )
63
67
. onAppear {
64
68
conductor. start ( )
@@ -70,3 +74,25 @@ struct InstrumentSFZView: View {
70
74
Color . clear : Color ( red: 0.9 , green: 0.9 , blue: 0.9 ) )
71
75
}
72
76
}
77
+
78
+ extension Array {
79
+ func chunked( into size: Int ) -> [ [ Element ] ] {
80
+ return stride ( from: 0 , to: count, by: size) . map {
81
+ Array ( self [ $0 ..< Swift . min ( $0 + size, count) ] )
82
+ }
83
+ }
84
+ }
85
+
86
+ extension NodeParameter : Hashable {
87
+ public func hash( into hasher: inout Hasher ) {
88
+ hasher. combine ( def. identifier)
89
+ }
90
+ }
91
+
92
+ extension NodeParameter : Equatable {
93
+ public static func == ( lhs: NodeParameter , rhs: NodeParameter ) -> Bool {
94
+ // NodeParameter wraps AUParameter which should
95
+ // conform to equtable as they are NSObjects
96
+ return lhs. parameter == rhs. parameter
97
+ }
98
+ }
0 commit comments