diff --git a/Memola.xcodeproj/project.pbxproj b/Memola.xcodeproj/project.pbxproj index 30ef618..cef513d 100644 --- a/Memola.xcodeproj/project.pbxproj +++ b/Memola.xcodeproj/project.pbxproj @@ -62,6 +62,10 @@ ECA738F42BE612A000A4542E /* Array++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738F32BE612A000A4542E /* Array++.swift */; }; ECA738F62BE612B700A4542E /* MTLDevice++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738F52BE612B700A4542E /* MTLDevice++.swift */; }; ECA738F82BE612EB00A4542E /* Quad.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738F72BE612EB00A4542E /* Quad.swift */; }; + ECA738FC2BE61C5200A4542E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738FB2BE61C5200A4542E /* Persistence.swift */; }; + ECA739012BE61D9C00A4542E /* MemolaModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = ECA738FF2BE61D9C00A4542E /* MemolaModel.xcdatamodeld */; }; + ECA739052BE61E3100A4542E /* Memo.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA739042BE61E3100A4542E /* Memo.swift */; }; + ECA739082BE623F300A4542E /* PenToolView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA739072BE623F300A4542E /* PenToolView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -121,6 +125,10 @@ ECA738F32BE612A000A4542E /* Array++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array++.swift"; sourceTree = ""; }; ECA738F52BE612B700A4542E /* MTLDevice++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MTLDevice++.swift"; sourceTree = ""; }; ECA738F72BE612EB00A4542E /* Quad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Quad.swift; sourceTree = ""; }; + ECA738FB2BE61C5200A4542E /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; + ECA739002BE61D9C00A4542E /* MemolaModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MemolaModel.xcdatamodel; sourceTree = ""; }; + ECA739042BE61E3100A4542E /* Memo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Memo.swift; sourceTree = ""; }; + ECA739072BE623F300A4542E /* PenToolView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenToolView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -157,6 +165,7 @@ ECA7387E2BE5FE4200A4542E /* Canvas */, ECA738A12BE601F700A4542E /* Extensions */, ECA738772BE5EEE800A4542E /* Features */, + ECA738FA2BE61B1700A4542E /* Persistence */, EC7F6BF12BE5E6E400A34A7B /* Preview Content */, ECA738802BE5FE6000A4542E /* Resources */, ); @@ -200,6 +209,7 @@ isa = PBXGroup; children = ( ECA7387C2BE5EF4B00A4542E /* MemoView.swift */, + ECA739072BE623F300A4542E /* PenToolView.swift */, ); path = Memo; sourceTree = ""; @@ -224,7 +234,8 @@ ECA738802BE5FE6000A4542E /* Resources */ = { isa = PBXGroup; children = ( - EC7F6BEF2BE5E6E400A34A7B /* Assets.xcassets */, + ECA738FE2BE61D5700A4542E /* Models */, + ECA738FD2BE61D4700A4542E /* Assets */, ); path = Resources; sourceTree = ""; @@ -336,7 +347,6 @@ ECA738B12BE60D8800A4542E /* Tool */ = { isa = PBXGroup; children = ( - ECA738C22BE60E7200A4542E /* PenStyles */, ECA738BD2BE60E2800A4542E /* Pen */, ECA738BB2BE60E0300A4542E /* Tool.swift */, ); @@ -356,8 +366,8 @@ ECA738BD2BE60E2800A4542E /* Pen */ = { isa = PBXGroup; children = ( - ECA738BE2BE60E3400A4542E /* Pen.swift */, - ECA738C02BE60E5300A4542E /* PenStyle.swift */, + ECA739062BE61F7500A4542E /* Core */, + ECA738C22BE60E7200A4542E /* PenStyles */, ); path = Pen; sourceTree = ""; @@ -420,6 +430,56 @@ path = Geometries; sourceTree = ""; }; + ECA738FA2BE61B1700A4542E /* Persistence */ = { + isa = PBXGroup; + children = ( + ECA739032BE61E2600A4542E /* Entities */, + ECA739022BE61DE700A4542E /* Core */, + ); + path = Persistence; + sourceTree = ""; + }; + ECA738FD2BE61D4700A4542E /* Assets */ = { + isa = PBXGroup; + children = ( + EC7F6BEF2BE5E6E400A34A7B /* Assets.xcassets */, + ); + path = Assets; + sourceTree = ""; + }; + ECA738FE2BE61D5700A4542E /* Models */ = { + isa = PBXGroup; + children = ( + ECA738FF2BE61D9C00A4542E /* MemolaModel.xcdatamodeld */, + ); + path = Models; + sourceTree = ""; + }; + ECA739022BE61DE700A4542E /* Core */ = { + isa = PBXGroup; + children = ( + ECA738FB2BE61C5200A4542E /* Persistence.swift */, + ); + path = Core; + sourceTree = ""; + }; + ECA739032BE61E2600A4542E /* Entities */ = { + isa = PBXGroup; + children = ( + ECA739042BE61E3100A4542E /* Memo.swift */, + ); + path = Entities; + sourceTree = ""; + }; + ECA739062BE61F7500A4542E /* Core */ = { + isa = PBXGroup; + children = ( + ECA738BE2BE60E3400A4542E /* Pen.swift */, + ECA738C02BE60E5300A4542E /* PenStyle.swift */, + ); + path = Core; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -499,6 +559,7 @@ ECA738A82BE6025900A4542E /* GraphicUniforms.swift in Sources */, ECA738E62BE611FD00A4542E /* CGRect++.swift in Sources */, ECA738E82BE6120F00A4542E /* Color++.swift in Sources */, + ECA738FC2BE61C5200A4542E /* Persistence.swift in Sources */, ECA7387A2BE5EF0400A4542E /* MemosView.swift in Sources */, ECA738BA2BE60DEF00A4542E /* HistoryAction.swift in Sources */, ECA738AA2BE6026D00A4542E /* Uniforms.swift in Sources */, @@ -513,16 +574,19 @@ ECA738862BE5FF2500A4542E /* Canvas.swift in Sources */, ECA738882BE5FF4400A4542E /* Renderer.swift in Sources */, ECA738D42BE60F9100A4542E /* StrokeGenerator.swift in Sources */, + ECA739082BE623F300A4542E /* PenToolView.swift in Sources */, ECA738CB2BE60F1900A4542E /* ViewPortContext.swift in Sources */, ECA738EE2BE6125D00A4542E /* simd_float4x4++.swift in Sources */, ECA7388C2BE6009600A4542E /* Textures.swift in Sources */, ECA738B82BE60DDC00A4542E /* HistoryEvent.swift in Sources */, ECA738952BE6012D00A4542E /* ViewPort.metal in Sources */, + ECA739012BE61D9C00A4542E /* MemolaModel.xcdatamodeld in Sources */, ECA738F02BE6127700A4542E /* CGSize++.swift in Sources */, ECA738EC2BE6124E00A4542E /* CGAffineTransform++.swift in Sources */, ECA738E22BE610D000A4542E /* GraphicRenderPass.swift in Sources */, ECA738DC2BE6108D00A4542E /* StrokeRenderPass.swift in Sources */, ECA738F42BE612A000A4542E /* Array++.swift in Sources */, + ECA739052BE61E3100A4542E /* Memo.swift in Sources */, ECA7388F2BE600DA00A4542E /* Grid.metal in Sources */, ECA738C92BE60EF700A4542E /* GraphicContext.swift in Sources */, ECA738F62BE612B700A4542E /* MTLDevice++.swift in Sources */, @@ -754,6 +818,19 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + ECA738FF2BE61D9C00A4542E /* MemolaModel.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + ECA739002BE61D9C00A4542E /* MemolaModel.xcdatamodel */, + ); + currentVersion = ECA739002BE61D9C00A4542E /* MemolaModel.xcdatamodel */; + path = MemolaModel.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ }; rootObject = EC7F6BE02BE5E6E300A34A7B /* Project object */; } diff --git a/Memola/Persistence/Core/Persistence.swift b/Memola/Persistence/Core/Persistence.swift new file mode 100644 index 0000000..4dee7f9 --- /dev/null +++ b/Memola/Persistence/Core/Persistence.swift @@ -0,0 +1,66 @@ +// +// Persistence.swift +// Memola +// +// Created by Dscyre Scotti on 5/4/24. +// + +import CoreData +import Foundation + +class Persistence { + private let modelName = "MemolaModel" + + static let shared: Persistence = Persistence() + + private init() { } + + var viewContext: NSManagedObjectContext { + persistentContainer.viewContext + } + + lazy var persistentContainer: NSPersistentContainer = { + let persistentStore = NSPersistentStoreDescription() + persistentStore.shouldMigrateStoreAutomatically = true + persistentStore.shouldInferMappingModelAutomatically = true + let container = NSPersistentContainer(name: modelName, managedObjectModel: managedObjectModel) + do { + let coordinator = container.persistentStoreCoordinator + if let oldStore = coordinator.persistentStores.first { + try coordinator.remove(oldStore) + } + _ = try coordinator.addPersistentStore(type: .sqlite, at: sqliteURL) + } catch { + fatalError("[Memola] - \(error.localizedDescription)") + } + container.persistentStoreDescriptions = [persistentStore] + container.loadPersistentStores { description, error in + if let error { + fatalError("[Memola]: \(error.localizedDescription)") + } + } + return container + }() + + private lazy var managedObjectModel: NSManagedObjectModel = { + guard let modelURL = Bundle.main.url(forResource: modelName, withExtension: ".momd"), let model = NSManagedObjectModel(contentsOf: modelURL) else { + fatalError("[Memola]: Unable to load model.") + } + return model + }() + + private lazy var sqliteURL: URL = { + do { + let fileURL = try FileManager.default.url( + for: .documentDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: true + ).appendingPathComponent("\(modelName).sqlite") + NSLog(fileURL.absoluteString) + return fileURL + } catch { + fatalError("[Memola]: \(error.localizedDescription)") + } + }() +} diff --git a/Memola/Persistence/Entities/Memo.swift b/Memola/Persistence/Entities/Memo.swift new file mode 100644 index 0000000..3ea1cad --- /dev/null +++ b/Memola/Persistence/Entities/Memo.swift @@ -0,0 +1,20 @@ +// +// Memo.swift +// Memola +// +// Created by Dscyre Scotti on 5/4/24. +// + +import CoreData +import Foundation + +@objc(Memo) +class Memo: NSManagedObject { + @NSManaged var id: UUID + @NSManaged var title: String + @NSManaged var data: Data + @NSManaged var createdAt: Date + @NSManaged var updatedAt: Date +} + +extension Memo: Identifiable { } diff --git a/Memola/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Memola/Resources/Assets.xcassets/AccentColor.colorset/Contents.json rename to Memola/Resources/Assets/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Memola/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Memola/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Memola/Resources/Assets/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Memola/Resources/Assets.xcassets/Contents.json b/Memola/Resources/Assets/Assets.xcassets/Contents.json similarity index 100% rename from Memola/Resources/Assets.xcassets/Contents.json rename to Memola/Resources/Assets/Assets.xcassets/Contents.json diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/Contents.json b/Memola/Resources/Assets/Assets.xcassets/graphics/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/graphics/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/Contents.json b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/Contents.json new file mode 100644 index 0000000..58541c1 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "eraser.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "eraser@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "eraser@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser.png b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser.png new file mode 100644 index 0000000..efe860c Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser@2x.png b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser@2x.png new file mode 100644 index 0000000..0f7d179 Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser@2x.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser@3x.png b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser@3x.png new file mode 100644 index 0000000..464763a Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/eraser/eraser.imageset/eraser@3x.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/Contents.json b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/Contents.json new file mode 100644 index 0000000..2734a89 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "bullet-base.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "bullet-base@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "bullet-base@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base.png b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base.png new file mode 100644 index 0000000..e14b91e Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base@2x.png b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base@2x.png new file mode 100644 index 0000000..c21a5a9 Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base@2x.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base@3x.png b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base@3x.png new file mode 100644 index 0000000..2146f61 Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-base.imageset/bullet-base@3x.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/Contents.json new file mode 100644 index 0000000..6c3c92a --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "bullet-tip.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "bullet-tip@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "bullet-tip@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip.png b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip.png new file mode 100644 index 0000000..fefdcfc Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip@2x.png b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip@2x.png new file mode 100644 index 0000000..6175f55 Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip@2x.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip@3x.png b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip@3x.png new file mode 100644 index 0000000..6cf4a48 Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/graphics/pens/marker-tip.imageset/bullet-tip@3x.png differ diff --git a/Memola/Resources/Assets/Assets.xcassets/textures/Contents.json b/Memola/Resources/Assets/Assets.xcassets/textures/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/textures/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Contents.json new file mode 100644 index 0000000..cb0e052 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "textures" : [ + { + "filename" : "Universal.mipmapset", + "idiom" : "universal" + } + ] +} diff --git a/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Universal.mipmapset/Contents.json b/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Universal.mipmapset/Contents.json new file mode 100644 index 0000000..1574a62 --- /dev/null +++ b/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Universal.mipmapset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "levels" : [ + { + "filename" : "point-texture.png", + "mipmap-level" : "base" + } + ] +} diff --git a/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Universal.mipmapset/point-texture.png b/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Universal.mipmapset/point-texture.png new file mode 100644 index 0000000..6653eb0 Binary files /dev/null and b/Memola/Resources/Assets/Assets.xcassets/textures/point-texture.textureset/Universal.mipmapset/point-texture.png differ diff --git a/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents b/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents new file mode 100644 index 0000000..bc23036 --- /dev/null +++ b/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file