Skip to content

Commit

Permalink
Implementing ring layout
Browse files Browse the repository at this point in the history
  • Loading branch information
cellularmitosis committed Jan 18, 2021
1 parent 26aed2c commit c0e68f1
Show file tree
Hide file tree
Showing 13 changed files with 783 additions and 185 deletions.
30 changes: 26 additions & 4 deletions GridNotes/GridNotes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@
2B45543725AB735000A95718 /* Yamaha Grand Piano.sf2 in Resources */ = {isa = PBXBuildFile; fileRef = 2B45542725AB735000A95718 /* Yamaha Grand Piano.sf2 */; };
2B45543F25AB8D6C00A95718 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B45543E25AB8D6C00A95718 /* SettingsViewController.swift */; };
2B45544425ABDEA800A95718 /* KeyRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B45544325ABDEA800A95718 /* KeyRowView.swift */; };
2B45544925ACC62E00A95718 /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B45544825ACC62E00A95718 /* Note.swift */; };
2B45544925ACC62E00A95718 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B45544825ACC62E00A95718 /* AppState.swift */; };
2B6D2B9D25B510FC003AE01F /* RingKeyboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6D2B9C25B510FC003AE01F /* RingKeyboardViewController.swift */; };
2B6D2BA225B51140003AE01F /* CGRect+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6D2BA125B51140003AE01F /* CGRect+.swift */; };
2B6D2BA725B5116C003AE01F /* UIColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6D2BA625B5116C003AE01F /* UIColor+.swift */; };
2B6D2BAC25B511B6003AE01F /* Bundle+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6D2BAB25B511B6003AE01F /* Bundle+.swift */; };
2B6D2BB425B51BF2003AE01F /* KeyboardContainerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6D2BB325B51BF2003AE01F /* KeyboardContainerController.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -82,7 +87,12 @@
2B45542725AB735000A95718 /* Yamaha Grand Piano.sf2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Yamaha Grand Piano.sf2"; sourceTree = "<group>"; };
2B45543E25AB8D6C00A95718 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
2B45544325ABDEA800A95718 /* KeyRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyRowView.swift; sourceTree = "<group>"; };
2B45544825ACC62E00A95718 /* Note.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Note.swift; sourceTree = "<group>"; };
2B45544825ACC62E00A95718 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
2B6D2B9C25B510FC003AE01F /* RingKeyboardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingKeyboardViewController.swift; sourceTree = "<group>"; };
2B6D2BA125B51140003AE01F /* CGRect+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect+.swift"; sourceTree = "<group>"; };
2B6D2BA625B5116C003AE01F /* UIColor+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+.swift"; sourceTree = "<group>"; };
2B6D2BAB25B511B6003AE01F /* Bundle+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+.swift"; sourceTree = "<group>"; };
2B6D2BB325B51BF2003AE01F /* KeyboardContainerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardContainerController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -134,11 +144,16 @@
isa = PBXGroup;
children = (
2B45541225AB722300A95718 /* Midi.swift */,
2B45544825ACC62E00A95718 /* Note.swift */,
2B45544825ACC62E00A95718 /* AppState.swift */,
2B45540D25AB71CD00A95718 /* GridKeyboardViewController.swift */,
2B45544325ABDEA800A95718 /* KeyRowView.swift */,
2B6D2B9C25B510FC003AE01F /* RingKeyboardViewController.swift */,
2B45543E25AB8D6C00A95718 /* SettingsViewController.swift */,
2B4553D125AB706500A95718 /* AppDelegate.swift */,
2B6D2BB325B51BF2003AE01F /* KeyboardContainerController.swift */,
2B6D2BA125B51140003AE01F /* CGRect+.swift */,
2B6D2BA625B5116C003AE01F /* UIColor+.swift */,
2B6D2BAB25B511B6003AE01F /* Bundle+.swift */,
2B4553DA25AB706700A95718 /* Assets.xcassets */,
2B4553DC25AB706700A95718 /* LaunchScreen.storyboard */,
2B4553DF25AB706700A95718 /* Info.plist */,
Expand Down Expand Up @@ -331,12 +346,17 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2B6D2B9D25B510FC003AE01F /* RingKeyboardViewController.swift in Sources */,
2B45540E25AB71CD00A95718 /* GridKeyboardViewController.swift in Sources */,
2B45541325AB722300A95718 /* Midi.swift in Sources */,
2B6D2BA225B51140003AE01F /* CGRect+.swift in Sources */,
2B4553D225AB706500A95718 /* AppDelegate.swift in Sources */,
2B45544425ABDEA800A95718 /* KeyRowView.swift in Sources */,
2B6D2BB425B51BF2003AE01F /* KeyboardContainerController.swift in Sources */,
2B45543F25AB8D6C00A95718 /* SettingsViewController.swift in Sources */,
2B45544925ACC62E00A95718 /* Note.swift in Sources */,
2B45544925ACC62E00A95718 /* AppState.swift in Sources */,
2B6D2BA725B5116C003AE01F /* UIColor+.swift in Sources */,
2B6D2BAC25B511B6003AE01F /* Bundle+.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -505,6 +525,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = CPE62329FB;
INFOPLIST_FILE = GridNotes/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
Expand All @@ -525,6 +546,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = CPE62329FB;
INFOPLIST_FILE = GridNotes/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
Expand Down
8 changes: 6 additions & 2 deletions GridNotes/GridNotes/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

initAudio()
window = UIWindow()
window?.makeKeyAndVisible()
window?.rootViewController = GridKeyboardViewController()
window?.rootViewController = KeyboardContainerController(initialState: AppState.defaultState)
return true
}
}
106 changes: 105 additions & 1 deletion GridNotes/GridNotes/Note.swift → GridNotes/GridNotes/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,49 @@
// Created by Jason Pepas on 1/11/21.
//

import Foundation
import UIKit


struct AppState {
var interface: Interface = .grid
var tonicNote: Note = .C
var scale: Scale = .major
var octaves: [Octave]
var keysPerOctave: KeysPerOctave
var nonScaleStyle: NonDiatonicKeyStyle = .disabled
var stickyKeys: Bool = false
var stuckKeys: Set<AbsoluteNote> = []

static var defaultState: AppState {
switch UIDevice.current.userInterfaceIdiom {
case .phone:
return AppState(
octaves: Octave.octavesForPhone,
keysPerOctave: .diatonicKeys
)
case .pad:
return AppState(
octaves: Octave.octavesForPad,
keysPerOctave: .chromaticKeys
)
default:
fatalError()
}
}
}


enum Interface: String, CaseIterable {
case grid
case ring

var name: String {
switch self {
case .grid: return "Grid"
case .ring: return "Ring"
}
}
}


enum Note: String, CaseIterable, Hashable {
Expand Down Expand Up @@ -110,6 +152,24 @@ struct AbsoluteNote: Hashable {
}
}

var buttonText: String {
switch note {
case .A, .B, .C, .D, .E, .F, .G:
return "\(note.rawValue)\(octave.rawValue)"
case .AsBb:
return "A\(octave.rawValue)\nB\(octave.rawValue)"
case .CsDb:
return "C\(octave.rawValue)\nD\(octave.rawValue)"
case .DsEb:
return "D\(octave.rawValue)\nE\(octave.rawValue)"
case .FsGb:
return "F\(octave.rawValue)\nG\(octave.rawValue)"
case .GsAb:
return "G\(octave.rawValue)\nA\(octave.rawValue)"
}
}


var next: AbsoluteNote? {
switch note {
case .GsAb:
Expand Down Expand Up @@ -196,6 +256,20 @@ enum Scale: String, CaseIterable {
}
}

func sparseAbsoluteNotes(fromTonic tonic: AbsoluteNote) -> [AbsoluteNote?] {
var notes: [AbsoluteNote?] = []
var note: AbsoluteNote? = tonic
for i in 0..<12 {
if semitoneIndices.contains(i) {
notes.append(note)
} else {
notes.append(nil)
}
note = note?.next
}
return notes
}

func absoluteNotes(fromTonic tonic: AbsoluteNote) -> [AbsoluteNote?] {
var notes: [AbsoluteNote?] = []
var note: AbsoluteNote? = tonic
Expand All @@ -208,3 +282,33 @@ enum Scale: String, CaseIterable {
return notes
}
}


enum KeysPerOctave: String, CaseIterable {
case chromaticKeys
case diatonicKeys

var name: String {
switch self {
case .chromaticKeys:
return "Chromatic (all 12 keys)"
case .diatonicKeys:
return "Diatonic (only in-scale keys)"
}
}
}


enum NonDiatonicKeyStyle: String, CaseIterable {
case shaded
case disabled

var name: String {
switch self {
case .shaded:
return "Shaded, but Enabled"
case .disabled:
return "Shaded and Disabled"
}
}
}
15 changes: 15 additions & 0 deletions GridNotes/GridNotes/Bundle+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Bundle+.swift
// GridNotes
//
// Created by Jason Pepas on 1/17/21.
//

import UIKit


extension Bundle {
var marketingVersion: String {
return infoDictionary!["CFBundleShortVersionString"] as! String
}
}
22 changes: 22 additions & 0 deletions GridNotes/GridNotes/CGRect+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// CGRect+.swift
// GridNotes
//
// Created by Jason Pepas on 1/17/21.
//

import UIKit


extension CGRect {
static func square(dimension: CGFloat) -> CGRect {
return CGRect(x: 0, y: 0, width: dimension, height: dimension)
}

func centered(within containingRect: CGRect) -> CGRect {
var centeredRect = self
centeredRect.origin.x = (containingRect.width - width) / 2
centeredRect.origin.y = (containingRect.height - height) / 2
return centeredRect
}
}
Loading

0 comments on commit c0e68f1

Please sign in to comment.