From 5a5ff0c17e32a694abfb10a5ca287177b7944eb3 Mon Sep 17 00:00:00 2001 From: Yusuke Hosonuma Date: Thu, 13 Aug 2020 15:29:31 +0900 Subject: [PATCH 1/3] fix: build error in macOS --- Shared/Model/Cache/MemoryStorage.swift | 13 +++++-------- iOS/Shared/BoardThumbnailImage.swift | 6 +++--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Shared/Model/Cache/MemoryStorage.swift b/Shared/Model/Cache/MemoryStorage.swift index 1ab5f93..bbc67fe 100644 --- a/Shared/Model/Cache/MemoryStorage.swift +++ b/Shared/Model/Cache/MemoryStorage.swift @@ -1,23 +1,20 @@ // -// MemoryStorage.swift +// MemoryCacheStorage.swift // LifeGameApp // // Created by Yusuke Hosonuma on 2020/08/12. // import Foundation -import UIKit -final class ThumbnailImageCacheStorage { - static var shared = ThumbnailImageCacheStorage() +final class MemoryCacheStorage { + private let cache = NSCache() - private let cache = NSCache() - - func store(key: String, image: UIImage) { + func store(key: String, image: T) { cache.setObject(image, forKey: key as NSString) } - func value(forKey key: String) -> UIImage? { + func value(forKey key: String) -> T? { guard let value = cache.object(forKey: key as NSString) else { return nil } return value } diff --git a/iOS/Shared/BoardThumbnailImage.swift b/iOS/Shared/BoardThumbnailImage.swift index 839f060..41974f3 100644 --- a/iOS/Shared/BoardThumbnailImage.swift +++ b/iOS/Shared/BoardThumbnailImage.swift @@ -8,15 +8,15 @@ import SwiftUI import LifeGame +private let cacheStorage = MemoryCacheStorage() + struct BoardThumbnailImage: View { @Environment(\.colorScheme) var colorScheme var board: Board var cellColor: Color? var cacheKey: String? - - private let cacheStorage = ThumbnailImageCacheStorage.shared - + var body: some View { Image(uiImage: thumbnailImage) .antialiased(false) From a811bd39afa835e70e954acb0b9df27afa28d175 Mon Sep 17 00:00:00 2001 From: Yusuke Hosonuma Date: Thu, 13 Aug 2020 18:08:27 +0900 Subject: [PATCH 2/3] improve: BoardThumbnailImage can be used from multi-platform --- LifeGameApp.xcodeproj/project.pbxproj | 22 ++++++++++--- Shared/Extensions/Color+.swift | 10 ++++++ Shared/Extensions/Image+.swift | 20 ++++++++++++ Shared/Util/GraphicsImageRenderer.swift | 36 +++++++++++++++++++++ iOS/Shared/BoardThumbnailImage.swift | 32 +++++++++++-------- macOS/View/BoardThumnailView.swift | 42 ------------------------- macOS/View/PresetListView.swift | 3 +- 7 files changed, 105 insertions(+), 60 deletions(-) create mode 100644 Shared/Extensions/Image+.swift create mode 100644 Shared/Util/GraphicsImageRenderer.swift delete mode 100644 macOS/View/BoardThumnailView.swift diff --git a/LifeGameApp.xcodeproj/project.pbxproj b/LifeGameApp.xcodeproj/project.pbxproj index 512ba4f..7abfbb6 100644 --- a/LifeGameApp.xcodeproj/project.pbxproj +++ b/LifeGameApp.xcodeproj/project.pbxproj @@ -57,7 +57,6 @@ E55F7AA624DD0C1000DBC175 /* MacRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55F7AA524DD0C1000DBC175 /* MacRootView.swift */; }; E55F7AA824DD0D9300DBC175 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55F7AA724DD0D9300DBC175 /* ContentView.swift */; }; E55F7AAA24DD101900DBC175 /* PresetListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55F7AA924DD101900DBC175 /* PresetListView.swift */; }; - E55F7AAC24DD119700DBC175 /* BoardThumnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55F7AAB24DD119700DBC175 /* BoardThumnailView.swift */; }; E5604AA124CC3ED600EA59C3 /* PreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5604AA024CC3ED600EA59C3 /* PreferenceView.swift */; }; E56A422824E2BB6800F9AC24 /* BoardDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = E52FE5DC24DC012A00D93764 /* BoardDocument.swift */; }; E56A422924E2C0B100F9AC24 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E558A97224DB70D00012E443 /* GoogleService-Info.plist */; }; @@ -98,6 +97,13 @@ E5D9F27424BEBDBD009A526B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5D9F24A24BEBDBC009A526B /* Application.swift */; }; E5D9F27524BEBDBD009A526B /* MainGameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5D9F24B24BEBDBC009A526B /* MainGameView.swift */; }; E5DB4C9524D853C000AADA66 /* PhotoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5DB4C9424D853C000AADA66 /* PhotoPicker.swift */; }; + E5E50A2524E52C5300CD64B6 /* GraphicsImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E50A2424E52C5300CD64B6 /* GraphicsImageRenderer.swift */; }; + E5E50A2624E52EE000CD64B6 /* BoardThumbnailImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E6EB1524DFF33E0012E911 /* BoardThumbnailImage.swift */; }; + E5E50A2724E5327E00CD64B6 /* GraphicsImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E50A2424E52C5300CD64B6 /* GraphicsImageRenderer.swift */; }; + E5E50A2824E535AD00CD64B6 /* GraphicsImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E50A2424E52C5300CD64B6 /* GraphicsImageRenderer.swift */; }; + E5E50A2A24E539C900CD64B6 /* Image+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E50A2924E539C900CD64B6 /* Image+.swift */; }; + E5E50A2B24E539C900CD64B6 /* Image+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E50A2924E539C900CD64B6 /* Image+.swift */; }; + E5E50A2C24E539C900CD64B6 /* Image+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E50A2924E539C900CD64B6 /* Image+.swift */; }; E5E6EB1424DFF27C0012E911 /* BoardSelectCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E6EB1324DFF27C0012E911 /* BoardSelectCell.swift */; }; E5E6EB1624DFF33E0012E911 /* BoardThumbnailImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E6EB1524DFF33E0012E911 /* BoardThumbnailImage.swift */; }; E5FA934224C0570800229AAA /* ButtonStyleCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5FA934124C0570800229AAA /* ButtonStyleCircle.swift */; }; @@ -186,7 +192,6 @@ E55F7AA524DD0C1000DBC175 /* MacRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacRootView.swift; sourceTree = ""; }; E55F7AA724DD0D9300DBC175 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; E55F7AA924DD101900DBC175 /* PresetListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresetListView.swift; sourceTree = ""; }; - E55F7AAB24DD119700DBC175 /* BoardThumnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardThumnailView.swift; sourceTree = ""; }; E5604AA024CC3ED600EA59C3 /* PreferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferenceView.swift; sourceTree = ""; }; E56DBCAB24E4ED5000849CE4 /* LifeGameConfig.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = LifeGameConfig.intentdefinition; sourceTree = ""; }; E56DBCAE24E4FE3200849CE4 /* Array+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+.swift"; sourceTree = ""; }; @@ -219,6 +224,8 @@ E5D9F27024BEBDBD009A526B /* Tests_macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_macOS.swift; sourceTree = ""; }; E5D9F27224BEBDBD009A526B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; E5DB4C9424D853C000AADA66 /* PhotoPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPicker.swift; sourceTree = ""; }; + E5E50A2424E52C5300CD64B6 /* GraphicsImageRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicsImageRenderer.swift; sourceTree = ""; }; + E5E50A2924E539C900CD64B6 /* Image+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image+.swift"; sourceTree = ""; }; E5E6EB1324DFF27C0012E911 /* BoardSelectCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardSelectCell.swift; sourceTree = ""; }; E5E6EB1524DFF33E0012E911 /* BoardThumbnailImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardThumbnailImage.swift; sourceTree = ""; }; E5FA934124C0570800229AAA /* ButtonStyleCircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonStyleCircle.swift; sourceTree = ""; }; @@ -377,6 +384,7 @@ E571536424D51B5B003B4C9E /* Util */ = { isa = PBXGroup; children = ( + E5E50A2424E52C5300CD64B6 /* GraphicsImageRenderer.swift */, E571536524D51B73003B4C9E /* UserDefaultConvertible.swift */, E571536824D51B9F003B4C9E /* UserDefault.swift */, E518C88E24E3670C00B02027 /* UserDefaultGroup.swift */, @@ -460,7 +468,6 @@ E55F7AA524DD0C1000DBC175 /* MacRootView.swift */, E55F7AA724DD0D9300DBC175 /* ContentView.swift */, E55F7AA924DD101900DBC175 /* PresetListView.swift */, - E55F7AAB24DD119700DBC175 /* BoardThumnailView.swift */, ); path = View; sourceTree = ""; @@ -624,6 +631,7 @@ E5FA934F24C07AE300229AAA /* Collection+.swift */, E518213224CC2E5300ABD16B /* Color+.swift */, E56DBCAE24E4FE3200849CE4 /* Array+.swift */, + E5E50A2924E539C900CD64B6 /* Image+.swift */, ); path = Extensions; sourceTree = ""; @@ -952,6 +960,7 @@ E5B7516124E3D7A00004D8AE /* FirestoreBoardRepository.swift in Sources */, E56DBCB324E4FFF400849CE4 /* Array+.swift in Sources */, E5438E3A24E2AB0B007A3EB7 /* LifeGameWidget.swift in Sources */, + E5E50A2824E535AD00CD64B6 /* GraphicsImageRenderer.swift in Sources */, E518C89824E3690600B02027 /* Color+.swift in Sources */, E56DBCAD24E4ED5000849CE4 /* LifeGameConfig.intentdefinition in Sources */, E56A422824E2BB6800F9AC24 /* BoardDocument.swift in Sources */, @@ -959,6 +968,7 @@ E518C89624E368A700B02027 /* UserDefaultGroup.swift in Sources */, E5438E4724E2AD1D007A3EB7 /* BoardPreset.swift in Sources */, E5438E4524E2ACD4007A3EB7 /* BoardThumbnailImage.swift in Sources */, + E5E50A2C24E539C900CD64B6 /* Image+.swift in Sources */, E518C89724E368D600B02027 /* UserDefaultConvertible.swift in Sources */, E518C89524E3684A00B02027 /* UserDefaultSettingGroup.swift in Sources */, ); @@ -997,6 +1007,7 @@ E547C30A24E3F4CF0022DF3A /* MemoryStorage.swift in Sources */, E5D9F27324BEBDBD009A526B /* Application.swift in Sources */, E5B0572824CC3465005EE1AA /* CellView.swift in Sources */, + E5E50A2724E5327E00CD64B6 /* GraphicsImageRenderer.swift in Sources */, E5FA935024C07AE300229AAA /* Collection+.swift in Sources */, E518C89324E3684A00B02027 /* UserDefaultSettingGroup.swift in Sources */, E5B7519B24E3DD6D0004D8AE /* DesigntimeFirestoreBoardRepository.swift in Sources */, @@ -1004,6 +1015,7 @@ E51169D224D644E3002D40B6 /* SpeedSliderView.swift in Sources */, E5DB4C9524D853C000AADA66 /* PhotoPicker.swift in Sources */, E5FA934224C0570800229AAA /* ButtonStyleCircle.swift in Sources */, + E5E50A2A24E539C900CD64B6 /* Image+.swift in Sources */, E54904AF24DD5E2D003AE7C7 /* BoardView.swift in Sources */, E5CE237324C199F200BC5820 /* LifeGameContext.swift in Sources */, ); @@ -1036,14 +1048,16 @@ E5B7519C24E3DD6D0004D8AE /* DesigntimeFirestoreBoardRepository.swift in Sources */, E5B0572924CC3465005EE1AA /* CellView.swift in Sources */, E5FA935124C07AE300229AAA /* Collection+.swift in Sources */, - E55F7AAC24DD119700DBC175 /* BoardThumnailView.swift in Sources */, E5FA934324C0570800229AAA /* ButtonStyleCircle.swift in Sources */, E580AA6D24E12F34007C60F1 /* BoardPresetFile.swift in Sources */, E571536A24D51B9F003B4C9E /* UserDefault.swift in Sources */, E5CE237424C199F200BC5820 /* LifeGameContext.swift in Sources */, + E5E50A2624E52EE000CD64B6 /* BoardThumbnailImage.swift in Sources */, + E5E50A2524E52C5300CD64B6 /* GraphicsImageRenderer.swift in Sources */, E55F7AA824DD0D9300DBC175 /* ContentView.swift in Sources */, E547C30B24E3F4CF0022DF3A /* MemoryStorage.swift in Sources */, E5604AA124CC3ED600EA59C3 /* PreferenceView.swift in Sources */, + E5E50A2B24E539C900CD64B6 /* Image+.swift in Sources */, E573BD8224D053F90096BF75 /* LifeGameCommands.swift in Sources */, E518C89424E3684A00B02027 /* UserDefaultSettingGroup.swift in Sources */, ); diff --git a/Shared/Extensions/Color+.swift b/Shared/Extensions/Color+.swift index ebbd8bd..53d4f44 100644 --- a/Shared/Extensions/Color+.swift +++ b/Shared/Extensions/Color+.swift @@ -7,6 +7,16 @@ import SwiftUI +extension Color { + var cgColor: CGColor { + #if os(macOS) + return NSColor(self).cgColor + #else + return UIColor(self).cgColor + #endif + } +} + extension Color: RawRepresentable { public var rawValue: Data { #if os(macOS) diff --git a/Shared/Extensions/Image+.swift b/Shared/Extensions/Image+.swift new file mode 100644 index 0000000..f416bb5 --- /dev/null +++ b/Shared/Extensions/Image+.swift @@ -0,0 +1,20 @@ +// +// Image+.swift +// LifeGameApp +// +// Created by Yusuke Hosonuma on 2020/08/13. +// + +import SwiftUI + +extension Image { + #if os(macOS) + init(image: NSImage) { + self = Image(nsImage: image) + } + #else + init(image: UIImage) { + self = Image(uiImage: image) + } + #endif +} diff --git a/Shared/Util/GraphicsImageRenderer.swift b/Shared/Util/GraphicsImageRenderer.swift new file mode 100644 index 0000000..bd9b295 --- /dev/null +++ b/Shared/Util/GraphicsImageRenderer.swift @@ -0,0 +1,36 @@ +// +// GraphicsImageRenderer.swift +// LifeGameApp (macOS) +// +// Created by Yusuke Hosonuma on 2020/08/13. +// + +#if os(macOS) +import AppKit +#else +import UIKit +#endif + +final class GraphicsImageRenderer { + let size: CGSize + + init(size: CGSize) { + self.size = size + } + + #if os(macOS) + func image(actions: (CGContext) -> ()) -> NSImage { + let image = NSImage(size: size) + image.lockFocusFlipped(true) + actions(NSGraphicsContext.current!.cgContext) + image.unlockFocus() + return image + } + #else + func image(actions: @escaping (CGContext) -> ()) -> UIImage { + UIGraphicsImageRenderer(size: size).image { context in + actions(context.cgContext) + } + } + #endif +} diff --git a/iOS/Shared/BoardThumbnailImage.swift b/iOS/Shared/BoardThumbnailImage.swift index 41974f3..6897f16 100644 --- a/iOS/Shared/BoardThumbnailImage.swift +++ b/iOS/Shared/BoardThumbnailImage.swift @@ -8,7 +8,13 @@ import SwiftUI import LifeGame -private let cacheStorage = MemoryCacheStorage() +#if os(macOS) +private typealias XImage = NSImage +#else +private typealias XImage = UIImage +#endif + +private let cacheStorage = MemoryCacheStorage() struct BoardThumbnailImage: View { @Environment(\.colorScheme) var colorScheme @@ -18,7 +24,7 @@ struct BoardThumbnailImage: View { var cacheKey: String? var body: some View { - Image(uiImage: thumbnailImage) + Image(image: thumbnailImage) .antialiased(false) .resizable() .scaledToFit() @@ -26,19 +32,19 @@ struct BoardThumbnailImage: View { private var fillColor: CGColor { if let color = cellColor { - return UIColor(color).cgColor + return color.cgColor } else { return colorScheme == .dark - ? UIColor(Color.white).cgColor - : UIColor(Color.black).cgColor + ? Color.white.cgColor + : Color.black.cgColor } } private var gridColor: CGColor { - UIColor(Color.gray.opacity(0.3)).cgColor + Color.gray.opacity(0.3).cgColor } - - private var thumbnailImage: UIImage { + + private var thumbnailImage: XImage { guard let cacheKey = cacheKey else { return renderImage() } @@ -53,14 +59,14 @@ struct BoardThumbnailImage: View { return image } } - - private func renderImage() -> UIImage { + + private func renderImage() -> XImage { let scale = max(2, 140 / board.size) let size = CGSize(width: board.size * scale + 1, height: board.size * scale + 1) - return UIGraphicsImageRenderer(size: size) + return GraphicsImageRenderer(size: size) .image(actions: { context in - context.cgContext.setFillColor(fillColor) + context.setFillColor(fillColor) for (index, cell) in board.cells.enumerated() { let x = (index % board.size) * scale @@ -71,7 +77,7 @@ struct BoardThumbnailImage: View { } // Draw grid - context.cgContext.setFillColor(gridColor) + context.setFillColor(gridColor) for index in 0...board.size + 1 { let length = board.size * scale + 1 context.fill(CGRect(x: scale * index, y: 0, width: 1, height: length)) // vertical lines diff --git a/macOS/View/BoardThumnailView.swift b/macOS/View/BoardThumnailView.swift deleted file mode 100644 index 946583d..0000000 --- a/macOS/View/BoardThumnailView.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// BoardThumnailView.swift -// LifeGameApp (macOS) -// -// Created by Yusuke Hosonuma on 2020/08/07. -// - -import SwiftUI -import LifeGame - -struct BoardThumnailView: View { - @Environment(\.colorScheme) private var colorScheme: ColorScheme - - var board: LifeGameBoard - - var body: some View { - VStack(spacing: 0) { - ForEach(board.rows.withIndex(), id: \.0) { y, row in - HStack(spacing: 0) { - ForEach(row.withIndex(), id: \.0) { x, cell in - CellView(color: cellColor(cell), size: 100.0 / CGFloat(board.size)) // TODO: 盤面サイズで全体の大きさが変わってしまうのでそのうち修正 - } - } - } - } - } - - private func cellColor(_ cell: Cell) -> Color { - switch (cell, colorScheme) { - case (.die, _): return .clear - case (.alive, .light): return .black - case (.alive, .dark): return .white - @unknown default: fatalError() - } - } -} - -struct BoardThumnailView_Previews: PreviewProvider { - static var previews: some View { - BoardThumnailView(board: BoardPreset.nebura.board) - } -} diff --git a/macOS/View/PresetListView.swift b/macOS/View/PresetListView.swift index a39cb78..04a9239 100644 --- a/macOS/View/PresetListView.swift +++ b/macOS/View/PresetListView.swift @@ -17,7 +17,8 @@ struct PresetListView: View { Section(header: Text("Presets")) { ForEach(boardRepository.items) { item in HStack { - BoardThumnailView(board: LifeGameBoard(board: item.makeBoard())) + BoardThumbnailImage(board: item.makeBoard().extended(by: .die), cacheKey: item.id) + .frame(width: 120, height: 120, alignment: .center) Text("\(item.title)") } .contentShape(Rectangle()) // ❗not working in beta4 From 637a37b115dc04c5962542a6306c48d9e2d09bf5 Mon Sep 17 00:00:00 2001 From: Yusuke Hosonuma Date: Thu, 13 Aug 2020 18:25:25 +0900 Subject: [PATCH 3/3] refactor: --- iOS/Screen/BoardSelect/BoardSelectCell.swift | 4 ++-- iOS/Shared/BoardThumbnailImage.swift | 14 ++++++++++---- macOS/View/PresetListView.swift | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/iOS/Screen/BoardSelect/BoardSelectCell.swift b/iOS/Screen/BoardSelect/BoardSelectCell.swift index c1a9060..5139c68 100644 --- a/iOS/Screen/BoardSelect/BoardSelectCell.swift +++ b/iOS/Screen/BoardSelect/BoardSelectCell.swift @@ -18,7 +18,7 @@ struct BoardSelectCell: View { switch style { case .grid: VStack { - BoardThumbnailImage(board: item.makeBoard().extended(by: .die), cacheKey: item.id) + BoardThumbnailImage(board: item.makeBoard(), cacheKey: item.id) .matchedGeometryEffect(id: "thumbnail-\(item.title)", in: nspace) HStack { @@ -54,7 +54,7 @@ struct BoardSelectCell: View { .foregroundColor(.yellow) } Spacer() - BoardThumbnailImage(board: item.makeBoard().extended(by: .die), cacheKey: item.id) + BoardThumbnailImage(board: item.makeBoard(), cacheKey: item.id) .frame(width: 60, height: 60, alignment: .center) .matchedGeometryEffect(id: "thumbnail-\(item.title)", in: nspace) }.padding() diff --git a/iOS/Shared/BoardThumbnailImage.swift b/iOS/Shared/BoardThumbnailImage.swift index 6897f16..ac39427 100644 --- a/iOS/Shared/BoardThumbnailImage.swift +++ b/iOS/Shared/BoardThumbnailImage.swift @@ -19,10 +19,16 @@ private let cacheStorage = MemoryCacheStorage() struct BoardThumbnailImage: View { @Environment(\.colorScheme) var colorScheme - var board: Board - var cellColor: Color? - var cacheKey: String? - + private let board: Board + private let cellColor: Color? + private let cacheKey: String? + + init(board: Board, cellColor: Color? = nil, cacheKey: String? = nil) { + self.board = board.extended(by: .die) + self.cellColor = cellColor + self.cacheKey = cacheKey + } + var body: some View { Image(image: thumbnailImage) .antialiased(false) diff --git a/macOS/View/PresetListView.swift b/macOS/View/PresetListView.swift index 04a9239..b1b9928 100644 --- a/macOS/View/PresetListView.swift +++ b/macOS/View/PresetListView.swift @@ -17,7 +17,7 @@ struct PresetListView: View { Section(header: Text("Presets")) { ForEach(boardRepository.items) { item in HStack { - BoardThumbnailImage(board: item.makeBoard().extended(by: .die), cacheKey: item.id) + BoardThumbnailImage(board: item.makeBoard(), cacheKey: item.id) .frame(width: 120, height: 120, alignment: .center) Text("\(item.title)") }