Possible SwiftUI migration
|
|
@ -3,376 +3,399 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objectVersion = 55;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
C9188EE01CD65DCB00F0F8B6 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */; };
|
||||
C921B3C71CD6219F0091C1AD /* DetailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3C51CD6219F0091C1AD /* DetailController.swift */; };
|
||||
C921B3CA1CD629180091C1AD /* DetailTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3C91CD629180091C1AD /* DetailTableView.swift */; };
|
||||
C921B3CC1CD63EF30091C1AD /* ActionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921B3CB1CD63EF30091C1AD /* ActionCell.swift */; };
|
||||
C948814E1CD3EA5500209C09 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C948814D1CD3EA5500209C09 /* AppDelegate.swift */; };
|
||||
C94881501CD3EA5500209C09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C948814F1CD3EA5500209C09 /* Assets.xcassets */; };
|
||||
C9AE594A1CD4EAD80090655C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9AE59481CD4EAD80090655C /* Main.storyboard */; };
|
||||
C9AE594C1CD4F1C70090655C /* SourceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9AE594B1CD4F1C70090655C /* SourceController.swift */; };
|
||||
C9ECF8A41CD4CEE300499965 /* SimPlatform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */; };
|
||||
C9ECF8A61CD4CF1600499965 /* SimOSVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */; };
|
||||
C9ECF8A81CD4CF4000499965 /* SimDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A71CD4CF4000499965 /* SimDevice.swift */; };
|
||||
C9ECF8AA1CD4CF5A00499965 /* SimApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8A91CD4CF5A00499965 /* SimApp.swift */; };
|
||||
C9ECF8AC1CD4CF8400499965 /* Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9ECF8AB1CD4CF8400499965 /* Support.swift */; };
|
||||
C9ECF8B21CD4E26300499965 /* CoreUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9ECF8B11CD4E26300499965 /* CoreUI.framework */; };
|
||||
C982F859283B9F9000D491F4 /* SimDirsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F858283B9F9000D491F4 /* SimDirsApp.swift */; };
|
||||
C982F85B283B9F9000D491F4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F85A283B9F9000D491F4 /* ContentView.swift */; };
|
||||
C982F85D283B9F9200D491F4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C982F85C283B9F9200D491F4 /* Assets.xcassets */; };
|
||||
C982F860283B9F9200D491F4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */; };
|
||||
C982F86B283BA22100D491F4 /* SimPlatform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F86A283BA22100D491F4 /* SimPlatform.swift */; };
|
||||
C982F871283CE7B800D491F4 /* SimRuntime.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F870283CE7B800D491F4 /* SimRuntime.swift */; };
|
||||
C982F873283CE9AD00D491F4 /* SimDeviceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F872283CE9AD00D491F4 /* SimDeviceType.swift */; };
|
||||
C982F875283CEEBB00D491F4 /* SimDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F874283CEEBB00D491F4 /* SimDevice.swift */; };
|
||||
C982F877283D020C00D491F4 /* SimProductFamily.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F876283D020C00D491F4 /* SimProductFamily.swift */; };
|
||||
C982F879283D042E00D491F4 /* SimModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F878283D042E00D491F4 /* SimModel.swift */; };
|
||||
C982F87B283E40C800D491F4 /* SimCtl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87A283E40C800D491F4 /* SimCtl.swift */; };
|
||||
C982F87E283E57B200D491F4 /* PresentableModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87D283E57B200D491F4 /* PresentableModel.swift */; };
|
||||
C982F880283E57E600D491F4 /* PresentationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F87F283E57E600D491F4 /* PresentationItem.swift */; };
|
||||
C982F883283E813F00D491F4 /* DeviceTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C982F882283E813F00D491F4 /* DeviceTypeView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
|
||||
C921B3C51CD6219F0091C1AD /* DetailController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailController.swift; sourceTree = "<group>"; };
|
||||
C921B3C91CD629180091C1AD /* DetailTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailTableView.swift; sourceTree = "<group>"; };
|
||||
C921B3CB1CD63EF30091C1AD /* ActionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionCell.swift; sourceTree = "<group>"; };
|
||||
C948814B1CD3EA5500209C09 /* SimDirs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimDirs.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C948814D1CD3EA5500209C09 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
C948814F1CD3EA5500209C09 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
C94881541CD3EA5500209C09 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C9AE59491CD4EAD80090655C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
C9AE594B1CD4F1C70090655C /* SourceController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceController.swift; sourceTree = "<group>"; };
|
||||
C9AE594D1CD503850090655C /* CUINamedLayerStack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CUINamedLayerStack.h; sourceTree = "<group>"; };
|
||||
C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimPlatform.swift; sourceTree = "<group>"; };
|
||||
C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimOSVersion.swift; sourceTree = "<group>"; };
|
||||
C9ECF8A71CD4CF4000499965 /* SimDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimDevice.swift; sourceTree = "<group>"; };
|
||||
C9ECF8A91CD4CF5A00499965 /* SimApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimApp.swift; sourceTree = "<group>"; };
|
||||
C9ECF8AB1CD4CF8400499965 /* Support.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Support.swift; sourceTree = "<group>"; };
|
||||
C9ECF8AF1CD4E13500499965 /* CUICatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUICatalog.h; sourceTree = "<group>"; };
|
||||
C9ECF8B01CD4E14C00499965 /* SimDirs-Bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimDirs-Bridge.h"; sourceTree = "<group>"; };
|
||||
C9ECF8B11CD4E26300499965 /* CoreUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreUI.framework; path = /System/Library/PrivateFrameworks/CoreUI.framework; sourceTree = "<absolute>"; };
|
||||
C982F855283B9F9000D491F4 /* SimDirs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimDirs.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C982F858283B9F9000D491F4 /* SimDirsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDirsApp.swift; sourceTree = "<group>"; };
|
||||
C982F85A283B9F9000D491F4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
C982F85C283B9F9200D491F4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
C982F861283B9F9200D491F4 /* SimDirs.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SimDirs.entitlements; sourceTree = "<group>"; };
|
||||
C982F86A283BA22100D491F4 /* SimPlatform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimPlatform.swift; sourceTree = "<group>"; };
|
||||
C982F870283CE7B800D491F4 /* SimRuntime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimRuntime.swift; sourceTree = "<group>"; };
|
||||
C982F872283CE9AD00D491F4 /* SimDeviceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDeviceType.swift; sourceTree = "<group>"; };
|
||||
C982F874283CEEBB00D491F4 /* SimDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimDevice.swift; sourceTree = "<group>"; };
|
||||
C982F876283D020C00D491F4 /* SimProductFamily.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimProductFamily.swift; sourceTree = "<group>"; };
|
||||
C982F878283D042E00D491F4 /* SimModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimModel.swift; sourceTree = "<group>"; };
|
||||
C982F87A283E40C800D491F4 /* SimCtl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimCtl.swift; sourceTree = "<group>"; };
|
||||
C982F87D283E57B200D491F4 /* PresentableModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentableModel.swift; sourceTree = "<group>"; };
|
||||
C982F87F283E57E600D491F4 /* PresentationItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentationItem.swift; sourceTree = "<group>"; };
|
||||
C982F882283E813F00D491F4 /* DeviceTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceTypeView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
C94881481CD3EA5500209C09 /* Frameworks */ = {
|
||||
C982F852283B9F9000D491F4 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C9ECF8B21CD4E26300499965 /* CoreUI.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
C9194D1C19C09A03004178EB = {
|
||||
C982F84C283B9F9000D491F4 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C948814C1CD3EA5500209C09 /* SimDirs */,
|
||||
C9ECF8B31CD4E27B00499965 /* Frameworks */,
|
||||
C9194D2619C09A03004178EB /* Products */,
|
||||
C982F857283B9F9000D491F4 /* SimDirs */,
|
||||
C982F856283B9F9000D491F4 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C9194D2619C09A03004178EB /* Products */ = {
|
||||
C982F856283B9F9000D491F4 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C948814B1CD3EA5500209C09 /* SimDirs.app */,
|
||||
C982F855283B9F9000D491F4 /* SimDirs.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C948814C1CD3EA5500209C09 /* SimDirs */ = {
|
||||
C982F857283B9F9000D491F4 /* SimDirs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C9ECF8A21CD4CEC800499965 /* Model */,
|
||||
C9ECF8AE1CD4E13500499965 /* Support */,
|
||||
C9ECF8B41CD4E96A00499965 /* UI */,
|
||||
C948814D1CD3EA5500209C09 /* AppDelegate.swift */,
|
||||
C9ECF8AB1CD4CF8400499965 /* Support.swift */,
|
||||
C948814F1CD3EA5500209C09 /* Assets.xcassets */,
|
||||
C9AE59481CD4EAD80090655C /* Main.storyboard */,
|
||||
C94881541CD3EA5500209C09 /* Info.plist */,
|
||||
C982F858283B9F9000D491F4 /* SimDirsApp.swift */,
|
||||
C982F85A283B9F9000D491F4 /* ContentView.swift */,
|
||||
C982F867283BA09B00D491F4 /* Model */,
|
||||
C982F881283E7F0400D491F4 /* Views */,
|
||||
C982F85C283B9F9200D491F4 /* Assets.xcassets */,
|
||||
C982F861283B9F9200D491F4 /* SimDirs.entitlements */,
|
||||
C982F85E283B9F9200D491F4 /* Preview Content */,
|
||||
);
|
||||
path = SimDirs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C9ECF8A21CD4CEC800499965 /* Model */ = {
|
||||
C982F85E283B9F9200D491F4 /* Preview Content */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C9ECF8A91CD4CF5A00499965 /* SimApp.swift */,
|
||||
C9ECF8A71CD4CF4000499965 /* SimDevice.swift */,
|
||||
C9ECF8A51CD4CF1600499965 /* SimOSVersion.swift */,
|
||||
C9ECF8A31CD4CEE300499965 /* SimPlatform.swift */,
|
||||
C982F85F283B9F9200D491F4 /* Preview Assets.xcassets */,
|
||||
);
|
||||
path = "Preview Content";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C982F867283BA09B00D491F4 /* Model */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C982F87C283E579900D491F4 /* Presentation */,
|
||||
C982F87A283E40C800D491F4 /* SimCtl.swift */,
|
||||
C982F878283D042E00D491F4 /* SimModel.swift */,
|
||||
C982F874283CEEBB00D491F4 /* SimDevice.swift */,
|
||||
C982F872283CE9AD00D491F4 /* SimDeviceType.swift */,
|
||||
C982F86A283BA22100D491F4 /* SimPlatform.swift */,
|
||||
C982F876283D020C00D491F4 /* SimProductFamily.swift */,
|
||||
C982F870283CE7B800D491F4 /* SimRuntime.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C9ECF8AE1CD4E13500499965 /* Support */ = {
|
||||
C982F87C283E579900D491F4 /* Presentation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C9ECF8AF1CD4E13500499965 /* CUICatalog.h */,
|
||||
C9AE594D1CD503850090655C /* CUINamedLayerStack.h */,
|
||||
C9ECF8B01CD4E14C00499965 /* SimDirs-Bridge.h */,
|
||||
C982F87D283E57B200D491F4 /* PresentableModel.swift */,
|
||||
C982F87F283E57E600D491F4 /* PresentationItem.swift */,
|
||||
);
|
||||
path = Support;
|
||||
path = Presentation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C9ECF8B31CD4E27B00499965 /* Frameworks */ = {
|
||||
C982F881283E7F0400D491F4 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C9ECF8B11CD4E26300499965 /* CoreUI.framework */,
|
||||
C982F882283E813F00D491F4 /* DeviceTypeView.swift */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C9ECF8B41CD4E96A00499965 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C921B3CB1CD63EF30091C1AD /* ActionCell.swift */,
|
||||
C921B3C51CD6219F0091C1AD /* DetailController.swift */,
|
||||
C921B3C91CD629180091C1AD /* DetailTableView.swift */,
|
||||
C9AE594B1CD4F1C70090655C /* SourceController.swift */,
|
||||
C9188EDF1CD65DCB00F0F8B6 /* WindowController.swift */,
|
||||
);
|
||||
path = UI;
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
C948814A1CD3EA5500209C09 /* SimDirs */ = {
|
||||
C982F854283B9F9000D491F4 /* SimDirs */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C94881571CD3EA5500209C09 /* Build configuration list for PBXNativeTarget "SimDirs" */;
|
||||
buildConfigurationList = C982F864283B9F9200D491F4 /* Build configuration list for PBXNativeTarget "SimDirs" */;
|
||||
buildPhases = (
|
||||
C94881471CD3EA5500209C09 /* Sources */,
|
||||
C94881481CD3EA5500209C09 /* Frameworks */,
|
||||
C94881491CD3EA5500209C09 /* Resources */,
|
||||
C982F851283B9F9000D491F4 /* Sources */,
|
||||
C982F852283B9F9000D491F4 /* Frameworks */,
|
||||
C982F853283B9F9000D491F4 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SimDirs;
|
||||
productName = SimDirs2;
|
||||
productReference = C948814B1CD3EA5500209C09 /* SimDirs.app */;
|
||||
productName = SimDirs;
|
||||
productReference = C982F855283B9F9000D491F4 /* SimDirs.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
C9194D1D19C09A03004178EB /* Project object */ = {
|
||||
C982F84D283B9F9000D491F4 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastUpgradeCheck = 0600;
|
||||
ORGANIZATIONNAME = "Quiet Spark";
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1340;
|
||||
LastUpgradeCheck = 1340;
|
||||
TargetAttributes = {
|
||||
C948814A1CD3EA5500209C09 = {
|
||||
CreatedOnToolsVersion = 7.3;
|
||||
C982F854283B9F9000D491F4 = {
|
||||
CreatedOnToolsVersion = 13.4;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = C9194D2019C09A03004178EB /* Build configuration list for PBXProject "SimDirs" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
buildConfigurationList = C982F850283B9F9000D491F4 /* Build configuration list for PBXProject "SimDirs" */;
|
||||
compatibilityVersion = "Xcode 13.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = C9194D1C19C09A03004178EB;
|
||||
productRefGroup = C9194D2619C09A03004178EB /* Products */;
|
||||
mainGroup = C982F84C283B9F9000D491F4;
|
||||
productRefGroup = C982F856283B9F9000D491F4 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
C948814A1CD3EA5500209C09 /* SimDirs */,
|
||||
C982F854283B9F9000D491F4 /* SimDirs */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
C94881491CD3EA5500209C09 /* Resources */ = {
|
||||
C982F853283B9F9000D491F4 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C9AE594A1CD4EAD80090655C /* Main.storyboard in Resources */,
|
||||
C94881501CD3EA5500209C09 /* Assets.xcassets in Resources */,
|
||||
C982F860283B9F9200D491F4 /* Preview Assets.xcassets in Resources */,
|
||||
C982F85D283B9F9200D491F4 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
C94881471CD3EA5500209C09 /* Sources */ = {
|
||||
C982F851283B9F9000D491F4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C921B3C71CD6219F0091C1AD /* DetailController.swift in Sources */,
|
||||
C921B3CC1CD63EF30091C1AD /* ActionCell.swift in Sources */,
|
||||
C9ECF8A41CD4CEE300499965 /* SimPlatform.swift in Sources */,
|
||||
C9ECF8A61CD4CF1600499965 /* SimOSVersion.swift in Sources */,
|
||||
C921B3CA1CD629180091C1AD /* DetailTableView.swift in Sources */,
|
||||
C9AE594C1CD4F1C70090655C /* SourceController.swift in Sources */,
|
||||
C9ECF8AA1CD4CF5A00499965 /* SimApp.swift in Sources */,
|
||||
C9188EE01CD65DCB00F0F8B6 /* WindowController.swift in Sources */,
|
||||
C948814E1CD3EA5500209C09 /* AppDelegate.swift in Sources */,
|
||||
C9ECF8A81CD4CF4000499965 /* SimDevice.swift in Sources */,
|
||||
C9ECF8AC1CD4CF8400499965 /* Support.swift in Sources */,
|
||||
C982F883283E813F00D491F4 /* DeviceTypeView.swift in Sources */,
|
||||
C982F85B283B9F9000D491F4 /* ContentView.swift in Sources */,
|
||||
C982F875283CEEBB00D491F4 /* SimDevice.swift in Sources */,
|
||||
C982F873283CE9AD00D491F4 /* SimDeviceType.swift in Sources */,
|
||||
C982F877283D020C00D491F4 /* SimProductFamily.swift in Sources */,
|
||||
C982F859283B9F9000D491F4 /* SimDirsApp.swift in Sources */,
|
||||
C982F871283CE7B800D491F4 /* SimRuntime.swift in Sources */,
|
||||
C982F86B283BA22100D491F4 /* SimPlatform.swift in Sources */,
|
||||
C982F87E283E57B200D491F4 /* PresentableModel.swift in Sources */,
|
||||
C982F880283E57E600D491F4 /* PresentationItem.swift in Sources */,
|
||||
C982F879283D042E00D491F4 /* SimModel.swift in Sources */,
|
||||
C982F87B283E40C800D491F4 /* SimCtl.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
C9AE59481CD4EAD80090655C /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
C9AE59491CD4EAD80090655C /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
C9194D4019C09A03004178EB /* Debug */ = {
|
||||
C982F862283B9F9200D491F4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.3;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C9194D4119C09A03004178EB /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C94881551CD3EA5500209C09 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
|
||||
);
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/SimDirs/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.quietspark.SimDirs;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "SimDirs/Support/SimDirs-Bridge.h";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C94881561CD3EA5500209C09 /* Release */ = {
|
||||
C982F863283B9F9200D491F4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.3;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C982F865283B9F9200D491F4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = SimDirs/SimDirs.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"SimDirs/Preview Content\"";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/SimDirs/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.quietspark.SimDirs;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sgntn.SimDirs;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "SimDirs/Support/SimDirs-Bridge.h";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C982F866283B9F9200D491F4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = SimDirs/SimDirs.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"SimDirs/Preview Content\"";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sgntn.SimDirs;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
C9194D2019C09A03004178EB /* Build configuration list for PBXProject "SimDirs" */ = {
|
||||
C982F850283B9F9000D491F4 /* Build configuration list for PBXProject "SimDirs" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C9194D4019C09A03004178EB /* Debug */,
|
||||
C9194D4119C09A03004178EB /* Release */,
|
||||
C982F862283B9F9200D491F4 /* Debug */,
|
||||
C982F863283B9F9200D491F4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C94881571CD3EA5500209C09 /* Build configuration list for PBXNativeTarget "SimDirs" */ = {
|
||||
C982F864283B9F9200D491F4 /* Build configuration list for PBXNativeTarget "SimDirs" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C94881551CD3EA5500209C09 /* Debug */,
|
||||
C94881561CD3EA5500209C09 /* Release */,
|
||||
C982F865283B9F9200D491F4 /* Debug */,
|
||||
C982F866283B9F9200D491F4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = C9194D1D19C09A03004178EB /* Project object */;
|
||||
rootObject = C982F84D283B9F9000D491F4 /* Project object */;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:SimDirs.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
//
|
||||
// AppDelegate.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/29/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
func applicationDidFinishLaunching(aNotification: NSNotification) {
|
||||
}
|
||||
|
||||
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
11
SimDirs/Assets.xcassets/AccentColor.colorset/Contents.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +1,58 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_16x16.png",
|
||||
"scale" : "1x"
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_16x16@2x.png",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_32x32.png",
|
||||
"scale" : "1x"
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_32x32@2x.png",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_128x128.png",
|
||||
"scale" : "1x"
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_128x128@2x.png",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_256x256.png",
|
||||
"scale" : "1x"
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_256x256@2x.png",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_512x512.png",
|
||||
"scale" : "1x"
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_512x512@2x.png",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 438 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "default_icon.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "defaultt_icon@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -1,488 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
<scene sceneID="JPo-4y-FX3">
|
||||
<objects>
|
||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="SimDirs" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="SimDirs" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About SimDirs" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide SimDirs" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit SimDirs" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="dMs-cI-mzQ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<items>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<connections>
|
||||
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
||||
</connections>
|
||||
</application>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="SimDirs" customModuleProvider="target"/>
|
||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="0.0"/>
|
||||
</scene>
|
||||
<!--Window Controller-->
|
||||
<scene sceneID="R2V-B0-nI4">
|
||||
<objects>
|
||||
<windowController id="B8D-0N-5wS" customClass="WindowController" customModule="SimDirs" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<window key="window" title="SimDirs" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="" animationBehavior="default" id="IQv-IB-iLA">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="35" y="482" width="480" height="270"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="B8D-0N-5wS" id="qkq-Ka-avA"/>
|
||||
</connections>
|
||||
</window>
|
||||
<connections>
|
||||
<segue destination="utk-XN-WFQ" kind="relationship" relationship="window.shadowedContentViewController" id="cNr-LA-6PI"/>
|
||||
</connections>
|
||||
</windowController>
|
||||
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="250"/>
|
||||
</scene>
|
||||
<!--Split View Controller-->
|
||||
<scene sceneID="ANE-qI-AzX">
|
||||
<objects>
|
||||
<splitViewController id="utk-XN-WFQ" sceneMemberID="viewController">
|
||||
<splitViewItems>
|
||||
<splitViewItem holdingPriority="255" behavior="contentList" id="vjm-YC-n35"/>
|
||||
<splitViewItem id="zem-yq-moN"/>
|
||||
</splitViewItems>
|
||||
<splitView key="splitView" dividerStyle="thin" vertical="YES" id="4n7-1p-MYG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="utk-XN-WFQ" id="zcR-4y-jcI"/>
|
||||
</connections>
|
||||
</splitView>
|
||||
<connections>
|
||||
<outlet property="splitView" destination="4n7-1p-MYG" id="anq-oS-l0b"/>
|
||||
<segue destination="iYR-B6-n1S" kind="relationship" relationship="splitItems" id="5zw-PK-lrP"/>
|
||||
<segue destination="F48-sT-ymT" kind="relationship" relationship="splitItems" id="wSa-fB-x8O"/>
|
||||
</connections>
|
||||
</splitViewController>
|
||||
<customObject id="fvM-of-U7k" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="704"/>
|
||||
</scene>
|
||||
<!--Source Controller-->
|
||||
<scene sceneID="95M-fv-kdk">
|
||||
<objects>
|
||||
<viewController id="iYR-B6-n1S" customClass="SourceController" customModule="SimDirs" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="MGo-Qu-2zB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="220" height="299"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AbX-mV-QBL">
|
||||
<rect key="frame" x="0.0" y="30" width="220" height="269"/>
|
||||
<clipView key="contentView" id="Pi5-bv-Sst">
|
||||
<rect key="frame" x="0.0" y="0.0" width="220" height="269"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="mzD-l4-yhs" id="mUb-N5-ueO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="220" height="269"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn identifier="title" editable="NO" width="188" minWidth="40" maxWidth="1000" id="mzD-l4-yhs">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" alignment="left" title="Text Cell" id="mde-rH-ONI">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="TextCell" id="HAO-IX-sxc" userLabel="Text Cell">
|
||||
<rect key="frame" x="11" y="1" width="197" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="bfY-42-aRq">
|
||||
<rect key="frame" x="2" y="1" width="197" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="cnA-t8-jTo">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="bfY-42-aRq" firstAttribute="leading" secondItem="HAO-IX-sxc" secondAttribute="leading" constant="4" id="89t-I4-nZh"/>
|
||||
<constraint firstAttribute="centerY" secondItem="bfY-42-aRq" secondAttribute="centerY" id="D1b-kz-ps5"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bfY-42-aRq" secondAttribute="trailing" id="Dud-KT-aci"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="textField" destination="bfY-42-aRq" id="ucp-nv-3Ke"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="ImageCell" id="Dwi-Dl-LE4" userLabel="Image & Text Cell">
|
||||
<rect key="frame" x="11" y="21" width="197" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="5Mz-bX-925">
|
||||
<rect key="frame" x="4" y="-2" width="22" height="28"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="22" id="9JV-jh-a9G"/>
|
||||
<constraint firstAttribute="height" constant="22" id="p7O-pN-kXh"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="MLC-9O-NVW"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wgX-ci-hFu">
|
||||
<rect key="frame" x="28" y="4" width="171" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="jZj-fZ-DCx">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerY" secondItem="5Mz-bX-925" secondAttribute="centerY" id="BKo-y7-kUK"/>
|
||||
<constraint firstAttribute="trailing" secondItem="wgX-ci-hFu" secondAttribute="trailing" id="dit-vg-hyV"/>
|
||||
<constraint firstItem="wgX-ci-hFu" firstAttribute="leading" secondItem="5Mz-bX-925" secondAttribute="trailing" constant="4" id="sVg-cY-ZoA"/>
|
||||
<constraint firstAttribute="centerY" secondItem="wgX-ci-hFu" secondAttribute="centerY" id="t56-t6-q7e"/>
|
||||
<constraint firstItem="5Mz-bX-925" firstAttribute="leading" secondItem="Dwi-Dl-LE4" secondAttribute="leading" constant="4" id="yqi-4E-9SK"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="imageView" destination="5Mz-bX-925" id="Tqr-NH-n33"/>
|
||||
<outlet property="textField" destination="wgX-ci-hFu" id="QM1-92-bQC"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="iYR-B6-n1S" id="r6O-sY-vDK"/>
|
||||
<outlet property="delegate" destination="iYR-B6-n1S" id="dFv-mO-hVs"/>
|
||||
</connections>
|
||||
</outlineView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="200" id="Prh-ue-cFO"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="yeB-eV-8JM"/>
|
||||
</constraints>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="UKV-0Z-h3q">
|
||||
<rect key="frame" x="1" y="284" width="448" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="xTK-zV-3rC">
|
||||
<rect key="frame" x="184" y="1" width="15" height="0.0"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="DfU-U7-lPF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="220" height="30"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8XW-ii-1pm">
|
||||
<rect key="frame" x="72" y="-2" width="76" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Reload" bezelStyle="rounded" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="gGy-Fx-TPk">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="rescan:" target="iYR-B6-n1S" id="K6Y-C3-2it"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="07R-e0-RcD"/>
|
||||
<constraint firstItem="8XW-ii-1pm" firstAttribute="centerX" secondItem="DfU-U7-lPF" secondAttribute="centerX" id="o8I-3P-AaK"/>
|
||||
<constraint firstItem="8XW-ii-1pm" firstAttribute="centerY" secondItem="DfU-U7-lPF" secondAttribute="centerY" id="yWq-r4-QMO"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="DfU-U7-lPF" firstAttribute="top" secondItem="AbX-mV-QBL" secondAttribute="bottom" id="GkT-KT-J9Q"/>
|
||||
<constraint firstItem="DfU-U7-lPF" firstAttribute="leading" secondItem="MGo-Qu-2zB" secondAttribute="leading" id="Je2-3P-DQe"/>
|
||||
<constraint firstAttribute="trailing" secondItem="DfU-U7-lPF" secondAttribute="trailing" id="Kh3-dO-bzm"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DfU-U7-lPF" secondAttribute="bottom" id="cjT-GE-N46"/>
|
||||
<constraint firstAttribute="trailing" secondItem="AbX-mV-QBL" secondAttribute="trailing" id="elr-8R-0p9"/>
|
||||
<constraint firstItem="AbX-mV-QBL" firstAttribute="top" secondItem="MGo-Qu-2zB" secondAttribute="top" id="h7M-GY-dLb"/>
|
||||
<constraint firstItem="AbX-mV-QBL" firstAttribute="leading" secondItem="MGo-Qu-2zB" secondAttribute="leading" id="isG-f2-jDQ"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="outlineView" destination="mUb-N5-ueO" id="qcM-cj-dLn"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="HIA-tb-x8L" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="715" y="455"/>
|
||||
</scene>
|
||||
<!--Detail Controller-->
|
||||
<scene sceneID="Wbg-Th-oFy">
|
||||
<objects>
|
||||
<viewController id="F48-sT-ymT" customClass="DetailController" customModule="SimDirs" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="UMm-Xy-nBF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="460" height="298"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0W4-aZ-Ae5">
|
||||
<rect key="frame" x="18" y="262" width="93" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Detail Header" id="ZtP-3C-2L8">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cnN-cy-Bac">
|
||||
<rect key="frame" x="435" y="278" width="5" height="0.0"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="36a-uZ-g0s"/>
|
||||
</imageView>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JAP-se-fpu">
|
||||
<rect key="frame" x="20" y="0.0" width="399" height="254"/>
|
||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="tnM-9n-jrP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="399" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="eyA-kU-AI2" customClass="DetailTableView" customModule="SimDirs" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="399" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
|
||||
<tableViewGridLines key="gridStyleMask" horizontal="YES"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn identifier="title" width="160" minWidth="40" maxWidth="1000" id="tCe-6w-h4v">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Ls1-dG-GNl">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="PropertyTitleCell" id="lRo-ld-RBC" userLabel="Property Title">
|
||||
<rect key="frame" x="11" y="1" width="165" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="TBX-NI-YIG">
|
||||
<rect key="frame" x="0.0" y="4" width="159" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="fjI-nE-FBC">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="TBX-NI-YIG" firstAttribute="leading" secondItem="lRo-ld-RBC" secondAttribute="leading" constant="2" id="BUg-Ur-Hzl"/>
|
||||
<constraint firstItem="TBX-NI-YIG" firstAttribute="centerY" secondItem="lRo-ld-RBC" secondAttribute="centerY" id="INO-aQ-3HN"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TBX-NI-YIG" secondAttribute="trailing" constant="8" id="dQf-Hb-UI8"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="textField" destination="TBX-NI-YIG" id="KpA-dH-uNj"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="value" width="204" minWidth="40" maxWidth="1000" id="pRb-SO-D2D">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="hs3-Z6-Um2">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="PropertyValueCell" id="M6i-yS-c78" userLabel="Property Value">
|
||||
<rect key="frame" x="179" y="1" width="208" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="IMg-r6-yjW">
|
||||
<rect key="frame" x="-2" y="4" width="212" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="05K-5u-HvY">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="IMg-r6-yjW" secondAttribute="trailing" id="EF1-3C-aMi"/>
|
||||
<constraint firstItem="IMg-r6-yjW" firstAttribute="centerY" secondItem="M6i-yS-c78" secondAttribute="centerY" id="Ude-WE-2uY"/>
|
||||
<constraint firstItem="IMg-r6-yjW" firstAttribute="leading" secondItem="M6i-yS-c78" secondAttribute="leading" id="Zhq-i0-zHb"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="textField" destination="IMg-r6-yjW" id="OA5-by-P3W"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<customView identifier="PropertyActionCell" id="q5G-P3-EGm" userLabel="Reveal Cell" customClass="ActionCell" customModule="SimDirs" customModuleProvider="target">
|
||||
<rect key="frame" x="179" y="27" width="208" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jjs-nn-o9R">
|
||||
<rect key="frame" x="-7" y="-5" width="124" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Show In Finder" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="qaa-xT-Nnr">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="executeAction:" target="q5G-P3-EGm" id="4Id-0c-7mK"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Jjs-nn-o9R" firstAttribute="centerY" secondItem="q5G-P3-EGm" secondAttribute="centerY" id="njz-TZ-q0l"/>
|
||||
<constraint firstItem="Jjs-nn-o9R" firstAttribute="leading" secondItem="q5G-P3-EGm" secondAttribute="leading" id="xBT-kv-Yby"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="Jjs-nn-o9R" id="IiA-iD-gPo"/>
|
||||
</connections>
|
||||
</customView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="F48-sT-ymT" id="Iq0-Oq-XqV"/>
|
||||
<outlet property="delegate" destination="F48-sT-ymT" id="f1b-rA-9VC"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="360" id="FDG-SK-zLr"/>
|
||||
</constraints>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="mGJ-QF-84J">
|
||||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="U02-Dv-BpL">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="cnN-cy-Bac" secondAttribute="trailing" constant="20" symbolic="YES" id="6jt-1y-I45"/>
|
||||
<constraint firstItem="JAP-se-fpu" firstAttribute="top" secondItem="0W4-aZ-Ae5" secondAttribute="bottom" constant="8" symbolic="YES" id="I2y-6k-eoF"/>
|
||||
<constraint firstItem="cnN-cy-Bac" firstAttribute="leading" secondItem="JAP-se-fpu" secondAttribute="trailing" constant="16" id="Mp2-4Z-5Wj"/>
|
||||
<constraint firstItem="0W4-aZ-Ae5" firstAttribute="leading" secondItem="UMm-Xy-nBF" secondAttribute="leading" constant="20" symbolic="YES" id="NxN-dt-Qik"/>
|
||||
<constraint firstItem="JAP-se-fpu" firstAttribute="leading" secondItem="UMm-Xy-nBF" secondAttribute="leading" constant="20" symbolic="YES" id="Tpt-YG-xYq"/>
|
||||
<constraint firstAttribute="bottom" secondItem="JAP-se-fpu" secondAttribute="bottom" id="e1L-p4-1Hj"/>
|
||||
<constraint firstItem="cnN-cy-Bac" firstAttribute="top" secondItem="UMm-Xy-nBF" secondAttribute="top" constant="20" symbolic="YES" id="fKO-Jw-6co"/>
|
||||
<constraint firstItem="0W4-aZ-Ae5" firstAttribute="top" secondItem="UMm-Xy-nBF" secondAttribute="top" constant="20" symbolic="YES" id="g8h-kr-Or3"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="headerLabel" destination="0W4-aZ-Ae5" id="BcX-er-8kA"/>
|
||||
<outlet property="imageView" destination="cnN-cy-Bac" id="teZ-DG-dWn"/>
|
||||
<outlet property="propertyTable" destination="eyA-kU-AI2" id="Bq9-nt-FtY"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="F92-9s-t7r" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="715" y="904"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="NSActionTemplate" width="15" height="15"/>
|
||||
</resources>
|
||||
</document>
|
||||
80
SimDirs/ContentView.swift
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// ContentView.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/23/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct Item: Identifiable {
|
||||
var id: Int
|
||||
var name: String
|
||||
|
||||
init(id: Int) {
|
||||
self.id = id
|
||||
self.name = "\(id)"
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView: View {
|
||||
@EnvironmentObject var modelData : PresentableModel
|
||||
@State private var toggleVal = false
|
||||
|
||||
let testItems = (0..<10).map({ Item(id: $0) })
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List {
|
||||
OutlineGroup(modelData.items, children: \.children) { item in
|
||||
NavigationLink {
|
||||
VStack {
|
||||
HStack {
|
||||
switch item.underlying {
|
||||
case let deviceType as SimDeviceType:
|
||||
DeviceTypeView(deviceType: deviceType)
|
||||
|
||||
default:
|
||||
Text("\(item.title)")
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.all)
|
||||
.navigationTitle(item.title)
|
||||
} label: {
|
||||
Label(item.title, systemImage: item.imageName)
|
||||
}
|
||||
}
|
||||
.padding(.leading, 2.0)
|
||||
}
|
||||
.frame(minWidth: 200)
|
||||
.toolbar {
|
||||
ToolbarItem {
|
||||
Menu {
|
||||
// Picker("Category", selection: $filter) {
|
||||
// ForEach(FilterCategory.allCases) { category in
|
||||
// Text(category.rawValue).tag(category)
|
||||
// }
|
||||
// }
|
||||
// .pickerStyle(.inline)
|
||||
Toggle(isOn: $toggleVal) {
|
||||
Label("Toggle", systemImage: "star.fill")
|
||||
}
|
||||
} label: {
|
||||
Label("Filter", systemImage: "slider.horizontal.3")
|
||||
}
|
||||
}
|
||||
}
|
||||
Text("SimDirs") // If this isn't here things looks weird
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
.environmentObject(PresentableModel())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.6</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Quiet Spark. All rights reserved.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
100
SimDirs/Model/Presentation/PresentableModel.swift
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// PresentableModel.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/25/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class PresentableModel: ObservableObject {
|
||||
enum Style {
|
||||
case byDevice
|
||||
case byRuntime
|
||||
}
|
||||
|
||||
var baseModel = SimModel()
|
||||
var style = Style.byDevice
|
||||
var items = [PresentationItem]()
|
||||
|
||||
init() {
|
||||
rebuildPresentation()
|
||||
// dumpPresentationItems(items)
|
||||
}
|
||||
|
||||
func rebuildPresentation() {
|
||||
switch style {
|
||||
case .byDevice: items = itemsForDevicePresentation()
|
||||
case .byRuntime: items = itemsForRuntimePresentation()
|
||||
}
|
||||
}
|
||||
|
||||
func itemsForDevicePresentation() -> [PresentationItem] {
|
||||
return SimProductFamily.presentation.map{ family in
|
||||
var familyItem = PresentationItem(family)
|
||||
|
||||
familyItem.children = baseModel.deviceTypes.filter({ $0.supports(productFamily: family) }).map { deviceType in
|
||||
var deviceTypeItem = PresentationItem(deviceType, identifier: deviceType.id)
|
||||
let deviceTypeChildren : [PresentationItem] = baseModel.runtimes.filter({ $0.supports(deviceType: deviceType) }).map { runtime in
|
||||
var runtimeItem = PresentationItem(runtime, identifier: "\(deviceType.id) - \(runtime.id)")
|
||||
let runtimeItemChildren = runtime.devices.filter({ $0.isDeviceOfType(deviceType) }).map { PresentationItem($0, image: family.imageName) }
|
||||
|
||||
if !runtimeItemChildren.isEmpty {
|
||||
runtimeItem.children = runtimeItemChildren
|
||||
}
|
||||
|
||||
return runtimeItem
|
||||
}
|
||||
|
||||
if !deviceTypeChildren.isEmpty {
|
||||
deviceTypeItem.children = deviceTypeChildren
|
||||
}
|
||||
|
||||
return deviceTypeItem
|
||||
}
|
||||
|
||||
return familyItem
|
||||
}
|
||||
}
|
||||
|
||||
func itemsForRuntimePresentation() -> [PresentationItem] {
|
||||
return SimPlatform.presentation.map{ platform in
|
||||
var platformItem = PresentationItem(platform)
|
||||
|
||||
platformItem.children = baseModel.runtimes.filter({ $0.supports(platform: platform) }).map { runtime in
|
||||
var runtimeItem = PresentationItem(runtime)
|
||||
let runtimeItemChildren : [PresentationItem] = baseModel.deviceTypes.filter({ $0.supports(runtime: runtime) }).map { deviceType in
|
||||
var deviceTypeItem = PresentationItem(deviceType, identifier: "\(runtime.id) - \(deviceType.id)")
|
||||
let deviceTypeChildren = runtime.devices.filter({ $0.isDeviceOfType(deviceType) }).map { PresentationItem($0, image: deviceType.imageName) }
|
||||
|
||||
if !deviceTypeChildren.isEmpty {
|
||||
deviceTypeItem.children = deviceTypeChildren
|
||||
}
|
||||
|
||||
return deviceTypeItem
|
||||
}
|
||||
|
||||
if !runtimeItemChildren.isEmpty {
|
||||
runtimeItem.children = runtimeItemChildren
|
||||
}
|
||||
|
||||
return runtimeItem
|
||||
}
|
||||
|
||||
return platformItem
|
||||
}
|
||||
}
|
||||
|
||||
func dumpPresentationItems(_ items: [PresentationItem], level: Int = 0) {
|
||||
let ident = Array(repeating: "\t", count: level).joined()
|
||||
|
||||
for item in items {
|
||||
print("\(ident)\(item.title) [\(item.id)]")
|
||||
|
||||
if let children = item.children {
|
||||
dumpPresentationItems(children, level: level + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
SimDirs/Model/Presentation/PresentationItem.swift
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// PresentationItem.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/25/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
protocol PresentableItem {
|
||||
var title : String { get }
|
||||
var id : String { get }
|
||||
var imageName : String { get }
|
||||
}
|
||||
|
||||
protocol PresentableContent {
|
||||
associatedtype Content : View
|
||||
|
||||
var view : Content { get }
|
||||
}
|
||||
|
||||
struct PresentationContent<T: PresentableContent> {
|
||||
let underlying : T
|
||||
}
|
||||
|
||||
struct PresentationItem: Identifiable {
|
||||
let underlying : PresentableItem
|
||||
var children : [PresentationItem]?
|
||||
var id : String
|
||||
var customImage : String?
|
||||
|
||||
var title : String { return underlying.title }
|
||||
var imageName : String { return customImage ?? underlying.imageName }
|
||||
|
||||
init(_ presentable: PresentableItem, image: String? = nil, identifier: String? = nil) {
|
||||
underlying = presentable
|
||||
id = identifier ?? underlying.id
|
||||
customImage = image
|
||||
}
|
||||
}
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
//
|
||||
// SimApp.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class SimApp: OutlineProvider, PropertyProvider {
|
||||
let bundleID : String
|
||||
var bundleName = ""
|
||||
var displayName = ""
|
||||
var shortVersion = ""
|
||||
var version = ""
|
||||
var minOSVersion : String?
|
||||
var icon : NSImage?
|
||||
var hasValidPaths : Bool { return self.validatedBundlePath != nil || self.validatedSandboxPath != nil }
|
||||
var bundleURL : URL? { return self.validatedBundlePath.map { URL(fileURLWithPath: $0) } }
|
||||
var sandboxURL : URL? { return self.validatedSandboxPath.map { URL(fileURLWithPath: $0) } }
|
||||
private var validatedBundlePath : String?
|
||||
private var validatedSandboxPath : String?
|
||||
|
||||
var bundlePath : String? {
|
||||
get { return self.validatedBundlePath }
|
||||
set {
|
||||
guard let newPath = newValue else { return }
|
||||
if self.validatedBundlePath == nil && newPath.validPath {
|
||||
self.validatedBundlePath = newPath
|
||||
}
|
||||
}
|
||||
}
|
||||
var sandboxPath : String? {
|
||||
get { return self.validatedSandboxPath }
|
||||
set {
|
||||
guard let newPath = newValue else { return }
|
||||
if self.validatedSandboxPath == nil && newPath.validPath {
|
||||
self.validatedSandboxPath = newPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init(bundleID: String) {
|
||||
self.bundleID = bundleID
|
||||
}
|
||||
|
||||
func completeScan() {
|
||||
self.refinePaths()
|
||||
self.loadInfoPlist()
|
||||
}
|
||||
|
||||
func updateFrom(launchBundleInfo: [String : AnyObject]) {
|
||||
self.bundlePath = launchBundleInfo["BundleContainer"] as? String
|
||||
self.sandboxPath = launchBundleInfo["Container"] as? String
|
||||
}
|
||||
|
||||
func updateFrom(appStateInfo: [String : AnyObject]) {
|
||||
guard let compatInfo = appStateInfo["compatibilityInfo"] as? [String : AnyObject] else { return }
|
||||
|
||||
self.bundlePath = compatInfo["bundlePath"] as? String
|
||||
self.sandboxPath = compatInfo["sandboxPath"] as? String
|
||||
}
|
||||
|
||||
func refinePaths() {
|
||||
guard let bundleURL = self.bundleURL else { return }
|
||||
let fileMgr = FileManager.default
|
||||
|
||||
if !bundleURL.lastPathComponent.contains("app") {
|
||||
if let dirEnumerator = fileMgr.enumerator(at: bundleURL, includingPropertiesForKeys: nil, options: [ .skipsSubdirectoryDescendants, .skipsHiddenFiles ]) {
|
||||
|
||||
for appURL in dirEnumerator.allObjects.compactMap({ $0 as? URL}) {
|
||||
if appURL.lastPathComponent.contains(".app") {
|
||||
self.validatedBundlePath = appURL.path
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadInfoPlist() {
|
||||
guard let bundleURL = self.bundleURL else { return }
|
||||
let infoPlistURL = bundleURL.appendingPathComponent("Info.plist")
|
||||
|
||||
if let plistInfo = PropertyListSerialization.propertyListWithURL(infoPlistURL) {
|
||||
self.bundleName = plistInfo[String(kCFBundleNameKey)] as? String ?? ""
|
||||
self.displayName = plistInfo["CFBundleDisplayName"] as? String ?? ""
|
||||
self.shortVersion = plistInfo["CFBundleShortVersionString"] as? String ?? ""
|
||||
self.version = plistInfo[String(kCFBundleVersionKey)] as? String ?? ""
|
||||
self.minOSVersion = plistInfo["MinimumOSVersion"] as? String
|
||||
|
||||
if self.displayName.isEmpty {
|
||||
self.displayName = self.bundleName
|
||||
}
|
||||
|
||||
if let bundleIcons = plistInfo["CFBundleIcons"] as? [String : AnyObject] {
|
||||
let primaryIconValue = bundleIcons["CFBundlePrimaryIcon"].flatMap { item -> [String : AnyObject]? in
|
||||
switch item {
|
||||
case let dict as [String : AnyObject]: return dict
|
||||
case let str as String: return ["CFBundleIconFiles" : [str]] as [String : AnyObject]
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
if let primaryIcon = primaryIconValue {
|
||||
if let bundleIconFiles = primaryIcon["CFBundleIconFiles"] as? [String] {
|
||||
for iconName in bundleIconFiles {
|
||||
var iconURL = bundleURL.appendingPathComponent(iconName)
|
||||
let icon2XURL = bundleURL.appendingPathComponent("\(iconName)@2x.png")
|
||||
|
||||
if iconURL.pathExtension.isEmpty {
|
||||
iconURL = iconURL.appendingPathComponent("png")
|
||||
}
|
||||
|
||||
// .car files not yet working :/
|
||||
|
||||
// if !iconURL.validPath && !icon2XURL.validPath { // Believe this would only happen once per bundle
|
||||
// let assetFileURL = bundleURL.URLByAppendingPathComponent("Assets.car")
|
||||
//
|
||||
// if assetFileURL.validPath {
|
||||
// if let catalog = try? CUICatalog.init(URL: assetFileURL) {
|
||||
// let catalogImages = catalog.imagesWithName(iconName)
|
||||
//
|
||||
// for catalogImage in catalogImages {
|
||||
// if let namedImage = catalogImage as? CUINamedImage where !(namedImage is CUINamedLayerStack) {
|
||||
// if self.icon?.size.width ?? 0 < namedImage.size.width {
|
||||
// let imageRep = NSBitmapImageRep(CGImage: namedImage.image)
|
||||
//
|
||||
// imageRep.size = namedImage.size
|
||||
// if let pngData = imageRep.representationUsingType(.NSPNGFileType, properties: [NSImageInterlaced : false]) where pngData.length > 0 {
|
||||
// self.icon = NSImage(data: pngData)
|
||||
// }
|
||||
// self.icon = NSImage(CGImage: namedImage.image, size: namedImage.size)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
if let icon = NSImage(contentsOf: iconURL) {
|
||||
if self.icon?.size.width ?? 0 < icon.size.width {
|
||||
self.icon = icon
|
||||
}
|
||||
}
|
||||
|
||||
if let icon = NSImage(contentsOf: icon2XURL) {
|
||||
if self.icon?.size.width ?? 0 < icon.size.width {
|
||||
self.icon = icon
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.icon == nil {
|
||||
self.icon = NSImage(named: "default_icon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - OutlineProvider -
|
||||
|
||||
var outlineTitle : String { return self.displayName }
|
||||
var outlineImage : NSImage? { return self.icon }
|
||||
var childCount : Int { return 0 }
|
||||
|
||||
func childAt(index: Int) -> OutlineProvider? {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MARK: - PropertyProvider -
|
||||
|
||||
var header : String { return "App Information" }
|
||||
var image : NSImage? { return self.icon }
|
||||
var properties : [SimProperty] {
|
||||
var version = self.shortVersion
|
||||
var properties : [SimProperty]
|
||||
|
||||
if self.shortVersion != self.version {
|
||||
version += " \((self.version))"
|
||||
}
|
||||
|
||||
properties = [
|
||||
SimProperty(title: "Display Name", value: .Text(text: self.displayName)),
|
||||
SimProperty(title: "Bundle Name", value: .Text(text: self.bundleName)),
|
||||
SimProperty(title: "Bundle ID", value: .Text(text: self.bundleID)),
|
||||
SimProperty(title: "Version", value: .Text(text: version))
|
||||
]
|
||||
if let minOSVersion = self.minOSVersion {
|
||||
properties.append(SimProperty(title: "Minimum OS Version", value: .Text(text: minOSVersion)))
|
||||
}
|
||||
if let bundleURL = self.bundleURL {
|
||||
properties.append(SimProperty(title: "Bundle", value: .Location(url: bundleURL)))
|
||||
}
|
||||
if let sandboxURL = self.sandboxURL {
|
||||
properties.append(SimProperty(title: "Sandbox", value: .Location(url: sandboxURL)))
|
||||
}
|
||||
|
||||
return properties
|
||||
}
|
||||
}
|
||||
52
SimDirs/Model/SimCtl.swift
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// SimCtl.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/23/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class SimCtl {
|
||||
static func run(args: [String]) throws -> Data {
|
||||
let process = Process()
|
||||
let pipe = Pipe()
|
||||
|
||||
process.executableURL = URL(fileURLWithPath: "/usr/bin/xcrun")
|
||||
process.arguments = ["simctl"] + args
|
||||
process.standardOutput = pipe
|
||||
try process.run()
|
||||
|
||||
return pipe.fileHandleForReading.readDataToEndOfFile()
|
||||
}
|
||||
|
||||
static func run(args: [String]) throws -> String {
|
||||
return String(data: try run(args: args), encoding: .utf8) ?? ""
|
||||
}
|
||||
|
||||
static func dumpRuntimes() {
|
||||
print("dumpRuntimes")
|
||||
|
||||
do {
|
||||
let json : String = try run(args: ["list", "-j", "runtimes"])
|
||||
|
||||
print("json: \(json)")
|
||||
}
|
||||
catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
static func dumpDevices() {
|
||||
print("dumpDevices")
|
||||
|
||||
do {
|
||||
let json : String = try run(args: ["list", "-j", "devices"])
|
||||
|
||||
print("json: \(json)")
|
||||
}
|
||||
catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,150 +2,31 @@
|
|||
// SimDevice.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
// Created by Casey Fleser on 5/24/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class SimDevice: OutlineProvider, PropertyProvider {
|
||||
let name : String
|
||||
let type : String
|
||||
let udid : String
|
||||
let baseURL : URL
|
||||
var platformName = "Unknown"
|
||||
var platformVersion = ""
|
||||
var platformBuild = ""
|
||||
var apps = [SimApp]()
|
||||
struct SimDevice: Decodable {
|
||||
let name : String
|
||||
let udid : String
|
||||
let state : String
|
||||
let dataPath : String
|
||||
let dataPathSize : Int
|
||||
let logPath : String
|
||||
let isAvailable : Bool
|
||||
let deviceTypeIdentifier : String
|
||||
let availabilityError : String?
|
||||
|
||||
init(name: String, type: String, udid: String, baseURL: URL) {
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.udid = udid
|
||||
self.baseURL = baseURL
|
||||
|
||||
self.gatherBuildInfo()
|
||||
|
||||
self.gatherAppInfoFromLastLaunchMap()
|
||||
self.gatherAppInfoFromAppState()
|
||||
// self.gatherAppInfoFromCaches() obsolete
|
||||
self.gatherAppInfoFromInstallLogs()
|
||||
}
|
||||
|
||||
func completeScan(platformName: String) {
|
||||
self.platformName = platformName
|
||||
self.apps = self.apps.filter { return $0.hasValidPaths }
|
||||
|
||||
for app in self.apps {
|
||||
app.completeScan()
|
||||
}
|
||||
self.apps.sort(by: { $0.displayName < $1.displayName })
|
||||
}
|
||||
|
||||
func gatherBuildInfo() {
|
||||
let buildInfoURL = self.baseURL.appendingPathComponent("data/Library/MobileInstallation/LastBuildInfo.plist")
|
||||
guard let buildInfo = PropertyListSerialization.propertyListWithURL(buildInfoURL) else { return }
|
||||
|
||||
self.platformVersion = buildInfo["ProductVersion"] as? String ?? ""
|
||||
self.platformBuild = buildInfo["ProductBuildVersion"] as? String ?? ""
|
||||
}
|
||||
|
||||
// LastLaunchServicesMap.plist seems to be the most reliable location to gather app info
|
||||
func gatherAppInfoFromLastLaunchMap() {
|
||||
let launchMapInfoURL = self.baseURL.appendingPathComponent("data/Library/MobileInstallation/LastLaunchServicesMap.plist")
|
||||
guard let launchInfo = PropertyListSerialization.propertyListWithURL(launchMapInfoURL) else { return }
|
||||
guard let userInfo = launchInfo["User"] as? [String : AnyObject] else { return }
|
||||
|
||||
for (bundleID, bundleInfo) in userInfo {
|
||||
guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue }
|
||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
||||
|
||||
simApp.updateFrom(launchBundleInfo: bundleInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// applicationState.plist sometimes has info that LastLaunchServicesMap.plist doesn't
|
||||
func gatherAppInfoFromAppState() {
|
||||
for pathComponent in ["data/Library/FrontBoard/applicationState.plist", "data/Library/BackBoard/applicationState.plist"] {
|
||||
let appStateInfoURL = self.baseURL.appendingPathComponent(pathComponent)
|
||||
guard let stateInfo = PropertyListSerialization.propertyListWithURL(appStateInfoURL) else { continue }
|
||||
|
||||
for (bundleID, bundleInfo) in stateInfo {
|
||||
if !bundleID.contains("com.apple") {
|
||||
guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue }
|
||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
||||
|
||||
simApp.updateFrom(appStateInfo: bundleInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mobile_installation.log.0 is my least favorite, most fragile way to scan for app installations
|
||||
// try this after everything else
|
||||
func gatherAppInfoFromInstallLogs() {
|
||||
let installLogURL = self.baseURL.appendingPathComponent("data/Library/Logs/MobileInstallation/mobile_installation.log.0")
|
||||
|
||||
if let installLog = try? String(contentsOf: installLogURL) {
|
||||
let lines = installLog.components(separatedBy: .newlines)
|
||||
|
||||
for line in lines.reversed() {
|
||||
if !line.contains("com.apple") {
|
||||
if line.contains("makeContainerLiveReplacingContainer") {
|
||||
self.extractBundleLocationFrom(logEntry: line)
|
||||
}
|
||||
if line.contains("_refreshUUIDForContainer") {
|
||||
self.extractSandboxLocationFrom(logEntry: line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func extractBundleLocationFrom(logEntry: String) {
|
||||
let logComponents = logEntry.split(separator: (" ")).map({ String($0) })
|
||||
|
||||
if let bundlePath = logComponents.last {
|
||||
if let bundleID = logComponents[safe: logComponents.count - 3] {
|
||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
||||
|
||||
simApp.bundlePath = bundlePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func extractSandboxLocationFrom(logEntry: String) {
|
||||
let logComponents = logEntry.split(separator: (" ")).map({ String($0) })
|
||||
|
||||
if let sandboxPath = logComponents.last {
|
||||
if let bundleID = logComponents[safe: logComponents.count - 5] {
|
||||
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
|
||||
|
||||
simApp.sandboxPath = sandboxPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - OutlineProvider -
|
||||
|
||||
var outlineTitle : String { return self.name }
|
||||
var outlineImage : NSImage? { return nil }
|
||||
var childCount : Int { return self.apps.count }
|
||||
|
||||
func childAt(index: Int) -> OutlineProvider? {
|
||||
return self.apps[index]
|
||||
}
|
||||
|
||||
// MARK: - PropertyProvider -
|
||||
var header : String { return "Device Information" }
|
||||
var image : NSImage? { return nil }
|
||||
var properties : [SimProperty] {
|
||||
return [
|
||||
SimProperty(title: "Name", value: .Text(text: self.name)),
|
||||
SimProperty(title: "Simulated Model", value: .Text(text: self.type)),
|
||||
SimProperty(title: self.platformName, value: .Text(text: "\(self.platformVersion) (\(self.platformBuild))")),
|
||||
SimProperty(title: "Identifier", value: .Text(text: self.udid)),
|
||||
SimProperty(title: "Location", value: .Location(url: self.baseURL))
|
||||
]
|
||||
}
|
||||
func isDeviceOfType(_ deviceType: SimDeviceType) -> Bool {
|
||||
return deviceTypeIdentifier == deviceType.identifier
|
||||
}
|
||||
}
|
||||
|
||||
extension SimDevice: PresentableItem {
|
||||
var title : String { return name }
|
||||
var id : String { return udid }
|
||||
|
||||
var imageName : String { return "shippingbox" } // FIXME
|
||||
}
|
||||
|
||||
|
|
|
|||
46
SimDirs/Model/SimDeviceType.swift
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// SimDeviceType.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/24/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SimDeviceType: Decodable {
|
||||
// enum CodingKeys: String, CodingKey {
|
||||
// case bundlePath
|
||||
// case identifier
|
||||
// case maxRuntimeVersion
|
||||
// case maxRuntimeVersionString
|
||||
// case minRuntimeVersion
|
||||
// case minRuntimeVersionString
|
||||
// case modelIdentifier
|
||||
// case name
|
||||
// case productFamily
|
||||
// }
|
||||
//
|
||||
let name : String
|
||||
let identifier : String
|
||||
let productFamily : SimProductFamily
|
||||
let modelIdentifier : String
|
||||
let bundlePath : String
|
||||
let minRuntimeVersion : Int
|
||||
let maxRuntimeVersion : Int
|
||||
let minRuntimeVersionString : String
|
||||
let maxRuntimeVersionString : String
|
||||
|
||||
func supports(productFamily: SimProductFamily) -> Bool {
|
||||
return productFamily == self.productFamily
|
||||
}
|
||||
|
||||
func supports(runtime: SimRuntime) -> Bool {
|
||||
return runtime.supportedDeviceTypes.contains { $0.identifier == identifier }
|
||||
}
|
||||
}
|
||||
|
||||
extension SimDeviceType: PresentableItem {
|
||||
var title : String { return name }
|
||||
var id : String { return identifier }
|
||||
var imageName : String { return productFamily.imageName }
|
||||
}
|
||||
53
SimDirs/Model/SimModel.swift
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// SimModel.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/24/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SimError: Error {
|
||||
case deviceParsingFailure
|
||||
}
|
||||
|
||||
struct SimModel {
|
||||
var deviceTypes : [SimDeviceType]
|
||||
var runtimes : [SimRuntime]
|
||||
|
||||
init() {
|
||||
do {
|
||||
var json : Data
|
||||
let decoder = JSONDecoder()
|
||||
let runtimeDevs : [String : [SimDevice]]
|
||||
|
||||
// - [SimDeviceType]
|
||||
json = try SimCtl.run(args: ["list", "-j", "devicetypes"])
|
||||
deviceTypes = try decoder.decode([String : [SimDeviceType]].self, from: json)["devicetypes"] ?? []
|
||||
|
||||
// - [SimRuntime]
|
||||
json = try SimCtl.run(args: ["list", "-j", "runtimes"])
|
||||
runtimes = try decoder.decode([String : [SimRuntime]].self, from: json)["runtimes"] ?? []
|
||||
|
||||
// - [SimDevice]
|
||||
json = try SimCtl.run(args: ["list", "-j", "devices"])
|
||||
runtimeDevs = try decoder.decode([String : [String : [SimDevice]]] .self, from: json)["devices"] ?? [:]
|
||||
|
||||
for (runtimeID, devices) in runtimeDevs {
|
||||
do {
|
||||
let runtimeIdx = try runtimes.indexOfMatchedOrCreated(identifier: runtimeID)
|
||||
|
||||
runtimes[runtimeIdx].setDevices(devices, from: deviceTypes)
|
||||
}
|
||||
catch {
|
||||
print("Warning: Unable to create placeholder runtime from \(runtimeID)")
|
||||
}
|
||||
}
|
||||
|
||||
runtimes.sort()
|
||||
}
|
||||
catch {
|
||||
fatalError("Failed to initialize data model:\n\(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
//
|
||||
// SimOSVersion.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class SimOSVersion: OutlineProvider {
|
||||
let name : String
|
||||
var devices = [SimDevice]()
|
||||
|
||||
init(name: String, deviceInfo: [String : AnyObject]) {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
func completeScan(platformName: String) {
|
||||
for device in self.devices {
|
||||
device.completeScan(platformName: platformName)
|
||||
}
|
||||
self.devices.sort(by: { $0.name < $1.name })
|
||||
}
|
||||
|
||||
func updateWith(deviceInfo: [String : AnyObject], baseURL: URL) {
|
||||
guard let deviceName = deviceInfo["name"] as? String else { return }
|
||||
guard let deviceUDID = deviceInfo["UDID"] as? String else { return }
|
||||
guard var deviceType = deviceInfo["deviceType"] as? String else { return }
|
||||
|
||||
deviceType = deviceType.replacingOccurrences(of: "com.apple.CoreSimulator.SimDeviceType.", with: "")
|
||||
deviceType = deviceType.replacingOccurrences(of: "-", with: " ")
|
||||
|
||||
self.devices.append(SimDevice(name: deviceName, type: deviceType, udid: deviceUDID, baseURL: baseURL))
|
||||
}
|
||||
|
||||
// MARK: - OutlineProvider -
|
||||
|
||||
var outlineTitle : String { return self.name }
|
||||
var outlineImage : NSImage? { return nil }
|
||||
var childCount : Int { return self.devices.count }
|
||||
|
||||
func childAt(index: Int) -> OutlineProvider? {
|
||||
return self.devices[index]
|
||||
}
|
||||
}
|
||||
|
|
@ -2,71 +2,27 @@
|
|||
// SimPlatform.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
// Created by Casey Fleser on 5/23/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class SimPlatform: OutlineProvider {
|
||||
let name : String
|
||||
var osVersions = [SimOSVersion]()
|
||||
enum SimPlatform: String, Decodable {
|
||||
case iOS
|
||||
case tvOS
|
||||
case watchOS
|
||||
|
||||
class func scan() -> [SimPlatform] {
|
||||
let fileMgr = FileManager.default
|
||||
var platforms = [SimPlatform]()
|
||||
|
||||
if let libraryURL = fileMgr.urls(for: .libraryDirectory, in: .userDomainMask).first {
|
||||
let deviceURL = libraryURL.appendingPathComponent("Developer/CoreSimulator/Devices")
|
||||
|
||||
if let dirEnumerator = fileMgr.enumerator(at: deviceURL, includingPropertiesForKeys: nil, options: [ .skipsSubdirectoryDescendants, .skipsHiddenFiles ], errorHandler: nil) {
|
||||
for baseURL in dirEnumerator.allObjects.compactMap({ $0 as? URL }) {
|
||||
let deviceURL = baseURL.appendingPathComponent("device.plist")
|
||||
guard let deviceInfo = PropertyListSerialization.propertyListWithURL(deviceURL) else { continue }
|
||||
guard let runtime = deviceInfo["runtime"] as? String else { continue }
|
||||
let runtimeComponents = runtime.replacingOccurrences(of: "com.apple.CoreSimulator.SimRuntime.", with: "").split(separator: "-").map({ String($0) })
|
||||
|
||||
if let platformName = runtimeComponents.first {
|
||||
let platform = platforms.match({ $0.name == platformName }, orMake: { SimPlatform(runtimeComponents: runtimeComponents, deviceInfo: deviceInfo) })
|
||||
|
||||
platform.updateWith(runtimeComponents, deviceInfo: deviceInfo, baseURL: baseURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for platform in platforms {
|
||||
platform.completeScan()
|
||||
}
|
||||
|
||||
return platforms.sorted { $0.name < $1.name }
|
||||
}
|
||||
|
||||
init(runtimeComponents: [String], deviceInfo: [String : AnyObject]) {
|
||||
self.name = runtimeComponents[0]
|
||||
}
|
||||
|
||||
func completeScan() {
|
||||
for osVersion in self.osVersions {
|
||||
osVersion.completeScan(platformName: self.name)
|
||||
}
|
||||
self.osVersions.sort(by: { $0.name > $1.name })
|
||||
}
|
||||
|
||||
func updateWith(_ runtimeComponents: [String], deviceInfo: [String : AnyObject], baseURL: URL) {
|
||||
let versionID = "\(runtimeComponents[safe: 1] ?? "0").\(runtimeComponents[safe: 2] ?? "0")"
|
||||
let osVersion = self.osVersions.match({ $0.name == versionID }, orMake: { SimOSVersion(name: versionID, deviceInfo: deviceInfo) })
|
||||
|
||||
osVersion.updateWith(deviceInfo: deviceInfo, baseURL: baseURL)
|
||||
}
|
||||
|
||||
// MARK: - OutlineProvider -
|
||||
|
||||
var outlineTitle : String { return self.name }
|
||||
var outlineImage : NSImage? { return nil }
|
||||
var childCount : Int { return self.osVersions.count }
|
||||
|
||||
func childAt(index: Int) -> OutlineProvider? {
|
||||
return self.osVersions[index]
|
||||
}
|
||||
static let presentation : [SimPlatform] = [.iOS, .watchOS, .tvOS]
|
||||
}
|
||||
|
||||
extension SimPlatform: PresentableItem {
|
||||
var title : String { return self.rawValue }
|
||||
var id : String { return self.rawValue }
|
||||
var imageName : String {
|
||||
switch self {
|
||||
case .iOS: return "iphone"
|
||||
case .tvOS: return "appletv"
|
||||
case .watchOS: return "applewatch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
31
SimDirs/Model/SimProductFamily.swift
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// SimProductFamily.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/24/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SimProductFamily: String, Decodable {
|
||||
case appleTV = "Apple TV"
|
||||
case appleWatch = "Apple Watch"
|
||||
case iPad
|
||||
case iPhone
|
||||
|
||||
static let presentation : [SimProductFamily] = [.iPhone, .iPad, .appleWatch, .appleTV]
|
||||
}
|
||||
|
||||
extension SimProductFamily: PresentableItem {
|
||||
var title : String { return self.rawValue }
|
||||
var id : String { return self.rawValue }
|
||||
|
||||
var imageName : String {
|
||||
switch self {
|
||||
case .iPad: return "ipad"
|
||||
case .iPhone: return "iphone"
|
||||
case .appleTV: return "appletv"
|
||||
case .appleWatch: return "applewatch"
|
||||
}
|
||||
}
|
||||
}
|
||||
130
SimDirs/Model/SimRuntime.swift
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// SimRuntime.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/24/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SimRuntime: Comparable, Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case availabilityError
|
||||
case bundlePath
|
||||
case buildversion
|
||||
case identifier
|
||||
case isAvailable
|
||||
case isInternal
|
||||
case name
|
||||
case platform
|
||||
case runtimeRoot
|
||||
case supportedDeviceTypes
|
||||
case version
|
||||
}
|
||||
|
||||
struct DeviceType: Decodable {
|
||||
let name : String
|
||||
let bundlePath : String
|
||||
let identifier : String
|
||||
let productFamily : SimProductFamily
|
||||
|
||||
init(canonical: SimDeviceType) {
|
||||
name = canonical.name
|
||||
bundlePath = canonical.bundlePath
|
||||
identifier = canonical.identifier
|
||||
productFamily = canonical.productFamily
|
||||
}
|
||||
}
|
||||
|
||||
let name : String
|
||||
let version : String
|
||||
let identifier : String
|
||||
let platform : SimPlatform
|
||||
|
||||
let bundlePath : String
|
||||
let buildversion : String
|
||||
let runtimeRoot : String
|
||||
let isInternal : Bool
|
||||
let isAvailable : Bool
|
||||
var supportedDeviceTypes : [DeviceType]
|
||||
let availabilityError : String?
|
||||
|
||||
var devices = [SimDevice]()
|
||||
var isPlaceholder = false
|
||||
|
||||
static func < (lhs: SimRuntime, rhs: SimRuntime) -> Bool {
|
||||
return lhs.name < rhs.name
|
||||
}
|
||||
|
||||
static func == (lhs: SimRuntime, rhs: SimRuntime) -> Bool {
|
||||
return lhs.identifier == rhs.identifier
|
||||
}
|
||||
|
||||
init(platformID: String) throws {
|
||||
guard let lastComponent = platformID.split(separator: ".").last else { throw SimError.deviceParsingFailure }
|
||||
let vComps = lastComponent.split(separator: "-")
|
||||
|
||||
if vComps.count == 3 {
|
||||
guard let compPlatform = SimPlatform(rawValue: String(vComps[0])) else { throw SimError.deviceParsingFailure }
|
||||
guard let major = Int(vComps[1]) else { throw SimError.deviceParsingFailure }
|
||||
guard let minor = Int(vComps[2]) else { throw SimError.deviceParsingFailure }
|
||||
|
||||
platform = compPlatform
|
||||
version = "\(major).\(minor)"
|
||||
name = "\(platform) \(version)"
|
||||
identifier = platformID
|
||||
|
||||
bundlePath = ""
|
||||
buildversion = ""
|
||||
runtimeRoot = ""
|
||||
isInternal = false
|
||||
isAvailable = false
|
||||
supportedDeviceTypes = []
|
||||
availabilityError = "Missing runtime"
|
||||
isPlaceholder = true
|
||||
}
|
||||
else {
|
||||
throw SimError.deviceParsingFailure
|
||||
}
|
||||
}
|
||||
|
||||
func supports(deviceType: SimDeviceType) -> Bool {
|
||||
return supportedDeviceTypes.contains { $0.identifier == deviceType.identifier }
|
||||
}
|
||||
|
||||
func supports(platform: SimPlatform) -> Bool {
|
||||
return self.platform == platform
|
||||
}
|
||||
|
||||
mutating func setDevices(_ devices: [SimDevice], from devTypes: [SimDeviceType]) {
|
||||
self.devices = devices
|
||||
|
||||
// If this runtime is a placeholder it will be missing supported device types
|
||||
// create device type stubs based on the devices being added using supplied
|
||||
// fully described device types
|
||||
|
||||
if isPlaceholder {
|
||||
let devTypeIDs = Set(devices.map({ $0.deviceTypeIdentifier }))
|
||||
|
||||
self.supportedDeviceTypes = devTypeIDs.compactMap { devTypeID in
|
||||
devTypes.first(where: { $0.identifier == devTypeID }).map({ SimRuntime.DeviceType(canonical: $0) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SimRuntime: PresentableItem {
|
||||
var title : String { return name }
|
||||
var id : String { return identifier }
|
||||
var imageName : String { return "v.circle" }
|
||||
}
|
||||
|
||||
extension Array where Element == SimRuntime {
|
||||
mutating func indexOfMatchedOrCreated(identifier: String) throws -> Index {
|
||||
return try firstIndex { $0.identifier == identifier } ?? {
|
||||
try self.append(SimRuntime(platformID: identifier))
|
||||
|
||||
return self.endIndex - 1
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
36
SimDirs/SimDirsApp.swift
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// SimDirsApp.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/23/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct SimDirsApp: App {
|
||||
@StateObject private var modelData = PresentableModel()
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
.environmentObject(modelData)
|
||||
}
|
||||
.commands {
|
||||
SimCommands()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SimCommands: Commands {
|
||||
var body: some Commands {
|
||||
SidebarCommands()
|
||||
|
||||
CommandMenu("Commands") {
|
||||
Button("Command") {
|
||||
print("Command")
|
||||
}
|
||||
.keyboardShortcut("f", modifiers: [.shift, .option])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
//
|
||||
// Support.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
// Assorted convenience extensions
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Array {
|
||||
mutating func match(_ predicate: (Element) -> Bool, orMake: () -> Element) -> Element {
|
||||
let element : Element
|
||||
|
||||
if let match = self.first(where: predicate) {
|
||||
element = match
|
||||
}
|
||||
else {
|
||||
element = orMake()
|
||||
self.append(element)
|
||||
}
|
||||
|
||||
return element
|
||||
}
|
||||
}
|
||||
|
||||
extension Collection {
|
||||
subscript (safe index: Index) -> Iterator.Element? {
|
||||
return indices.contains(index) ? self[index] : nil
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
var validPath : Bool { return FileManager.default.fileExists(atPath: self) }
|
||||
}
|
||||
|
||||
extension NSURL {
|
||||
var validPath : Bool { return self.path.map { FileManager.default.fileExists(atPath: $0) } ?? false }
|
||||
}
|
||||
|
||||
extension PropertyListSerialization {
|
||||
class func propertyListWithURL(_ url: URL) -> [String : AnyObject]? {
|
||||
guard let plistData = try? Data(contentsOf: url) else { return nil }
|
||||
let plist : [String : AnyObject]?
|
||||
|
||||
do {
|
||||
plist = try PropertyListSerialization.propertyList(from: plistData, options: [], format: nil) as? [String : AnyObject]
|
||||
} catch {
|
||||
plist = nil
|
||||
}
|
||||
|
||||
return plist
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// CUICatalog.h
|
||||
// Asset Catalog Tinkerer
|
||||
//
|
||||
// Created by Guilherme Rambo on 27/09/15.
|
||||
// Copyright (c) 2014 Guilherme Rambo. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface CUINamedImage : NSObject
|
||||
|
||||
@property (copy, nonatomic) NSString *name;
|
||||
@property (readonly, nonatomic) int exifOrientation;
|
||||
@property (readonly, nonatomic) BOOL isStructured;
|
||||
@property (readonly, nonatomic) NSInteger templateRenderingMode;
|
||||
@property (readonly, nonatomic) BOOL isTemplate;
|
||||
@property (readonly, nonatomic) BOOL isVectorBased;
|
||||
@property (readonly, nonatomic) BOOL hasSliceInformation;
|
||||
@property (readonly, nonatomic) NSInteger resizingMode;
|
||||
@property (readonly, nonatomic) int blendMode;
|
||||
@property (readonly, nonatomic) CGFloat opacity;
|
||||
@property (readonly, nonatomic) NSInteger imageType;
|
||||
@property (readonly, nonatomic) CGFloat scale;
|
||||
@property (readonly, nonatomic) NSSize size;
|
||||
@property (readonly, nonatomic) CGImageRef image;
|
||||
|
||||
@end
|
||||
|
||||
@interface CUICatalog : NSObject
|
||||
|
||||
+ (instancetype)systemUICatalog;
|
||||
+ (instancetype)defaultUICatalog;
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url error:(NSError **)outError;
|
||||
|
||||
@property (nonatomic, readonly) NSArray *allImageNames;
|
||||
- (NSArray *)imagesWithName:(NSString *)name;
|
||||
|
||||
@end
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// CUINamedLayerStack.h
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CUICatalog.h"
|
||||
|
||||
@interface CUINamedLayerStack : CUINamedImage
|
||||
|
||||
@property(retain, nonatomic) NSArray *layers; // @synthesize layers=_layers;
|
||||
|
||||
@property(readonly, nonatomic) struct CGImage *radiosityImage;
|
||||
@property(readonly, nonatomic) struct CGImage *flattenedImage;
|
||||
- (id)layerImageAtIndex:(unsigned long long)arg1;
|
||||
@property(readonly, nonatomic) struct CGSize size;
|
||||
|
||||
@end
|
||||
|
||||
@interface CUINamedLayerImage : CUINamedImage
|
||||
|
||||
@property(nonatomic) int blendMode; // @synthesize blendMode=_blendMode;
|
||||
@property(nonatomic) double opacity; // @synthesize opacity=_opacity;
|
||||
@property(nonatomic) struct CGRect frame; // @synthesize frame=_frame;
|
||||
|
||||
@end
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
//
|
||||
// SimDirs-Bridge.h
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CUICatalog.h"
|
||||
#import "CUINamedLayerStack.h"
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// ActionCell.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/1/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class ActionCell: NSView {
|
||||
@IBOutlet weak var actionButton : NSButton!
|
||||
var action : (() -> ())?
|
||||
|
||||
@IBAction func executeAction(_ sender: Any) {
|
||||
action?()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
//
|
||||
// DetailController.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/1/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
struct SimProperty {
|
||||
enum Value {
|
||||
case Text(text: String)
|
||||
case Location(url: URL)
|
||||
}
|
||||
|
||||
let title : String
|
||||
let value : Value
|
||||
|
||||
init(title: String, value: Value) {
|
||||
self.title = title
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
|
||||
protocol PropertyProvider: AnyObject {
|
||||
var header : String { get }
|
||||
var image : NSImage? { get }
|
||||
var properties : [SimProperty] { get }
|
||||
}
|
||||
|
||||
class EmptyProvider: PropertyProvider {
|
||||
let header = ""
|
||||
let image : NSImage? = nil
|
||||
let properties = [SimProperty]()
|
||||
}
|
||||
|
||||
class DetailController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
|
||||
@IBOutlet weak var headerLabel : NSTextField!
|
||||
@IBOutlet weak var imageView : NSImageView!
|
||||
@IBOutlet weak var propertyTable : NSTableView!
|
||||
let emptyProvider = EmptyProvider()
|
||||
var selectedItem : Any? { didSet { self.reload() } }
|
||||
var selectedProvider : PropertyProvider { return (self.selectedItem as? PropertyProvider) ?? self.emptyProvider }
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
self.reload()
|
||||
}
|
||||
|
||||
func reload() {
|
||||
self.headerLabel.stringValue = self.selectedProvider.header
|
||||
self.imageView.image = self.selectedProvider.image
|
||||
self.propertyTable.reloadData()
|
||||
}
|
||||
|
||||
// MARK: - NSTableViewDataSource -
|
||||
|
||||
func numberOfRows(in tableView: NSTableView) -> Int {
|
||||
return self.selectedProvider.properties.count
|
||||
}
|
||||
|
||||
// MARK: - NSTableViewDelegate -
|
||||
|
||||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||
let selectedProperty = self.selectedProvider.properties[row]
|
||||
let columnIdentifier = tableColumn?.identifier ?? NSUserInterfaceItemIdentifier("")
|
||||
let view : NSView?
|
||||
|
||||
switch columnIdentifier.rawValue {
|
||||
case "value":
|
||||
switch selectedProperty.value {
|
||||
case .Text(let text):
|
||||
view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyValueCell"), owner: self)
|
||||
(view as? NSTableCellView)?.textField?.stringValue = text
|
||||
|
||||
case .Location(let url):
|
||||
view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyActionCell"), owner: self)
|
||||
if let actionCell = view as? ActionCell {
|
||||
actionCell.action = { NSWorkspace.shared.activateFileViewerSelecting([url]) }
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyTitleCell"), owner: self)
|
||||
(view as? NSTableCellView)?.textField?.stringValue = selectedProperty.title
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// DetailTableView.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/1/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class DetailTableView: NSTableView {
|
||||
override func drawGrid(inClipRect: NSRect) {
|
||||
let lastRowRect = self.rect(ofRow: self.numberOfRows - 1)
|
||||
let adjClipRect = NSRect(x: 0.0, y: 0.0, width: lastRowRect.width, height: lastRowRect.maxY)
|
||||
|
||||
super.drawGrid(inClipRect: NSIntersectionRect(inClipRect, adjClipRect))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
//
|
||||
// SourceController.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 4/30/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
protocol OutlineProvider: AnyObject {
|
||||
var outlineTitle : String { get }
|
||||
var outlineImage : NSImage? { get }
|
||||
var childCount : Int { get }
|
||||
|
||||
func childAt(index: Int) -> OutlineProvider?
|
||||
}
|
||||
|
||||
extension OutlineProvider {
|
||||
var expandable : Bool { return self.childCount > 0 }
|
||||
}
|
||||
|
||||
class SourceController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {
|
||||
@IBOutlet weak var outlineView : NSOutlineView!
|
||||
private var platforms = [SimPlatform]()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
self.rescan(nil)
|
||||
}
|
||||
|
||||
// MARK: - NSOutlineViewDataSource -
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
||||
return (item as? OutlineProvider)?.childCount ?? self.platforms.count
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
||||
return (item as? OutlineProvider)?.childAt(index: index) ?? self.platforms[index]
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
|
||||
return (item as? OutlineProvider)?.expandable ?? (self.platforms.count > 0)
|
||||
}
|
||||
|
||||
// MARK: - NSOutlineViewDelegate -
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
|
||||
var view : NSTableCellView? = nil
|
||||
var title = ""
|
||||
var image : NSImage? = nil
|
||||
|
||||
if let outlineProvider = item as? OutlineProvider {
|
||||
title = outlineProvider.outlineTitle
|
||||
image = outlineProvider.outlineImage
|
||||
}
|
||||
|
||||
if let outlineCell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(image != nil ? "ImageCell" : "TextCell"), owner: self) as? NSTableCellView {
|
||||
outlineCell.textField?.stringValue = title
|
||||
outlineCell.imageView?.image = image
|
||||
view = outlineCell
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
|
||||
return (item as? OutlineProvider)?.outlineImage != nil ? 24.0 : 20.0
|
||||
}
|
||||
|
||||
func outlineViewSelectionDidChange(_ notification: Notification) {
|
||||
if let thing = (self.parent as? NSSplitViewController)?.splitViewItems[safe: 1]?.viewController as? DetailController {
|
||||
var selectedItem : Any? = nil
|
||||
let row = self.outlineView.selectedRow
|
||||
|
||||
if row != NSNotFound {
|
||||
selectedItem = self.outlineView.item(atRow: row)
|
||||
}
|
||||
|
||||
thing.selectedItem = selectedItem
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Interaction -
|
||||
|
||||
@IBAction func rescan(_ sender: AnyObject?) {
|
||||
self.platforms = SimPlatform.scan()
|
||||
self.outlineView.reloadData()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// WindowController.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/1/16.
|
||||
// Copyright © 2016 Quiet Spark. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class WindowController: NSWindowController {
|
||||
|
||||
override func windowDidLoad() {
|
||||
super.windowDidLoad()
|
||||
|
||||
self.window?.setFrameAutosaveName("main")
|
||||
}
|
||||
|
||||
}
|
||||
38
SimDirs/Views/DeviceTypeView.swift
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// DeviceTypeView.swift
|
||||
// SimDirs
|
||||
//
|
||||
// Created by Casey Fleser on 5/25/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct DeviceTypeView: View {
|
||||
var deviceType : SimDeviceType
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 2.0) {
|
||||
// Text(deviceType.name)
|
||||
// .font(.title)
|
||||
// .padding(.bottom, 5.0)
|
||||
Group {
|
||||
Text("Product Family: \(deviceType.productFamily.title)")
|
||||
Text("Model ID: \(deviceType.modelIdentifier)")
|
||||
Text("Identifier: \(deviceType.identifier)")
|
||||
Text("Min Runtime: \(deviceType.minRuntimeVersionString)")
|
||||
Text("Max Runtime: \(UInt32.max == deviceType.maxRuntimeVersion ? "-" : deviceType.maxRuntimeVersionString)")
|
||||
Text("Bundle Path: \(deviceType.bundlePath)")
|
||||
}
|
||||
.font(.subheadline)
|
||||
}
|
||||
// .background(Color.red)
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceTypeView_Previews: PreviewProvider {
|
||||
static let model = PresentableModel().baseModel
|
||||
|
||||
static var previews: some View {
|
||||
DeviceTypeView(deviceType: model.deviceTypes[26])
|
||||
}
|
||||
}
|
||||