Changed Console(View) to new core data swiftu ibest practices. Removed generation and added releaseDate. Adjustes Import/Export
This commit is contained in:
@@ -15,7 +15,6 @@
|
|||||||
B93D60D122E5009700DD390F /* GameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60D022E5009700DD390F /* GameViewModel.swift */; };
|
B93D60D122E5009700DD390F /* GameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60D022E5009700DD390F /* GameViewModel.swift */; };
|
||||||
B94112DE233A37DD00159AE4 /* DateConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DD233A37DD00159AE4 /* DateConversion.swift */; };
|
B94112DE233A37DD00159AE4 /* DateConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DD233A37DD00159AE4 /* DateConversion.swift */; };
|
||||||
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DF233A4EF800159AE4 /* GamePickupsView.swift */; };
|
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DF233A4EF800159AE4 /* GamePickupsView.swift */; };
|
||||||
B94112E2233B55B100159AE4 /* ConsoleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112E1233B55B100159AE4 /* ConsoleViewModel.swift */; };
|
|
||||||
B94112E4233B597D00159AE4 /* ConsoleEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112E3233B597D00159AE4 /* ConsoleEditView.swift */; };
|
B94112E4233B597D00159AE4 /* ConsoleEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112E3233B597D00159AE4 /* ConsoleEditView.swift */; };
|
||||||
B94CB4FF22D1352F0029BFAD /* Accessory+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */; };
|
B94CB4FF22D1352F0029BFAD /* Accessory+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */; };
|
||||||
B94CB50022D1352F0029BFAD /* Accessory+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */; };
|
B94CB50022D1352F0029BFAD /* Accessory+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */; };
|
||||||
@@ -45,6 +44,7 @@
|
|||||||
B9A0550322F8C2740054D9A0 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550222F8C2740054D9A0 /* MainView.swift */; };
|
B9A0550322F8C2740054D9A0 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550222F8C2740054D9A0 /* MainView.swift */; };
|
||||||
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */; };
|
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */; };
|
||||||
B9BCCEB92653BDEA005F46D6 /* ICloudManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */; };
|
B9BCCEB92653BDEA005F46D6 /* ICloudManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */; };
|
||||||
|
B9BCCEBB2653CA8E005F46D6 /* SwiftUIBindingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEBA2653CA8E005F46D6 /* SwiftUIBindingExtension.swift */; };
|
||||||
B9BCF4CA2168ACB600ECBAAC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */; };
|
B9BCF4CA2168ACB600ECBAAC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */; };
|
||||||
B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */; };
|
B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */; };
|
||||||
B9E2A079233B69D400EAEB14 /* GameSeriesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */; };
|
B9E2A079233B69D400EAEB14 /* GameSeriesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */; };
|
||||||
@@ -95,7 +95,6 @@
|
|||||||
B93D60D022E5009700DD390F /* GameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewModel.swift; sourceTree = "<group>"; };
|
B93D60D022E5009700DD390F /* GameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewModel.swift; sourceTree = "<group>"; };
|
||||||
B94112DD233A37DD00159AE4 /* DateConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateConversion.swift; sourceTree = "<group>"; };
|
B94112DD233A37DD00159AE4 /* DateConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateConversion.swift; sourceTree = "<group>"; };
|
||||||
B94112DF233A4EF800159AE4 /* GamePickupsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamePickupsView.swift; sourceTree = "<group>"; };
|
B94112DF233A4EF800159AE4 /* GamePickupsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamePickupsView.swift; sourceTree = "<group>"; };
|
||||||
B94112E1233B55B100159AE4 /* ConsoleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleViewModel.swift; sourceTree = "<group>"; };
|
|
||||||
B94112E3233B597D00159AE4 /* ConsoleEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleEditView.swift; sourceTree = "<group>"; };
|
B94112E3233B597D00159AE4 /* ConsoleEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleEditView.swift; sourceTree = "<group>"; };
|
||||||
B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataClass.swift"; sourceTree = "<group>"; };
|
B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
@@ -129,6 +128,7 @@
|
|||||||
B9A0550222F8C2740054D9A0 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
B9A0550222F8C2740054D9A0 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
||||||
B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesLibraryView.swift; sourceTree = "<group>"; };
|
B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesLibraryView.swift; sourceTree = "<group>"; };
|
||||||
B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudManager.swift; sourceTree = "<group>"; };
|
B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudManager.swift; sourceTree = "<group>"; };
|
||||||
|
B9BCCEBA2653CA8E005F46D6 /* SwiftUIBindingExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIBindingExtension.swift; sourceTree = "<group>"; };
|
||||||
B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryViewModel.swift; sourceTree = "<group>"; };
|
B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryViewModel.swift; sourceTree = "<group>"; };
|
||||||
B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesViewModel.swift; sourceTree = "<group>"; };
|
B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesViewModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -201,6 +201,7 @@
|
|||||||
B9EC09812383F94B004BC9AB /* LibraryExport.swift */,
|
B9EC09812383F94B004BC9AB /* LibraryExport.swift */,
|
||||||
B90E03EA238557D900E79643 /* LibraryImport.swift */,
|
B90E03EA238557D900E79643 /* LibraryImport.swift */,
|
||||||
B98CBBE2265045AC00B1B7AC /* URLExtension.swift */,
|
B98CBBE2265045AC00B1B7AC /* URLExtension.swift */,
|
||||||
|
B9BCCEBA2653CA8E005F46D6 /* SwiftUIBindingExtension.swift */,
|
||||||
);
|
);
|
||||||
path = Utils;
|
path = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -248,7 +249,6 @@
|
|||||||
B93D60CF22E5006F00DD390F /* ViewModel */ = {
|
B93D60CF22E5006F00DD390F /* ViewModel */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
B94112E1233B55B100159AE4 /* ConsoleViewModel.swift */,
|
|
||||||
B93D60D022E5009700DD390F /* GameViewModel.swift */,
|
B93D60D022E5009700DD390F /* GameViewModel.swift */,
|
||||||
B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */,
|
B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */,
|
||||||
B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */,
|
B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */,
|
||||||
@@ -432,7 +432,6 @@
|
|||||||
B98CBBE3265045AC00B1B7AC /* URLExtension.swift in Sources */,
|
B98CBBE3265045AC00B1B7AC /* URLExtension.swift in Sources */,
|
||||||
B9839992233A0E19002F9946 /* GameSeriesCover+CoreDataClass.swift in Sources */,
|
B9839992233A0E19002F9946 /* GameSeriesCover+CoreDataClass.swift in Sources */,
|
||||||
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */,
|
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */,
|
||||||
B94112E2233B55B100159AE4 /* ConsoleViewModel.swift in Sources */,
|
|
||||||
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */,
|
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */,
|
||||||
B9839983233A086A002F9946 /* Overview.swift in Sources */,
|
B9839983233A086A002F9946 /* Overview.swift in Sources */,
|
||||||
B93C1B9D21496BFD0014FD6E /* AppDelegate.swift in Sources */,
|
B93C1B9D21496BFD0014FD6E /* AppDelegate.swift in Sources */,
|
||||||
@@ -462,6 +461,7 @@
|
|||||||
B9E2A07B233B6A8F00EAEB14 /* GameSeriesEditView.swift in Sources */,
|
B9E2A07B233B6A8F00EAEB14 /* GameSeriesEditView.swift in Sources */,
|
||||||
B926F14721502D53004D36B7 /* CodableExtensionAny.swift in Sources */,
|
B926F14721502D53004D36B7 /* CodableExtensionAny.swift in Sources */,
|
||||||
B94CB50422D1352F0029BFAD /* Game+CoreDataProperties.swift in Sources */,
|
B94CB50422D1352F0029BFAD /* Game+CoreDataProperties.swift in Sources */,
|
||||||
|
B9BCCEBB2653CA8E005F46D6 /* SwiftUIBindingExtension.swift in Sources */,
|
||||||
B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */,
|
B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */,
|
||||||
B98A736022C1738800FB3410 /* CDManager.swift in Sources */,
|
B98A736022C1738800FB3410 /* CDManager.swift in Sources */,
|
||||||
B94CB50222D1352F0029BFAD /* Cover+CoreDataProperties.swift in Sources */,
|
B94CB50222D1352F0029BFAD /* Cover+CoreDataProperties.swift in Sources */,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ extension Accessory : Encodable {
|
|||||||
try container.encode(manufacturer, forKey: .manufacturer)
|
try container.encode(manufacturer, forKey: .manufacturer)
|
||||||
try container.encode(name, forKey: .name)
|
try container.encode(name, forKey: .name)
|
||||||
try container.encode(inWishlist, forKey: .inWishlist)
|
try container.encode(inWishlist, forKey: .inWishlist)
|
||||||
try container.encode(console?.uuid!.uuidString ?? "", forKey: .console)
|
try container.encode(console?.uuid.uuidString ?? "", forKey: .console)
|
||||||
try container.encode(lentTo, forKey: .lentTo)
|
try container.encode(lentTo, forKey: .lentTo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,32 +14,6 @@ import UIKit
|
|||||||
|
|
||||||
@objc(Console)
|
@objc(Console)
|
||||||
public class Console: NSManagedObject, Identifiable {
|
public class Console: NSManagedObject, Identifiable {
|
||||||
|
|
||||||
var logoAsUIImage : UIImage? {
|
|
||||||
get {
|
|
||||||
if let logoImage = self.logo?.image {
|
|
||||||
return logoImage
|
|
||||||
}
|
|
||||||
|
|
||||||
return .none
|
|
||||||
}
|
|
||||||
|
|
||||||
set {
|
|
||||||
if let logoImage = newValue {
|
|
||||||
let newLogo = Logo(context: CDManager.shared.viewContext)
|
|
||||||
newLogo.console = self
|
|
||||||
newLogo.image = logoImage
|
|
||||||
self.logo = newLogo
|
|
||||||
}/*else{
|
|
||||||
//This deletes the cover?
|
|
||||||
if let logo = self.logo {
|
|
||||||
print("Console::logoImage::set DELETE Logo")
|
|
||||||
CDManager.shared.viewContext.delete(logo)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func compareConsolesByNewestGame(consoleA : Console, consoleB : Console) -> Bool {
|
public static func compareConsolesByNewestGame(consoleA : Console, consoleB : Console) -> Bool {
|
||||||
guard let newestGameConsoleA = (consoleA.games!.allObjects as! [Game]).max(by:{
|
guard let newestGameConsoleA = (consoleA.games!.allObjects as! [Game]).max(by:{
|
||||||
Game.compareByCreationDate(gameA: $0, gameB: $1)
|
Game.compareByCreationDate(gameA: $0, gameB: $1)
|
||||||
@@ -59,6 +33,13 @@ public class Console: NSManagedObject, Identifiable {
|
|||||||
return self.objectID
|
return self.objectID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defining default values during creation
|
||||||
|
public override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
|
||||||
|
super.init(entity: entity, insertInto: context)
|
||||||
|
self.uuid = UUID()
|
||||||
|
self.releaseDate = Date()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Console : Encodable {
|
extension Console : Encodable {
|
||||||
@@ -67,12 +48,11 @@ extension Console : Encodable {
|
|||||||
case uuid
|
case uuid
|
||||||
case name
|
case name
|
||||||
case shortName
|
case shortName
|
||||||
case generation
|
|
||||||
case manufacturer
|
case manufacturer
|
||||||
case accessories
|
case accessories
|
||||||
case games
|
case games
|
||||||
case logo
|
|
||||||
case logo_icloud_path
|
case logo_icloud_path
|
||||||
|
case releaseDate
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@@ -80,9 +60,10 @@ extension Console : Encodable {
|
|||||||
try container.encode(uuid, forKey: .uuid)
|
try container.encode(uuid, forKey: .uuid)
|
||||||
try container.encode(name, forKey: .name)
|
try container.encode(name, forKey: .name)
|
||||||
try container.encode(shortName ?? "", forKey: .shortName)
|
try container.encode(shortName ?? "", forKey: .shortName)
|
||||||
try container.encode(generation, forKey: .generation)
|
|
||||||
try container.encode(manufacturer ?? "", forKey: .manufacturer)
|
try container.encode(manufacturer ?? "", forKey: .manufacturer)
|
||||||
try container.encode(logo_icloud_path ?? "", forKey: .logo_icloud_path)
|
try container.encode(logo_icloud_path ?? "", forKey: .logo_icloud_path)
|
||||||
|
print("Encode releaseDate: \(releaseDate)")
|
||||||
|
try container.encode(releaseDate, forKey: .releaseDate)
|
||||||
var accessoryList : [String] = []
|
var accessoryList : [String] = []
|
||||||
for accessory in accessories! {
|
for accessory in accessories! {
|
||||||
if let accessory = accessory as? Accessory {
|
if let accessory = accessory as? Accessory {
|
||||||
@@ -98,8 +79,5 @@ extension Console : Encodable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
try container.encode(gamesList, forKey: .games)
|
try container.encode(gamesList, forKey: .games)
|
||||||
|
|
||||||
let logoBase64 = logo?.image?.pngData()?.base64EncodedString() ?? ""
|
|
||||||
try container.encode(logoBase64, forKey: .logo)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,15 @@ extension Console {
|
|||||||
return NSFetchRequest<Console>(entityName: "Console")
|
return NSFetchRequest<Console>(entityName: "Console")
|
||||||
}
|
}
|
||||||
|
|
||||||
@NSManaged public var circumstances: String?
|
|
||||||
@NSManaged public var generation: Int64
|
@NSManaged public var generation: Int64
|
||||||
@NSManaged public var manufacturer: String?
|
@NSManaged public var manufacturer: String?
|
||||||
@NSManaged public var name: String?
|
@NSManaged public var name: String?
|
||||||
@NSManaged public var shortName: String?
|
@NSManaged public var shortName: String?
|
||||||
@NSManaged public var uuid: UUID?
|
@NSManaged public var uuid: UUID
|
||||||
@NSManaged public var accessories: NSSet?
|
@NSManaged public var accessories: NSSet?
|
||||||
@NSManaged public var games: NSSet?
|
@NSManaged public var games: NSSet?
|
||||||
@NSManaged public var logo: Logo?
|
|
||||||
@NSManaged public var logo_icloud_path : String?
|
@NSManaged public var logo_icloud_path : String?
|
||||||
|
@NSManaged public var releaseDate : Date
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ extension Game : Encodable {
|
|||||||
try container.encode(isFinished, forKey: .isFinished)
|
try container.encode(isFinished, forKey: .isFinished)
|
||||||
try container.encode(inWishlist, forKey: .inWishlist)
|
try container.encode(inWishlist, forKey: .inWishlist)
|
||||||
|
|
||||||
let consoleUUID : String = console?.uuid?.uuidString ?? ""
|
let consoleUUID : String = console?.uuid.uuidString ?? ""
|
||||||
let gameSeriesUUID : String = series?.uuid.uuidString ?? ""
|
let gameSeriesUUID : String = series?.uuid.uuidString ?? ""
|
||||||
try container.encode(consoleUUID, forKey: .console)
|
try container.encode(consoleUUID, forKey: .console)
|
||||||
try container.encode(gameSeriesUUID, forKey: .gameSeries)
|
try container.encode(gameSeriesUUID, forKey: .gameSeries)
|
||||||
|
|||||||
@@ -12,12 +12,6 @@ import CoreData
|
|||||||
import UIKit.UIImage
|
import UIKit.UIImage
|
||||||
|
|
||||||
extension Logo {
|
extension Logo {
|
||||||
|
|
||||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Logo> {
|
|
||||||
return NSFetchRequest<Logo>(entityName: "Logo")
|
|
||||||
}
|
|
||||||
|
|
||||||
@NSManaged public var image: UIImage?
|
@NSManaged public var image: UIImage?
|
||||||
@NSManaged public var console: Console?
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,12 +112,8 @@ class LibraryImport {
|
|||||||
cdConsole.uuid = console.uuid
|
cdConsole.uuid = console.uuid
|
||||||
cdConsole.manufacturer = console.manufacturer
|
cdConsole.manufacturer = console.manufacturer
|
||||||
cdConsole.shortName = console.shortName
|
cdConsole.shortName = console.shortName
|
||||||
cdConsole.generation = Int64(console.generation)
|
cdConsole.logo_icloud_path = console.logo_icloud_path
|
||||||
|
cdConsole.releaseDate = console.releaseDate
|
||||||
let cdLogo = Logo(context: CDManager.shared.viewContext)
|
|
||||||
cdLogo.image = console.logo
|
|
||||||
cdLogo.console = cdConsole
|
|
||||||
cdConsole.logo = cdLogo
|
|
||||||
|
|
||||||
return cdConsole
|
return cdConsole
|
||||||
}
|
}
|
||||||
@@ -290,9 +286,9 @@ struct BHLGameSeries : Decodable {
|
|||||||
struct BHLConsole : Decodable {
|
struct BHLConsole : Decodable {
|
||||||
let uuid : UUID
|
let uuid : UUID
|
||||||
let name : String
|
let name : String
|
||||||
let logo : UIImage?
|
let logo_icloud_path : String?
|
||||||
let generation : Int
|
|
||||||
let manufacturer : String?
|
let manufacturer : String?
|
||||||
|
let releaseDate : Date
|
||||||
let shortName : String?
|
let shortName : String?
|
||||||
let accessories : [UUID]
|
let accessories : [UUID]
|
||||||
let games : [UUID]
|
let games : [UUID]
|
||||||
@@ -300,9 +296,9 @@ struct BHLConsole : Decodable {
|
|||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case uuid
|
case uuid
|
||||||
case name
|
case name
|
||||||
case logo
|
case logo_icloud_path
|
||||||
case generation
|
|
||||||
case manufacturer
|
case manufacturer
|
||||||
|
case releaseDate
|
||||||
case shortName
|
case shortName
|
||||||
case accessories
|
case accessories
|
||||||
case games
|
case games
|
||||||
@@ -312,17 +308,12 @@ struct BHLConsole : Decodable {
|
|||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
uuid = try container.decode(UUID.self, forKey: .uuid)
|
uuid = try container.decode(UUID.self, forKey: .uuid)
|
||||||
name = try container.decode(String.self, forKey: .name)
|
name = try container.decode(String.self, forKey: .name)
|
||||||
generation = try container.decode(Int.self, forKey: .generation)
|
logo_icloud_path = try container.decode(String.self, forKey: .logo_icloud_path)
|
||||||
manufacturer = try container.decode(String?.self, forKey: .manufacturer)
|
manufacturer = try container.decode(String?.self, forKey: .manufacturer)
|
||||||
shortName = try container.decode(String?.self, forKey: .shortName)
|
shortName = try container.decode(String?.self, forKey: .shortName)
|
||||||
accessories = try container.decode([UUID].self, forKey: .accessories)
|
accessories = try container.decode([UUID].self, forKey: .accessories)
|
||||||
|
releaseDate = try container.decode(Date.self, forKey: .releaseDate)
|
||||||
|
print("Decode releaseDate: \(releaseDate)")
|
||||||
games = try container.decode([UUID].self, forKey: .games)
|
games = try container.decode([UUID].self, forKey: .games)
|
||||||
|
|
||||||
if let coverBase64 = try container.decode(String?.self, forKey: .logo),
|
|
||||||
let coverData = Data(base64Encoded: coverBase64) {
|
|
||||||
logo = UIImage(data: coverData)
|
|
||||||
}else {
|
|
||||||
logo = .none
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
Zockerhoehle/Utils/SwiftUIBindingExtension.swift
Normal file
17
Zockerhoehle/Utils/SwiftUIBindingExtension.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// SwiftUIBindingExtension.swift
|
||||||
|
// Zockerhoehle
|
||||||
|
//
|
||||||
|
// Created by Julian-Steffen Müller on 18.05.21.
|
||||||
|
// Copyright © 2021 Julian-Steffen Müller. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
func ??<T>(lhs: Binding<Optional<T>>, rhs: T) -> Binding<T> {
|
||||||
|
Binding(
|
||||||
|
get: { lhs.wrappedValue ?? rhs },
|
||||||
|
set: { lhs.wrappedValue = $0 }
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
//
|
|
||||||
// ConsoleViewModel.swift
|
|
||||||
// Zockerhoehle
|
|
||||||
//
|
|
||||||
// Created by Julian-Steffen Müller on 25.09.19.
|
|
||||||
// Copyright © 2019 Julian-Steffen Müller. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
class ConsoleViewModel : ObservableObject {
|
|
||||||
//var objectWillChange = ObservableObjectPublisher()
|
|
||||||
|
|
||||||
init(_ console: Console) {
|
|
||||||
self.console = console
|
|
||||||
self.name = console.name!
|
|
||||||
}
|
|
||||||
|
|
||||||
private var console : Console? {
|
|
||||||
didSet {
|
|
||||||
guard let console = console else { return }
|
|
||||||
|
|
||||||
self.name = console.name!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Published var name : String {
|
|
||||||
didSet {
|
|
||||||
guard let console = console else { return }
|
|
||||||
console.name = name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var logo : UIImage? {
|
|
||||||
get {
|
|
||||||
if let logoImage = self.console?.logo?.image {
|
|
||||||
return logoImage
|
|
||||||
}
|
|
||||||
|
|
||||||
return .none
|
|
||||||
}
|
|
||||||
|
|
||||||
set {
|
|
||||||
if let console = self.console {
|
|
||||||
if let logoImage = newValue {
|
|
||||||
let newLogo = Logo(context: CDManager.shared.viewContext)
|
|
||||||
newLogo.console = console
|
|
||||||
newLogo.image = logoImage
|
|
||||||
console.logo = newLogo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,18 +16,24 @@ struct ModalAddConsoleToLibrary : View {
|
|||||||
|
|
||||||
@State var modalConsoleName : String = ""
|
@State var modalConsoleName : String = ""
|
||||||
@State var modalConsoleLogoICloudPath : String? = .none
|
@State var modalConsoleLogoICloudPath : String? = .none
|
||||||
|
@State var modalConsoleShortName : String = ""
|
||||||
@State var isImporting : Bool = false
|
@State var modalConsoleManufacturer : String = ""
|
||||||
|
@State var modalConsoleReleaseDate : Date = Date()
|
||||||
|
@State var isImportingLogo : Bool = false
|
||||||
|
|
||||||
let defaultImage = UIImage()
|
let defaultImage = UIImage()
|
||||||
|
|
||||||
var addButton : some View {
|
var addButton : some View {
|
||||||
return Button(action: {
|
return Button(action: {
|
||||||
let console = Console(context: viewContext)
|
let console = Console(context: viewContext)
|
||||||
console.name = self.modalConsoleName
|
console.name = modalConsoleName
|
||||||
console.logo_icloud_path = self.modalConsoleLogoICloudPath
|
console.shortName = modalConsoleShortName
|
||||||
|
console.manufacturer = modalConsoleManufacturer
|
||||||
|
console.releaseDate = modalConsoleReleaseDate
|
||||||
|
|
||||||
self.presentationMode.wrappedValue.dismiss()},
|
console.logo_icloud_path = self.modalConsoleLogoICloudPath
|
||||||
|
|
||||||
|
self.presentationMode.wrappedValue.dismiss()},
|
||||||
label: { Text("Fertig") })
|
label: { Text("Fertig") })
|
||||||
.disabled(self.modalConsoleName.trimmingCharacters(in: .whitespacesAndNewlines) == "" )
|
.disabled(self.modalConsoleName.trimmingCharacters(in: .whitespacesAndNewlines) == "" )
|
||||||
}
|
}
|
||||||
@@ -36,11 +42,16 @@ struct ModalAddConsoleToLibrary : View {
|
|||||||
NavigationView {
|
NavigationView {
|
||||||
Form {
|
Form {
|
||||||
TextField("Name", text: $modalConsoleName)
|
TextField("Name", text: $modalConsoleName)
|
||||||
|
TextField("Abkürzung", text: $modalConsoleShortName)
|
||||||
|
TextField("Hersteller", text: $modalConsoleManufacturer)
|
||||||
|
DatePicker(selection: $modalConsoleReleaseDate, in: ...Date(), displayedComponents: .date) {
|
||||||
|
Text("Erscheinungsjahr")
|
||||||
|
}
|
||||||
Image(uiImage: ICloudManager.imageFrom(path: self.modalConsoleLogoICloudPath) ?? defaultImage)
|
Image(uiImage: ICloudManager.imageFrom(path: self.modalConsoleLogoICloudPath) ?? defaultImage)
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
Button(action: {
|
Button(action: {
|
||||||
isImporting = true;
|
isImportingLogo = true;
|
||||||
}, label: { Text("Bla")})
|
}, label: { Text("Bla")})
|
||||||
}
|
}
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
@@ -51,7 +62,7 @@ struct ModalAddConsoleToLibrary : View {
|
|||||||
trailing: addButton)
|
trailing: addButton)
|
||||||
.navigationViewStyle(StackNavigationViewStyle())
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
.fileImporter(
|
.fileImporter(
|
||||||
isPresented: $isImporting,
|
isPresented: $isImportingLogo,
|
||||||
allowedContentTypes: [.jpeg, .png],
|
allowedContentTypes: [.jpeg, .png],
|
||||||
allowsMultipleSelection: false
|
allowsMultipleSelection: false
|
||||||
) { result in
|
) { result in
|
||||||
@@ -70,7 +81,6 @@ struct ModalAddConsoleToLibrary : View {
|
|||||||
}catch{
|
}catch{
|
||||||
print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'")
|
print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,34 +9,47 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct ConsoleEditView: View {
|
struct ConsoleEditView: View {
|
||||||
@ObservedObject var consoleViewModel : ConsoleViewModel
|
@ObservedObject var console : Console
|
||||||
|
|
||||||
@State var showLogoImagePicker = false
|
@State var isImportingLogo : Bool = false
|
||||||
|
let defaultImage = UIImage()
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
TextField("Name der Konsole", text: $consoleViewModel.name)
|
TextField("Name der Konsole", text: $console.name ?? "n/a")
|
||||||
|
TextField("Abkürzung", text: $console.shortName ?? "")
|
||||||
consoleViewModel.logo.map {
|
TextField("Hersteller", text: $console.manufacturer ?? "")
|
||||||
Image (uiImage: $0)
|
DatePicker(selection: $console.releaseDate, in: ...Date(), displayedComponents: .date) {
|
||||||
.resizable()
|
Text("Erscheinungsjahr")
|
||||||
.frame(width:100, height: 100)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(action: { self.showLogoImagePicker = true }, label: { Text("Pick Image") })
|
Image(uiImage: ICloudManager.imageFrom(path: self.console.logo_icloud_path) ?? defaultImage)
|
||||||
|
.resizable()
|
||||||
|
.frame(width:100, height: 100)
|
||||||
|
|
||||||
|
Button(action: { self.isImportingLogo = true }, label: { Text("Pick Image") })
|
||||||
}
|
}
|
||||||
.navigationBarTitle("Editiere Konsole")
|
.navigationBarTitle("Editiere Konsole")
|
||||||
.sheet(isPresented: $showLogoImagePicker) {
|
.fileImporter(
|
||||||
ImagePicker.shared.view
|
isPresented: $isImportingLogo,
|
||||||
}
|
allowedContentTypes: [.jpeg, .png],
|
||||||
.onReceive(ImagePicker.shared.objectWillChange, perform: { image in
|
allowsMultipleSelection: false
|
||||||
if let image = image {
|
) { result in
|
||||||
self.consoleViewModel.logo = image
|
do {
|
||||||
|
let selectedFile : URL = try result.get().first!
|
||||||
|
|
||||||
|
//It seems that isUbiquitousItem checks if the file is contained in the Apps iCloud folder
|
||||||
|
if (FileManager.default.isUbiquitousItem(at: selectedFile)) {
|
||||||
|
console.logo_icloud_path = ICloudManager.relativePathFrom(url: selectedFile)
|
||||||
|
|
||||||
|
print("Selected Image in iCloud Path \(console.logo_icloud_path ?? "n/a")")
|
||||||
|
}else{
|
||||||
|
Alert(title: Text("Falscher Ordner"))
|
||||||
|
print("Außerhalb \(selectedFile.relativeString)")
|
||||||
|
}
|
||||||
|
}catch{
|
||||||
|
print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'")
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
|
||||||
|
|
||||||
init(_ console : Console) {
|
|
||||||
self.consoleViewModel = ConsoleViewModel(console)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ struct ConsoleLibraryView : View {
|
|||||||
.navigationBarTitle(Text("\(self.console?.name ?? "N/A")"), displayMode: .automatic)
|
.navigationBarTitle(Text("\(self.console?.name ?? "N/A")"), displayMode: .automatic)
|
||||||
.navigationBarItems(trailing:
|
.navigationBarItems(trailing:
|
||||||
HStack {
|
HStack {
|
||||||
NavigationLink(destination: ConsoleEditView(self.console!)) {
|
NavigationLink(destination: ConsoleEditView(console: self.console!)) {
|
||||||
Image(systemName: "pencil.and.ellipsis.rectangle")
|
Image(systemName: "pencil.and.ellipsis.rectangle")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ struct Overview: View {
|
|||||||
@ObservedObject var featuredStore = FeaturedStore()
|
@ObservedObject var featuredStore = FeaturedStore()
|
||||||
|
|
||||||
|
|
||||||
|
let defaultImage = UIImage()
|
||||||
|
|
||||||
var ConsolesOverview : some View {
|
var ConsolesOverview : some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
OverviewHeader(title: "Aktivste Konsolen", destination: ConsolesListView())
|
OverviewHeader(title: "Aktivste Konsolen", destination: ConsolesListView())
|
||||||
@@ -70,12 +72,10 @@ struct Overview: View {
|
|||||||
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Group {
|
Group {
|
||||||
console.logo?.image.map {
|
Image(uiImage: ICloudManager.imageFrom(path: console.logo_icloud_path) ?? defaultImage)
|
||||||
Image(uiImage: $0)
|
.resizable()
|
||||||
.resizable()
|
.padding(10)
|
||||||
.padding(10)
|
.cornerRadius(5)
|
||||||
.cornerRadius(5)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 100, height: 100)
|
||||||
//.background(Color(UIColor.lightGray))
|
//.background(Color(UIColor.lightGray))
|
||||||
@@ -184,10 +184,11 @@ struct Overview: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
if featuredStore.featuredConsole != nil {
|
if featuredStore.featuredConsole != nil {
|
||||||
NavigationLink(destination: ConsoleLibraryView(console: featuredStore.featuredConsole!)) {
|
NavigationLink(destination: ConsoleLibraryView(console: featuredStore.featuredConsole!)) {
|
||||||
if featuredStore.featuredConsole?.logo?.image != nil {
|
if ICloudManager.fileExists(at: featuredStore.featuredConsole?.logo_icloud_path) {
|
||||||
featuredStore.featuredConsole?.logo?.image.map {
|
Image(uiImage: ICloudManager.imageFrom(path: featuredStore.featuredConsole?.logo_icloud_path) ?? defaultImage)
|
||||||
Image(uiImage: $0).resizable().frame(width: 200, height: 200)
|
.resizable()
|
||||||
}
|
.padding(10)
|
||||||
|
.cornerRadius(5)
|
||||||
}else{
|
}else{
|
||||||
//TODO: Symbol für fehlendes Bild
|
//TODO: Symbol für fehlendes Bild
|
||||||
Image(systemName: "cave").frame(width: 200, height: 200)
|
Image(systemName: "cave").frame(width: 200, height: 200)
|
||||||
|
|||||||
@@ -11,16 +11,15 @@
|
|||||||
<relationship name="console" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Console" inverseName="accessories" inverseEntity="Console"/>
|
<relationship name="console" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Console" inverseName="accessories" inverseEntity="Console"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="Console" representedClassName="Console" syncable="YES">
|
<entity name="Console" representedClassName="Console" syncable="YES">
|
||||||
<attribute name="circumstances" optional="YES" attributeType="String"/>
|
|
||||||
<attribute name="generation" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="generation" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<attribute name="logo_icloud_path" optional="YES" attributeType="String"/>
|
<attribute name="logo_icloud_path" optional="YES" attributeType="String"/>
|
||||||
<attribute name="manufacturer" optional="YES" attributeType="String"/>
|
<attribute name="manufacturer" optional="YES" attributeType="String"/>
|
||||||
<attribute name="name" attributeType="String" defaultValueString=""/>
|
<attribute name="name" attributeType="String" defaultValueString=""/>
|
||||||
|
<attribute name="releaseDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="shortName" optional="YES" attributeType="String"/>
|
<attribute name="shortName" optional="YES" attributeType="String"/>
|
||||||
<attribute name="uuid" optional="YES" attributeType="UUID" defaultValueString="00000000-0000-0000-0000-000000000000" usesScalarValueType="NO"/>
|
<attribute name="uuid" optional="YES" attributeType="UUID" defaultValueString="00000000-0000-0000-0000-000000000000" usesScalarValueType="NO"/>
|
||||||
<relationship name="accessories" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Accessory" inverseName="console" inverseEntity="Accessory"/>
|
<relationship name="accessories" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Accessory" inverseName="console" inverseEntity="Accessory"/>
|
||||||
<relationship name="games" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Game" inverseName="console" inverseEntity="Game"/>
|
<relationship name="games" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Game" inverseName="console" inverseEntity="Game"/>
|
||||||
<relationship name="logo" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Logo" inverseName="console" inverseEntity="Logo"/>
|
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="Cover" representedClassName="Cover" syncable="YES">
|
<entity name="Cover" representedClassName="Cover" syncable="YES">
|
||||||
<attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/>
|
<attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/>
|
||||||
@@ -56,15 +55,14 @@
|
|||||||
</entity>
|
</entity>
|
||||||
<entity name="Logo" representedClassName="Logo" syncable="YES">
|
<entity name="Logo" representedClassName="Logo" syncable="YES">
|
||||||
<attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/>
|
<attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/>
|
||||||
<relationship name="console" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Console" inverseName="logo" inverseEntity="Console"/>
|
|
||||||
</entity>
|
</entity>
|
||||||
<elements>
|
<elements>
|
||||||
<element name="Accessory" positionX="-265.9140625" positionY="29.15625" width="128" height="149"/>
|
<element name="Accessory" positionX="-265.9140625" positionY="29.15625" width="128" height="149"/>
|
||||||
<element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="179"/>
|
<element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="164"/>
|
||||||
<element name="Cover" positionX="-66.69921875" positionY="223.48046875" width="128" height="59"/>
|
<element name="Cover" positionX="-66.69921875" positionY="223.48046875" width="128" height="59"/>
|
||||||
<element name="Game" positionX="-288.828125" positionY="276.7421875" width="128" height="245"/>
|
<element name="Game" positionX="-288.828125" positionY="276.7421875" width="128" height="245"/>
|
||||||
<element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/>
|
<element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/>
|
||||||
<element name="GameSeriesCover" positionX="-477" positionY="180" width="128" height="59"/>
|
<element name="GameSeriesCover" positionX="-477" positionY="180" width="128" height="59"/>
|
||||||
<element name="Logo" positionX="-66.7109375" positionY="110.9765625" width="128" height="73"/>
|
<element name="Logo" positionX="-66.7109375" positionY="110.9765625" width="128" height="44"/>
|
||||||
</elements>
|
</elements>
|
||||||
</model>
|
</model>
|
||||||
Reference in New Issue
Block a user