Skip to content

Commit

Permalink
Added rudimentary Canvas based keyboard not touch-activated
Browse files Browse the repository at this point in the history
  • Loading branch information
aure committed Aug 8, 2023
1 parent b0caf2a commit df6249b
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 3 deletions.
4 changes: 1 addition & 3 deletions Sources/Keyboard/Layouts/Piano.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ struct Piano<Content>: View where Content: View {
ZStack(alignment: .topLeading) {
HStack(spacing: 0) {
ForEach(spacer.whiteKeys, id: \.self) { pitch in
KeyContainer(model: keyboard,
pitch: pitch,
content: content)
KeyContainer(model: keyboard, pitch: pitch, content: content)
.frame(width: spacer.whiteKeyWidth(geo.size.width))
}
}
Expand Down
95 changes: 95 additions & 0 deletions Sources/Keyboard/MIDIMonitorKeyboard.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@

import SwiftUI
import Tonic

extension GraphicsContext {
func fill(rect: CGRect, with color: Color) {
fill(Path(roundedRect: rect, cornerRadius: 0), with: GraphicsContext.Shading.color(color))
}
}

struct MIDIMonitorKeyboard: View {

var layout: KeyboardLayout
var activatedPitches: PitchSet
var colorFunction: (Pitch)->Color
var spacer: PianoSpacer = PianoSpacer(pitchRange: Pitch(60) ... Pitch(72), initialSpacerRatio: PianoSpacer.defaultInitialSpacerRatio, spacerRatio: PianoSpacer.defaultSpacerRatio)

public init(layout: KeyboardLayout = .piano(pitchRange: Pitch(60) ... Pitch(72)),
activatedPitches: PitchSet = PitchSet(),
colorFunction: @escaping (Pitch)->Color = { _ in Color.red }
)
{
self.layout = layout
self.activatedPitches = activatedPitches
self.colorFunction = colorFunction

switch layout {
case let .piano(pitchRange, initialSpacerRatio, spacerRatio, relativeBlackKeyWidth, relativeBlackKeyHeight):
spacer = PianoSpacer(pitchRange: pitchRange,
initialSpacerRatio: initialSpacerRatio,
spacerRatio: spacerRatio,
relativeBlackKeyWidth: relativeBlackKeyWidth,
relativeBlackKeyHeight: relativeBlackKeyHeight)
default:
print("Unimplimented")
}
}

var body: some View {
switch layout {
case let .piano(pitchRange, initialSpacerRatio, spacerRatio, relativeBlackKeyWidth, relativeBlackKeyHeight):

Canvas { cx, size in
cx.fill(rect: CGRect(origin: .zero, size: size), with: .black)
var color = Color.white
for (i, pitch) in spacer.whiteKeys.enumerated() {
color = Color.white
if activatedPitches.contains(pitch) {
color = colorFunction(pitch)
}
let r = CGRect(x: CGFloat(i) * spacer.whiteKeyWidth(size.width),
y: 0,
width: spacer.whiteKeyWidth(size.width) - 1,
height: size.height)
cx.fill(rect: r, with: color)
}

var x: CGFloat = spacer.initialSpacerWidth(size.width)
if spacer.pitchRange.lowerBound != spacer.pitchRangeBoundedByNaturals.lowerBound {
x += spacer.lowerBoundSpacerWidth(size.width)
}
for pitch in spacer.pitchRange {
color = Color.black

let r = CGRect(x: x,
y: 0,
width: spacer.blackKeyWidth(size.width),
height: size.height * spacer.relativeBlackKeyHeight)

if activatedPitches.contains(pitch) {
color = colorFunction(pitch)
}


if spacer.isBlackKey(pitch) {
cx.fill(rect: r, with: color)
x += spacer.blackKeyWidth(size.width)
} else {
x += spacer.blackKeySpacerWidth(size.width, pitch: pitch)
}
}
}
default:
EmptyView()
}
}
}

var p = PitchSet(pitches: [Pitch(65), Pitch(68), Pitch(71), Pitch(74)])
#Preview {
MIDIMonitorKeyboard(layout: .piano(pitchRange: Pitch(61)...Pitch(88)),
activatedPitches: p,
colorFunction: { x in Color(cgColor: PitchColor.helmholtz[Int(x.pitchClass)])}
).frame(width: 600, height: 100)
}

0 comments on commit df6249b

Please sign in to comment.