diff --git a/Memola.xcodeproj/project.pbxproj b/Memola.xcodeproj/project.pbxproj index 8ce3dd4..b8a89fa 100644 --- a/Memola.xcodeproj/project.pbxproj +++ b/Memola.xcodeproj/project.pbxproj @@ -21,17 +21,12 @@ EC1815082C2D980B00541369 /* Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815072C2D980B00541369 /* Sort.swift */; }; EC18150A2C2DA09E00541369 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815092C2DA09E00541369 /* Filter.swift */; }; EC18150D2C2DAC3700541369 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC18150C2C2DAC3700541369 /* Placeholder.swift */; }; - EC18150F2C2DB13200541369 /* Date++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC18150E2C2DB13200541369 /* Date++.swift */; }; EC1B783D2BFA0AC9005A34E2 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */; }; EC2106AD2C10C2A700FBE27C /* AnyStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */; }; EC2BEBF42C0F5FF7005DB0AF /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */; }; EC2BEBF62C0F600D005DB0AF /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF52C0F600D005DB0AF /* Box.swift */; }; EC2BEBF82C0F601A005DB0AF /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF72C0F601A005DB0AF /* Node.swift */; }; - EC3565522BEFC65F00A4E0BF /* NSManagedObjectContext++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3565512BEFC65F00A4E0BF /* NSManagedObjectContext++.swift */; }; - EC3565542BEFC6AD00A4E0BF /* View++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3565532BEFC6AD00A4E0BF /* View++.swift */; }; - EC3565562BEFC7B300A4E0BF /* NSManagedObject++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3565552BEFC7B300A4E0BF /* NSManagedObject++.swift */; }; EC35655A2BF060D900A4E0BF /* Quad.metal in Sources */ = {isa = PBXBuildFile; fileRef = EC3565592BF060D900A4E0BF /* Quad.metal */; }; - EC35655C2BF0712A00A4E0BF /* Float++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC35655B2BF0712A00A4E0BF /* Float++.swift */; }; EC37FB122C1B2DD90008D976 /* ToolSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC37FB112C1B2DD90008D976 /* ToolSelection.swift */; }; EC42F7852C25267000E86E96 /* ElementGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC42F7842C25267000E86E96 /* ElementGroup.swift */; }; EC4538892BEBCAE000A86FEC /* Quad.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC4538882BEBCAE000A86FEC /* Quad.swift */; }; @@ -61,7 +56,6 @@ ECA7389C2BE601AF00A4542E /* PointGridVertex.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA7389B2BE601AF00A4542E /* PointGridVertex.swift */; }; ECA7389E2BE601CB00A4542E /* QuadVertex.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA7389D2BE601CB00A4542E /* QuadVertex.swift */; }; ECA738A02BE601E400A4542E /* ViewPortVertex.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA7389F2BE601E400A4542E /* ViewPortVertex.swift */; }; - ECA738A32BE6020A00A4542E /* CGFloat++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738A22BE6020A00A4542E /* CGFloat++.swift */; }; ECA738A62BE6023F00A4542E /* GridUniforms.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738A52BE6023F00A4542E /* GridUniforms.swift */; }; ECA738A82BE6025900A4542E /* GraphicUniforms.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738A72BE6025900A4542E /* GraphicUniforms.swift */; }; ECA738AA2BE6026D00A4542E /* Uniforms.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738A92BE6026D00A4542E /* Uniforms.swift */; }; @@ -88,22 +82,11 @@ ECA738E02BE610B900A4542E /* EraserRenderPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738DF2BE610B900A4542E /* EraserRenderPass.swift */; }; ECA738E22BE610D000A4542E /* GraphicRenderPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738E12BE610D000A4542E /* GraphicRenderPass.swift */; }; ECA738E42BE6110800A4542E /* Drawable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738E32BE6110800A4542E /* Drawable.swift */; }; - ECA738E62BE611FD00A4542E /* CGRect++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738E52BE611FD00A4542E /* CGRect++.swift */; }; - ECA738E82BE6120F00A4542E /* Color++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738E72BE6120F00A4542E /* Color++.swift */; }; - ECA738EA2BE6122E00A4542E /* CGPoint++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738E92BE6122E00A4542E /* CGPoint++.swift */; }; - ECA738EC2BE6124E00A4542E /* CGAffineTransform++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738EB2BE6124E00A4542E /* CGAffineTransform++.swift */; }; - ECA738EE2BE6125D00A4542E /* simd_float4x4++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738ED2BE6125D00A4542E /* simd_float4x4++.swift */; }; - ECA738F02BE6127700A4542E /* CGSize++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738EF2BE6127700A4542E /* CGSize++.swift */; }; - ECA738F22BE6128F00A4542E /* Collection++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738F12BE6128F00A4542E /* Collection++.swift */; }; - ECA738F42BE612A000A4542E /* Array++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738F32BE612A000A4542E /* Array++.swift */; }; - ECA738F62BE612B700A4542E /* MTLDevice++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738F52BE612B700A4542E /* MTLDevice++.swift */; }; ECA738FC2BE61C5200A4542E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA738FB2BE61C5200A4542E /* Persistence.swift */; }; ECA739082BE623F300A4542E /* PenDock.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA739072BE623F300A4542E /* PenDock.swift */; }; ECBE52962C1D5900006BDB3D /* PhotoPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBE52952C1D5900006BDB3D /* PhotoPreview.swift */; }; ECBE529C2C1D94A4006BDB3D /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBE529A2C1D94A4006BDB3D /* CameraView.swift */; }; - ECBE529E2C1DAB21006BDB3D /* UIImage++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */; }; ECC995A32C1E8F2800B2699A /* PhotoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC995A22C1E8F2800B2699A /* PhotoItem.swift */; }; - ECC995A52C1EB4CC00B2699A /* Data++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC995A42C1EB4CC00B2699A /* Data++.swift */; }; ECD12A862C19EE3900B96E12 /* ElementObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A852C19EE3900B96E12 /* ElementObject.swift */; }; ECD12A8A2C19EFB000B96E12 /* Element.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A892C19EFB000B96E12 /* Element.swift */; }; ECD12A8C2C1AEAA900B96E12 /* PhotoObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A8B2C1AEAA900B96E12 /* PhotoObject.swift */; }; @@ -113,11 +96,29 @@ ECD12A952C1B1FA200B96E12 /* PhotoVertex.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A942C1B1FA200B96E12 /* PhotoVertex.swift */; }; ECDAC07B2C318DBC0000ED77 /* ElementToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECDAC07A2C318DBC0000ED77 /* ElementToolbar.swift */; }; ECDDD40D2C366B3B00DF9D5E /* PreviewRenderPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECDDD40C2C366B3B00DF9D5E /* PreviewRenderPass.swift */; }; - ECDDD40F2C368B2700DF9D5E /* MTLTexture++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECDDD40E2C368B2700DF9D5E /* MTLTexture++.swift */; }; ECE883BD2C00AA170045C53D /* EraserStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECE883BC2C00AA170045C53D /* EraserStroke.swift */; }; ECE883BF2C00AB440045C53D /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECE883BE2C00AB440045C53D /* Stroke.swift */; }; ECE883C12C00C9CB0045C53D /* StrokeStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECE883C02C00C9CB0045C53D /* StrokeStyle.swift */; }; ECEC01A82BEE11BA006DA24C /* QuadShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECEC01A72BEE11BA006DA24C /* QuadShape.swift */; }; + ECF7B2D02C39169C004D2C57 /* Array++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2BD2C39169C004D2C57 /* Array++.swift */; }; + ECF7B2D12C39169C004D2C57 /* CGAffineTransform++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2BE2C39169C004D2C57 /* CGAffineTransform++.swift */; }; + ECF7B2D22C39169C004D2C57 /* CGFloat++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2BF2C39169C004D2C57 /* CGFloat++.swift */; }; + ECF7B2D32C39169C004D2C57 /* CGPoint++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C02C39169C004D2C57 /* CGPoint++.swift */; }; + ECF7B2D42C39169C004D2C57 /* CGRect++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C12C39169C004D2C57 /* CGRect++.swift */; }; + ECF7B2D52C39169C004D2C57 /* CGSize++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C22C39169C004D2C57 /* CGSize++.swift */; }; + ECF7B2D62C39169C004D2C57 /* Collection++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C32C39169C004D2C57 /* Collection++.swift */; }; + ECF7B2D72C39169C004D2C57 /* Color++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C42C39169C004D2C57 /* Color++.swift */; }; + ECF7B2D82C39169C004D2C57 /* Data++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C52C39169C004D2C57 /* Data++.swift */; }; + ECF7B2D92C39169C004D2C57 /* Date++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C62C39169C004D2C57 /* Date++.swift */; }; + ECF7B2DA2C39169C004D2C57 /* Float++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C72C39169C004D2C57 /* Float++.swift */; }; + ECF7B2DB2C39169C004D2C57 /* MTLDevice++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C82C39169C004D2C57 /* MTLDevice++.swift */; }; + ECF7B2DC2C39169C004D2C57 /* MTLTexture++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2C92C39169C004D2C57 /* MTLTexture++.swift */; }; + ECF7B2DD2C39169C004D2C57 /* NSManagedObject++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2CA2C39169C004D2C57 /* NSManagedObject++.swift */; }; + ECF7B2DE2C39169C004D2C57 /* NSManagedObjectContext++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2CB2C39169C004D2C57 /* NSManagedObjectContext++.swift */; }; + ECF7B2DF2C39169C004D2C57 /* simd_float4x4++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2CC2C39169C004D2C57 /* simd_float4x4++.swift */; }; + ECF7B2E02C39169C004D2C57 /* Image++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2CD2C39169C004D2C57 /* Image++.swift */; }; + ECF7B2E12C39169C004D2C57 /* View++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2CE2C39169C004D2C57 /* View++.swift */; }; + ECF7B2E42C39174D004D2C57 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF7B2E32C39174D004D2C57 /* Platform.swift */; }; ECFA15202BEF21EF00455818 /* MemoObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECFA151F2BEF21EF00455818 /* MemoObject.swift */; }; ECFA15222BEF21F500455818 /* CanvasObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECFA15212BEF21F500455818 /* CanvasObject.swift */; }; ECFA15242BEF223300455818 /* GraphicContextObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECFA15232BEF223300455818 /* GraphicContextObject.swift */; }; @@ -141,17 +142,12 @@ EC1815072C2D980B00541369 /* Sort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sort.swift; sourceTree = ""; }; EC1815092C2DA09E00541369 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = ""; }; EC18150C2C2DAC3700541369 /* Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = ""; }; - EC18150E2C2DB13200541369 /* Date++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date++.swift"; sourceTree = ""; }; EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = ""; }; EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyStroke.swift; sourceTree = ""; }; EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = ""; }; EC2BEBF52C0F600D005DB0AF /* Box.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Box.swift; sourceTree = ""; }; EC2BEBF72C0F601A005DB0AF /* Node.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = ""; }; - EC3565512BEFC65F00A4E0BF /* NSManagedObjectContext++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext++.swift"; sourceTree = ""; }; - EC3565532BEFC6AD00A4E0BF /* View++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View++.swift"; sourceTree = ""; }; - EC3565552BEFC7B300A4E0BF /* NSManagedObject++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObject++.swift"; sourceTree = ""; }; EC3565592BF060D900A4E0BF /* Quad.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Quad.metal; sourceTree = ""; }; - EC35655B2BF0712A00A4E0BF /* Float++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Float++.swift"; sourceTree = ""; }; EC37FB112C1B2DD90008D976 /* ToolSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolSelection.swift; sourceTree = ""; }; EC42F7842C25267000E86E96 /* ElementGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementGroup.swift; sourceTree = ""; }; EC4538882BEBCAE000A86FEC /* Quad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Quad.swift; sourceTree = ""; }; @@ -183,7 +179,6 @@ ECA7389B2BE601AF00A4542E /* PointGridVertex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointGridVertex.swift; sourceTree = ""; }; ECA7389D2BE601CB00A4542E /* QuadVertex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuadVertex.swift; sourceTree = ""; }; ECA7389F2BE601E400A4542E /* ViewPortVertex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewPortVertex.swift; sourceTree = ""; }; - ECA738A22BE6020A00A4542E /* CGFloat++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGFloat++.swift"; sourceTree = ""; }; ECA738A52BE6023F00A4542E /* GridUniforms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridUniforms.swift; sourceTree = ""; }; ECA738A72BE6025900A4542E /* GraphicUniforms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicUniforms.swift; sourceTree = ""; }; ECA738A92BE6026D00A4542E /* Uniforms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Uniforms.swift; sourceTree = ""; }; @@ -210,22 +205,11 @@ ECA738DF2BE610B900A4542E /* EraserRenderPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EraserRenderPass.swift; sourceTree = ""; }; ECA738E12BE610D000A4542E /* GraphicRenderPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicRenderPass.swift; sourceTree = ""; }; ECA738E32BE6110800A4542E /* Drawable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Drawable.swift; sourceTree = ""; }; - ECA738E52BE611FD00A4542E /* CGRect++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect++.swift"; sourceTree = ""; }; - ECA738E72BE6120F00A4542E /* Color++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color++.swift"; sourceTree = ""; }; - ECA738E92BE6122E00A4542E /* CGPoint++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGPoint++.swift"; sourceTree = ""; }; - ECA738EB2BE6124E00A4542E /* CGAffineTransform++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGAffineTransform++.swift"; sourceTree = ""; }; - ECA738ED2BE6125D00A4542E /* simd_float4x4++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "simd_float4x4++.swift"; sourceTree = ""; }; - ECA738EF2BE6127700A4542E /* CGSize++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGSize++.swift"; sourceTree = ""; }; - ECA738F12BE6128F00A4542E /* Collection++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection++.swift"; sourceTree = ""; }; - ECA738F32BE612A000A4542E /* Array++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array++.swift"; sourceTree = ""; }; - ECA738F52BE612B700A4542E /* MTLDevice++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MTLDevice++.swift"; sourceTree = ""; }; ECA738FB2BE61C5200A4542E /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; ECA739072BE623F300A4542E /* PenDock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenDock.swift; sourceTree = ""; }; ECBE52952C1D5900006BDB3D /* PhotoPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPreview.swift; sourceTree = ""; }; ECBE529A2C1D94A4006BDB3D /* CameraView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = ""; }; - ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage++.swift"; sourceTree = ""; }; ECC995A22C1E8F2800B2699A /* PhotoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoItem.swift; sourceTree = ""; }; - ECC995A42C1EB4CC00B2699A /* Data++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data++.swift"; sourceTree = ""; }; ECD12A852C19EE3900B96E12 /* ElementObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementObject.swift; sourceTree = ""; }; ECD12A892C19EFB000B96E12 /* Element.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Element.swift; sourceTree = ""; }; ECD12A8B2C1AEAA900B96E12 /* PhotoObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoObject.swift; sourceTree = ""; }; @@ -235,11 +219,29 @@ ECD12A942C1B1FA200B96E12 /* PhotoVertex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoVertex.swift; sourceTree = ""; }; ECDAC07A2C318DBC0000ED77 /* ElementToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementToolbar.swift; sourceTree = ""; }; ECDDD40C2C366B3B00DF9D5E /* PreviewRenderPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewRenderPass.swift; sourceTree = ""; }; - ECDDD40E2C368B2700DF9D5E /* MTLTexture++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MTLTexture++.swift"; sourceTree = ""; }; ECE883BC2C00AA170045C53D /* EraserStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EraserStroke.swift; sourceTree = ""; }; ECE883BE2C00AB440045C53D /* Stroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stroke.swift; sourceTree = ""; }; ECE883C02C00C9CB0045C53D /* StrokeStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrokeStyle.swift; sourceTree = ""; }; ECEC01A72BEE11BA006DA24C /* QuadShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuadShape.swift; sourceTree = ""; }; + ECF7B2BD2C39169C004D2C57 /* Array++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array++.swift"; sourceTree = ""; }; + ECF7B2BE2C39169C004D2C57 /* CGAffineTransform++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGAffineTransform++.swift"; sourceTree = ""; }; + ECF7B2BF2C39169C004D2C57 /* CGFloat++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGFloat++.swift"; sourceTree = ""; }; + ECF7B2C02C39169C004D2C57 /* CGPoint++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGPoint++.swift"; sourceTree = ""; }; + ECF7B2C12C39169C004D2C57 /* CGRect++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGRect++.swift"; sourceTree = ""; }; + ECF7B2C22C39169C004D2C57 /* CGSize++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGSize++.swift"; sourceTree = ""; }; + ECF7B2C32C39169C004D2C57 /* Collection++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Collection++.swift"; sourceTree = ""; }; + ECF7B2C42C39169C004D2C57 /* Color++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Color++.swift"; sourceTree = ""; }; + ECF7B2C52C39169C004D2C57 /* Data++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data++.swift"; sourceTree = ""; }; + ECF7B2C62C39169C004D2C57 /* Date++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date++.swift"; sourceTree = ""; }; + ECF7B2C72C39169C004D2C57 /* Float++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Float++.swift"; sourceTree = ""; }; + ECF7B2C82C39169C004D2C57 /* MTLDevice++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MTLDevice++.swift"; sourceTree = ""; }; + ECF7B2C92C39169C004D2C57 /* MTLTexture++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MTLTexture++.swift"; sourceTree = ""; }; + ECF7B2CA2C39169C004D2C57 /* NSManagedObject++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject++.swift"; sourceTree = ""; }; + ECF7B2CB2C39169C004D2C57 /* NSManagedObjectContext++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext++.swift"; sourceTree = ""; }; + ECF7B2CC2C39169C004D2C57 /* simd_float4x4++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "simd_float4x4++.swift"; sourceTree = ""; }; + ECF7B2CD2C39169C004D2C57 /* Image++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Image++.swift"; sourceTree = ""; }; + ECF7B2CE2C39169C004D2C57 /* View++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "View++.swift"; sourceTree = ""; }; + ECF7B2E32C39174D004D2C57 /* Platform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; ECFA151F2BEF21EF00455818 /* MemoObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoObject.swift; sourceTree = ""; }; ECFA15212BEF21F500455818 /* CanvasObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CanvasObject.swift; sourceTree = ""; }; ECFA15232BEF223300455818 /* GraphicContextObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicContextObject.swift; sourceTree = ""; }; @@ -455,13 +457,13 @@ children = ( ECA738762BE5EE4E00A4542E /* App */, ECA7387E2BE5FE4200A4542E /* Canvas */, - EC5050102BF670EE00B4D86E /* Config */, EC50500A2BF6672000B4D86E /* Components */, - ECA738A12BE601F700A4542E /* Extensions */, + EC5050102BF670EE00B4D86E /* Config */, ECA738772BE5EEE800A4542E /* Features */, ECA738FA2BE61B1700A4542E /* Persistence */, EC7F6BF12BE5E6E400A34A7B /* Preview Content */, ECA738802BE5FE6000A4542E /* Resources */, + ECF7B2E52C391DFA004D2C57 /* Utilies */, ); path = Memola; sourceTree = ""; @@ -613,31 +615,6 @@ path = Vertices; sourceTree = ""; }; - ECA738A12BE601F700A4542E /* Extensions */ = { - isa = PBXGroup; - children = ( - ECA738F32BE612A000A4542E /* Array++.swift */, - ECA738EB2BE6124E00A4542E /* CGAffineTransform++.swift */, - ECA738A22BE6020A00A4542E /* CGFloat++.swift */, - ECA738E92BE6122E00A4542E /* CGPoint++.swift */, - ECA738E52BE611FD00A4542E /* CGRect++.swift */, - ECA738EF2BE6127700A4542E /* CGSize++.swift */, - ECA738F12BE6128F00A4542E /* Collection++.swift */, - ECA738E72BE6120F00A4542E /* Color++.swift */, - ECA738F52BE612B700A4542E /* MTLDevice++.swift */, - ECA738ED2BE6125D00A4542E /* simd_float4x4++.swift */, - EC3565512BEFC65F00A4E0BF /* NSManagedObjectContext++.swift */, - EC3565532BEFC6AD00A4E0BF /* View++.swift */, - EC3565552BEFC7B300A4E0BF /* NSManagedObject++.swift */, - EC35655B2BF0712A00A4E0BF /* Float++.swift */, - ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */, - ECC995A42C1EB4CC00B2699A /* Data++.swift */, - EC18150E2C2DB13200541369 /* Date++.swift */, - ECDDD40E2C368B2700DF9D5E /* MTLTexture++.swift */, - ); - path = Extensions; - sourceTree = ""; - }; ECA738A42BE6022F00A4542E /* Uniforms */ = { isa = PBXGroup; children = ( @@ -871,6 +848,48 @@ path = Core; sourceTree = ""; }; + ECF7B2CF2C39169C004D2C57 /* Extensions */ = { + isa = PBXGroup; + children = ( + ECF7B2BD2C39169C004D2C57 /* Array++.swift */, + ECF7B2BE2C39169C004D2C57 /* CGAffineTransform++.swift */, + ECF7B2BF2C39169C004D2C57 /* CGFloat++.swift */, + ECF7B2C02C39169C004D2C57 /* CGPoint++.swift */, + ECF7B2C12C39169C004D2C57 /* CGRect++.swift */, + ECF7B2C22C39169C004D2C57 /* CGSize++.swift */, + ECF7B2C32C39169C004D2C57 /* Collection++.swift */, + ECF7B2C42C39169C004D2C57 /* Color++.swift */, + ECF7B2C52C39169C004D2C57 /* Data++.swift */, + ECF7B2C62C39169C004D2C57 /* Date++.swift */, + ECF7B2C72C39169C004D2C57 /* Float++.swift */, + ECF7B2C82C39169C004D2C57 /* MTLDevice++.swift */, + ECF7B2C92C39169C004D2C57 /* MTLTexture++.swift */, + ECF7B2CA2C39169C004D2C57 /* NSManagedObject++.swift */, + ECF7B2CB2C39169C004D2C57 /* NSManagedObjectContext++.swift */, + ECF7B2CC2C39169C004D2C57 /* simd_float4x4++.swift */, + ECF7B2CD2C39169C004D2C57 /* Image++.swift */, + ECF7B2CE2C39169C004D2C57 /* View++.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + ECF7B2E22C39172D004D2C57 /* Platform */ = { + isa = PBXGroup; + children = ( + ECF7B2E32C39174D004D2C57 /* Platform.swift */, + ); + path = Platform; + sourceTree = ""; + }; + ECF7B2E52C391DFA004D2C57 /* Utilies */ = { + isa = PBXGroup; + children = ( + ECF7B2CF2C39169C004D2C57 /* Extensions */, + ECF7B2E22C39172D004D2C57 /* Platform */, + ); + path = Utilies; + sourceTree = ""; + }; ECFA151E2BEF21BE00455818 /* Objects */ = { isa = PBXGroup; children = ( @@ -981,73 +1000,71 @@ EC8F54B02C2AF5E9001C7C74 /* LineGridContext.swift in Sources */, EC35655A2BF060D900A4E0BF /* Quad.metal in Sources */, ECA738912BE600F500A4542E /* Cache.metal in Sources */, + ECF7B2D82C39169C004D2C57 /* Data++.swift in Sources */, ECA7389C2BE601AF00A4542E /* PointGridVertex.swift in Sources */, ECA738A82BE6025900A4542E /* GraphicUniforms.swift in Sources */, EC01511E2C305CA9008A115E /* DashboardView.swift in Sources */, EC8F54AE2C2AF5A4001C7C74 /* LineGridVertex.swift in Sources */, - ECA738E62BE611FD00A4542E /* CGRect++.swift in Sources */, EC5E83902BFDB69C00261D9C /* MovingAverage.swift in Sources */, ECFA15262BEF224900455818 /* StrokeObject.swift in Sources */, - ECA738E82BE6120F00A4542E /* Color++.swift in Sources */, ECA738FC2BE61C5200A4542E /* Persistence.swift in Sources */, ECA7387A2BE5EF0400A4542E /* MemosView.swift in Sources */, ECA738BA2BE60DEF00A4542E /* HistoryAction.swift in Sources */, - EC3565522BEFC65F00A4E0BF /* NSManagedObjectContext++.swift in Sources */, ECFA15222BEF21F500455818 /* CanvasObject.swift in Sources */, ECA738AA2BE6026D00A4542E /* Uniforms.swift in Sources */, + ECF7B2D12C39169C004D2C57 /* CGAffineTransform++.swift in Sources */, EC1815082C2D980B00541369 /* Sort.swift in Sources */, ECA7387D2BE5EF4B00A4542E /* MemoView.swift in Sources */, ECDDD40D2C366B3B00DF9D5E /* PreviewRenderPass.swift in Sources */, + ECF7B2E12C39169C004D2C57 /* View++.swift in Sources */, ECA738DA2BE60FF100A4542E /* CacheRenderPass.swift in Sources */, + ECF7B2DA2C39169C004D2C57 /* Float++.swift in Sources */, ECA738CD2BE60F2F00A4542E /* PointGridContext.swift in Sources */, ECFA15202BEF21EF00455818 /* MemoObject.swift in Sources */, ECE883C12C00C9CB0045C53D /* StrokeStyle.swift in Sources */, EC37FB122C1B2DD90008D976 /* ToolSelection.swift in Sources */, ECA738C62BE60E9D00A4542E /* EraserPenStyle.swift in Sources */, - ECA738EA2BE6122E00A4542E /* CGPoint++.swift in Sources */, ECA738A62BE6023F00A4542E /* GridUniforms.swift in Sources */, ECA738D72BE60FC100A4542E /* SolidPointStrokeGenerator.swift in Sources */, - EC3565542BEFC6AD00A4E0BF /* View++.swift in Sources */, - ECBE529E2C1DAB21006BDB3D /* UIImage++.swift in Sources */, EC2BEBF62C0F600D005DB0AF /* Box.swift in Sources */, ECA738832BE5FEFE00A4542E /* RenderPass.swift in Sources */, ECEC01A82BEE11BA006DA24C /* QuadShape.swift in Sources */, + ECF7B2DC2C39169C004D2C57 /* MTLTexture++.swift in Sources */, ECA738862BE5FF2500A4542E /* Canvas.swift in Sources */, + ECF7B2DE2C39169C004D2C57 /* NSManagedObjectContext++.swift in Sources */, ECA738882BE5FF4400A4542E /* Renderer.swift in Sources */, + ECF7B2D72C39169C004D2C57 /* Color++.swift in Sources */, EC01512C2C306BEF008A115E /* MemoCard.swift in Sources */, ECA738D42BE60F9100A4542E /* StrokeGenerator.swift in Sources */, + ECF7B2D52C39169C004D2C57 /* CGSize++.swift in Sources */, ECA739082BE623F300A4542E /* PenDock.swift in Sources */, ECA738CB2BE60F1900A4542E /* ViewPortContext.swift in Sources */, - ECA738EE2BE6125D00A4542E /* simd_float4x4++.swift in Sources */, ECA7388C2BE6009600A4542E /* Textures.swift in Sources */, ECFC51272BF8885700D0D051 /* ColorPicker.swift in Sources */, ECA738B82BE60DDC00A4542E /* HistoryEvent.swift in Sources */, EC0D14262BF7A8C9009BFE5F /* PenObject.swift in Sources */, ECA738952BE6012D00A4542E /* ViewPort.metal in Sources */, ECD12A952C1B1FA200B96E12 /* PhotoVertex.swift in Sources */, + ECF7B2DD2C39169C004D2C57 /* NSManagedObject++.swift in Sources */, ECD12A8C2C1AEAA900B96E12 /* PhotoObject.swift in Sources */, ECD12A862C19EE3900B96E12 /* ElementObject.swift in Sources */, EC0D14242BF79C98009BFE5F /* MemolaModel.xcdatamodeld in Sources */, - ECA738F02BE6127700A4542E /* CGSize++.swift in Sources */, ECFA15242BEF223300455818 /* GraphicContextObject.swift in Sources */, - EC3565562BEFC7B300A4E0BF /* NSManagedObject++.swift in Sources */, - ECA738EC2BE6124E00A4542E /* CGAffineTransform++.swift in Sources */, - EC35655C2BF0712A00A4E0BF /* Float++.swift in Sources */, ECA738E22BE610D000A4542E /* GraphicRenderPass.swift in Sources */, ECE883BF2C00AB440045C53D /* Stroke.swift in Sources */, ECA738DC2BE6108D00A4542E /* StrokeRenderPass.swift in Sources */, - ECA738F42BE612A000A4542E /* Array++.swift in Sources */, + ECF7B2D22C39169C004D2C57 /* CGFloat++.swift in Sources */, EC4538892BEBCAE000A86FEC /* Quad.swift in Sources */, ECE883BD2C00AA170045C53D /* EraserStroke.swift in Sources */, EC42F7852C25267000E86E96 /* ElementGroup.swift in Sources */, - EC18150F2C2DB13200541369 /* Date++.swift in Sources */, ECD12A8F2C1AEBA400B96E12 /* Photo.swift in Sources */, + ECF7B2D42C39169C004D2C57 /* CGRect++.swift in Sources */, + ECF7B2D62C39169C004D2C57 /* Collection++.swift in Sources */, EC0151232C306089008A115E /* Sidebar.swift in Sources */, ECD12A932C1B062000B96E12 /* Photo.metal in Sources */, ECA7388F2BE600DA00A4542E /* Grid.metal in Sources */, EC2BEBF42C0F5FF7005DB0AF /* RTree.swift in Sources */, ECA738C92BE60EF700A4542E /* GraphicContext.swift in Sources */, - ECA738F62BE612B700A4542E /* MTLDevice++.swift in Sources */, EC0D14212BF79C73009BFE5F /* ToolObject.swift in Sources */, ECDAC07B2C318DBC0000ED77 /* ElementToolbar.swift in Sources */, EC50500D2BF6674400B4D86E /* OnDragViewModifier.swift in Sources */, @@ -1059,30 +1076,33 @@ EC01512A2C306935008A115E /* MemoGrid.swift in Sources */, ECA738C42BE60E8800A4542E /* MarkerPenStyle.swift in Sources */, EC0151262C3067B9008A115E /* TrashView.swift in Sources */, + ECF7B2D92C39169C004D2C57 /* Date++.swift in Sources */, ECA738BF2BE60E3400A4542E /* Pen.swift in Sources */, ECFA15282BEF225000455818 /* QuadObject.swift in Sources */, ECA738932BE6011100A4542E /* Stroke.metal in Sources */, ECA738B62BE60DCD00A4542E /* History.swift in Sources */, ECA738D22BE60F7B00A4542E /* PenStroke.swift in Sources */, EC01512E2C30727F008A115E /* MemoPreview.swift in Sources */, - ECA738F22BE6128F00A4542E /* Collection++.swift in Sources */, EC5050072BF65CED00B4D86E /* PenDropDelegate.swift in Sources */, - ECA738A32BE6020A00A4542E /* CGFloat++.swift in Sources */, + ECF7B2E42C39174D004D2C57 /* Platform.swift in Sources */, ECA738C12BE60E5300A4542E /* PenStyle.swift in Sources */, + ECF7B2DF2C39169C004D2C57 /* simd_float4x4++.swift in Sources */, + ECF7B2D02C39169C004D2C57 /* Array++.swift in Sources */, ECBE52962C1D5900006BDB3D /* PhotoPreview.swift in Sources */, ECA738DE2BE610A000A4542E /* ViewPortRenderPass.swift in Sources */, EC8F54AC2C2ACDA8001C7C74 /* GridMode.swift in Sources */, EC7F6BEC2BE5E6E300A34A7B /* MemolaApp.swift in Sources */, EC2BEBF82C0F601A005DB0AF /* Node.swift in Sources */, - ECDDD40F2C368B2700DF9D5E /* MTLTexture++.swift in Sources */, - ECC995A52C1EB4CC00B2699A /* Data++.swift in Sources */, ECA738A02BE601E400A4542E /* ViewPortVertex.swift in Sources */, ECD12A8A2C19EFB000B96E12 /* Element.swift in Sources */, EC0D14282BF7BF20009BFE5F /* ContextMenuViewModifier.swift in Sources */, EC2106AD2C10C2A700FBE27C /* AnyStroke.swift in Sources */, + ECF7B2DB2C39169C004D2C57 /* MTLDevice++.swift in Sources */, ECC995A32C1E8F2800B2699A /* PhotoItem.swift in Sources */, ECA738BC2BE60E0300A4542E /* Tool.swift in Sources */, + ECF7B2E02C39169C004D2C57 /* Image++.swift in Sources */, ECA738972BE6014200A4542E /* Graphic.metal in Sources */, + ECF7B2D32C39169C004D2C57 /* CGPoint++.swift in Sources */, ECA7388A2BE6006A00A4542E /* PipelineStates.swift in Sources */, EC18150D2C2DAC3700541369 /* Placeholder.swift in Sources */, ); @@ -1231,12 +1251,13 @@ "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.0; MARKETING_VERSION = 1.0; MTLLINKER_FLAGS = ""; MTL_COMPILER_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.example.Memola; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1266,12 +1287,13 @@ "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.0; MARKETING_VERSION = 1.0; MTLLINKER_FLAGS = ""; MTL_COMPILER_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.example.Memola; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/Memola/App/MemolaApp.swift b/Memola/App/MemolaApp.swift index c5aca74..ed5c025 100644 --- a/Memola/App/MemolaApp.swift +++ b/Memola/App/MemolaApp.swift @@ -13,7 +13,7 @@ struct MemolaApp: App { WindowGroup { DashboardView() .persistence(\.viewContext) - .onReceive(NotificationCenter.default.publisher(for: UIApplication.willTerminateNotification)) { _ in + .onReceive(NotificationCenter.default.publisher(for: Platform.Application.willTerminateNotification)) { _ in withPersistenceSync(\.viewContext) { context in try context.saveIfNeeded() } diff --git a/Memola/Canvas/Core/Canvas.swift b/Memola/Canvas/Core/Canvas.swift index 1798f51..f1546b5 100644 --- a/Memola/Canvas/Core/Canvas.swift +++ b/Memola/Canvas/Core/Canvas.swift @@ -85,7 +85,11 @@ extension Canvas { func save(for memoObject: MemoObject, completion: @escaping () -> Void) { state = .closing let previewImage = renderer?.drawPreview(on: self) + #if os(macOS) + #warning("TODO: implement for macos") + #else memoObject.preview = previewImage?.jpegData(compressionQuality: 0.8) + #endif withPersistenceSync(\.viewContext) { context in try context.saveIfNeeded() } @@ -135,7 +139,7 @@ extension Canvas { self.previewTransform = simd_float4x4(transform) } - func updateClipBounds(_ scrollView: UIScrollView, on drawingView: DrawingView) { + func updateClipBounds(_ scrollView: Platform.ScrollView, on drawingView: DrawingView) { let ratio = drawingView.ratio let bounds = scrollView.convert(scrollView.bounds, to: drawingView) clipBounds = CGRect(origin: bounds.origin.muliply(by: ratio), size: bounds.size.multiply(by: ratio)) diff --git a/Memola/Canvas/Core/Renderer.swift b/Memola/Canvas/Core/Renderer.swift index e5292b9..7d43ceb 100644 --- a/Memola/Canvas/Core/Renderer.swift +++ b/Memola/Canvas/Core/Renderer.swift @@ -110,7 +110,7 @@ final class Renderer { viewPortRenderPass.draw(into: commandBuffer, on: canvas, with: self) } - func drawPreview(on canvas: Canvas) -> UIImage? { + func drawPreview(on canvas: Canvas) -> Platform.Image? { guard let commandBuffer = commandQueue.makeCommandBuffer() else { NSLog("[Memola] - Unable to create command buffer") return nil @@ -124,6 +124,11 @@ final class Renderer { guard let cgImage = previewRenderPass.previewTexture?.getImage() else { return nil } + #if os(macOS) + #warning("TODO: implement here") + return nil + #else return UIImage(cgImage: cgImage, scale: 1.0, orientation: .downMirrored) + #endif } } diff --git a/Memola/Canvas/Elements/Photo/Photo.swift b/Memola/Canvas/Elements/Photo/Photo.swift index cf2fdaa..ed6a77c 100644 --- a/Memola/Canvas/Elements/Photo/Photo.swift +++ b/Memola/Canvas/Elements/Photo/Photo.swift @@ -12,7 +12,7 @@ final class Photo: @unchecked Sendable, Equatable { var id: UUID = UUID() var size: CGSize var origin: CGPoint - var image: UIImage? + var image: Platform.Image? var url: URL? var bounds: [CGFloat] var createdAt: Date diff --git a/Memola/Canvas/Tool/Core/Tool.swift b/Memola/Canvas/Tool/Core/Tool.swift index 38d9b9e..cb906f7 100644 --- a/Memola/Canvas/Tool/Core/Tool.swift +++ b/Memola/Canvas/Tool/Core/Tool.swift @@ -127,7 +127,7 @@ public class Tool: NSObject, ObservableObject { } } - func selectPhoto(_ image: UIImage, for canvasID: NSManagedObjectID) { + func selectPhoto(_ image: Platform.Image, for canvasID: NSManagedObjectID) { guard let (resizedImage, dimension) = resizePhoto(of: image) else { return } let photoItem = bookmarkPhoto(of: resizedImage, and: image, in: dimension, with: canvasID) withAnimation { @@ -136,7 +136,7 @@ public class Tool: NSObject, ObservableObject { } } - private func resizePhoto(of image: UIImage) -> (UIImage, CGSize)? { + private func resizePhoto(of image: Platform.Image) -> (Platform.Image, CGSize)? { let targetSize = CGSize(width: 512, height: 512) let size = image.size let widthRatio = targetSize.width / size.width @@ -147,6 +147,9 @@ public class Tool: NSObject, ObservableObject { ) let rect = CGRect(origin: .zero, size: targetSize) + #if os(macOS) + return (image, dimension) + #else UIGraphicsBeginImageContextWithOptions(targetSize, true, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() @@ -155,10 +158,16 @@ public class Tool: NSObject, ObservableObject { guard let newImage else { return nil } return (newImage, dimension) + #endif } - private func bookmarkPhoto(of image: UIImage, and previewImage: UIImage, in dimension: CGSize, with canvasID: NSManagedObjectID) -> PhotoItem? { + private func bookmarkPhoto(of image: Platform.Image, and previewImage: Platform.Image, in dimension: CGSize, with canvasID: NSManagedObjectID) -> PhotoItem? { + #if os(macOS) + #warning("TODO: implement for macos") + let data = Data() + #else guard let data = image.jpegData(compressionQuality: 1) else { return nil } + #endif let fileManager = FileManager.default guard let directory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil diff --git a/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift b/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift index 3875932..c1342d4 100644 --- a/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift +++ b/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift @@ -10,14 +10,14 @@ import SwiftUI import MetalKit import Foundation -class CanvasViewController: UIViewController { +class CanvasViewController: Platform.ViewController { let drawingView: DrawingView - let scrollView: UIScrollView = UIScrollView() + let scrollView: Platform.ScrollView = Platform.ScrollView() var renderView: MTKView { drawingView.renderView } - var photoInsertGesture: UITapGestureRecognizer? + var photoInsertGesture: Platform.TapGestureRecognizer? let tool: Tool let canvas: Canvas @@ -47,6 +47,28 @@ class CanvasViewController: UIViewController { configureListeners() } + #if os(macOS) + override func viewWillAppear() { + super.viewWillAppear() + resizeDocumentView() + updateDocumentBounds() + loadMemo() + } + + override func viewDidLayout() { + super.viewDidLayout() + drawingView.disableUserInteraction() + drawingView.updateDrawableSize(with: view.frame.size) + renderer.resize(on: renderView, to: renderView.drawableSize) + renderView.draw() + drawingView.enableUserInteraction() + } + + override func viewDidDisappear() { + super.viewDidDisappear() + history.resetRedo() + } + #else override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) resizeDocumentView() @@ -67,11 +89,16 @@ class CanvasViewController: UIViewController { super.viewDidDisappear(animated) history.resetRedo() } + #endif } extension CanvasViewController { func configureViews() { + #if os(macOS) + #warning("TODO: implement for macos") + #else view.backgroundColor = .white + renderView.autoResizeDrawable = false renderView.enableSetNeedsDisplay = true renderView.translatesAutoresizingMaskIntoConstraints = false @@ -105,9 +132,13 @@ extension CanvasViewController { scrollView.addSubview(drawingView) drawingView.backgroundColor = .clear drawingView.isUserInteractionEnabled = false + #endif } func resizeDocumentView(to newSize: CGSize? = nil) { + #if os(macOS) + #warning("TODO: implement for macos") + #else scrollView.layoutIfNeeded() let size = canvas.size @@ -130,17 +161,25 @@ extension CanvasViewController { scrollView.setContentOffset(point, animated: true) drawingView.updateDrawableSize(with: view.frame.size) + #endif } func centerDocumentView(to newSize: CGSize? = nil) { + #if os(macOS) + #warning("TODO: implement for macos") + #else let documentViewSize = drawingView.frame.size let scrollViewSize = newSize ?? view.frame.size let verticalPadding = documentViewSize.height < scrollViewSize.height ? (scrollViewSize.height - documentViewSize.height) / 2 : 0 let horizontalPadding = documentViewSize.width < scrollViewSize.width ? (scrollViewSize.width - documentViewSize.width) / 2 : 0 self.scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding) + #endif } func updateDocumentBounds() { + #if os(macOS) + #warning("TODO: implement for macos") + #else var bounds = scrollView.bounds.muliply(by: drawingView.ratio / scrollView.zoomScale) let xDelta = bounds.minX * 0.0 let yDelta = bounds.minY * 0.0 @@ -152,6 +191,7 @@ extension CanvasViewController { if canvas.state == .loaded { canvas.loadStrokes(bounds) } + #endif } } @@ -231,13 +271,17 @@ extension CanvasViewController: MTKViewDelegate { extension CanvasViewController { func configureGestures() { - let photoInsertGesture = UITapGestureRecognizer(target: self, action: #selector(recognizeTapGesture)) + let photoInsertGesture = Platform.TapGestureRecognizer(target: self, action: #selector(recognizeTapGesture)) + #if os(macOS) + photoInsertGesture.numberOfClicksRequired = 1 + #else photoInsertGesture.numberOfTapsRequired = 1 + #endif self.photoInsertGesture = photoInsertGesture scrollView.addGestureRecognizer(photoInsertGesture) } - @objc func recognizeTapGesture(_ gesture: UITapGestureRecognizer) { + @objc func recognizeTapGesture(_ gesture: Platform.TapGestureRecognizer) { guard let photoItem = tool.selectedPhotoItem else { return } withAnimation { tool.selectedPhotoItem = nil @@ -249,6 +293,8 @@ extension CanvasViewController { } } +#if os(macOS) +#else extension CanvasViewController: UIScrollViewDelegate { func viewForZooming(in scrollView: UIScrollView) -> UIView? { drawingView @@ -294,6 +340,7 @@ extension CanvasViewController: UIScrollViewDelegate { draggingEnded() } } +#endif extension CanvasViewController { func magnificationStarted() { @@ -352,20 +399,32 @@ extension CanvasViewController { enablesDrawing = false enablesPhotoInsertion = true } + #if os(macOS) + #warning("TODO: implement for macos") + #else scrollView.isScrollEnabled = enablesScrolling drawingView.isUserInteractionEnabled = enablesDrawing photoInsertGesture?.isEnabled = enablesPhotoInsertion enablesDrawing ? drawingView.enableUserInteraction() : drawingView.disableUserInteraction() + #endif } } extension CanvasViewController { func zoomChanged(_ zoomScale: CGFloat) { + #if os(macOS) + #warning("TODO: implement for macos") + #else scrollView.setZoomScale(zoomScale, animated: true) + #endif } func lockModeChanged(_ state: Bool) { + #if os(macOS) + #warning("TODO: implement for macos") + #else scrollView.pinchGestureRecognizer?.isEnabled = !state + #endif } func gridModeChanged(_ mode: GridMode) { diff --git a/Memola/Canvas/View/Bridge/Views/DrawingView.swift b/Memola/Canvas/View/Bridge/Views/DrawingView.swift index 2e98577..be3a87a 100644 --- a/Memola/Canvas/View/Bridge/Views/DrawingView.swift +++ b/Memola/Canvas/View/Bridge/Views/DrawingView.swift @@ -5,11 +5,11 @@ // Created by Dscyre Scotti on 5/4/24. // -import UIKit +import SwiftUI import MetalKit import Foundation -class DrawingView: UIView { +class DrawingView: Platform.View { let tool: Tool let canvas: Canvas let history: History @@ -36,7 +36,10 @@ class DrawingView: UIView { func updateDrawableSize(with size: CGSize) { renderView.drawableSize = size.multiply(by: 2) } - + + #if os(macOS) + #warning("TODO: to implement touch events") + #else override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { !canvas.hasValidStroke } @@ -78,6 +81,7 @@ class DrawingView: UIView { let point = touch.preciseLocation(in: self) touchEnded(at: point) } + #endif func touchBegan(at point: CGPoint) { guard !disablesUserInteraction else { return } diff --git a/Memola/Canvas/View/Canvas/CanvasView.swift b/Memola/Canvas/View/Canvas/CanvasView.swift index d697358..9c03657 100644 --- a/Memola/Canvas/View/Canvas/CanvasView.swift +++ b/Memola/Canvas/View/Canvas/CanvasView.swift @@ -7,14 +7,22 @@ import SwiftUI -struct CanvasView: UIViewControllerRepresentable { +struct CanvasView: Platform.ViewControllerRepresentable { @ObservedObject var tool: Tool @ObservedObject var canvas: Canvas @ObservedObject var history: History + #if os(macOS) + func makeNSViewController(context: Context) -> CanvasViewController { + CanvasViewController(tool: tool, canvas: canvas, history: history) + } + + func updateNSViewController(_ nsViewController: CanvasViewController, context: Context) { } + #else func makeUIViewController(context: Context) -> CanvasViewController { CanvasViewController(tool: tool, canvas: canvas, history: history) } func updateUIViewController(_ uiViewController: CanvasViewController, context: Context) { } + #endif } diff --git a/Memola/Components/Views/CameraView/CameraView.swift b/Memola/Components/Views/CameraView/CameraView.swift index 4be3e8b..523a4ea 100644 --- a/Memola/Components/Views/CameraView/CameraView.swift +++ b/Memola/Components/Views/CameraView/CameraView.swift @@ -7,6 +7,7 @@ import SwiftUI +#if os(iOS) struct CameraView: UIViewControllerRepresentable { @Binding var image: UIImage? @@ -44,3 +45,4 @@ struct CameraView: UIViewControllerRepresentable { } } } +#endif diff --git a/Memola/Features/Dashboard/Dashboard/DashboardView.swift b/Memola/Features/Dashboard/Dashboard/DashboardView.swift index c6aa549..68cc0b3 100644 --- a/Memola/Features/Dashboard/Dashboard/DashboardView.swift +++ b/Memola/Features/Dashboard/Dashboard/DashboardView.swift @@ -26,6 +26,9 @@ struct DashboardView: View { MemosView(memo: $memo) } } + #if os(macOS) + #warning("TODO: implement for macOS") + #else .fullScreenCover(item: $memo) { memo in MemoView(memo: memo) .onDisappear { @@ -35,5 +38,6 @@ struct DashboardView: View { } } } + #endif } } diff --git a/Memola/Features/Dashboard/Details/Memos/MemosView.swift b/Memola/Features/Dashboard/Details/Memos/MemosView.swift index 53e71ae..726c629 100644 --- a/Memola/Features/Dashboard/Details/Memos/MemosView.swift +++ b/Memola/Features/Dashboard/Details/Memos/MemosView.swift @@ -46,9 +46,14 @@ struct MemosView: View { memoCard(memoObject, cellWidth) } .navigationTitle(horizontalSizeClass == .compact ? "Memos" : "") + #if os(iOS) .navigationBarTitleDisplayMode(.inline) + #endif .searchable(text: $query, placement: .toolbar, prompt: Text("Search")) .toolbar { + #if os(macOS) + #warning("TODO: implement for macos") + #else if horizontalSizeClass == .regular { ToolbarItem(placement: .topBarLeading) { Text("Memola") @@ -111,6 +116,7 @@ struct MemosView: View { } } } + #endif } .onChange(of: sort) { oldValue, newValue in memoObjects.sortDescriptors = newValue.memoSortDescriptors diff --git a/Memola/Features/Dashboard/Details/Shared/MemoGrid.swift b/Memola/Features/Dashboard/Details/Shared/MemoGrid.swift index 319fc14..2b4fa69 100644 --- a/Memola/Features/Dashboard/Details/Shared/MemoGrid.swift +++ b/Memola/Features/Dashboard/Details/Shared/MemoGrid.swift @@ -42,6 +42,10 @@ struct MemoGrid: View { } } } - .background(Color(uiColor: .secondarySystemBackground)) + #if os(macOS) + .background(Color(color: .windowBackgroundColor)) + #else + .background(Color(color: .secondarySystemBackground)) + #endif } } diff --git a/Memola/Features/Dashboard/Details/Shared/MemoPreview.swift b/Memola/Features/Dashboard/Details/Shared/MemoPreview.swift index c5fc94c..b57f80f 100644 --- a/Memola/Features/Dashboard/Details/Shared/MemoPreview.swift +++ b/Memola/Features/Dashboard/Details/Shared/MemoPreview.swift @@ -21,8 +21,8 @@ struct MemoPreview: View { var body: some View { Group { - if let preview, let previewImage = UIImage(data: preview) { - Image(uiImage: previewImage) + if let preview, let previewImage = Platform.Image(data: preview) { + Image(image: previewImage) .resizable() .aspectRatio(contentMode: .fit) } else { diff --git a/Memola/Features/Dashboard/Details/Trash/TrashView.swift b/Memola/Features/Dashboard/Details/Trash/TrashView.swift index 815e068..f5af75e 100644 --- a/Memola/Features/Dashboard/Details/Trash/TrashView.swift +++ b/Memola/Features/Dashboard/Details/Trash/TrashView.swift @@ -46,9 +46,14 @@ struct TrashView: View { memoCard(memoObject, cellWidth) } .navigationTitle(horizontalSizeClass == .compact ? "Trash" : "") + #if os(iOS) .navigationBarTitleDisplayMode(.inline) + #endif .searchable(text: $query, placement: .toolbar, prompt: Text("Search")) .toolbar { + #if os(macOS) + #warning("TODO: implement for macos") + #else if horizontalSizeClass == .regular { ToolbarItem(placement: .topBarLeading) { Text("Memola") @@ -56,6 +61,7 @@ struct TrashView: View { .fontWeight(.bold) } } + #endif } .onChange(of: query) { oldValue, newValue in updatePredicate() diff --git a/Memola/Features/Dashboard/Sidebar/Sidebar.swift b/Memola/Features/Dashboard/Sidebar/Sidebar.swift index 06eb780..0314677 100644 --- a/Memola/Features/Dashboard/Sidebar/Sidebar.swift +++ b/Memola/Features/Dashboard/Sidebar/Sidebar.swift @@ -38,9 +38,15 @@ struct Sidebar: View { .listStyle(.sidebar) .navigationTitle(horizontalSizeClass == .compact ? "Memola" : "") .scrollContentBackground(.hidden) - .background(Color(uiColor: .secondarySystemBackground)) + #if os(macOS) + .background(Color(color: .windowBackgroundColor)) + #else + .background(Color(color: .secondarySystemBackground)) + #endif .navigationSplitViewColumnWidth(min: 250, ideal: 250, max: 250) + #if os(iOS) .navigationBarTitleDisplayMode(horizontalSizeClass == .compact ? .automatic : .inline) + #endif } } diff --git a/Memola/Features/Memo/ElementToolbar/ElementToolbar.swift b/Memola/Features/Memo/ElementToolbar/ElementToolbar.swift index d3c62a3..3d2873c 100644 --- a/Memola/Features/Memo/ElementToolbar/ElementToolbar.swift +++ b/Memola/Features/Memo/ElementToolbar/ElementToolbar.swift @@ -43,6 +43,7 @@ struct ElementToolbar: View { .padding(.bottom, 10) } } + #if os(iOS) .fullScreenCover(isPresented: $opensCamera) { let image: Binding = Binding { tool.selectedPhotoItem?.image @@ -55,8 +56,8 @@ struct ElementToolbar: View { } .alert("Camera Access Denied", isPresented: $isCameraAccessDenied) { Button { - if let url = URL(string: UIApplication.openSettingsURLString + "&path=CAMERA/\(String(describing: Bundle.main.bundleIdentifier))") { - UIApplication.shared.open(url) + if let url = URL(string: Platform.Application.openSettingsURLString + "&path=CAMERA/\(String(describing: Bundle.main.bundleIdentifier))") { + Platform.Application.shared.open(url) } } label: { Text("Open Settings") @@ -65,12 +66,13 @@ struct ElementToolbar: View { } message: { Text("Memola requires access to the camera to capture photos. Please open Settings and enable camera access.") } + #endif .onChange(of: photosPickerItem) { oldValue, newValue in if newValue != nil { Task { tool.isLoadingPhoto = true let data = try? await newValue?.loadTransferable(type: Data.self) - if let data, let image = UIImage(data: data) { + if let data, let image = Platform.Image(data: data) { tool.selectPhoto(image, for: canvas.canvasID) } photosPickerItem = nil @@ -93,7 +95,9 @@ struct ElementToolbar: View { .foregroundStyle(tool.selection == .hand ? Color.white : Color.accentColor) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif .background { if tool.selection == .hand { Color.accentColor @@ -113,7 +117,9 @@ struct ElementToolbar: View { .foregroundStyle(tool.selection == .pen ? Color.white : Color.accentColor) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif .background { if tool.selection == .pen { Color.accentColor @@ -133,7 +139,9 @@ struct ElementToolbar: View { .foregroundStyle(tool.selection == .photo ? Color.white : Color.accentColor) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif .background { if tool.selection == .photo { Color.accentColor @@ -179,7 +187,9 @@ struct ElementToolbar: View { .frame(width: size, height: size) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif Button { withAnimation { tool.selectTool(.photo) @@ -190,7 +200,9 @@ struct ElementToolbar: View { .frame(width: size, height: size) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif } .background { RoundedRectangle(cornerRadius: 8) @@ -211,14 +223,18 @@ struct ElementToolbar: View { .frame(width: size, height: size) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif PhotosPicker(selection: $photosPickerItem, matching: .images, preferredItemEncoding: .compatible) { Image(systemName: "photo.fill.on.rectangle.fill") .contentShape(.circle) .frame(width: size, height: size) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif } } diff --git a/Memola/Features/Memo/Memo/MemoView.swift b/Memola/Features/Memo/Memo/MemoView.swift index 722e431..13c9d2d 100644 --- a/Memola/Features/Memo/Memo/MemoView.swift +++ b/Memola/Features/Memo/Memo/MemoView.swift @@ -158,7 +158,9 @@ struct MemoView: View { .clipShape(.rect(cornerRadius: 8)) .padding(10) } + #if os(iOS) .hoverEffect(.lift) + #endif .transition(.move(edge: .bottom).combined(with: .blurReplace)) } } diff --git a/Memola/Features/Memo/PenDock/PenDock.swift b/Memola/Features/Memo/PenDock/PenDock.swift index f053c3a..677980f 100644 --- a/Memola/Features/Memo/PenDock/PenDock.swift +++ b/Memola/Features/Memo/PenDock/PenDock.swift @@ -201,7 +201,11 @@ struct PenDock: View { } preview: { penPreview(pen) .drawingGroup() + #if os(macOS) + #warning("TODO: implement for macos") + #else .contentShape(.contextMenuPreview, .rect(cornerRadius: 10)) + #endif } .onDrag(if: pen.strokeStyle != .eraser) { tool.draggedPen = pen @@ -274,7 +278,11 @@ struct PenDock: View { } preview: { penPreview(pen) .drawingGroup() + #if os(macOS) + #warning("TODO: implement for macos") + #else .contentShape(.contextMenuPreview, .rect(cornerRadius: 10)) + #endif } .onDrag(if: pen.strokeStyle != .eraser) { tool.draggedPen = pen @@ -356,7 +364,9 @@ struct PenDock: View { .drawingGroup() } .buttonStyle(.plain) + #if os(iOS) .hoverEffect(.lift) + #endif .popover(isPresented: $opensColorPicker) { let color = Binding( get: { pen.color }, @@ -397,8 +407,10 @@ struct PenDock: View { .frame(width: size + 2, height: size + 2) } } + #if os(iOS) .hoverEffect(.lift) .pickerStyle(.wheel) + #endif .frame(width: width * factor - 18, height: 35) .onChange(of: pen.thickness) { _, _ in withPersistence(\.viewContext) { context in @@ -429,8 +441,10 @@ struct PenDock: View { .frame(width: size + 2, height: size + 2) } } + #if os(iOS) .hoverEffect(.lift) .pickerStyle(.wheel) + #endif .frame(width: 50, height: 30) .onChange(of: pen.thickness) { _, _ in withPersistence(\.viewContext) { context in @@ -453,7 +467,9 @@ struct PenDock: View { } } .foregroundStyle(.green) + #if os(iOS) .hoverEffect(.lift) + #endif } func penPreview(_ pen: Pen) -> some View { @@ -532,7 +548,9 @@ struct PenDock: View { .background(.regularMaterial) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif .contentTransition(.symbolEffect(.replace)) } diff --git a/Memola/Features/Memo/PhotoPreview/PhotoItem.swift b/Memola/Features/Memo/PhotoPreview/PhotoItem.swift index 79e2539..821d7fb 100644 --- a/Memola/Features/Memo/PhotoPreview/PhotoItem.swift +++ b/Memola/Features/Memo/PhotoPreview/PhotoItem.swift @@ -5,13 +5,13 @@ // Created by Dscyre Scotti on 6/16/24. // -import UIKit +import SwiftUI import Foundation struct PhotoItem: Identifiable, Equatable { var id: URL - let image: UIImage - let previewImage: UIImage + let image: Platform.Image + let previewImage: Platform.Image let dimension: CGSize let bookmark: Data diff --git a/Memola/Features/Memo/PhotoPreview/PhotoPreview.swift b/Memola/Features/Memo/PhotoPreview/PhotoPreview.swift index beb923e..440d2f1 100644 --- a/Memola/Features/Memo/PhotoPreview/PhotoPreview.swift +++ b/Memola/Features/Memo/PhotoPreview/PhotoPreview.swift @@ -14,7 +14,7 @@ struct PhotoPreview: View { @ObservedObject var tool: Tool var body: some View { - Image(uiImage: photoItem.previewImage) + Image(image: photoItem.previewImage) .resizable() .scaledToFit() .frame(width: horizontalSizeClass == .compact ? 80 : nil, height: horizontalSizeClass == .compact ? nil : 100) @@ -40,7 +40,9 @@ struct PhotoPreview: View { } } .foregroundStyle(.red) + #if os(iOS) .hoverEffect(.lift) + #endif .offset(x: -12, y: -12) } .padding(10) diff --git a/Memola/Features/Memo/Toolbar/Toolbar.swift b/Memola/Features/Memo/Toolbar/Toolbar.swift index 1f41fbd..8ea359e 100644 --- a/Memola/Features/Memo/Toolbar/Toolbar.swift +++ b/Memola/Features/Memo/Toolbar/Toolbar.swift @@ -66,7 +66,9 @@ struct Toolbar: View { .background(.regularMaterial) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif .disabled(textFieldState) .transition(.move(edge: .top).combined(with: .blurReplace)) } @@ -103,7 +105,9 @@ struct Toolbar: View { Image(systemName: "arrow.uturn.backward.circle") .contentShape(.circle) } + #if os(iOS) .hoverEffect(.lift) + #endif .disabled(history.undoDisabled) Button { history.historyPublisher.send(.redo) @@ -111,7 +115,9 @@ struct Toolbar: View { Image(systemName: "arrow.uturn.forward.circle") .contentShape(.circle) } + #if os(iOS) .hoverEffect(.lift) + #endif .disabled(history.redoDisabled) } .frame(width: size * 2, height: size) @@ -142,7 +148,9 @@ struct Toolbar: View { .background(.regularMaterial) .clipShape(.rect(cornerRadius: 8)) } + #if os(iOS) .hoverEffect(.lift) + #endif .contentTransition(.symbolEffect(.replace)) .transition(.move(edge: .top).combined(with: .blurReplace)) } diff --git a/Memola/Extensions/Array++.swift b/Memola/Utilies/Extensions/Array++.swift similarity index 100% rename from Memola/Extensions/Array++.swift rename to Memola/Utilies/Extensions/Array++.swift diff --git a/Memola/Extensions/CGAffineTransform++.swift b/Memola/Utilies/Extensions/CGAffineTransform++.swift similarity index 100% rename from Memola/Extensions/CGAffineTransform++.swift rename to Memola/Utilies/Extensions/CGAffineTransform++.swift diff --git a/Memola/Extensions/CGFloat++.swift b/Memola/Utilies/Extensions/CGFloat++.swift similarity index 100% rename from Memola/Extensions/CGFloat++.swift rename to Memola/Utilies/Extensions/CGFloat++.swift diff --git a/Memola/Extensions/CGPoint++.swift b/Memola/Utilies/Extensions/CGPoint++.swift similarity index 100% rename from Memola/Extensions/CGPoint++.swift rename to Memola/Utilies/Extensions/CGPoint++.swift diff --git a/Memola/Extensions/CGRect++.swift b/Memola/Utilies/Extensions/CGRect++.swift similarity index 100% rename from Memola/Extensions/CGRect++.swift rename to Memola/Utilies/Extensions/CGRect++.swift diff --git a/Memola/Extensions/CGSize++.swift b/Memola/Utilies/Extensions/CGSize++.swift similarity index 100% rename from Memola/Extensions/CGSize++.swift rename to Memola/Utilies/Extensions/CGSize++.swift diff --git a/Memola/Extensions/Collection++.swift b/Memola/Utilies/Extensions/Collection++.swift similarity index 100% rename from Memola/Extensions/Collection++.swift rename to Memola/Utilies/Extensions/Collection++.swift diff --git a/Memola/Extensions/Color++.swift b/Memola/Utilies/Extensions/Color++.swift similarity index 50% rename from Memola/Extensions/Color++.swift rename to Memola/Utilies/Extensions/Color++.swift index 332db55..493769c 100644 --- a/Memola/Extensions/Color++.swift +++ b/Memola/Utilies/Extensions/Color++.swift @@ -8,8 +8,16 @@ import SwiftUI extension Color { + init(color: Platform.Color) { + #if os(macOS) + self = Color(nsColor: color) + #else + self = Color(uiColor: color) + #endif + } + var components: [CGFloat] { - let color = UIColor(self) + let color = Platform.Color(self) return color.components } @@ -20,6 +28,16 @@ extension Color { extension Color { var hsba: (hue: Double, saturation: Double, brightness: Double, alpha: Double) { + #if os(macOS) + #warning("TODO: need double check") + let nsColor = NSColor(self) + var hue: CGFloat = 0 + var saturation: CGFloat = 0 + var brightness: CGFloat = 0 + var alpha: CGFloat = 0 + nsColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) + return (hue, saturation, brightness, alpha) + #else let uiColor = UIColor(self) var hue: CGFloat = 0 var saturation: CGFloat = 0 @@ -27,13 +45,21 @@ extension Color { var alpha: CGFloat = 0 uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) return (hue, saturation, brightness, alpha) + #endif } } -extension UIColor { +extension Platform.Color { var components: [CGFloat] { + #if os(macOS) + #warning("TODO: need double check") + let nsColor: NSColor = self + let ciColor: CIColor = .init(color: nsColor) ?? CIColor(red: 0, green: 0, blue: 0) + return [ciColor.red, ciColor.green, ciColor.blue, ciColor.alpha] + #else let uiColor: UIColor = self let ciColor: CIColor = .init(color: uiColor) return [ciColor.red, ciColor.green, ciColor.blue, ciColor.alpha] + #endif } } diff --git a/Memola/Extensions/Data++.swift b/Memola/Utilies/Extensions/Data++.swift similarity index 100% rename from Memola/Extensions/Data++.swift rename to Memola/Utilies/Extensions/Data++.swift diff --git a/Memola/Extensions/Date++.swift b/Memola/Utilies/Extensions/Date++.swift similarity index 100% rename from Memola/Extensions/Date++.swift rename to Memola/Utilies/Extensions/Date++.swift diff --git a/Memola/Extensions/Float++.swift b/Memola/Utilies/Extensions/Float++.swift similarity index 100% rename from Memola/Extensions/Float++.swift rename to Memola/Utilies/Extensions/Float++.swift diff --git a/Memola/Extensions/UIImage++.swift b/Memola/Utilies/Extensions/Image++.swift similarity index 68% rename from Memola/Extensions/UIImage++.swift rename to Memola/Utilies/Extensions/Image++.swift index 983ad0f..0f9fc16 100644 --- a/Memola/Extensions/UIImage++.swift +++ b/Memola/Utilies/Extensions/Image++.swift @@ -1,13 +1,24 @@ // -// UIImage++.swift +// Image++.swift // Memola // // Created by Dscyre Scotti on 6/15/24. // -import UIKit +import SwiftUI import Foundation +extension Image { + init(image: Platform.Image) { + #if os(macOS) + self = Image(nsImage: image) + #else + self = Image(uiImage: image) + #endif + } +} + +#if os(iOS) extension UIImage { func imageWithUpOrientation() -> UIImage? { switch imageOrientation { @@ -22,3 +33,4 @@ extension UIImage { } } } +#endif diff --git a/Memola/Extensions/MTLDevice++.swift b/Memola/Utilies/Extensions/MTLDevice++.swift similarity index 100% rename from Memola/Extensions/MTLDevice++.swift rename to Memola/Utilies/Extensions/MTLDevice++.swift diff --git a/Memola/Extensions/MTLTexture++.swift b/Memola/Utilies/Extensions/MTLTexture++.swift similarity index 100% rename from Memola/Extensions/MTLTexture++.swift rename to Memola/Utilies/Extensions/MTLTexture++.swift diff --git a/Memola/Extensions/NSManagedObject++.swift b/Memola/Utilies/Extensions/NSManagedObject++.swift similarity index 100% rename from Memola/Extensions/NSManagedObject++.swift rename to Memola/Utilies/Extensions/NSManagedObject++.swift diff --git a/Memola/Extensions/NSManagedObjectContext++.swift b/Memola/Utilies/Extensions/NSManagedObjectContext++.swift similarity index 100% rename from Memola/Extensions/NSManagedObjectContext++.swift rename to Memola/Utilies/Extensions/NSManagedObjectContext++.swift diff --git a/Memola/Extensions/View++.swift b/Memola/Utilies/Extensions/View++.swift similarity index 100% rename from Memola/Extensions/View++.swift rename to Memola/Utilies/Extensions/View++.swift diff --git a/Memola/Extensions/simd_float4x4++.swift b/Memola/Utilies/Extensions/simd_float4x4++.swift similarity index 100% rename from Memola/Extensions/simd_float4x4++.swift rename to Memola/Utilies/Extensions/simd_float4x4++.swift diff --git a/Memola/Utilies/Platform/Platform.swift b/Memola/Utilies/Platform/Platform.swift new file mode 100644 index 0000000..db900e3 --- /dev/null +++ b/Memola/Utilies/Platform/Platform.swift @@ -0,0 +1,30 @@ +// +// Platform.swift +// Memola +// +// Created by Dscyre Scotti on 7/6/24. +// + +import SwiftUI + +enum Platform { + #if os(macOS) + typealias View = NSView + typealias Color = NSColor + typealias Image = NSImage + typealias ScrollView = NSScrollView + typealias Application = NSApplication + typealias ViewController = NSViewController + typealias TapGestureRecognizer = NSClickGestureRecognizer + typealias ViewControllerRepresentable = NSViewControllerRepresentable + #else + typealias View = UIView + typealias Color = UIColor + typealias Image = UIImage + typealias ScrollView = UIScrollView + typealias Application = UIApplication + typealias ViewController = UIViewController + typealias TapGestureRecognizer = UITapGestureRecognizer + typealias ViewControllerRepresentable = UIViewControllerRepresentable + #endif +}