diff --git a/Demo/Shared/ContentView.swift b/Demo/Shared/ContentView.swift index 61709fb..587a5b2 100644 --- a/Demo/Shared/ContentView.swift +++ b/Demo/Shared/ContentView.swift @@ -21,8 +21,7 @@ struct ContentView: View { var body: some View { HStack { - Keyboard(pitchRange: Pitch(48)...Pitch(77), - layout: .pianoRoll).frame(width: 200) + Keyboard(layout: .pianoRoll(pitchRange: Pitch(48)...Pitch(77))).frame(width: 200) VStack { HStack { Stepper("Lowest Note: \(Pitch(intValue: lowNote).note(in: .C).description)", @@ -48,10 +47,9 @@ struct ContentView: View { }) } - Keyboard(pitchRange: Pitch(intValue: lowNote)...Pitch(intValue: highNote), + Keyboard(layout: .piano(pitchRange: Pitch(intValue: lowNote)...Pitch(intValue: highNote)), noteOn: noteOn, noteOff: noteOff) - Keyboard(pitchRange: Pitch(12)...Pitch(84), - layout: .isomorphic, + Keyboard(layout: .isomorphic(pitchRange: Pitch(12)...Pitch(84)), noteOn: noteOn, noteOff: noteOff) Keyboard(layout: .guitar(openPitches: [Pitch(64), Pitch(59), Pitch(55), Pitch(50), Pitch(45), Pitch(40)], fretcount: 22), noteOn: noteOn, noteOff: noteOff) { pitch, isActivated in @@ -61,8 +59,7 @@ struct ContentView: View { pressedColor: Color(PitchColor.newtonian[Int(pitch.pitchClass)]), alignment: .center) } - Keyboard(pitchRange: Pitch(48)...Pitch(65), - layout: .isomorphic) { pitch, isActivated in + Keyboard(layout: .isomorphic(pitchRange: Pitch(48)...Pitch(65))) { pitch, isActivated in KeyboardKey(pitch: pitch, isActivated: isActivated, text: pitch.note(in: .F).description, diff --git a/Sources/Keyboard/Keyboard.swift b/Sources/Keyboard/Keyboard.swift index 38ad1f7..830fe11 100644 --- a/Sources/Keyboard/Keyboard.swift +++ b/Sources/Keyboard/Keyboard.swift @@ -6,19 +6,17 @@ public struct Keyboard: View where Content: View { @StateObject var model: KeyboardModel = KeyboardModel() - var pitchRange: ClosedRange var latching: Bool var noteOn: (Pitch) -> Void var noteOff: (Pitch) -> Void var layout: KeyboardLayout - public init(pitchRange: ClosedRange = (Pitch(60)...Pitch(72)), + public init(layout: KeyboardLayout = .piano(pitchRange: (Pitch(60)...Pitch(72))), latching: Bool = false, - layout: KeyboardLayout = .piano, + noteOn: @escaping (Pitch) -> Void = { _ in }, noteOff: @escaping (Pitch) -> Void = { _ in }, @ViewBuilder content: @escaping (Pitch, Bool)->Content) { - self.pitchRange = pitchRange self.latching = latching self.layout = layout self.noteOn = noteOn @@ -29,13 +27,13 @@ public struct Keyboard: View where Content: View { public var body: some View { Group { switch layout { - case .piano: + case .piano(let pitchRange): Piano(content: content, model: model, pitchRange: pitchRange, latching: latching) - case .isomorphic: + case .isomorphic(let pitchRange): Isomorphic(content: content, model: model, pitchRange: pitchRange, latching: latching) case .guitar(let openPitches, let fretCount): Guitar(content: content, model: model, openPitches: openPitches, fretCount: fretCount, latching: latching) - case .pianoRoll: + case .pianoRoll(let pitchRange): PianoRoll(content: content, model: model, pitchRange: pitchRange, latching: latching) } @@ -52,26 +50,28 @@ public struct Keyboard: View where Content: View { extension Keyboard where Content == KeyboardKey { - public init(pitchRange: ClosedRange = (Pitch(60)...Pitch(72)), + public init(layout: KeyboardLayout = .piano(pitchRange: (Pitch(60)...Pitch(72))), latching: Bool = false, - layout: KeyboardLayout = .piano, noteOn: @escaping (Pitch) -> Void = { _ in }, noteOff: @escaping (Pitch) -> Void = { _ in }){ - self.pitchRange = pitchRange - self.latching = latching self.layout = layout + self.latching = latching self.noteOn = noteOn self.noteOff = noteOff + var alignment: Alignment = .bottom + + var flatTop = false switch layout { case .guitar(_, _): alignment = .center - case .pianoRoll: - alignment = .trailing - default: + case .isomorphic(_): alignment = .bottom - + case .piano(_): + flatTop = true + case .pianoRoll(_): + alignment = .trailing } - self.content = { KeyboardKey(pitch: $0, isActivated: $1, flatTop: layout == .piano, alignment: alignment) } + self.content = { KeyboardKey(pitch: $0, isActivated: $1, flatTop: flatTop, alignment: alignment) } } } diff --git a/Sources/Keyboard/Layouts/KeyboardLayout.swift b/Sources/Keyboard/Layouts/KeyboardLayout.swift index 02a8164..0272758 100644 --- a/Sources/Keyboard/Layouts/KeyboardLayout.swift +++ b/Sources/Keyboard/Layouts/KeyboardLayout.swift @@ -3,15 +3,15 @@ import Tonic /// Types of keyboards we can generate public enum KeyboardLayout: Equatable, Hashable { - /// Traditional Piano layout with raised black keys over white keys - case piano - - /// All notes linearly right after one another - case isomorphic - /// Guitar in arbitrary tuning, from first string (highest) to loweset string case guitar(openPitches: [Pitch], fretcount: Int) + /// All notes linearly right after one another + case isomorphic(pitchRange: ClosedRange) + + /// Traditional Piano layout with raised black keys over white keys + case piano(pitchRange: ClosedRange) + /// Vertical isomorphic - case pianoRoll + case pianoRoll(pitchRange: ClosedRange) }