Compare commits
378 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
60586a9e1b | ||
|
fb7b2f3973 | ||
|
4a6ba96803 | ||
|
73ab4e0e41 | ||
|
828c938e52 | ||
|
d1a2dcba21 | ||
|
5de27856ed | ||
|
8da2ff4a20 | ||
|
e89536c932 | ||
|
d2b592c7e5 | ||
|
0afa433151 | ||
|
c2323ac998 | ||
|
45fe32893f | ||
|
308b15277c | ||
|
bdd9df44ed | ||
|
c58ff589dd | ||
|
e3985856f3 | ||
|
a28c42a2b6 | ||
|
78bcc88694 | ||
|
7e1e2fb8c5 | ||
|
7e64d6720d | ||
|
ef8a4412f8 | ||
|
68429262c0 | ||
|
c2baf07256 | ||
|
cac8c1c054 | ||
|
0718aa5944 | ||
|
8b37b5e840 | ||
|
565e1109ff | ||
|
b7149a0b0d | ||
|
8283a3beec | ||
|
17945e68ba | ||
|
49e3e397d2 | ||
|
5efa2b2cbf | ||
|
c536b8edb5 | ||
|
a6747e4f57 | ||
|
7dbaf4e12d | ||
|
24e3b01803 | ||
|
d6a3e1e347 | ||
|
0244fbcc0b | ||
|
ee1da060a3 | ||
|
6ce2fbc2d8 | ||
|
56b34a4099 | ||
|
9f7c49e3e0 | ||
|
70fc811b0d | ||
|
377e6bc04e | ||
|
6ef3911da7 | ||
|
9b3223478c | ||
|
2198467def | ||
|
63a60ed8b7 | ||
|
9005cfe0ec | ||
|
2e62b33fb1 | ||
|
e04d441cc5 | ||
|
f116c9ff1f | ||
|
92cf747d65 | ||
|
743fa57a44 | ||
|
970cbd6cdc | ||
|
3ce9df6650 | ||
|
d84c5d7be3 | ||
|
79617329e8 | ||
|
dc67db2ce6 | ||
|
9031b481ce | ||
|
f38ab3288d | ||
|
0aea4006cc | ||
|
06233137a9 | ||
|
8bc7e26279 | ||
|
aea14d8dd4 | ||
|
23946962ad | ||
|
d0987932a8 | ||
|
c03f888032 | ||
|
2b127ac5a8 | ||
|
c6edfe91f2 | ||
|
11ba25588b | ||
|
695ed00552 | ||
|
c8e3c95240 | ||
|
4acd3d51a7 | ||
|
93cb6c5276 | ||
|
52e9f00b92 | ||
|
453e2bd497 | ||
|
c722b28ef3 | ||
|
7a077e5ec8 | ||
|
436694a0b6 | ||
|
01e36939aa | ||
|
20c767021c | ||
|
b64ca73346 | ||
|
62767971ee | ||
|
6b2c4c408a | ||
|
bbcc41cc10 | ||
|
f651ca6b26 | ||
|
16036d9df0 | ||
|
41653fcae1 | ||
|
87b4cc9494 | ||
|
9b349e699f | ||
|
03c8306718 | ||
|
41ad1f0d7a | ||
|
d5ed5f74a2 | ||
|
2409ad55a1 | ||
|
601e56ccaa | ||
|
d5d90ba6be | ||
|
4a0caa2e78 | ||
|
23a05d5414 | ||
|
4ffd8d1f44 | ||
|
f52470eb2e | ||
|
65aedba94b | ||
|
8707b4a246 | ||
|
5a0fdd5a7e | ||
|
4e05ff7e8c | ||
|
781d8ada60 | ||
|
d258fd2a48 | ||
|
2b2f3a2fd8 | ||
|
9bb0cc468a | ||
|
79c3eba93e | ||
|
e09a151c91 | ||
|
ce35015218 | ||
|
1dd3664a2b | ||
|
0616991a1b | ||
|
7633887391 | ||
|
c49c4df9bf | ||
|
eda219faa2 | ||
|
5382447dc9 | ||
|
8f989c0d3f | ||
|
1141e3da0d | ||
|
c5eeec9b6d | ||
|
2122f0707b | ||
|
809e344a2d | ||
|
405e802176 | ||
|
d352e7c45d | ||
|
5af5e2e300 | ||
|
afc3ac608a | ||
|
c200672650 | ||
|
345d4f3d74 | ||
|
b795d60995 | ||
|
09b4972084 | ||
|
49c191bf5f | ||
|
7f5efc1479 | ||
|
c7fa95c918 | ||
|
7178118ea9 | ||
|
e9654f01c0 | ||
|
098b8cb7da | ||
|
35b60b1358 | ||
|
0c56be79f3 | ||
|
e66502ea42 | ||
|
70f4738264 | ||
|
026a9e7704 | ||
|
7a482191ab | ||
|
3827cce320 | ||
|
82fbe43795 | ||
|
acfc37675b | ||
|
fa64005345 | ||
|
f79fb60883 | ||
|
d92145f6b4 | ||
|
139ab22f2a | ||
|
b58a859398 | ||
|
a278f679b0 | ||
|
0c55214085 | ||
|
7c704e577d | ||
|
d52c2cd9d1 | ||
|
5aa8990ac6 | ||
|
82a73ef79c | ||
|
0d4a08113b | ||
|
fc3bae79c3 | ||
|
053b9d84db | ||
|
c7d0a2aecb | ||
|
5a098b9d00 | ||
|
abf4e027ee | ||
|
ec020cf028 | ||
|
9ab4b8373d | ||
|
796b1f2fc8 | ||
|
d7b3c763dd | ||
|
32aad8cb61 | ||
|
1eb3811611 | ||
|
ac459adb57 | ||
|
d058aa6588 | ||
|
3889b42c14 | ||
|
34fcc3b3ed | ||
|
c10f2153ff | ||
|
23afbd8952 | ||
|
5fbc00e375 | ||
|
5dd04cd3b7 | ||
|
27bfc1cd8b | ||
|
800087096d | ||
|
669e9a16f4 | ||
|
7c766ba76e | ||
|
c307ab0403 | ||
|
7d1e1bf6bd | ||
|
9da9f6bd63 | ||
|
4144a6ad03 | ||
|
76ac6f777a | ||
|
6b43c42682 | ||
|
67f2c60286 | ||
|
cae68c7f5a | ||
|
681c70d515 | ||
|
7abb2f68a0 | ||
|
4c003007f5 | ||
|
a5a6222c9f | ||
|
058da073ee | ||
|
5e0d31a772 | ||
|
e958ffe65a | ||
|
2b0e6d4d9d | ||
|
33d6c651d0 | ||
|
0381037356 | ||
|
c4c2defc01 | ||
|
46fe931103 | ||
|
141877f8cb | ||
|
e9d348ec71 | ||
|
37b085e45f | ||
|
7af810d14f | ||
|
884f8b190a | ||
|
7b55c37128 | ||
|
c0534f0107 | ||
|
69f56830ca | ||
|
b8697d326c | ||
|
ef2bbeb9c3 | ||
|
3d5a2951bb | ||
|
789d61d9f1 | ||
|
5ffc85f9fc | ||
|
7b67522156 | ||
|
f14b291e60 | ||
|
576931cd71 | ||
|
9ed83bf316 | ||
|
751083ea26 | ||
|
1b7faf3ac4 | ||
|
bfbac2cc20 | ||
|
3bf2f63bf6 | ||
|
6468ee2629 | ||
|
5f84c4b2c1 | ||
|
8944c88339 | ||
|
3d4d0c92c7 | ||
|
e48e2a9223 | ||
|
a8e03a9490 | ||
|
5e87627251 | ||
|
41de913e5f | ||
|
5f3c346562 | ||
|
d992b6960d | ||
|
bc9e156af0 | ||
|
9be960bb8e | ||
|
f3680e0309 | ||
|
2465b38916 | ||
|
cafecda333 | ||
|
2e6edaba1b | ||
|
94dfbc6e3e | ||
|
821a84923f | ||
|
311a3461f6 | ||
|
88c12a4832 | ||
|
6ca897739a | ||
|
2a0462cc41 | ||
|
fe0d690f87 | ||
|
ffb76a31f9 | ||
|
123a51d52f | ||
|
f89c932b77 | ||
|
0d13fa7167 | ||
|
e1eecac557 | ||
|
f8b3a1d882 | ||
|
9e5b8d45ca | ||
|
e975980a3a | ||
|
6177001a4c | ||
|
b2907eda08 | ||
|
48cdd702be | ||
|
2f514a1db3 | ||
|
d37fb49781 | ||
|
34970cb476 | ||
|
9626a6588f | ||
|
dc7adde938 | ||
|
328ab815fb | ||
|
d433920740 | ||
|
5d5c477bee | ||
|
4676c7c1ba | ||
|
760f9e6693 | ||
|
5f8b00f021 | ||
|
750df30533 | ||
|
9a7b5e6af0 | ||
|
521d33ba55 | ||
|
4c1541a7da | ||
|
29cfb6c2a0 | ||
|
f74f5aaf11 | ||
|
e3edc368fe | ||
|
9323151102 | ||
|
6acbadb195 | ||
|
3a03b2180a | ||
|
52d140d07d | ||
|
0c7c9e9d1b | ||
|
dc5ab08d4b | ||
|
c51ae648d9 | ||
|
74c67be366 | ||
|
bfa371ec0c | ||
|
2046eed6f4 | ||
|
28b1074da2 | ||
|
40336585b3 | ||
|
07d0e78d04 | ||
|
c88fe397f7 | ||
|
e86b5c3236 | ||
|
6f8e2d806b | ||
|
7286ae4f5a | ||
|
7587f8c5ef | ||
|
93b9995260 | ||
|
dd1263a31c | ||
|
ed88a87b69 | ||
|
6e4a516610 | ||
|
6ca8ae2dc9 | ||
|
c40f1e621d | ||
|
b089220d81 | ||
|
c92ab50079 | ||
|
a3f96076f5 | ||
|
d06bf9b1d6 | ||
|
f9d4489e48 | ||
|
cabffd23ea | ||
|
170a3864fe | ||
|
3c81d4d2ce | ||
|
1022ebcbba | ||
|
32d6cdf004 | ||
|
f72bed14a5 | ||
|
57a7e24d21 | ||
|
f3137585c1 | ||
|
6e7acb88e2 | ||
|
5840c4ae0c | ||
|
0c8587beb5 | ||
|
9f6870585f | ||
|
4425fe33f8 | ||
|
68136487ff | ||
|
5745a99ea2 | ||
|
484dd39b67 | ||
|
ad12d40052 | ||
|
e1a3d39021 | ||
|
0befba12a5 | ||
|
13d78a94ed | ||
|
4bfc4c027f | ||
|
f90f5a6bf3 | ||
|
ecfd5fb7a8 | ||
|
7a085301cf | ||
|
bf619da42d | ||
|
d5d869a407 | ||
|
59ce93bbc0 | ||
|
0d88e3e93a | ||
|
4ca9d2caaf | ||
|
531c3096e9 | ||
|
376f808d29 | ||
|
97c27328d0 | ||
|
0dfd7c0605 | ||
|
afa29a9e91 | ||
|
65a1a9e6c6 | ||
|
7ef1edfe81 | ||
|
2ab55c0454 | ||
|
8362692523 | ||
|
416310fe69 | ||
|
9d8f645c69 | ||
|
9946d341a7 | ||
|
b2bfb6ea11 | ||
|
c6bd70f9ef | ||
|
d8f0794679 | ||
|
09b9830840 | ||
|
6452cf5e0a | ||
|
d7ffdd841a | ||
|
9905ddf96e | ||
|
95c7a77982 | ||
|
8b901fc415 | ||
|
2ba85fc3f8 | ||
|
49e2462b28 | ||
|
a829b4feea | ||
|
0a78177485 | ||
|
5d54bbd636 | ||
|
531cee122b | ||
|
e9fff9aa08 | ||
|
ee02dee982 | ||
|
9a64879336 | ||
|
f45db5383d | ||
|
4b34ff977d | ||
|
2fa6a90374 | ||
|
7b41e5bf46 | ||
|
f2b08c45a3 | ||
|
498fd337eb | ||
|
3cdae0e386 | ||
|
9eb3727e1e | ||
|
af3ad78b94 | ||
|
8906d7825f | ||
|
be04b5a00b | ||
|
8e7e6fa396 | ||
|
ad33f06f98 | ||
|
3c77f0a309 | ||
|
69023c4af3 |
19
.github/workflows/xcodebuild.yml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
name: xcodebuild
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: build
|
||||
run: xcodebuild -project "Ample.xcodeproj" -target "Ample Lite" | xcpretty
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Ample Lite
|
||||
path: build/Release/
|
3
.gitignore
vendored
|
@ -1,6 +1,9 @@
|
|||
dist
|
||||
embedded/mame64
|
||||
embedded/SDL2.framework
|
||||
embedded/Sparkle.framework
|
||||
embedded/Sparkle-*
|
||||
embedded/SDL2-*
|
||||
build
|
||||
embedded/mame-data.tgz
|
||||
__pycache__
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
<dict>
|
||||
<key>Ample Lite.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<true/>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
|
@ -24,6 +26,36 @@
|
|||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>pty_shell.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
<key>vmnet_helper.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<true/>
|
||||
<key>orderHint</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>B6841BCF251EC913006A5C39</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>B6BA257A24E99BE9005FB8FF</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>B6E4B5AE24FDE2670094A35C</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
|
|
@ -11,13 +11,46 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
/* ~/Library/ApplicationSupport/Ample/ */
|
||||
NSURL *SupportDirectory(void);
|
||||
NSString *SupportDirectoryPath(void);
|
||||
|
||||
/* mame executable URL */
|
||||
NSURL *MameURL(void);
|
||||
NSString *MamePath(void);
|
||||
|
||||
/* mame working directory */
|
||||
NSURL *MameWorkingDirectory(void);
|
||||
NSString *MameWorkingDirectoryPath(void);
|
||||
|
||||
NSString *InternString(NSString *key);
|
||||
|
||||
NSDictionary *MameMachine(NSString *machine);
|
||||
|
||||
/* NSUserDefaults keys */
|
||||
extern NSString *kUseCustomMame;
|
||||
extern NSString *kMamePath;
|
||||
extern NSString *kMameWorkingDirectory;
|
||||
extern NSString *kAutoCloseLogWindow;
|
||||
extern NSString *kMameComponentsDate;
|
||||
extern NSString *kUseLogWindow;
|
||||
|
||||
extern NSString *kDownloadURL;
|
||||
extern NSString *kDownloadExtension;
|
||||
|
||||
extern NSString *kDefaultDownloadURL;
|
||||
extern NSString *kDefaultDownloadExtension;
|
||||
|
||||
extern NSString *kNotificationDiskImageAdded;
|
||||
extern NSString *kNotificationDiskImageMagicRoute;
|
||||
extern NSString *kNotificationBookmarkMagicRoute;
|
||||
|
||||
@protocol Bookmark <NSObject>
|
||||
-(BOOL)loadBookmark: (NSDictionary *)bookmark;
|
||||
-(BOOL)saveBookmark: (NSMutableDictionary *)bookmark;
|
||||
|
||||
-(void)willLoadBookmark: (NSDictionary *)bookmark;
|
||||
-(void)didLoadBookmark: (NSDictionary *)bookmark;
|
||||
@end
|
||||
|
||||
#endif /* Ample_h */
|
||||
|
|
101
Ample/Ample.m
|
@ -35,7 +35,108 @@ NSString *SupportDirectoryPath(void) {
|
|||
}
|
||||
|
||||
|
||||
NSURL *MameURL(void) {
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
|
||||
if ([defaults boolForKey: kUseCustomMame]) {
|
||||
NSString *path = [defaults stringForKey: kMamePath];
|
||||
if ([path length]) return [NSURL fileURLWithPath: path];
|
||||
}
|
||||
|
||||
return [bundle URLForAuxiliaryExecutable: @"mame64"];
|
||||
}
|
||||
|
||||
NSString *MamePath(void) {
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
|
||||
NSString *path;
|
||||
|
||||
if ([defaults boolForKey: kUseCustomMame]) {
|
||||
path = [defaults stringForKey: kMamePath];
|
||||
if ([path length]) return path;
|
||||
}
|
||||
path = [bundle pathForAuxiliaryExecutable: @"mame64"];
|
||||
if ([path length]) return path;
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
NSURL *MameWorkingDirectory(void) {
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
if ([defaults boolForKey: kUseCustomMame]) {
|
||||
NSString *path = [defaults stringForKey: kMameWorkingDirectory];
|
||||
if (![path length]) return [NSURL fileURLWithPath: path];
|
||||
}
|
||||
|
||||
return SupportDirectory();
|
||||
}
|
||||
|
||||
NSString *MameWorkingDirectoryPath(void) {
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
if ([defaults boolForKey: kUseCustomMame]) {
|
||||
NSString *path = [defaults stringForKey: kMameWorkingDirectory];
|
||||
if (![path length]) return path;
|
||||
}
|
||||
|
||||
return SupportDirectoryPath();
|
||||
}
|
||||
|
||||
|
||||
NSDictionary *MameMachine(NSString *machine) {
|
||||
static NSMutableDictionary *cache;
|
||||
|
||||
if (!cache) cache = [NSMutableDictionary new];
|
||||
NSDictionary *d;
|
||||
|
||||
if (!machine) return nil;
|
||||
d = [cache objectForKey: machine];
|
||||
if (d) return d;
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSURL *url= [bundle URLForResource: machine withExtension: @"plist"];
|
||||
|
||||
d = [NSDictionary dictionaryWithContentsOfURL: url];
|
||||
if (d) [cache setObject: d forKey: machine];
|
||||
return d;
|
||||
}
|
||||
|
||||
/* NSCache doesn't retain it's key. This essentially interns it. */
|
||||
/* could just abuse NSSelectorFromString() */
|
||||
NSString *InternString(NSString *key) {
|
||||
static NSMutableSet *storage = nil;
|
||||
|
||||
if (!storage) {
|
||||
storage = [NSMutableSet new];
|
||||
}
|
||||
NSString *copy = [storage member: key];
|
||||
if (!copy) {
|
||||
copy = [key copy];
|
||||
[storage addObject: copy];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
NSString *kUseCustomMame = @"UseCustomMame";
|
||||
NSString *kMamePath = @"MamePath";
|
||||
NSString *kMameWorkingDirectory = @"MameWorkingDirectory";
|
||||
NSString *kAutoCloseLogWindow = @"AutoCloseLogWindow";
|
||||
NSString *kUseLogWindow = @"UseLogWindow";
|
||||
NSString *kMameComponentsDate = @"MameComponentsDate";
|
||||
NSString *kDefaultDownloadURL = @"DefaultDownloadURL";
|
||||
NSString *kDefaultDownloadExtension = @"DefaultDownloadExtension";
|
||||
|
||||
NSString *kDownloadURL = @"DownloadURL";
|
||||
NSString *kDownloadExtension = @"DownloadExtension";
|
||||
|
||||
NSString *kNotificationDiskImageAdded = @"Disk Image Added";
|
||||
NSString *kNotificationDiskImageMagicRoute = @"Disk Image Magic Route";
|
||||
NSString *kNotificationBookmarkMagicRoute = @"Bookmark Magic Route";
|
||||
|
|
26
Ample/AmpleLite.m
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// AmpleLite.m
|
||||
// Ample Lite
|
||||
//
|
||||
// Created by Kelvin Sherlock on 6/14/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class NSMenuItem;
|
||||
|
||||
@interface SUUpdater : NSObject
|
||||
@end
|
||||
|
||||
@implementation SUUpdater
|
||||
|
||||
- (IBAction)checkForUpdates:(id)sender {
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -11,6 +11,6 @@
|
|||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
- (IBAction)displayPreferences:(id)sender;
|
||||
|
||||
- (IBAction)manageBookmarks: (id)sender;
|
||||
@end
|
||||
|
||||
|
|
|
@ -10,6 +10,14 @@
|
|||
#import "LaunchWindowController.h"
|
||||
#import "PreferencesWindowController.h"
|
||||
#import "DownloadWindowController.h"
|
||||
#import "DiskImagesWindowController.h"
|
||||
#import "CheatSheetWindowController.h"
|
||||
#import "BookmarkWindowController.h"
|
||||
|
||||
#import "Transformers.h"
|
||||
#import "BookmarkManager.h"
|
||||
|
||||
#import "LogWindowController.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
@property (weak) IBOutlet NSWindow *installWindow;
|
||||
|
@ -20,6 +28,10 @@
|
|||
NSWindowController *_prefs;
|
||||
NSWindowController *_launcher;
|
||||
NSWindowController *_downloader;
|
||||
NSWindowController *_diskImages;
|
||||
NSWindowController *_cheatSheet;
|
||||
NSWindowController *_bookmarks;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +43,10 @@
|
|||
NSDictionary *dict;
|
||||
|
||||
|
||||
RegisterTransformers();
|
||||
|
||||
//BookmarkManager *bm = [BookmarkManager sharedManager];
|
||||
|
||||
path = [bundle pathForResource: @"Defaults" ofType: @"plist"];
|
||||
dict = [NSDictionary dictionaryWithContentsOfFile: path];
|
||||
|
||||
|
@ -39,14 +55,17 @@
|
|||
[[NSUserDefaults standardUserDefaults] registerDefaults: dict];
|
||||
}
|
||||
|
||||
|
||||
_diskImages = [DiskImagesWindowController sharedInstance]; //[DiskImagesWindowController new];
|
||||
|
||||
if ([self installMameComponents]) {
|
||||
|
||||
[self displayLaunchWindow];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-(void)displayLaunchWindow {
|
||||
|
||||
if (!_launcher) {
|
||||
|
@ -69,12 +88,21 @@
|
|||
NSDate *newDate = [defaults objectForKey: kMameComponentsDate];
|
||||
if (![newDate isKindOfClass: [NSDate class]])
|
||||
newDate = nil;
|
||||
|
||||
|
||||
|
||||
|
||||
if (!newDate) return YES; //????
|
||||
if (oldDate && [oldDate compare: newDate] >= 0) return YES;
|
||||
|
||||
#if 0
|
||||
NSString *path = [bundle pathForResource: @"mame-data" ofType: @"tgz"];
|
||||
if (!path) return YES; // Ample Lite?
|
||||
#endif
|
||||
|
||||
NSString *ssp = [bundle sharedSupportPath];
|
||||
NSString *path = [ssp stringByAppendingPathComponent: @"mame-data.tgz"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath: path])
|
||||
return YES; // Ample Lite?
|
||||
|
||||
|
||||
NSWindow *win = _installWindow;
|
||||
|
@ -84,18 +112,23 @@
|
|||
@"xfz",
|
||||
path
|
||||
];
|
||||
[task setExecutableURL: [NSURL fileURLWithPath: @"/usr/bin/tar"]];
|
||||
if (@available(macOS 10.13, *)) {
|
||||
[task setExecutableURL: [NSURL fileURLWithPath: @"/usr/bin/tar"]];
|
||||
[task setCurrentDirectoryURL: sd];
|
||||
} else {
|
||||
[task setLaunchPath: @"/usr/bin/tar"];
|
||||
[task setCurrentDirectoryPath: SupportDirectoryPath()];
|
||||
}
|
||||
[task setArguments: argv];
|
||||
[task setCurrentDirectoryURL: sd];
|
||||
|
||||
|
||||
|
||||
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
|
||||
[task setTerminationHandler: ^(NSTask *task){
|
||||
|
||||
|
||||
int st = [task terminationStatus];
|
||||
// delay so the install window is visible, I think
|
||||
dispatch_after(when, dispatch_get_main_queue(), ^{
|
||||
|
||||
int st = [task terminationStatus];
|
||||
|
||||
if (st) {
|
||||
NSAlert *alert = [NSAlert new];
|
||||
[alert setMessageText: @"An error occurred extracting MAME components"];
|
||||
|
@ -112,6 +145,7 @@
|
|||
}
|
||||
[win close];
|
||||
[self displayLaunchWindow];
|
||||
[self displayROMS: nil];
|
||||
});
|
||||
|
||||
}];
|
||||
|
@ -123,6 +157,7 @@
|
|||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||
// Insert code here to tear down your application
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
|
||||
|
@ -130,6 +165,18 @@
|
|||
}
|
||||
|
||||
|
||||
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
|
||||
|
||||
NSString *ext = [[filename pathExtension] lowercaseString];
|
||||
|
||||
if ([ext isEqualToString: @"vgm"] || [ext isEqualToString: @"vgz"]) {
|
||||
// run mame...
|
||||
NSArray *args = @[ @"vgmplay", @"-window", @"-nomax", @"-skip_gameinfo", @"-quik", filename ];
|
||||
|
||||
[LogWindowController controllerForArgs: args];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - IBActions
|
||||
|
@ -143,12 +190,127 @@
|
|||
}
|
||||
|
||||
|
||||
- (IBAction)downloadROMS:(id)sender {
|
||||
|
||||
- (IBAction)displayROMS:(id)sender {
|
||||
if (!_downloader) {
|
||||
_downloader = [DownloadWindowController new];
|
||||
_downloader = [DownloadWindowController sharedInstance];
|
||||
}
|
||||
[_downloader showWindow: sender];
|
||||
}
|
||||
|
||||
- (IBAction)displayRecentDiskImages:(id)sender {
|
||||
if (!_diskImages) {
|
||||
_diskImages = [DiskImagesWindowController sharedInstance];
|
||||
}
|
||||
[_diskImages showWindow: sender];
|
||||
}
|
||||
|
||||
- (IBAction)displayCheatSheet:(id)sender {
|
||||
if (!_cheatSheet) {
|
||||
_cheatSheet = [CheatSheetWindowController new];
|
||||
}
|
||||
[_cheatSheet showWindow: sender];
|
||||
}
|
||||
|
||||
- (IBAction)displaySupportDirectory:(id)sender {
|
||||
NSURL *url = SupportDirectory();
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
[ws openURL: url];
|
||||
}
|
||||
- (IBAction)mameDocumentation:(id)sender {
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
NSURL *url = [NSURL URLWithString: @"https://docs.mamedev.org"];
|
||||
[ws openURL: url];
|
||||
}
|
||||
|
||||
- (IBAction)mameAppleWiki:(id)sender {
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
NSURL *url = [NSURL URLWithString: @"https://wiki.mamedev.org/index.php/Driver:Apple_II"];
|
||||
[ws openURL: url];
|
||||
}
|
||||
|
||||
- (IBAction)mameMac68kWiki:(id)sender {
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
NSURL *url = [NSURL URLWithString: @"https://wiki.mamedev.org/index.php/Driver:Mac_68K"];
|
||||
[ws openURL: url];
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)manageBookmarks: (id)sender {
|
||||
|
||||
if (!_bookmarks) {
|
||||
_bookmarks = [BookmarkWindowController new];
|
||||
}
|
||||
[_bookmarks showWindow: sender];
|
||||
}
|
||||
|
||||
|
||||
-(IBAction)installMameComponents:(id)sender {
|
||||
|
||||
|
||||
/* install the mame data components. */
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSURL *sd = SupportDirectory();
|
||||
|
||||
NSURL *ample_url = [sd URLByAppendingPathComponent: @"Ample.plist"];
|
||||
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithContentsOfURL: ample_url];
|
||||
|
||||
//NSDate *oldDate = [d objectForKey: kMameComponentsDate];
|
||||
NSDate *newDate = [defaults objectForKey: kMameComponentsDate];
|
||||
if (![newDate isKindOfClass: [NSDate class]])
|
||||
newDate = nil;
|
||||
|
||||
NSString *path = [bundle pathForResource: @"mame-data" ofType: @"tgz"];
|
||||
if (!path) return; // Ample Lite?
|
||||
|
||||
|
||||
NSWindow *win = _installWindow;
|
||||
[win makeKeyAndOrderFront: nil];
|
||||
NSTask *task = [NSTask new];
|
||||
NSArray *argv = @[
|
||||
@"xfz",
|
||||
path
|
||||
];
|
||||
if (@available(macOS 10.13, *)) {
|
||||
[task setExecutableURL: [NSURL fileURLWithPath: @"/usr/bin/tar"]];
|
||||
[task setCurrentDirectoryURL: sd];
|
||||
} else {
|
||||
[task setLaunchPath: @"/usr/bin/tar"];
|
||||
[task setCurrentDirectoryPath: SupportDirectoryPath()];
|
||||
}
|
||||
[task setArguments: argv];
|
||||
|
||||
|
||||
//dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
|
||||
[task setTerminationHandler: ^(NSTask *task){
|
||||
|
||||
int st = [task terminationStatus];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
if (st) {
|
||||
NSAlert *alert = [NSAlert new];
|
||||
[alert setMessageText: @"An error occurred extracting MAME components"];
|
||||
[alert runModal];
|
||||
[win close];
|
||||
return;
|
||||
}
|
||||
|
||||
if (d) {
|
||||
[d setObject: newDate forKey: kMameComponentsDate];
|
||||
[d writeToURL: ample_url atomically: YES];
|
||||
} else {
|
||||
[@{ kMameComponentsDate: newDate } writeToURL: ample_url atomically: YES];
|
||||
}
|
||||
[win close];
|
||||
// need to reload the software list data.
|
||||
});
|
||||
|
||||
}];
|
||||
[task launch];
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,53 +1,63 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-32.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-64.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-256.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-256.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-512.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-512.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon-1024.png",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
|
|
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-1024.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-128.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-16.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-256.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-32.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-512.png
Normal file
After Width: | Height: | Size: 447 KiB |
BIN
Ample/Assets.xcassets/AppIcon.appiconset/icon-64.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
42
Ample/AutocompleteControl.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// AutocompleteControl.h
|
||||
// Autocomplete
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/20/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class AutocompleteControl;
|
||||
|
||||
@protocol AutocompleteItem
|
||||
-(NSString *)menuTitle;
|
||||
-(NSAttributedString *)menuAttributedTitle; //?? can it still handle color?
|
||||
-(BOOL)menuEnabled;
|
||||
-(BOOL)menuIsHeader;
|
||||
@end
|
||||
|
||||
|
||||
@protocol AutoCompleteDelegate
|
||||
|
||||
-(NSArray<id<AutocompleteItem>> *)autocomplete: (AutocompleteControl *)control completionsForString: (NSString *)string;
|
||||
-(NSArray<id<AutocompleteItem>> *)autocomplete: (AutocompleteControl *)control completionsForItem: (id<AutocompleteItem>)item;
|
||||
|
||||
@end
|
||||
|
||||
@interface AutocompleteControl : NSSearchField
|
||||
|
||||
@property NSInteger minWidth;
|
||||
@property NSInteger maxDisplayItems;
|
||||
@property (nullable, weak) id<AutoCompleteDelegate> autocompleteDelegate;
|
||||
|
||||
-(void)invalidate;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
885
Ample/AutocompleteControl.m
Normal file
|
@ -0,0 +1,885 @@
|
|||
//
|
||||
// AutocompleteControl.m
|
||||
// Autocomplete
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/20/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AutocompleteControl.h"
|
||||
#include <wctype.h>
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Todo --
|
||||
- when there is a value, can filter the list by only including header items and the selected value
|
||||
- draw inactive menu items
|
||||
- when menu is hidden then text is manually deleted (not esc canceled), then down/up arrow the list needs to update.
|
||||
- eliminate nib and do it manually.
|
||||
- when menus is too tall, macos moves it to the top of the screen.
|
||||
- 1. it's not moved someplace more appropriate when the size shrinks
|
||||
- 2. it should display to the left or right in that case.
|
||||
- need to know parent's frame.
|
||||
|
||||
- fuzzy search - minimum distance between letters?
|
||||
*/
|
||||
|
||||
|
||||
@interface ACMenuView : NSView
|
||||
@property (nonatomic) NSArray<id<AutocompleteItem>> *items;
|
||||
|
||||
@property (weak) AutocompleteControl *parent;
|
||||
|
||||
-(void)reset;
|
||||
-(void)reset: (id<AutocompleteItem>)value;
|
||||
-(void)setItems:(NSArray<id<AutocompleteItem>> *)items;
|
||||
-(void)setItems:(NSArray<id<AutocompleteItem>> *)items value: (id<AutocompleteItem>)value;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface AutocompleteControl ()
|
||||
{
|
||||
IBOutlet NSPanel *_panel;
|
||||
__weak IBOutlet ACMenuView *_menuView;
|
||||
__weak IBOutlet NSScrollView *_scrollView;
|
||||
|
||||
id<AutocompleteItem> _value;
|
||||
BOOL _editing;
|
||||
BOOL _dirty;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface AutocompleteControl (SearchField) <NSSearchFieldDelegate>
|
||||
-(void)fixTextColor: (BOOL)editing;
|
||||
@end
|
||||
|
||||
@implementation AutocompleteControl
|
||||
|
||||
-(void)_init {
|
||||
|
||||
[self setDelegate: self];
|
||||
[self setPlaceholderString: @""];
|
||||
[(NSSearchFieldCell *)[self cell] setSearchButtonCell: nil];
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSNib *nib = [[NSNib alloc] initWithNibNamed: @"Autocomplete" bundle: bundle];
|
||||
|
||||
NSArray *topLevel = nil;
|
||||
[nib instantiateWithOwner: self topLevelObjects: &topLevel];
|
||||
|
||||
[_panel setMovable: NO];
|
||||
[_panel setBecomesKeyOnlyIfNeeded: YES];
|
||||
[_menuView setParent: self];
|
||||
}
|
||||
|
||||
-(id)initWithFrame:(NSRect)frameRect {
|
||||
if ((self = [super initWithFrame: frameRect])) {
|
||||
[self _init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)coder {
|
||||
if ((self = [super initWithCoder: coder])) {
|
||||
[self _init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#if 0
|
||||
-(NSString *)stringValue {
|
||||
return [super stringValue];
|
||||
}
|
||||
#endif
|
||||
|
||||
-(id)objectValue {
|
||||
return _value;
|
||||
}
|
||||
|
||||
-(void)setStringValue:(NSString *)stringValue {
|
||||
[super setStringValue: stringValue ? stringValue : @""];
|
||||
if (_value && [[_value menuTitle] isEqualToString: stringValue] == NO) {
|
||||
// post change notification?
|
||||
_value = nil;
|
||||
[_menuView reset];
|
||||
}
|
||||
|
||||
[self fixTextColor: _editing];
|
||||
// todo -- search for a matching item, update text color.
|
||||
}
|
||||
|
||||
// todo -- _menuView has second copy of value, need to update that.
|
||||
-(void)setObjectValue:(id)objectValue {
|
||||
if (_value == objectValue) return;
|
||||
if (![objectValue conformsToProtocol: @protocol(AutocompleteItem)]) {
|
||||
_value = nil;
|
||||
[_menuView reset];
|
||||
[super setStringValue: @""];
|
||||
[self fixTextColor: _editing];
|
||||
return;
|
||||
}
|
||||
_value = objectValue;
|
||||
if (!_value) [super setStringValue: @""]; //
|
||||
else {
|
||||
[super setStringValue: [_value menuTitle]];
|
||||
[_menuView reset: _value];
|
||||
// TODO -- menu view currently uses text search.
|
||||
//NSArray *array = [_autocompleteDelegate autocomplete: self completionsForItem: _value];
|
||||
//[_menuView setItems: array value: _value];
|
||||
}
|
||||
[self fixTextColor: NO];
|
||||
}
|
||||
|
||||
-(BOOL)valid {
|
||||
return _value != nil;
|
||||
}
|
||||
|
||||
|
||||
-(void)hideSuggestions: (id)sender {
|
||||
|
||||
if (![_panel isVisible]) return;
|
||||
|
||||
NSWindow *window = [self window];
|
||||
|
||||
[window removeChildWindow: _panel];
|
||||
[_panel orderOut: sender];
|
||||
|
||||
}
|
||||
|
||||
-(void)showSuggestions: (id)sender {
|
||||
|
||||
if ([_panel isVisible]) return;
|
||||
NSWindow *window = [self window];
|
||||
|
||||
NSRect wFrame = [_panel frame];
|
||||
NSRect vFrame = [self frame];
|
||||
|
||||
NSRect rect = { .origin = vFrame.origin, .size = wFrame.size };
|
||||
rect = [window convertRectToScreen:rect];
|
||||
|
||||
rect.origin.y -= wFrame.size.height + 4;
|
||||
rect.size.width = MAX(vFrame.size.width, _minWidth);
|
||||
// todo - min width option.
|
||||
[_panel setFrame: rect display: YES];
|
||||
|
||||
//[_panel setFrameOrigin: rect.origin];
|
||||
[window addChildWindow: _panel ordered: NSWindowAbove];
|
||||
}
|
||||
|
||||
-(void)updateSuggestions {
|
||||
|
||||
if (!_autocompleteDelegate) return;
|
||||
NSString *needle = [self stringValue];
|
||||
|
||||
NSArray *items = [_autocompleteDelegate autocomplete: self completionsForString: needle];
|
||||
|
||||
[_menuView setItems: items];
|
||||
if ([items count]) {
|
||||
[self showSuggestions: nil];
|
||||
} else {
|
||||
[self hideSuggestions: nil];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)invalidate {
|
||||
|
||||
if (!_autocompleteDelegate) return;
|
||||
|
||||
NSArray *items = nil;
|
||||
|
||||
/* if there is an object value, try to retain it. */
|
||||
if (_value) {
|
||||
|
||||
[_menuView reset];
|
||||
items = [_autocompleteDelegate autocomplete: self completionsForItem: _value];
|
||||
if (items) {
|
||||
[_menuView setItems: items];
|
||||
return;
|
||||
}
|
||||
_value = nil;
|
||||
[self invoke];
|
||||
}
|
||||
NSString *needle = [self stringValue];
|
||||
|
||||
if ([needle length]) {
|
||||
_dirty = YES;
|
||||
}
|
||||
// if only 1 match, auto-set value?
|
||||
items = [_autocompleteDelegate autocomplete: self completionsForString: needle];
|
||||
[self fixTextColor: _editing];
|
||||
[_menuView setItems: items];
|
||||
}
|
||||
|
||||
|
||||
// prevent action messages from the search field/cell.
|
||||
-(BOOL)sendAction:(SEL)action to:(id)target {
|
||||
if (action == [self action] && target == [self target]) return NO;
|
||||
return [super sendAction: action to: target];
|
||||
|
||||
}
|
||||
|
||||
-(void)invoke {
|
||||
_dirty = NO;
|
||||
[super sendAction: [self action] to: [self target]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation AutocompleteControl (SearchField)
|
||||
|
||||
-(void)fixTextColor: (BOOL)editing {
|
||||
NSColor *color = editing || _value ? [NSColor controlTextColor] : [NSColor systemRedColor];
|
||||
[self setTextColor: color];
|
||||
}
|
||||
|
||||
- (void)controlTextDidChange:(NSNotification *)notification {
|
||||
//NSLog(@"controlTextDidChange");
|
||||
|
||||
if (_value) {
|
||||
_dirty = YES;
|
||||
_value = nil;
|
||||
}
|
||||
|
||||
NSString *s = [self stringValue];
|
||||
if ([s length]) {
|
||||
[self updateSuggestions];
|
||||
} else {
|
||||
_dirty = YES;
|
||||
_value = nil;
|
||||
[_menuView reset];
|
||||
[_menuView setItems: nil];
|
||||
[self hideSuggestions: nil];
|
||||
[self invoke];
|
||||
}
|
||||
}
|
||||
- (void)controlTextDidBeginEditing:(NSNotification *)obj {
|
||||
//NSLog(@"controlTextDidBeginEditing");
|
||||
|
||||
_editing = YES;
|
||||
_dirty = NO;
|
||||
[self fixTextColor: YES];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)controlTextDidEndEditing:(NSNotification *)obj {
|
||||
//NSLog(@"controlTextDidEndEditing");
|
||||
|
||||
_editing = NO;
|
||||
|
||||
[self hideSuggestions: nil];
|
||||
|
||||
if (_dirty) {
|
||||
_value = nil;
|
||||
[self invoke];
|
||||
}
|
||||
[self fixTextColor: NO];
|
||||
}
|
||||
|
||||
|
||||
-(BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)selectItem:(id<AutocompleteItem>)item withSelector:(SEL)selector {
|
||||
|
||||
// for newline/mousedown, will still retain focus after updating
|
||||
// so we need to invalidate the value if it's edited further.
|
||||
if (selector == @selector(insertNewline:) || selector == @selector(mouseDown:) || selector == @selector(insertTab:)) {
|
||||
|
||||
_value = item;
|
||||
NSString *str = [item menuTitle];
|
||||
|
||||
[super setStringValue: str];
|
||||
|
||||
[self hideSuggestions: nil];
|
||||
|
||||
NSText *fieldEditor = [self currentEditor];
|
||||
//[fieldEditor setSelectedRange: NSMakeRange([str length], 0)];
|
||||
[fieldEditor setSelectedRange: NSMakeRange(0, [str length])];
|
||||
|
||||
[self invoke];
|
||||
|
||||
// need to invalidate the menu so it reloads
|
||||
|
||||
|
||||
#if 0
|
||||
NSArray *array = [_autocompleteDelegate autocomplete: self completionsForItem: _value];
|
||||
[_menuView setItems: array];
|
||||
#else
|
||||
[_menuView setItems: nil];
|
||||
#endif
|
||||
|
||||
//NSLog(@"selectItem:withSelector:");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
|
||||
|
||||
if (commandSelector == @selector(moveUp:)) {
|
||||
//[self showSuggestions: nil];
|
||||
if ([_panel isVisible]) {
|
||||
[_menuView moveUp: textView];
|
||||
} else {
|
||||
[self updateSuggestions];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (commandSelector == @selector(moveDown:)) {
|
||||
//[self showSuggestions: nil];
|
||||
if ([_panel isVisible]) {
|
||||
[_menuView moveDown: textView];
|
||||
} else {
|
||||
[self updateSuggestions];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (commandSelector == @selector(insertNewline:)) {
|
||||
if ([_panel isVisible])
|
||||
[_menuView insertNewline: textView];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (commandSelector == @selector(insertTab:)) {
|
||||
if ([_panel isVisible])
|
||||
[_menuView insertTab: textView];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (commandSelector == @selector(complete:)) {
|
||||
if ([_panel isVisible]) {
|
||||
[self hideSuggestions: nil];
|
||||
} else {
|
||||
[self updateSuggestions];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
// esc ?
|
||||
// if panel open, hide
|
||||
// if panel closed, delete.
|
||||
if (commandSelector == @selector(cancelOperation:)) {
|
||||
|
||||
if ([_panel isVisible]) {
|
||||
[self hideSuggestions: nil];
|
||||
} else {
|
||||
_value = nil;
|
||||
[super setStringValue: @""];
|
||||
|
||||
[self hideSuggestions: nil];
|
||||
[_menuView reset];
|
||||
//[_menuView setItems: _completions];
|
||||
// sigh...
|
||||
#if 0
|
||||
NSArray *items =[_autocompleteDelegate autocomplete: self completionsForString: @""];
|
||||
[_menuView setItems: items];
|
||||
#endif
|
||||
[self invoke];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (commandSelector == @selector(scrollPageDown:)) {
|
||||
if ([_panel isVisible]) {
|
||||
[_menuView scrollPageDown: textView];
|
||||
} else {
|
||||
[self updateSuggestions];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
if (commandSelector == @selector(scrollPageUp:)) {
|
||||
if ([_panel isVisible]) {
|
||||
[_menuView scrollPageUp: textView];
|
||||
} else {
|
||||
[self updateSuggestions];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
//NSLog(@"%@", NSStringFromSelector(commandSelector));
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ACMenuView () {
|
||||
id<AutocompleteItem> _value;
|
||||
NSInteger _index;
|
||||
NSInteger _count;
|
||||
NSArray<id<AutocompleteItem>> *_items;
|
||||
NSTrackingArea *_trackingArea;
|
||||
NSColor *_backgroundColor;
|
||||
NSColor *_selectedColor;
|
||||
BOOL _tracking;
|
||||
BOOL _clipped;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ACMenuView
|
||||
|
||||
#define MENU_FONT_SIZE 11
|
||||
#define MENU_HEIGHT 14
|
||||
#define MARGIN_TOP 0 //6
|
||||
#define MARGIN_BOTTOM 0 //6
|
||||
#define INDENT 7
|
||||
#define HEADER_INDENT 7
|
||||
#define MAX_DISPLAY_ITEMS 16
|
||||
|
||||
|
||||
-(void)_init {
|
||||
_backgroundColor = [NSColor windowBackgroundColor];
|
||||
if (@available(macOS 10.14, *)) {
|
||||
_selectedColor = [NSColor selectedContentBackgroundColor];
|
||||
} else {
|
||||
_selectedColor = [NSColor selectedTextBackgroundColor];
|
||||
}
|
||||
NSTrackingAreaOptions options = NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveInActiveApp;
|
||||
_trackingArea = [[NSTrackingArea alloc] initWithRect: NSZeroRect
|
||||
options: options
|
||||
owner: self
|
||||
userInfo: nil];
|
||||
|
||||
[self addTrackingArea: _trackingArea];
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)coder {
|
||||
if ((self = [super initWithCoder: coder])) {
|
||||
[self _init];
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse:(NSEvent *)event {
|
||||
return YES;
|
||||
}
|
||||
|
||||
static CGFloat HeightForItems(NSUInteger count) {
|
||||
return count * MENU_HEIGHT;
|
||||
}
|
||||
|
||||
-(NSSize)intrinsicContentSize {
|
||||
return NSMakeSize(NSViewNoIntrinsicMetric, _count * MENU_HEIGHT + MARGIN_TOP + MARGIN_BOTTOM);
|
||||
}
|
||||
|
||||
- (NSSize)sizeThatFits:(NSSize)size {
|
||||
size.height = _count * MENU_HEIGHT + MARGIN_TOP + MARGIN_BOTTOM;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void)sizeToFit {
|
||||
NSSize size = [self frame].size;
|
||||
size.height = _count * MENU_HEIGHT + MARGIN_TOP + MARGIN_BOTTOM;
|
||||
[self setFrameSize: size];
|
||||
[self setNeedsDisplay: YES];
|
||||
}
|
||||
|
||||
-(void)reset {
|
||||
[self invalidateRow: _index];
|
||||
_index = -1;
|
||||
_value = nil;
|
||||
_items = nil;
|
||||
}
|
||||
|
||||
-(void)reset: (id<AutocompleteItem>)value {
|
||||
[self invalidateRow: _index];
|
||||
_index = -1;
|
||||
_items = nil;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
-(void)setItems:(NSArray *)items value: (id<AutocompleteItem> )value {
|
||||
if (_items == items && _value == value) return;
|
||||
_items = [items copy];
|
||||
_index = -1;
|
||||
_count = [items count];
|
||||
_value = value;
|
||||
|
||||
if (!_items) {
|
||||
_value = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
// also check enabled status....
|
||||
if (_value) {
|
||||
_index = [_items indexOfObject: _value];
|
||||
if (_index == NSNotFound) {
|
||||
_index = -1;
|
||||
_value = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// if only 1 entry, auto-select it.
|
||||
if (!_value) {
|
||||
NSInteger count = -1;
|
||||
for (id<AutocompleteItem> item in _items) {
|
||||
++count;
|
||||
if ([item menuIsHeader]) continue;
|
||||
if (_value) {
|
||||
_value = nil;
|
||||
_index = -1;
|
||||
break;
|
||||
}
|
||||
_value = item;
|
||||
_index = count;
|
||||
}
|
||||
}
|
||||
|
||||
NSInteger displayCount = MIN(_count, MAX_DISPLAY_ITEMS);
|
||||
CGFloat newHeight = HeightForItems(displayCount) + 8 ; // 4px top/bottom
|
||||
NSWindow *window = [self window];
|
||||
NSRect wFrame = [window frame];
|
||||
|
||||
NSRect contentRect = [[[self enclosingScrollView] contentView] frame];
|
||||
|
||||
//NSSize size = [self intrinsicContentSize];
|
||||
//NSInteger minWidth = [_parent minWidth];
|
||||
//size.width = MAX(wFrame.size.width, minWidth);
|
||||
//size.height += 8;
|
||||
|
||||
CGFloat delta = wFrame.size.height - newHeight;
|
||||
|
||||
wFrame.origin.y += delta;
|
||||
wFrame.size.height = newHeight;
|
||||
|
||||
_clipped = (_count > displayCount);
|
||||
|
||||
[self setFrameSize: NSMakeSize(contentRect.size.width /*- 15.0*/, HeightForItems(_count))];
|
||||
[self setNeedsDisplay: YES];
|
||||
[window setFrame: wFrame display: YES];
|
||||
|
||||
if (_value) {
|
||||
[self scrollToRow: _index position: ScrollToCenter force: NO];
|
||||
} else {
|
||||
[self scrollToRow: 0 position: ScrollToTop force: YES];
|
||||
}
|
||||
|
||||
//[self sizeToFit];
|
||||
//[[self window] setContentSize: [self frame].size];
|
||||
|
||||
//NSLog(@"%@", NSStringFromRect(wFrame));
|
||||
}
|
||||
|
||||
-(void)setItems:(NSArray<id<AutocompleteItem>> *)items {
|
||||
|
||||
if (_items == items) return;
|
||||
[self setItems: items value: _value];
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(id<AutocompleteItem>)itemAtPoint: (NSPoint)point indexPtr: (NSInteger *)indexPtr {
|
||||
|
||||
NSInteger index = floor(point.y / MENU_HEIGHT);
|
||||
if (index < 0 || index >= _count) return nil;
|
||||
if (indexPtr) *indexPtr = index;
|
||||
return [_items objectAtIndex: index];
|
||||
}
|
||||
|
||||
enum {
|
||||
ScrollToTop,
|
||||
ScrollToBottom,
|
||||
ScrollToCenter,
|
||||
};
|
||||
|
||||
-(void)scrollToRow: (NSInteger)row position: (unsigned)position force: (BOOL)force {
|
||||
if (row < 0) return;
|
||||
if (!_clipped) return;
|
||||
|
||||
NSScrollView *scrollView = [self enclosingScrollView];
|
||||
NSClipView *clipView = [scrollView contentView];
|
||||
|
||||
NSRect visibleRect = [self visibleRect];
|
||||
if (!force) {
|
||||
NSRect mRect = NSMakeRect(0, row * MENU_HEIGHT, 1 , MENU_HEIGHT);
|
||||
if (NSContainsRect(visibleRect, mRect)) return;
|
||||
}
|
||||
|
||||
NSInteger topRow = row;
|
||||
switch (position) {
|
||||
case ScrollToTop:
|
||||
break;
|
||||
case ScrollToBottom:
|
||||
topRow -= MAX_DISPLAY_ITEMS -1;
|
||||
break;
|
||||
case ScrollToCenter:
|
||||
topRow -= MAX_DISPLAY_ITEMS/2 - 1;
|
||||
break;
|
||||
}
|
||||
if (topRow < 0) topRow = 0;
|
||||
if (topRow > _count - MAX_DISPLAY_ITEMS)
|
||||
topRow = _count - MAX_DISPLAY_ITEMS;
|
||||
NSPoint point = NSMakePoint(0, topRow * MENU_HEIGHT);
|
||||
|
||||
//[self scrollClipView: clipView toPoint: point];
|
||||
[clipView scrollToPoint: point];
|
||||
[scrollView reflectScrolledClipView: clipView];
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)moveUp:(id)sender {
|
||||
if (_count == 0 || _index <= 0) return;
|
||||
|
||||
NSInteger index = 0;
|
||||
id<AutocompleteItem> value = nil;
|
||||
for (index = _index - 1; index >= 0; --index) {
|
||||
value = [_items objectAtIndex: index];
|
||||
if ([value menuIsHeader]) continue;
|
||||
if (![value menuEnabled]) continue;
|
||||
break;
|
||||
}
|
||||
if (index < 0) return;
|
||||
if (index == _index) return;
|
||||
[self invalidateRow: _index];
|
||||
[self invalidateRow: index];
|
||||
|
||||
_index = index;
|
||||
_value = value;
|
||||
[self scrollToRow: index position: ScrollToTop force: NO];
|
||||
[_parent selectItem: _value withSelector: _cmd];
|
||||
}
|
||||
|
||||
-(void)moveDown:(id)sender {
|
||||
|
||||
// _index -1 selects first item.
|
||||
if (_count == 0 || _index == _count - 1) return;
|
||||
|
||||
NSInteger index = 0;
|
||||
id<AutocompleteItem> value = nil;
|
||||
for (index = _index + 1; index < _count ; ++index) {
|
||||
value = [_items objectAtIndex: index];
|
||||
if ([value menuIsHeader]) continue;
|
||||
if (![value menuEnabled]) continue;
|
||||
break;
|
||||
}
|
||||
if (index == _count) return;
|
||||
if (index == _index) return;
|
||||
[self invalidateRow: _index];
|
||||
[self invalidateRow: index];
|
||||
|
||||
_index = index;
|
||||
_value = value;
|
||||
|
||||
[self scrollToRow: index position: ScrollToBottom force: NO];
|
||||
[_parent selectItem: _value withSelector: _cmd];
|
||||
}
|
||||
|
||||
-(void)scrollPageUp:(id)sender {
|
||||
if (_count == 0 || _index <= 0) return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)scrollPageDown:(id)sender {
|
||||
if (_count == 0 || _index == _count - 1) return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)insertNewline:(id)sender {
|
||||
if (_value) {
|
||||
[_parent selectItem: _value withSelector: _cmd];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)insertTab:(id)sender {
|
||||
// if only one option, autocomplete?
|
||||
if (_value) {
|
||||
[_parent selectItem: _value withSelector: _cmd];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)mouseMoved:(NSEvent *)event {
|
||||
//NSLog(@"mouse moved");
|
||||
|
||||
if (!_tracking) return;
|
||||
|
||||
NSPoint p = [event locationInWindow];
|
||||
p = [self convertPoint: p fromView: nil];
|
||||
|
||||
|
||||
NSInteger index;
|
||||
id<AutocompleteItem> value = [self itemAtPoint: p indexPtr: &index];
|
||||
if (!value) return;
|
||||
if (index == _index) return;
|
||||
if ([value menuIsHeader]) return;
|
||||
if (![value menuEnabled]) return;
|
||||
|
||||
[self invalidateRow: _index];
|
||||
[self invalidateRow: index];
|
||||
|
||||
_index = index;
|
||||
_value = value;
|
||||
[_parent selectItem: _value withSelector: _cmd];
|
||||
}
|
||||
-(void)mouseDown:(NSEvent *)event {
|
||||
if (!_tracking) return;
|
||||
|
||||
NSPoint p = [event locationInWindow];
|
||||
p = [self convertPoint: p fromView: nil];
|
||||
|
||||
NSInteger index;
|
||||
id<AutocompleteItem> value = [self itemAtPoint: p indexPtr: &index];
|
||||
if (!value) return;
|
||||
if (index != _index) {
|
||||
if ([value menuIsHeader]) return;
|
||||
if (![value menuEnabled]) return;
|
||||
|
||||
[self invalidateRow: _index];
|
||||
[self invalidateRow: index];
|
||||
|
||||
_index = index;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
[_parent selectItem: _value withSelector: _cmd];
|
||||
}
|
||||
|
||||
-(void)mouseEntered:(NSEvent *)event {
|
||||
//NSLog(@"mouse entered");
|
||||
_tracking = YES;
|
||||
|
||||
}
|
||||
-(void)mouseExited:(NSEvent *)event {
|
||||
//NSLog(@"mouse exited");
|
||||
|
||||
_tracking = NO;
|
||||
}
|
||||
|
||||
-(void)invalidateRow:(NSInteger)row {
|
||||
if (row < 0 || row >= _count) return;
|
||||
|
||||
NSRect r = NSZeroRect;
|
||||
NSRect bounds = [self bounds];
|
||||
|
||||
r.size.width = bounds.size.width;
|
||||
r.size.height = MENU_HEIGHT;
|
||||
r.origin.y = MENU_HEIGHT * row + MARGIN_TOP;
|
||||
//NSLog(@"Invalidating %ld - %@", row, NSStringFromRect(r));
|
||||
[self setNeedsDisplayInRect: r];
|
||||
}
|
||||
|
||||
|
||||
static void DrawString(NSString *str, NSDictionary *attr, CGRect rect) {
|
||||
|
||||
NSSize size = [str sizeWithAttributes: attr];
|
||||
if (size.width <= rect.size.width) {
|
||||
[str drawInRect: rect withAttributes: attr];
|
||||
return;
|
||||
}
|
||||
NSMutableString *mstr = [str mutableCopy];
|
||||
// binary search is probably the best way to handle it :/
|
||||
NSInteger l = [mstr length];
|
||||
while (l > 2) {
|
||||
[mstr replaceCharactersInRange: NSMakeRange(l-2, 2) withString: @"…"];
|
||||
--l;
|
||||
size = [mstr sizeWithAttributes: attr];
|
||||
if (size.width <= rect.size.width) {
|
||||
[mstr drawInRect: rect withAttributes: attr];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)drawItem: (id<AutocompleteItem>)item inRect: (NSRect)rect {
|
||||
NSColor *textColor = [NSColor textColor];
|
||||
if (!item) return;
|
||||
|
||||
if (item == _value) {
|
||||
textColor = [NSColor selectedMenuItemTextColor];
|
||||
[_selectedColor setFill];
|
||||
NSRectFill(rect);
|
||||
}
|
||||
NSString *string = [item menuTitle];
|
||||
|
||||
if ([item menuIsHeader]) {
|
||||
textColor = [NSColor secondaryLabelColor];
|
||||
NSDictionary *attr = @{
|
||||
NSForegroundColorAttributeName: textColor,
|
||||
NSFontAttributeName: [NSFont systemFontOfSize: MENU_FONT_SIZE], // [NSFont boldSystemFontOfSize: 13],
|
||||
};
|
||||
NSRect r = NSInsetRect(rect, HEADER_INDENT, 0);
|
||||
DrawString(string, attr, r);
|
||||
} else {
|
||||
|
||||
NSDictionary *attr = @{
|
||||
NSForegroundColorAttributeName: textColor,
|
||||
NSFontAttributeName: [NSFont systemFontOfSize: MENU_FONT_SIZE],
|
||||
};
|
||||
NSRect r = NSInsetRect(rect, INDENT, 0);
|
||||
r.origin.x += INDENT;
|
||||
r.size.width -= INDENT;
|
||||
DrawString(string, attr, r);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect {
|
||||
[super drawRect:dirtyRect];
|
||||
|
||||
NSRect r = [self bounds];
|
||||
NSInteger begin = floor((NSMinY(dirtyRect) - MARGIN_TOP) / MENU_HEIGHT);
|
||||
NSInteger end = ceil((NSMaxY(dirtyRect) - MARGIN_TOP) / MENU_HEIGHT);
|
||||
if (begin < 0) begin = 0;
|
||||
if (end > _count) end = _count;
|
||||
|
||||
|
||||
r.origin.y = MENU_HEIGHT * begin + MARGIN_TOP;
|
||||
r.size.height = MENU_HEIGHT;
|
||||
for (NSInteger index = begin; index < end; ++index) {
|
||||
id<AutocompleteItem> item = [_items objectAtIndex: index];
|
||||
[self drawItem: item inRect: r];
|
||||
r.origin.y += MENU_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* custom scroller that doesn't draw a background. */
|
||||
@interface ACScroller : NSScroller
|
||||
@end
|
||||
|
||||
@implementation ACScroller
|
||||
|
||||
|
||||
-(void)drawRect:(NSRect)dirtyRect {
|
||||
//[[NSColor windowBackgroundColor] set];
|
||||
[[NSColor clearColor] set];
|
||||
NSRectFill(dirtyRect);
|
||||
[self drawKnob];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ACPanel : NSPanel
|
||||
@end
|
||||
|
||||
@implementation ACPanel
|
||||
|
||||
/* needed to prevent the pop-up child window from being moved when offscreen. */
|
||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen {
|
||||
return frameRect;
|
||||
}
|
||||
|
||||
|
||||
@end
|
55
Ample/Base.lproj/Autocomplete.xib
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="AutocompleteControl">
|
||||
<connections>
|
||||
<outlet property="_menuView" destination="F2h-9b-Ouu" id="min-gE-sma"/>
|
||||
<outlet property="_panel" destination="OYW-cj-FD5" id="DYJ-rN-6Ep"/>
|
||||
<outlet property="_scrollView" destination="VQ6-PE-hTH" id="iKA-Ps-nkl"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" titlebarAppearsTransparent="YES" titleVisibility="hidden" id="OYW-cj-FD5" customClass="ACPanel">
|
||||
<windowStyleMask key="styleMask" utility="YES" nonactivatingPanel="YES" fullSizeContentView="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="272" y="172" width="300" height="400"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="3pz-HL-mV1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="300" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="0.0" horizontalPageScroll="0.0" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" id="VQ6-PE-hTH">
|
||||
<rect key="frame" x="0.0" y="4" width="300" height="392"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="HWy-NN-aOV">
|
||||
<rect key="frame" x="0.0" y="0.0" width="300" height="392"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view id="F2h-9b-Ouu" customClass="ACMenuView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="300" height="392"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="Az6-1a-Hei">
|
||||
<rect key="frame" x="-100" y="-100" width="168" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="tng-g2-1LZ" customClass="ACScroller">
|
||||
<rect key="frame" x="285" y="0.0" width="15" height="392"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="127" y="73"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
223
Ample/Base.lproj/BookmarkWindow.xib
Normal file
|
@ -0,0 +1,223 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="BookmarkWindowController">
|
||||
<connections>
|
||||
<outlet property="arrayController" destination="7gA-MI-adT" id="XJ0-qj-ho5"/>
|
||||
<outlet property="bookmarkManager" destination="Ryd-Nr-sPf" id="LM4-IP-ehb"/>
|
||||
<outlet property="tableView" destination="mkQ-pQ-kXu" id="jqC-GF-vrE"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="ovK-qY-XrZ"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Bookmarks" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="400" height="450"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="450"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cgh-jG-i97">
|
||||
<rect key="frame" x="-1" y="-1" width="402" height="452"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" id="xDr-v4-sVR">
|
||||
<rect key="frame" x="1" y="1" width="400" height="450"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="hmS-CB-Huq" viewBased="YES" id="mkQ-pQ-kXu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="425"/>
|
||||
<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 width="232" minWidth="40" maxWidth="1000" id="U9x-dw-Kd3">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Name">
|
||||
<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="jIY-mU-1gw">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="caseInsensitiveCompare:" sortKey="name"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="R8h-Wj-cHA">
|
||||
<rect key="frame" x="1" y="1" width="237" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cIh-ya-lB0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="237" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="a7b-vf-Kzd">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="R8h-Wj-cHA" name="value" keyPath="objectValue.name" id="UWc-85-Ghw">
|
||||
<dictionary key="options">
|
||||
<bool key="NSValidatesImmediately" value="YES"/>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="cIh-ya-lB0" id="DMK-Kc-RpK"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn editable="NO" width="100" minWidth="100" maxWidth="100" id="fvh-YG-X9R">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Machine">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="waa-dh-M0V">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="machine"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="LUd-BZ-Kpw">
|
||||
<rect key="frame" x="241" y="1" width="100" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4Qd-Zj-XZi">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="ztJ-V1-N1t">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="LUd-BZ-Kpw" name="value" keyPath="objectValue.machine" id="IYK-LP-fHo"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="4Qd-Zj-XZi" id="u3u-3q-Vc2"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn editable="NO" width="50" minWidth="50" maxWidth="50" id="rmr-1r-2Cb">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Default">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="zuw-8H-5ck">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="automatic"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="f3C-qX-bVY">
|
||||
<rect key="frame" x="344" y="1" width="54" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LzD-ps-EdD">
|
||||
<rect key="frame" x="19" y="1" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSStatusAvailable" id="kH7-IH-D1y"/>
|
||||
<connections>
|
||||
<binding destination="f3C-qX-bVY" name="hidden" keyPath="objectValue.automatic" id="izX-1f-EU8">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSNegateBoolean</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="imageView" destination="LzD-ps-EdD" id="hef-CI-Ly8"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action trigger="doubleAction" selector="doubleClick:" target="-2" id="VaT-3X-cCf"/>
|
||||
<binding destination="7gA-MI-adT" name="content" keyPath="arrangedObjects" id="5So-FR-r94"/>
|
||||
<outlet property="dataSource" destination="-2" id="kso-yU-XdI"/>
|
||||
<outlet property="delegate" destination="-2" id="Lyf-Wr-8w0"/>
|
||||
<outlet property="menu" destination="cH2-L7-ScC" id="3MS-Tc-P04"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="O1o-6N-F5z">
|
||||
<rect key="frame" x="-100" y="-100" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="3n8-lN-RGL">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<tableHeaderView key="headerView" wantsLayer="YES" id="hmS-CB-Huq">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="4OM-KB-CAh"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-72" y="91"/>
|
||||
</window>
|
||||
<arrayController mode="entity" entityName="Bookmark" automaticallyPreparesContent="YES" preservesSelection="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" clearsFilterPredicateOnInsertion="NO" id="7gA-MI-adT">
|
||||
<connections>
|
||||
<binding destination="Ryd-Nr-sPf" name="managedObjectContext" keyPath="managedObjectContext" id="hMi-JG-LQC"/>
|
||||
<binding destination="-2" name="selectionIndexes" keyPath="tableView.selectedRowIndexes" id="dyb-Wv-Duo"/>
|
||||
<binding destination="-2" name="sortDescriptors" keyPath="tableView.sortDescriptors" previousBinding="dyb-Wv-Duo" id="fkc-Yv-ZLN"/>
|
||||
</connections>
|
||||
</arrayController>
|
||||
<customObject id="Ryd-Nr-sPf" customClass="BookmarkManagerProxy"/>
|
||||
<menu id="cH2-L7-ScC">
|
||||
<items>
|
||||
<menuItem title="Set Default" id="JGR-HC-oCO">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="setDefault:" target="-2" id="QQK-aI-l2p"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Clear Default" id="ulz-3z-Pgl">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="clearDefault:" target="-2" id="mIc-UM-kj0"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="B7V-fY-Cbe">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="deleteBookmark:" target="-2" id="zQl-vg-Eg4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="raV-YO-2UW"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="355" y="-28"/>
|
||||
</menu>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSStatusAvailable" width="16" height="16"/>
|
||||
</resources>
|
||||
</document>
|
29
Ample/Base.lproj/CheatSheet.xib
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CheatSheetWindowController">
|
||||
<connections>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="U2v-sN-OzH"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Keyboard Cheat Sheet" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="640" height="640"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="640" height="640"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="u4H-aq-RE2"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="42" y="198"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -1,14 +1,15 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;\cssrgb\c100000\c100000\c100000;}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red255\green255\blue255;\red38\green38\blue38;
|
||||
}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;\cssrgb\c100000\c100000\c100000;\cssrgb\c20000\c20000\c20000;
|
||||
}
|
||||
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
|
||||
\f0\b\fs36 \cf2 Ample\cf0
|
||||
\f1\b0\fs28 would like to thank\'85\
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
\cf0 \
|
||||
\
|
||||
\pard\pardeftab720\qc\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://www.mamedev.org"}}{\fldrslt
|
||||
\f0\b\fs36 \cf0 \cb3 \expnd0\expndtw0\kerning0
|
||||
|
@ -30,4 +31,26 @@ Please note that MAME is a registered trademark of Gregory Ember, and permission
|
|||
\cf0 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qj\partightenfactor0
|
||||
\cf0 \cb1 \kerning1\expnd0\expndtw0 SDL 2.0 is distributed under the {\field{\*\fldinst{HYPERLINK "https://libsdl.org/license.php"}}{\fldrslt zlib license}}. This license allows you to use SDL freely in any software.\
|
||||
}
|
||||
\
|
||||
\pard\pardeftab720\qc\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://sparkle-project.org/"}}{\fldrslt
|
||||
\f0\b\fs36 \cf0 \cb3 \expnd0\expndtw0\kerning0
|
||||
Sparkle}}\
|
||||
\pard\pardeftab720\partightenfactor0
|
||||
\cf0 \
|
||||
Sparkle is open source software available under the permissive MIT license, and is developed on GitHub by the Sparkle Project with the help of dozens of valued contributors.\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
|
||||
\cf0 \
|
||||
\pard\pardeftab720\qc\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://usdawatercolors.nal.usda.gov/pom/catalog.xhtml?id=POM00001916"}}{\fldrslt
|
||||
\f0\b\fs36 \cf0 \cb3 \expnd0\expndtw0\kerning0
|
||||
Icon}}
|
||||
\f0\b\fs36 \cb3 \expnd0\expndtw0\kerning0
|
||||
\
|
||||
\pard\pardeftab720\qj\partightenfactor0
|
||||
|
||||
\f1\b0\fs28 \cf0 \
|
||||
\pard\pardeftab720\qj\partightenfactor0
|
||||
\cf4 R.C. Steadman, 1921-06-01.\
|
||||
\
|
||||
U.S. Department of Agriculture Pomological Watercolor Collection. Rare and Special Collections, National Agricultural Library, Beltsville, MD 20705}
|
199
Ample/Base.lproj/DiskImages.xib
Normal file
|
@ -0,0 +1,199 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="DiskImagesWindowController">
|
||||
<connections>
|
||||
<outlet property="arrayController" destination="YmL-8S-msS" id="Pva-sz-XFI"/>
|
||||
<outlet property="tableView" destination="cqO-ig-A9t" id="hbI-ho-WYj"/>
|
||||
<outlet property="window" destination="AtY-lA-KIp" id="aaq-cR-kq8"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="stE-9g-lJ2" customClass="BookmarkManagerProxy"/>
|
||||
<arrayController mode="entity" entityName="DiskImage" automaticallyPreparesContent="YES" avoidsEmptySelection="NO" automaticallyRearrangesObjects="YES" id="YmL-8S-msS">
|
||||
<connections>
|
||||
<binding destination="stE-9g-lJ2" name="managedObjectContext" keyPath="managedObjectContext" id="GyD-kH-DBa"/>
|
||||
</connections>
|
||||
</arrayController>
|
||||
<menu id="bCS-1z-UOZ">
|
||||
<items>
|
||||
<menuItem title="Show in Finder" tag="1" id="roc-SG-geJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="showInFinder:" target="-2" id="ViY-7R-MNV"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Eject" tag="2" id="eJ1-Kd-hnR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="eject:" target="-2" id="c6U-xB-EnM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="22a-3e-eaK"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-667" y="170"/>
|
||||
</menu>
|
||||
<window title="Recent Disk Images" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="RecentDiskImagesWindow" animationBehavior="default" id="AtY-lA-KIp">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="283" y="305" width="408" height="270"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||
<view key="contentView" id="zHI-2R-bOe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="408" height="270"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a3G-Wf-K8I">
|
||||
<rect key="frame" x="-1" y="-1" width="410" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" id="SFr-s6-6di">
|
||||
<rect key="frame" x="1" y="1" width="408" height="270"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="iwP-JL-O3g" viewBased="YES" id="cqO-ig-A9t">
|
||||
<rect key="frame" x="0.0" y="0.0" width="408" height="245"/>
|
||||
<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 width="300" minWidth="40" maxWidth="1000" id="k9E-Si-iTY">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Name">
|
||||
<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="trJ-af-d0b">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="caseInsensitiveCompare:" sortKey="name"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="2Ic-UI-Je3">
|
||||
<rect key="frame" x="1" y="1" width="305" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gkM-KB-x76">
|
||||
<rect key="frame" x="0.0" y="0.0" width="305" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="PitchDark.2mg" id="Wcg-zo-CeN">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="2Ic-UI-Je3" name="value" keyPath="objectValue.name" id="FAu-HR-0jF"/>
|
||||
<binding destination="2Ic-UI-Je3" name="toolTip" keyPath="objectValue.path" id="0MM-sv-mET"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="gkM-KB-x76" id="tpG-TS-sXI"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn width="93" minWidth="40" maxWidth="1000" id="0aJ-xJ-YSS">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Size">
|
||||
<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="jRd-9Y-U6W">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="size"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="UW9-AF-U9F">
|
||||
<rect key="frame" x="309" y="1" width="97" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6Ry-Zn-euh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="97" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="32 MB" id="fXp-OZ-Qcu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="UW9-AF-U9F" name="value" keyPath="objectValue.size" id="Hca-7L-QN7">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">FileSizeTransformer</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="6Ry-Zn-euh" id="vUm-0h-5qV"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action trigger="doubleAction" selector="doubleClick:" target="-2" id="wdp-Ek-Olo"/>
|
||||
<binding destination="YmL-8S-msS" name="content" keyPath="arrangedObjects" id="v56-YR-Qve"/>
|
||||
<binding destination="YmL-8S-msS" name="sortDescriptors" keyPath="sortDescriptors" previousBinding="v56-YR-Qve" id="BGa-9c-RdD"/>
|
||||
<outlet property="dataSource" destination="-2" id="gCn-sa-fuX"/>
|
||||
<outlet property="delegate" destination="-2" id="VHT-aS-4iS"/>
|
||||
<outlet property="menu" destination="bCS-1z-UOZ" id="a2u-hd-hPS"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="Z7O-AK-X5q">
|
||||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="OLa-ra-vIN">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<tableHeaderView key="headerView" id="iwP-JL-O3g">
|
||||
<rect key="frame" x="0.0" y="0.0" width="408" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
<toolbar key="toolbar" implicitIdentifier="D9701924-6955-47B8-A2FF-DBD466AAEB92" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconOnly" sizeMode="regular" id="Gp6-Kl-lr2">
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="lBE-ee-rCy"/>
|
||||
<toolbarItem implicitItemIdentifier="C346E56F-4480-4D8A-8485-33A3A51D7B78" label="" paletteLabel="Filter" sizingBehavior="auto" id="DsU-uu-UmZ">
|
||||
<nil key="toolTip"/>
|
||||
<searchField key="view" wantsLayer="YES" verticalHuggingPriority="750" textCompletion="NO" id="qHV-IA-ysc">
|
||||
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" continuous="YES" borderStyle="bezel" placeholderString="Filter" usesSingleLineMode="YES" bezelStyle="round" id="BWo-eC-ahz">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</searchFieldCell>
|
||||
<connections>
|
||||
<action selector="filter:" target="-2" id="KhW-DS-b8s"/>
|
||||
</connections>
|
||||
</searchField>
|
||||
</toolbarItem>
|
||||
</allowedToolbarItems>
|
||||
<defaultToolbarItems>
|
||||
<toolbarItem reference="lBE-ee-rCy"/>
|
||||
<toolbarItem reference="lBE-ee-rCy"/>
|
||||
<toolbarItem reference="DsU-uu-UmZ"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<point key="canvasLocation" x="-196" y="513"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -8,53 +8,42 @@
|
|||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="DownloadWindowController">
|
||||
<connections>
|
||||
<outlet property="allFilterButton" destination="Kgj-LP-FsF" id="yub-s9-RVW"/>
|
||||
<outlet property="arrayController" destination="jhO-4z-Qwt" id="GHu-xb-4zU"/>
|
||||
<outlet property="downloadField" destination="sJz-So-jbA" id="WjK-48-FcE"/>
|
||||
<outlet property="formatButton" destination="2Rg-eX-DUq" id="oYo-MG-Sc6"/>
|
||||
<outlet property="missingFilterButton" destination="6c7-tU-3F3" id="89Y-wQ-9pB"/>
|
||||
<outlet property="tableView" destination="FLX-Wt-y53" id="a4O-pk-EAt"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="ROMs" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<window title="ROMs" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="DownloadManagerWindow" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="400" height="500"/>
|
||||
<rect key="contentRect" x="196" y="240" width="454" height="575"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<value key="minSize" type="size" width="300" height="300"/>
|
||||
<value key="minSize" type="size" width="454" height="300"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="500"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="454" height="575"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rg5-Qf-4Mw">
|
||||
<rect key="frame" x="324" y="19" width="56" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="i6Z-OM-lqE">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent">.</string>
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.active" id="mBP-8S-yGB"/>
|
||||
</connections>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="cancelAll:" target="-2" id="ycl-eJ-ByB"/>
|
||||
</connections>
|
||||
</button>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CMD-nT-mEa">
|
||||
<rect key="frame" x="0.0" y="58" width="402" height="443"/>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="51" horizontalPageScroll="10" verticalLineScroll="51" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CMD-nT-mEa">
|
||||
<rect key="frame" x="0.0" y="130" width="456" height="446"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="Igp-aH-flp">
|
||||
<rect key="frame" x="1" y="1" width="400" height="441"/>
|
||||
<rect key="frame" x="1" y="1" width="454" height="444"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="FLX-Wt-y53">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="441"/>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="49" rowSizeStyle="automatic" viewBased="YES" id="FLX-Wt-y53">
|
||||
<rect key="frame" x="0.0" y="0.0" width="454" height="444"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableViewGridLines key="gridStyleMask" dashed="YES"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="397" minWidth="40" maxWidth="1000" id="5jP-bY-fhI">
|
||||
<tableColumn width="451" minWidth="40" maxWidth="1000" id="5jP-bY-fhI">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -67,63 +56,69 @@
|
|||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="Cell" focusRingType="none" id="aBv-F5-XWo">
|
||||
<rect key="frame" x="1" y="1" width="397" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pWm-hb-BXB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="397" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="p71-gJ-vFV">
|
||||
<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>
|
||||
<connections>
|
||||
<outlet property="textField" destination="pWm-hb-BXB" id="NNG-rj-AAQ"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="DownloadCell" focusRingType="none" id="onK-6l-2iV" customClass="DownloadTableCellView">
|
||||
<rect key="frame" x="1" y="20" width="397" height="49"/>
|
||||
<tableCellView focusRingType="none" id="onK-6l-2iV">
|
||||
<rect key="frame" x="1" y="1" width="451" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="A44-us-TEl">
|
||||
<rect key="frame" x="25" y="28" width="371" height="17"/>
|
||||
<rect key="frame" x="41" y="28" width="409" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="NSU-6I-nsG">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="onK-6l-2iV" name="value" keyPath="objectValue.name" id="t1L-kM-AW6">
|
||||
<dictionary key="options">
|
||||
<string key="NSMultipleValuesPlaceholder">multiple</string>
|
||||
<string key="NSNoSelectionPlaceholder">no selection</string>
|
||||
<string key="NSNotApplicablePlaceholder">n/a</string>
|
||||
<string key="NSNullPlaceholder">null</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
<binding destination="onK-6l-2iV" name="textColor" keyPath="objectValue.titleColor" id="0Qx-rz-DEZ"/>
|
||||
<binding destination="onK-6l-2iV" name="toolTip" keyPath="objectValue.value" id="rUb-Jb-KbT"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="jBN-UJ-tWi">
|
||||
<rect key="frame" x="3" y="29" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</progressIndicator>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hfu-hP-QAH">
|
||||
<rect key="frame" x="25" y="3" width="371" height="17"/>
|
||||
<rect key="frame" x="41" y="3" width="409" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="1cQ-Zh-q0o">
|
||||
<font key="font" metaFont="system"/>
|
||||
<font key="font" metaFont="system" size="10"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="onK-6l-2iV" name="textColor" keyPath="objectValue.descriptionColor" id="KVi-3N-Swm"/>
|
||||
<binding destination="onK-6l-2iV" name="value" keyPath="objectValue.statusDescription" id="yV1-5r-YDh"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="jBN-UJ-tWi">
|
||||
<rect key="frame" x="3" y="9" width="32" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<connections>
|
||||
<binding destination="onK-6l-2iV" name="animate" keyPath="objectValue.task" id="d22-JL-3Z7">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNotNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</progressIndicator>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="activity" destination="jBN-UJ-tWi" id="ZwD-yU-Vne"/>
|
||||
<outlet property="statusTextField" destination="hfu-hP-QAH" id="8Hv-BB-kYA"/>
|
||||
<outlet property="textField" destination="A44-us-TEl" id="Ta5-nd-ed1"/>
|
||||
<outlet property="textField" destination="A44-us-TEl" id="ude-er-Gm4"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
<connections>
|
||||
<binding destination="jhO-4z-Qwt" name="value" keyPath="arrangedObjects.selection" id="KQP-Xo-Fbf"/>
|
||||
</connections>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-2" id="Ghf-k9-bRK"/>
|
||||
<outlet property="delegate" destination="-2" id="rpR-0W-4Nu"/>
|
||||
<action trigger="doubleAction" selector="doubleClick:" target="-2" id="y2y-h7-cfD"/>
|
||||
<binding destination="jhO-4z-Qwt" name="content" keyPath="arrangedObjects" id="2av-gV-V4K"/>
|
||||
<outlet property="menu" destination="RJM-21-hjO" id="xpL-0n-1jm"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
|
@ -139,10 +134,22 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sJz-So-jbA">
|
||||
<rect key="frame" x="51" y="101" width="383" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="HKe-di-YSs">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="downloadURLChanged:" target="-2" id="ah1-QS-G27"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Fhd-vr-Q2G">
|
||||
<rect key="frame" x="20" y="19" width="124" height="23"/>
|
||||
<rect key="frame" x="208" y="13" width="150" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Download Missing" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AKx-eg-iLS">
|
||||
<buttonCell key="cell" type="push" title="Download Missing" bezelStyle="rounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AKx-eg-iLS">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
|
@ -155,12 +162,134 @@
|
|||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d2z-4T-Wh1">
|
||||
<rect key="frame" x="10" y="104" width="30" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="URL" id="lcZ-R4-WsS">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZXO-bJ-btp">
|
||||
<rect key="frame" x="10" y="66" width="34" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Type" id="KGI-t9-OMF">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="AuM-pD-Gul">
|
||||
<rect key="frame" x="12" y="52" width="422" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dpY-qZ-2Nk">
|
||||
<rect key="frame" x="93" y="13" width="115" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="ROMs" bezelStyle="rounded" image="NSFolder" imagePosition="left" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="E0t-sX-rgE">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="showRomFolder:" target="-2" id="bys-Vs-b4m"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Lnv-mh-zAr">
|
||||
<rect key="frame" x="6" y="13" width="87" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Refresh" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mYS-h7-GUa">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent">r</string>
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="refreshROMs:" target="-2" id="E7j-Fa-IN1"/>
|
||||
</connections>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Rg-eX-DUq">
|
||||
<rect key="frame" x="49" y="60" width="98" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="zip" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" selectedItem="7Cq-Lh-dgg" id="uum-dC-XD0">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" autoenablesItems="NO" id="kcg-aZ-mD9">
|
||||
<items>
|
||||
<menuItem title="zip" state="on" tag="1" id="7Cq-Lh-dgg"/>
|
||||
<menuItem title="7z" tag="2" id="s5r-gg-Ma9"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="downloadExtensionChanged:" target="-2" id="tp2-tg-bms"/>
|
||||
<binding destination="-2" name="selectedTag" keyPath="self.downloadExtension" id="uck-nA-UPg">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">DownloadExtensionTransformer</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rg5-Qf-4Mw">
|
||||
<rect key="frame" x="358" y="13" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="i6Z-OM-lqE">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent">.</string>
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.active" id="mBP-8S-yGB"/>
|
||||
</connections>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="cancelAll:" target="-2" id="ycl-eJ-ByB"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<toolbar key="toolbar" implicitIdentifier="B60021E6-BFBC-44E6-97DC-120AA9FD3269" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconOnly" sizeMode="regular" id="kpz-W4-xgh">
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="tbY-ts-Irb"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="3Kc-zG-IdN"/>
|
||||
<toolbarItem implicitItemIdentifier="BD743A15-0B61-48FF-9EED-FD8D57EF8459" label="All" paletteLabel="All" tag="1" sizingBehavior="auto" id="Jj0-n8-I5a">
|
||||
<nil key="toolTip"/>
|
||||
<button key="view" verticalHuggingPriority="750" tag="1" id="Kgj-LP-FsF">
|
||||
<rect key="frame" x="0.0" y="14" width="74" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="recessed" title="All" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="9s7-S1-hW1">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="filterButton:" target="-2" id="gTc-Ul-FYR"/>
|
||||
</connections>
|
||||
</button>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="5B013840-E582-4568-8448-DDD7EE1E5AE2" label="Missing" paletteLabel="Missing" tag="2" sizingBehavior="auto" id="GV4-aX-5Ox">
|
||||
<nil key="toolTip"/>
|
||||
<button key="view" verticalHuggingPriority="750" tag="2" id="6c7-tU-3F3">
|
||||
<rect key="frame" x="0.0" y="14" width="74" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="recessed" title="Missing" bezelStyle="recessed" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ui2-dz-IZj">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="filterButton:" target="-2" id="R6W-hU-oqL"/>
|
||||
</connections>
|
||||
</button>
|
||||
</toolbarItem>
|
||||
</allowedToolbarItems>
|
||||
<defaultToolbarItems>
|
||||
<toolbarItem reference="Jj0-n8-I5a"/>
|
||||
<toolbarItem reference="GV4-aX-5Ox"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="142" y="179"/>
|
||||
<point key="canvasLocation" x="59" y="119.5"/>
|
||||
</window>
|
||||
<menu id="RJM-21-hjO">
|
||||
<items>
|
||||
|
@ -170,6 +299,12 @@
|
|||
<action selector="showInFinder:" target="-2" id="ltL-yL-7EP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Move to Trash" id="x1Q-OF-5hM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="moveToTrash:" target="-2" id="swr-yf-hA2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Download" tag="2" id="ree-Zg-jYB">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
|
@ -188,5 +323,10 @@
|
|||
</connections>
|
||||
<point key="canvasLocation" x="-348" y="164"/>
|
||||
</menu>
|
||||
<arrayController objectClassName="DownloadItem" editable="NO" preservesSelection="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" clearsFilterPredicateOnInsertion="NO" automaticallyRearrangesObjects="YES" id="jhO-4z-Qwt" customClass="DownloadItemArrayController"/>
|
||||
<userDefaultsController representsSharedInstance="YES" id="721-9N-Bma"/>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSFolder" width="32" height="32"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -8,66 +8,474 @@
|
|||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="LaunchWindowController">
|
||||
<connections>
|
||||
<outlet property="addBookmarkWindow" destination="yIt-hP-HBq" id="Qhx-WV-cg4"/>
|
||||
<outlet property="bookmarkErrorField" destination="RiJ-Xw-sgW" id="6y5-Fo-AnM"/>
|
||||
<outlet property="bookmarkTextField" destination="fAl-Vn-x1w" id="GNr-j6-BiQ"/>
|
||||
<outlet property="machineView" destination="oVt-eD-aaj" id="Q9V-Kr-6GN"/>
|
||||
<outlet property="machineViewController" destination="RgH-d9-xl8" id="DIa-h0-6y2"/>
|
||||
<outlet property="machineViewController" destination="FSD-3v-Wni" id="tXv-zJ-QO3"/>
|
||||
<outlet property="mediaController" destination="t7c-zy-czN" id="a7d-HC-TWx"/>
|
||||
<outlet property="mediaView" destination="J9O-xI-P5J" id="PmZ-VC-4SN"/>
|
||||
<outlet property="slotController" destination="lyS-mc-3Tf" id="LXo-Ii-fDX"/>
|
||||
<outlet property="slotView" destination="P9d-sS-qEb" id="qlH-u0-hzq"/>
|
||||
<outlet property="softwareListControl" destination="pNl-g4-ZLh" id="U0i-R9-GLE"/>
|
||||
<outlet property="window" destination="Vze-YF-m6e" id="JUs-Eb-MW8"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Ample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="Vze-YF-m6e">
|
||||
<window title="Ample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="LaunchWindow" animationBehavior="default" id="Vze-YF-m6e">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="718" height="763"/>
|
||||
<rect key="contentRect" x="335" y="390" width="1000" height="640"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="Ssv-Jw-EE0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="718" height="763"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="1000" height="640"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oVt-eD-aaj">
|
||||
<rect key="frame" x="0.0" y="563" width="718" height="200"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<customView id="P9d-sS-qEb" customClass="FlippedView">
|
||||
<rect key="frame" x="302" y="105" width="326" height="363"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zVI-uU-muo">
|
||||
<rect key="frame" x="18" y="102" width="71" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Window" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="vx1-I7-8kN">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<tabView initialItem="zUN-Qs-haG" id="l8R-bg-6Zm">
|
||||
<rect key="frame" x="295" y="466" width="692" height="160"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem label="Video" identifier="" id="zUN-Qs-haG">
|
||||
<view key="view" id="QQT-HS-xjI">
|
||||
<rect key="frame" x="10" y="33" width="672" height="114"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pD8-dV-ijg">
|
||||
<rect key="frame" x="143" y="87" width="172" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Default" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="g0W-Ka-7bb" id="ceP-aK-me8">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="ajo-1k-sbD">
|
||||
<items>
|
||||
<menuItem title="Default" state="on" id="g0W-Ka-7bb"/>
|
||||
<menuItem title="Metal" tag="1" id="93g-cb-opl"/>
|
||||
<menuItem title="OpenGL" tag="2" id="B1R-9E-dMw"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameBGFX" id="ZuQ-OY-TrP"/>
|
||||
<binding destination="-2" name="selectedIndex" keyPath="self.mameBackend" id="oE1-Ho-H22"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qGO-Pm-SD1">
|
||||
<rect key="frame" x="79" y="92" width="60" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Backend:" id="WDr-Pl-lV1">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ctE-fX-twN">
|
||||
<rect key="frame" x="318" y="92" width="51" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Effects:" id="Sqk-7k-PxQ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="826-p8-in8">
|
||||
<rect key="frame" x="15" y="91" width="57" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="BGFX" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Ubs-KZ-mpu">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameBGFX" id="9Ua-MZ-qbe"/>
|
||||
</connections>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hM8-FM-Agh">
|
||||
<rect key="frame" x="382" y="87" width="174" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Default" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Dsm-bi-Txy" id="mBS-h4-BWC">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="WdF-Hw-YI9">
|
||||
<items>
|
||||
<menuItem title="Default" state="on" id="Dsm-bi-Txy">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Unfiltered" tag="1" id="xgz-We-TFg">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="HLSL" tag="2" id="1UE-ea-V9a">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="CRT Geometry" tag="3" id="Dsx-wI-m3r">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="CRT Geometry Deluxe" tag="4" id="Ylw-Of-TM5">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="LCD Grid" tag="5" id="A6k-ku-z2M">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Fighters" id="1aA-ge-f8R">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameBGFX" id="DVB-Ex-VYF"/>
|
||||
<binding destination="-2" name="selectedIndex" keyPath="self.mameEffects" id="rCg-d6-OR6"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D5h-dm-fuZ">
|
||||
<rect key="frame" x="318" y="60" width="104" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Square Pixels" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="yWK-BP-7Z9">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameSquarePixels" id="BiP-wC-Hpn"/>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameWindowMode" id="X80-2K-kTO"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6gd-45-eLr">
|
||||
<rect key="frame" x="15" y="60" width="94" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Window Mode:" id="l8n-CI-o4t">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sei-LG-VM6">
|
||||
<rect key="frame" x="143" y="55" width="172" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Full Screen" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="0zZ-Ib-Fne" id="lsw-Vk-WcZ">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="m4N-Qw-mem">
|
||||
<items>
|
||||
<menuItem title="Full Screen" state="on" id="0zZ-Ib-Fne">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Window 1x" id="3bZ-rq-fCt">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Window 2x" id="KA4-Rs-yyK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Window 3x" id="Dbh-Js-pMx" userLabel="Window 3x">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Window 4x" id="GCs-En-3Jv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="selectedIndex" keyPath="self.mameWindowMode" id="B9e-SK-3RY"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" id="9Db-wA-FP9">
|
||||
<rect key="frame" x="15" y="29" width="115" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Capture Mouse" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="3xh-Q7-WFl">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameMouse" id="vWu-od-2d6"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XNa-8k-X89">
|
||||
<rect key="frame" x="143" y="29" width="137" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Disk Sound Effects" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="MBT-Uv-Lev">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameSamples" id="77G-8C-HgT"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="CPU" identifier="" id="nr5-4o-DyG">
|
||||
<view key="view" id="ElY-YI-LLI">
|
||||
<rect key="frame" x="10" y="33" width="672" height="114"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZUp-ni-Rr6">
|
||||
<rect key="frame" x="15" y="60" width="62" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Debug" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="6is-QN-JEc">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameDebug" id="vkc-sR-KnB"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PGK-yK-2ZK">
|
||||
<rect key="frame" x="15" y="91" width="43" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Speed" id="D9w-Mz-PXs">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FE4-gG-fPb">
|
||||
<rect key="frame" x="62" y="86" width="109" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="100%" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="proportionallyDown" inset="2" selectedItem="yoI-Ra-evu" id="M40-f0-awc">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="8Tv-0j-JhQ">
|
||||
<items>
|
||||
<menuItem title="100%" state="on" tag="1" id="yoI-Ra-evu"/>
|
||||
<menuItem title="200%" tag="2" id="UqT-yd-8o3"/>
|
||||
<menuItem title="300%" tag="3" id="awG-S1-uM4"/>
|
||||
<menuItem title="400%" tag="4" id="qJ5-Ed-W5U"/>
|
||||
<menuItem title="500%" tag="5" id="Phc-uW-Qog"/>
|
||||
<menuItem title="No Throttle" tag="-1" id="gAc-ME-eim"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="selectedTag" keyPath="self.mameSpeed" id="nFG-yA-KC1"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="knB-Rn-1Cm">
|
||||
<rect key="frame" x="15" y="40" width="67" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Rewind" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Y7b-jN-HCc">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameRewind" id="Hw5-n7-O27"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="A/V" identifier="" id="0T5-BN-lxE">
|
||||
<view key="view" id="knw-WE-UU3">
|
||||
<rect key="frame" x="10" y="33" width="672" height="114"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vWt-Dx-OGG">
|
||||
<rect key="frame" x="15" y="91" width="102" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Generate AVI" bezelStyle="regularSquare" imagePosition="left" inset="2" id="hRp-Lh-Ebr">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameAVI" id="G1O-YP-DXa"/>
|
||||
</connections>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ejn-wC-UXH">
|
||||
<rect key="frame" x="15" y="60" width="110" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Generate WAV" bezelStyle="regularSquare" imagePosition="left" inset="2" id="7Aa-N2-MHn">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameWAV" id="4r0-ZQ-nNC"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Yf-ZJ-8kx">
|
||||
<rect key="frame" x="132" y="59" width="523" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="/path/to/file.wav" drawsBackground="YES" usesSingleLineMode="YES" id="Xqc-zw-28b">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameWAV" id="lZM-6n-jAS"/>
|
||||
<binding destination="-2" name="value" keyPath="self.mameWAVPath" id="475-s3-0e4">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">/path/to/file.wav</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ne8-5I-D1H">
|
||||
<rect key="frame" x="132" y="28" width="523" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="/path/to/file.vgm" drawsBackground="YES" usesSingleLineMode="YES" id="xGs-Mi-wzj">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameVGM" id="TJV-4j-uVi"/>
|
||||
<binding destination="-2" name="value" keyPath="self.mameVGMPath" id="aK1-2A-QWB">
|
||||
<dictionary key="options">
|
||||
<string key="NSNoSelectionPlaceholder">/path/to/file.vgm</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameVGM" id="JZX-dA-3Bn"/>
|
||||
<binding destination="-2" name="value" keyPath="self.mameVGMPath" id="m7G-a0-QDZ">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">/path/to/file.vgm</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Xht-PS-Hw8">
|
||||
<rect key="frame" x="132" y="90" width="523" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="/path/to/file.avi" drawsBackground="YES" usesSingleLineMode="YES" id="iY4-FF-x2e">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameAVI" id="o4R-KR-zVV"/>
|
||||
<binding destination="-2" name="value" keyPath="self.mameAVIPath" id="dSK-1u-lh6">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">/path/to/file.avi</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YVz-a3-9Pj">
|
||||
<rect key="frame" x="15" y="29" width="111" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Generate VGM" bezelStyle="regularSquare" imagePosition="left" inset="2" id="F9b-kg-ZMV">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameVGM" id="Oyp-Pc-Uad"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Paths" identifier="" id="PVN-Iw-nYG">
|
||||
<view key="view" id="5qP-bQ-Id6">
|
||||
<rect key="frame" x="10" y="33" width="672" height="114"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VDW-FX-9az">
|
||||
<rect key="frame" x="132" y="90" width="523" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="/path/to/directory/" drawsBackground="YES" usesSingleLineMode="YES" id="ykl-aj-n1L">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="enabled" keyPath="self.mameShareDirectory" id="bPv-hU-XgK"/>
|
||||
<binding destination="-2" name="value" keyPath="self.mameShareDirectoryPath" id="ddj-BN-tsY">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">/path/to/directory/</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1fA-nr-wns">
|
||||
<rect key="frame" x="15" y="91" width="117" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Share Directory" bezelStyle="regularSquare" imagePosition="left" inset="2" id="xmA-1v-wU7">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameShareDirectory" id="x3D-ho-u4v"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
</tabViewItems>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameWindow" id="uS7-cg-wqb"/>
|
||||
<binding destination="-2" name="hidden" keyPath="machine" id="odt-eJ-VrX">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZUp-ni-Rr6">
|
||||
<rect key="frame" x="18" y="82" width="62" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Debug" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="6is-QN-JEc">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameDebug" id="vkc-sR-KnB"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pKK-yY-vnY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="718" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="bk2-0p-jUj">
|
||||
</tabView>
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="J9O-xI-P5J" customClass="FlippedView">
|
||||
<rect key="frame" x="654" y="107" width="326" height="331"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" id="2ue-XT-byh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1001" height="69"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="eSY-AU-tvi">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1001" height="69"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView focusRingType="none" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" allowsCharacterPickerTouchBarItem="NO" textCompletion="NO" id="c0R-8x-RL2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1001" height="69"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="minSize" width="1001" height="69"/>
|
||||
<size key="maxSize" width="1001" height="10000000"/>
|
||||
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.commandLine" id="deQ-gK-fgu">
|
||||
<dictionary key="options">
|
||||
<bool key="NSConditionallySetsEditable" value="NO"/>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="qto-12-JOq">
|
||||
<rect key="frame" x="-100" y="-100" width="225" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="FPs-uz-0v2">
|
||||
<rect key="frame" x="703" y="0.0" width="15" height="51"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<searchField wantsLayer="YES" verticalHuggingPriority="750" textCompletion="NO" id="pNl-g4-ZLh" customClass="AutocompleteControl">
|
||||
<rect key="frame" x="654" y="446" width="326" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Software List" usesSingleLineMode="YES" bezelStyle="round" id="sMi-a3-XEn">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<color key="backgroundColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
||||
</searchFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.commandLine" id="9gW-Y2-kvp"/>
|
||||
<action selector="softwareChanged:" target="-2" id="879-da-UEc"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</searchField>
|
||||
<customView id="oVt-eD-aaj" customClass="FlippedView">
|
||||
<rect key="frame" x="0.0" y="69" width="294" height="571"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="UwI-q9-hEm">
|
||||
<rect key="frame" x="0.0" y="67" width="1000" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<box horizontalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="xjH-Gv-MHt">
|
||||
<rect key="frame" x="291" y="69" width="5" height="571"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nKp-px-nHg">
|
||||
<rect key="frame" x="587" y="58" width="111" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<rect key="frame" x="869.5" y="76" width="111" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Launch" bezelStyle="texturedRounded" image="NSAppleMenuImage" imagePosition="left" alignment="center" borderStyle="border" inset="2" id="Ct1-Rb-7uI">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -78,69 +486,187 @@ DQ
|
|||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="launchAction:" target="-2" id="a4d-zv-1CU"/>
|
||||
<binding destination="-2" name="hidden" keyPath="machine" id="8Ks-FY-Tmk">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rLP-n2-0eY">
|
||||
<rect key="frame" x="18" y="62" width="91" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="No Throttle" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="NyE-jT-WqC">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameNoThrottle" id="tUN-EX-7PF"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D5h-dm-fuZ">
|
||||
<rect key="frame" x="131" y="102" width="104" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Square Pixels" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="yWK-BP-7Z9">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameSquarePixels" id="BiP-wC-Hpn"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zoQ-mU-ARl">
|
||||
<rect key="frame" x="261" y="102" width="67" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="No Blur" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="r3s-5h-Xv5">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.mameNoBlur" id="Pvn-zw-OsQ"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nNO-3T-OAy">
|
||||
<rect key="frame" x="470" y="58" width="109" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Reset Slots" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Uii-5h-2R2">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent">r</string>
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="resetSlots:" target="lyS-mc-3Tf" id="1qi-N0-Q8B"/>
|
||||
</connections>
|
||||
</button>
|
||||
<customView id="P9d-sS-qEb" customClass="FlippedView">
|
||||
<rect key="frame" x="20" y="155" width="306" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="J9O-xI-P5J" customClass="FlippedView">
|
||||
<rect key="frame" x="392" y="155" width="306" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="769" y="104.5"/>
|
||||
<toolbar key="toolbar" implicitIdentifier="ACA8EE70-5505-4CFD-9F78-7A480D93260B" autosavesConfiguration="NO" allowsUserCustomization="NO" prefersToBeShown="NO" displayMode="iconAndLabel" sizeMode="regular" id="b3J-Bx-3nk">
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarShowColorsItem" id="uHd-dY-alN"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarShowFontsItem" id="WEM-Gw-Utx"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarPrintItem" id="RCG-fn-6Ue"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="BRc-Qf-FCk"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="Dtt-KT-5NO"/>
|
||||
</allowedToolbarItems>
|
||||
<defaultToolbarItems/>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<outlet property="menu" destination="Aa5-Sk-gZX" id="Sj0-0o-oZb"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="590" y="40"/>
|
||||
</window>
|
||||
<viewController title="Media View" nibName="MediaView" id="t7c-zy-czN" customClass="MediaViewController"/>
|
||||
<viewController title="Slot View" nibName="SlotView" id="lyS-mc-3Tf" customClass="SlotViewController"/>
|
||||
<customObject id="RgH-d9-xl8" customClass="MachineViewController"/>
|
||||
<window title="Add Bookmark" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="yIt-hP-HBq">
|
||||
<windowStyleMask key="styleMask" titled="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="462" height="116"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" wantsLayer="YES" id="WVd-g4-Tbl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="462" height="116"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Gho-Xy-rn4">
|
||||
<rect key="frame" x="358" y="13" width="90" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Vxo-rD-aMe">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="bookmarkSave:" target="-2" id="wLF-LE-5RO"/>
|
||||
<binding destination="-2" name="enabled" keyPath="bookmarkName" id="U5R-gU-1bE">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">StringNotEmptyTransformer</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3sv-Kd-Ep5">
|
||||
<rect key="frame" x="268" y="13" width="90" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="jaa-RY-PAg">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="bookmarkCancel:" target="-2" id="uWM-vs-hz7"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1fO-x7-Gft">
|
||||
<rect key="frame" x="18" y="80" width="103" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Add Bookmark…" id="AZS-JR-SNt">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fAl-Vn-x1w">
|
||||
<rect key="frame" x="20" y="49" width="422" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="bookmark name" drawsBackground="YES" id="Enq-2z-cle">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="bookmarkName" id="84v-el-4Uk">
|
||||
<dictionary key="options">
|
||||
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
|
||||
<string key="NSNullPlaceholder">bookmark name</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RiJ-Xw-sgW">
|
||||
<rect key="frame" x="20" y="20" width="248" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Ehz-4Z-Tjq">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EFq-dZ-y90">
|
||||
<rect key="frame" x="378" y="79" width="66" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Default" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="cOs-WH-9Dr">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="bookmarkDefault" id="Oiv-hR-5fn"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-62" y="95"/>
|
||||
</window>
|
||||
<viewController nibName="MachineView" id="FSD-3v-Wni" customClass="NewMachineViewController"/>
|
||||
<menu id="Aa5-Sk-gZX">
|
||||
<items>
|
||||
<menuItem title="Launch" image="NSAppleMenuImage" id="OSH-7C-D6z">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="launchAction:" target="-2" id="ZY2-He-VyK"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Iti-F9-p35"/>
|
||||
<menuItem title="List Media…" id="M5h-4W-0nV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="listMedia:" target="-2" id="IO7-MG-zud"/>
|
||||
<binding destination="-2" name="hidden" keyPath="optionKey" id="LhL-2l-iss">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSNegateBoolean</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="List Slots…" id="cNj-Sb-KkE">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="listSlots:" target="-2" id="3nb-mV-eUK"/>
|
||||
<binding destination="-2" name="hidden" keyPath="optionKey" id="dwp-Kn-LfC">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSNegateBoolean</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="yZx-W2-lZg"/>
|
||||
<menuItem title="Reset All" id="PQ0-yO-SKz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="resetAll:" target="-2" id="hF5-fl-bMr"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Reset Machine" id="1by-3B-LSd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="resetMachine:" target="-2" id="7au-OM-Q88"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Reset Slots" id="ccx-xm-qeo">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="resetSlots:" target="lyS-mc-3Tf" id="39K-rS-u9D"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Reset Media" id="Opr-7k-fO1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="resetMedia:" target="-2" id="n5j-1R-NJl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="wqC-IG-63F"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-121" y="-2"/>
|
||||
</menu>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSAppleMenuImage" width="11" height="14"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="270"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hj3-ou-djb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="270"/>
|
||||
|
@ -52,10 +52,31 @@
|
|||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
<toolbar key="toolbar" implicitIdentifier="54C242E0-0A7F-491A-9B83-7279A9663A36" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconOnly" sizeMode="small" id="Cik-bA-ZYu">
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarShowColorsItem" id="zxC-EA-a7F"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarShowFontsItem" id="xZv-cQ-rPS"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarPrintItem" id="2BZ-oP-sMg"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="j5G-hW-61a"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="a72-iv-2QT"/>
|
||||
<toolbarItem implicitItemIdentifier="21A9965C-D1B3-4E82-A344-1688A467E870" label="Clear Log" paletteLabel="Clear Log" tag="-1" image="NSTrashEmpty" id="pn5-MM-9p1">
|
||||
<connections>
|
||||
<action selector="clearLog:" target="-2" id="VU3-mv-6WR"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
</allowedToolbarItems>
|
||||
<defaultToolbarItems>
|
||||
<toolbarItem reference="a72-iv-2QT"/>
|
||||
<toolbarItem reference="pn5-MM-9p1"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-285" y="-234"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSTrashEmpty" width="32" height="32"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
109
Ample/Base.lproj/MachineView.xib
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NewMachineViewController">
|
||||
<connections>
|
||||
<outlet property="outlineView" destination="9V6-He-b8A" id="XeC-DJ-oXY"/>
|
||||
<outlet property="view" destination="t3T-qF-D0e" id="Svb-w7-hs9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" id="t3T-qF-D0e">
|
||||
<rect key="frame" x="0.0" y="0.0" width="274" height="543"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" drawsBackground="NO" id="DyG-qq-uBF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="274" height="543"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" autosaveName="machine-view" rowHeight="24" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" autosaveExpandedItems="YES" outlineTableColumn="e67-js-boV" id="9V6-He-b8A">
|
||||
<rect key="frame" x="0.0" y="0.0" width="274" height="543"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="271" minWidth="16" maxWidth="1000" id="e67-js-boV">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<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="jZU-xV-PI4">
|
||||
<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="HeaderCell" id="2iF-4F-HfC">
|
||||
<rect key="frame" x="1" y="1" width="271" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9tU-X8-FZn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="271" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="HEADER CELL" id="EUi-TS-vlq">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="2iF-4F-HfC" name="value" keyPath="objectValue.description" id="He3-9c-g9A"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="9tU-X8-FZn" id="p2B-eV-6bS"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="DataCell" id="7b4-T1-d29">
|
||||
<rect key="frame" x="1" y="20" width="271" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FkS-zP-pRB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="271" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="g6t-E7-0lM">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="7b4-T1-d29" name="value" keyPath="objectValue.description" id="kp8-ww-1aE"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="FkS-zP-pRB" id="JkE-pr-7px"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action selector="clickAction:" target="-2" id="O3p-cV-gwk"/>
|
||||
<outlet property="dataSource" destination="-2" id="nW2-qs-3w6"/>
|
||||
<outlet property="delegate" destination="-2" id="4Wc-Pe-v81"/>
|
||||
</connections>
|
||||
</outlineView>
|
||||
</subviews>
|
||||
<nil key="backgroundColor"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="kig-a5-Ay0">
|
||||
<rect key="frame" x="-100" y="-100" width="238" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="lLp-pv-Fbj" customClass="TransparentScroller">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<point key="canvasLocation" x="-91" y="132"/>
|
||||
</scrollView>
|
||||
</objects>
|
||||
</document>
|
|
@ -13,12 +13,19 @@
|
|||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="rSq-qV-SGy" customClass="BookmarkManager">
|
||||
<connections>
|
||||
<outlet property="menu" destination="ha0-nx-PIl" id="Ozd-ID-egK"/>
|
||||
<outlet property="updateMenuItem" destination="30b-vT-HIa" id="AgZ-LE-no6"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="installWindow" destination="jWX-pY-Zpb" id="xAj-Vj-Vxn"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<customObject id="3aq-Tx-mno" customClass="SUUpdater"/>
|
||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="Ample" id="1Xt-HY-uBw">
|
||||
|
@ -31,13 +38,16 @@
|
|||
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Manage ROMs…" id="St3-qR-2Y8">
|
||||
<menuItem title="Check for Updates…" id="CPy-r4-rzr">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="downloadROMS:" target="Voe-Tx-rLC" id="jFm-nv-kRC"/>
|
||||
<action selector="checkForUpdates:" target="3aq-Tx-mno" id="qJG-Nv-0Lu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Reinstall MAME components" hidden="YES" id="c3P-WT-eUP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW">
|
||||
<connections>
|
||||
<action selector="displayPreferences:" target="Voe-Tx-rLC" id="Hsm-pX-sUc"/>
|
||||
|
@ -123,6 +133,12 @@
|
|||
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Export Shell Script…" id="LmB-h2-UBZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="exportShellScript:" target="-1" id="9eU-do-ffz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
|
@ -357,268 +373,6 @@
|
|||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
|
||||
<items>
|
||||
<menuItem title="Font" id="Gi5-1S-RQB">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="FYS-2b-JAY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
|
||||
<menuItem title="Kern" id="jBQ-r6-VK2">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="GUa-eO-cwY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="cDB-IK-hbR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="46P-cB-AYj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="ogc-rX-tC1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="o6e-r0-MWq">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="agt-UL-0e3">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="J7y-lM-qPV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="xQD-1f-W4t">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="OaQ-X3-Vso">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="3Om-Ey-2VK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="Rqc-34-cIF">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="I0S-gh-46l">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="2h7-ER-AoG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="1tx-W0-xDw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="Fal-I4-PZk">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="d9c-me-L2H">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="J5U-5w-g23">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
|
||||
<menuItem title="Writing Direction" id="H1b-Si-o9J">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="YGs-j5-SAR">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="Lbh-J2-qVU">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="jFq-tB-4Kx">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
|
||||
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="Nop-cj-93Q">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="BgM-ve-c93">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="RB4-Sm-HuC">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
|
||||
<menuItem title="Show Ruler" id="vLm-3I-IUL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
|
@ -651,6 +405,45 @@
|
|||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Bookmarks" id="vHO-2e-qJc">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Bookmarks" id="ha0-nx-PIl">
|
||||
<items>
|
||||
<menuItem title="Manage Bookmarks…" keyEquivalent="b" id="isI-q6-b1V">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="manageBookmarks:" target="-1" id="vOm-90-AoO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Add Bookmark…" keyEquivalent="d" id="1JF-xV-zmG">
|
||||
<connections>
|
||||
<action selector="addBookmark:" target="-1" id="cqp-ko-BfQ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Update Bookmark" keyEquivalent="D" id="30b-vT-HIa">
|
||||
<connections>
|
||||
<action selector="updateBookmark:" target="-1" id="Au0-Sp-cUD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Set Default" hidden="YES" id="vbR-vS-lqO">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="defaultSave:" target="-1" id="FP9-EX-OKP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gWR-Yl-mg6"/>
|
||||
<menuItem title="Default" hidden="YES" id="mXC-Lp-gem">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="defaultLoad:" target="-1" id="ErS-k6-azP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="rSq-qV-SGy" id="Z7N-CG-hU1"/>
|
||||
</connections>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
|
@ -666,6 +459,25 @@
|
|||
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kE9-em-OHN"/>
|
||||
<menuItem title="Ample Support Directory…" id="egj-hU-EtE">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="displaySupportDirectory:" target="Voe-Tx-rLC" id="XDA-Bv-9BJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Manage ROMs…" id="St3-qR-2Y8">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="displayROMS:" target="Voe-Tx-rLC" id="jFm-nv-kRC"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Recent Disk Images…" id="QY9-lF-kDy">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="displayRecentDiskImages:" target="Voe-Tx-rLC" id="9W1-nJ-8eJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
|
@ -685,6 +497,30 @@
|
|||
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MAME Keyboard Cheat Sheet" id="vcW-Dz-2Nx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="displayCheatSheet:" target="Voe-Tx-rLC" id="HvD-mQ-4pe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MAME Apple II Wiki" id="GLh-Cc-5uU">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="mameAppleWiki:" target="Voe-Tx-rLC" id="jRe-m6-mP0"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MAME Mac 68K Wiki" id="hDL-K6-iVF">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="mameMac68kWiki:" target="Voe-Tx-rLC" id="ZzB-54-vXN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MAME Documentation" id="1IW-V0-UWA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="mameDocumentation:" target="Voe-Tx-rLC" id="K8T-nZ-c5J"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
|
@ -711,5 +547,6 @@
|
|||
</view>
|
||||
<point key="canvasLocation" x="13" y="-182"/>
|
||||
</window>
|
||||
<userDefaultsController representsSharedInstance="YES" id="uGS-pc-Wsn"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
|
@ -14,21 +14,20 @@
|
|||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="20" horizontalPageScroll="10" verticalLineScroll="20" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="nVT-kT-bWl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="306" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="IBD-wb-pch">
|
||||
<rect key="frame" x="0.0" y="0.0" width="306" height="400"/>
|
||||
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="25" horizontalPageScroll="10" verticalLineScroll="25" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="nVT-kT-bWl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="331"/>
|
||||
<clipView key="contentView" autoresizesSubviews="NO" focusRingType="none" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IBD-wb-pch">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="331"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" selectionHighlightStyle="none" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="pBj-py-R6a" id="sIz-DD-PZQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="306" height="400"/>
|
||||
<outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="none" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="22" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="pBj-py-R6a" id="sIz-DD-PZQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="331"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="2" height="3"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn editable="NO" width="304" minWidth="40" maxWidth="1000" id="pBj-py-R6a">
|
||||
<tableColumn editable="NO" width="296" minWidth="40" maxWidth="1000" id="pBj-py-R6a">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -39,75 +38,210 @@
|
|||
<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"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="e4I-r0-vWM">
|
||||
<rect key="frame" x="1" y="1" width="304" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mig-Wj-m5e">
|
||||
<rect key="frame" x="0.0" y="0.0" width="304" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="ZcN-bl-2D8">
|
||||
<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>
|
||||
<connections>
|
||||
<outlet property="textField" destination="Mig-Wj-m5e" id="FYh-hX-PTU"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="CategoryView" focusRingType="none" id="33q-UT-ur5">
|
||||
<rect key="frame" x="1" y="21" width="304" height="17"/>
|
||||
<rect key="frame" x="1" y="1" width="296" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Pep-mX-LHY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="304" height="17"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="296" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Rrg-wr-8eL">
|
||||
<font key="font" metaFont="system"/>
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="33q-UT-ur5" name="value" keyPath="objectValue.title" id="JQR-UW-ifh"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="Pep-mX-LHY" id="hUe-cf-6vq"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="ItemView" id="yGq-lc-RCM" customClass="TablePathView">
|
||||
<rect key="frame" x="1" y="41" width="304" height="27"/>
|
||||
<tableCellView identifier="ItemView" translatesAutoresizingMaskIntoConstraints="NO" id="yGq-lc-RCM" customClass="PathTableCellView">
|
||||
<rect key="frame" x="1" y="21" width="296" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<pathControl focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f7R-TO-fmF">
|
||||
<rect key="frame" x="0.0" y="1" width="251" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<rect key="frame" x="20" y="0.0" width="244" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<pathCell key="cell" controlSize="small" selectable="YES" editable="YES" focusRingType="none" alignment="left" pathStyle="popUp" id="dcz-8y-tKb">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</pathCell>
|
||||
<connections>
|
||||
<action selector="pathAction:" target="-2" id="4oX-bW-ANp"/>
|
||||
<binding destination="yGq-lc-RCM" name="value" keyPath="objectValue.url" id="Ony-ph-VVo"/>
|
||||
<binding destination="yGq-lc-RCM" name="enabled" keyPath="objectValue.valid" id="f8P-gt-vmK"/>
|
||||
</connections>
|
||||
</pathControl>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zNo-ij-mUl">
|
||||
<rect key="frame" x="256" y="5" width="23" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="NSNavEjectButton.normalSelected" imagePosition="overlaps" alignment="center" controlSize="small" imageScaling="proportionallyDown" inset="2" id="IZA-Tu-olu">
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="6g1-NT-J1w">
|
||||
<rect key="frame" x="0.0" y="1" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageAlignment="left" image="drag-handle-4x10" id="x7F-qD-5y9"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zNo-ij-mUl" customClass="EjectButton">
|
||||
<rect key="frame" x="277" y="3" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="eject-16x16" imagePosition="only" alignment="center" alternateImage="eject-hover-16x16" imageScaling="proportionallyDown" inset="2" id="IZA-Tu-olu">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="deleteAction:" target="-2" id="XAl-eQ-nUj"/>
|
||||
<action selector="ejectAction:" target="-2" id="XAl-eQ-nUj"/>
|
||||
<binding destination="yGq-lc-RCM" name="enabled" keyPath="objectValue.occupied" id="4a4-L7-ztC"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="deleteButton" destination="zNo-ij-mUl" id="9br-3c-ddI"/>
|
||||
<outlet property="dragHandle" destination="6g1-NT-J1w" id="odc-Sw-3WS"/>
|
||||
<outlet property="ejectButton" destination="zNo-ij-mUl" id="uzY-tA-5Wf"/>
|
||||
<outlet property="pathControl" destination="f7R-TO-fmF" id="oH7-N3-JC7"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="BBItemView" id="2Nq-Xz-tkV" customClass="PathTableCellView">
|
||||
<rect key="frame" x="1" y="46" width="296" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="47E-Ef-Ott">
|
||||
<rect key="frame" x="0.0" y="1" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageAlignment="left" image="drag-handle-4x10" id="vwE-Ev-NBf"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zxn-1E-o34" customClass="EjectButton">
|
||||
<rect key="frame" x="277" y="3" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="eject-16x16" imagePosition="only" alignment="center" alternateImage="eject-hover-16x16" imageScaling="proportionallyDown" inset="2" id="Os7-NH-tnx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="ejectAction:" target="-2" id="uy2-92-9La"/>
|
||||
<binding destination="2Nq-Xz-tkV" name="enabled" keyPath="objectValue.occupied" id="SNi-sQ-J2W"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pNE-yJ-EK8">
|
||||
<rect key="frame" x="20" y="0.0" width="244" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="socket.address:port or /path/to/file" drawsBackground="YES" id="h2U-ig-Cms">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="textAction:" target="-2" id="lmX-t8-mEc"/>
|
||||
<binding destination="2Nq-Xz-tkV" name="value" keyPath="objectValue.string" id="2dZ-JJ-asM">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">socket.address:port or /path/to/file</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
<binding destination="2Nq-Xz-tkV" name="enabled" keyPath="objectValue.valid" id="ZTM-E3-Y9P"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="dragHandle" destination="47E-Ef-Ott" id="bnY-rz-24V"/>
|
||||
<outlet property="ejectButton" destination="zxn-1E-o34" id="eC6-Mf-tN6"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="OutputItemView" id="jQd-Ar-5uf" customClass="PathTableCellView">
|
||||
<rect key="frame" x="1" y="71" width="296" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="Jg1-Wh-HDk">
|
||||
<rect key="frame" x="0.0" y="1" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageAlignment="left" image="drag-handle-4x10" id="SjY-iM-xSZ"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vG4-PP-efF" customClass="EjectButton">
|
||||
<rect key="frame" x="277" y="3" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="eject-16x16" imagePosition="only" alignment="center" alternateImage="eject-hover-16x16" imageScaling="proportionallyDown" inset="2" id="VX6-hb-mCU">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="ejectAction:" target="-2" id="LNr-rK-kpx"/>
|
||||
<binding destination="jQd-Ar-5uf" name="enabled" keyPath="objectValue.occupied" id="p4S-6q-dCG"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Tm9-Zq-fag">
|
||||
<rect key="frame" x="20" y="0.0" width="244" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="/path/to/file" drawsBackground="YES" id="RUQ-s4-75A">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="textAction:" target="-2" id="N7h-6y-D8W"/>
|
||||
<binding destination="jQd-Ar-5uf" name="value" keyPath="objectValue.string" id="kXU-qJ-HKa">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">/path/to/file</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
<binding destination="jQd-Ar-5uf" name="enabled" keyPath="objectValue.valid" id="1wE-NY-Vb2"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="dragHandle" destination="Jg1-Wh-HDk" id="o14-ay-0Ou"/>
|
||||
<outlet property="ejectButton" destination="vG4-PP-efF" id="X2I-2N-t5r"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="MidiItemView" id="HDi-YM-iKn" customClass="MidiTableCellView">
|
||||
<rect key="frame" x="1" y="96" width="296" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="XcO-0S-W4c">
|
||||
<rect key="frame" x="0.0" y="1" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageAlignment="left" image="drag-handle-4x10" id="4a2-So-rxD"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F3v-8Z-LaF" customClass="EjectButton">
|
||||
<rect key="frame" x="277" y="3" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="eject-16x16" imagePosition="only" alignment="center" alternateImage="eject-hover-16x16" imageScaling="proportionallyDown" inset="2" id="b3t-Zp-2si">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="ejectAction:" target="-2" id="AvU-Sz-QKJ"/>
|
||||
<binding destination="HDi-YM-iKn" name="enabled" keyPath="objectValue.occupied" id="ERy-Iz-T9Q"/>
|
||||
</connections>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="L2F-mj-lkr">
|
||||
<rect key="frame" x="20" y="-3" width="244" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="CaJ-NG-vbR" id="Rac-za-bEQ">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" id="I55-5S-oM2">
|
||||
<items>
|
||||
<menuItem state="on" id="CaJ-NG-vbR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="midiAction:" target="-2" id="LDL-4h-xUR"/>
|
||||
<binding destination="HDi-YM-iKn" name="selectedValue" keyPath="objectValue.string" id="xjL-hx-VG3">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">EmptyStringTransformer</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="dragHandle" destination="XcO-0S-W4c" id="oKY-UF-LkW"/>
|
||||
<outlet property="ejectButton" destination="F3v-8Z-LaF" id="ql8-4u-qCA"/>
|
||||
<outlet property="popUpButton" destination="L2F-mj-lkr" id="Ktx-Yc-DIp"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
|
@ -117,20 +251,27 @@
|
|||
</connections>
|
||||
</outlineView>
|
||||
</subviews>
|
||||
<nil key="backgroundColor"/>
|
||||
<color key="backgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="9Vz-lW-4GG">
|
||||
<rect key="frame" x="-100" y="-100" width="306" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="f8l-nC-KhG">
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="f8l-nC-KhG" customClass="TransparentScroller">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
|
||||
<color key="value" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</scroller>
|
||||
<point key="canvasLocation" x="-161" y="55"/>
|
||||
<point key="canvasLocation" x="-161" y="54.5"/>
|
||||
</scrollView>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSNavEjectButton.normalSelected" width="16" height="16"/>
|
||||
<image name="drag-handle-4x10" width="4" height="10"/>
|
||||
<image name="eject-16x16" width="8" height="9"/>
|
||||
<image name="eject-hover-16x16" width="16" height="16"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="PreferencesWindowController">
|
||||
<connections>
|
||||
<outlet property="fixButton" destination="kt8-xs-My0" id="GeF-Kj-q2l"/>
|
||||
<outlet property="pathField" destination="Oz5-Xb-btk" id="EnV-kr-0XI"/>
|
||||
<outlet property="wdField" destination="l8V-pC-gml" id="exX-bU-pbh"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="xJa-tx-X62"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
|
@ -24,7 +26,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Oz5-Xb-btk">
|
||||
<rect key="frame" x="98" y="181" width="362" height="21"/>
|
||||
<rect key="frame" x="138" y="159" width="322" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="vDR-2V-qxd">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
|
@ -33,21 +35,35 @@
|
|||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="pathChanged:" target="-2" id="RRj-dC-q2y"/>
|
||||
<binding destination="yvB-HG-64y" name="enabled" keyPath="values.UseCustomMame" id="iex-A9-Db6"/>
|
||||
<binding destination="yvB-HG-64y" name="value" keyPath="values.MamePath" id="H3O-1l-peo"/>
|
||||
<binding destination="yvB-HG-64y" name="enabled" keyPath="values.UseCustomMame" id="iex-A9-Db6"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qmb-Ag-Xyr">
|
||||
<rect key="frame" x="18" y="184" width="74" height="16"/>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l8V-pC-gml">
|
||||
<rect key="frame" x="138" y="128" width="322" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="wfj-GY-Qu2">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="wdChanged:" target="-2" id="g1P-8l-ZXi"/>
|
||||
<binding destination="yvB-HG-64y" name="value" keyPath="values.MameWorkingDirectory" id="Kc9-Pc-XGU"/>
|
||||
<binding destination="yvB-HG-64y" name="enabled" keyPath="values.UseCustomMame" id="DeG-OW-Gd2"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vTJ-Ez-c1R">
|
||||
<rect key="frame" x="18" y="131" width="114" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="MAME Path" id="Xcq-4g-Wlw">
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Working Directory" id="UHt-0s-zxA">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KAN-P2-ydI">
|
||||
<rect key="frame" x="96" y="234" width="217" height="18"/>
|
||||
<rect key="frame" x="136" y="212" width="217" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Close log window on normal exit" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="QMz-O0-06U">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -58,7 +74,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="j7D-jC-17Q">
|
||||
<rect key="frame" x="96" y="208" width="139" height="18"/>
|
||||
<rect key="frame" x="136" y="186" width="139" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Use Custom MAME" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="V61-mz-QFo">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -68,9 +84,40 @@
|
|||
<binding destination="yvB-HG-64y" name="value" keyPath="values.UseCustomMame" id="lH4-dm-kQC"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kt8-xs-My0">
|
||||
<rect key="frame" x="287" y="13" width="179" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Fix VMNet Permissions" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ifc-ID-wbu">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="fixPerms:" target="-2" id="0e2-yf-UgY"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qmb-Ag-Xyr">
|
||||
<rect key="frame" x="58" y="162" width="74" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="MAME Path" id="Xcq-4g-Wlw">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qT7-cc-Phc">
|
||||
<rect key="frame" x="136" y="234" width="118" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Use log window" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Adv-KH-abG">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="yvB-HG-64y" name="value" keyPath="values.UseLogWindow" id="meK-Jb-s8b"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="140" y="147"/>
|
||||
<point key="canvasLocation" x="80" y="144"/>
|
||||
</window>
|
||||
<userDefaultsController id="KVS-Ag-1un"/>
|
||||
<userDefaultsController representsSharedInstance="YES" id="yvB-HG-64y"/>
|
||||
|
|
|
@ -8,625 +8,229 @@
|
|||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="SlotViewController">
|
||||
<connections>
|
||||
<outlet property="aux_menu" destination="3kq-qn-7YR" id="wic-Ry-yAf"/>
|
||||
<outlet property="exp_menu" destination="San-wP-1ez" id="X7u-dM-xrI"/>
|
||||
<outlet property="game_menu" destination="K8G-bZ-6mZ" id="IeQ-ZT-5F6"/>
|
||||
<outlet property="modem_menu" destination="KHf-kC-BpZ" id="Qab-mA-anC"/>
|
||||
<outlet property="printer_menu" destination="sTp-en-8Wd" id="zeu-LF-6mV"/>
|
||||
<outlet property="ram_menu" destination="Yks-M5-vi0" id="h5y-Un-jYJ"/>
|
||||
<outlet property="rs232_menu" destination="6ln-U2-0Pi" id="7CT-OE-idV"/>
|
||||
<outlet property="sl0_menu" destination="Jw1-t7-YyU" id="BB5-6y-zyf"/>
|
||||
<outlet property="sl1_menu" destination="bta-RS-JT4" id="cpI-db-kzX"/>
|
||||
<outlet property="sl2_menu" destination="cDU-b1-x5a" id="WtL-Fo-Q1B"/>
|
||||
<outlet property="sl3_menu" destination="aSh-cs-0Nn" id="24o-66-LjH"/>
|
||||
<outlet property="sl4_menu" destination="kU5-cR-hPZ" id="STc-6r-nxH"/>
|
||||
<outlet property="sl5_menu" destination="8z4-8f-kLU" id="cLl-Ee-LUD"/>
|
||||
<outlet property="sl6_menu" destination="GLb-F4-PWe" id="ubk-pt-e1Q"/>
|
||||
<outlet property="sl7_menu" destination="IV2-3M-qfw" id="s5k-4G-w4r"/>
|
||||
<outlet property="view" destination="OM3-7F-wiN" id="yre-ts-aHj"/>
|
||||
<outlet property="_popover" destination="QIT-2T-wdy" id="WUB-OS-kem"/>
|
||||
<outlet property="childOutlineView" destination="uM0-Gk-crn" id="aL5-uC-O28"/>
|
||||
<outlet property="outlineView" destination="Xj3-Qf-yek" id="AWE-Rg-XUM"/>
|
||||
<outlet property="view" destination="D45-lv-6Fv" id="av3-OE-ph2"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<gridView autoresizesSubviews="NO" xPlacement="leading" yPlacement="bottom" rowAlignment="none" translatesAutoresizingMaskIntoConstraints="NO" id="OM3-7F-wiN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="306" height="534"/>
|
||||
<rows>
|
||||
<gridRow yPlacement="center" height="30" id="tHD-ui-hIL">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.ram" id="ze9-jx-lv0">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="Ccd-U2-Gx5">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl0" id="YsR-kI-yrh">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="JGU-aq-3uw">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl1" id="1io-aZ-v2G">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="gVW-Ya-phU">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl2" id="AgS-hm-ePr">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="3fP-qp-zmi">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl3" id="98U-4P-iRh">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="86u-5p-UT6">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl4" id="hsy-pm-Qjk">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="Wdg-xb-xQx">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl5" id="0QC-RB-278">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="ein-Fe-vBw">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl6" id="731-3P-DUy">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="qjB-2w-AWE">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.sl7" id="sew-Ds-4I9">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="EEX-dh-jwn">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.exp" id="EOZ-lS-QHF">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="OaZ-ZQ-gKK">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.aux" id="OlF-v7-JZx">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="wQi-Oz-7Ye">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.rs232" id="AeP-bn-blv">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="gr2-eY-995">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.gameio" id="x3I-Bd-9di">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="1xN-lm-s4l">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.printer" id="T9a-lH-z5K">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
<gridRow yPlacement="center" height="30" id="M2s-qn-SIT">
|
||||
<connections>
|
||||
<binding destination="-2" name="hidden" keyPath="machine.modem" id="PSe-R3-S3e">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</gridRow>
|
||||
</rows>
|
||||
<columns>
|
||||
<gridColumn xPlacement="fill" width="100" id="zpB-Rf-dWg"/>
|
||||
<gridColumn xPlacement="fill" width="200" id="6Vn-yh-FoQ"/>
|
||||
</columns>
|
||||
<gridCells>
|
||||
<gridCell row="tHD-ui-hIL" column="zpB-Rf-dWg" id="deJ-sv-Hb7">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nHa-QG-HjJ">
|
||||
<rect key="frame" x="-2" y="511" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="RAM:" id="CvY-8m-Ni9">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="tHD-ui-hIL" column="6Vn-yh-FoQ" id="dak-Ha-01u">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="16" translatesAutoresizingMaskIntoConstraints="NO" id="Yks-M5-vi0">
|
||||
<rect key="frame" x="104" y="506" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="92u-m2-3yN" id="XFo-KF-ueS">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="k8O-sG-Qld">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="92u-m2-3yN">
|
||||
<attributedString key="attributedTitle"/>
|
||||
</menuItem>
|
||||
<menuItem title="Item 2" id="dPG-tR-M4A"/>
|
||||
<menuItem title="Item 3" id="q2n-oZ-46s"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="27" horizontalPageScroll="10" verticalLineScroll="27" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" id="D45-lv-6Fv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="386"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" autoresizesSubviews="NO" focusRingType="none" drawsBackground="NO" copiesOnScroll="NO" id="8x1-xN-a7c">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="386"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="25" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="2" autoresizesOutlineColumn="YES" outlineTableColumn="u7T-p8-F2Z" id="Xj3-Qf-yek">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="386"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn editable="NO" width="296" minWidth="40" maxWidth="1000" id="u7T-p8-F2Z">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<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="FM7-eO-FE4">
|
||||
<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"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="MenuCell" id="1RI-9K-5qj" customClass="SlotTableCellView">
|
||||
<rect key="frame" x="1" y="1" width="296" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qIF-d4-kOf">
|
||||
<rect key="frame" x="0.0" y="5" width="90" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="RAM:" id="tIz-xZ-ZJH">
|
||||
<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>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zQ8-o3-yBB">
|
||||
<rect key="frame" x="82" y="0.0" width="199" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" selectedItem="tGi-yg-GFr" id="gt4-HK-pd1">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" autoenablesItems="NO" id="KWV-nn-eiB">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="tGi-yg-GFr"/>
|
||||
<menuItem title="Item 2" id="XJr-Gb-4D4"/>
|
||||
<menuItem title="Item 3" id="JeB-Fb-DeQ"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="9MH-mu-u5V"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xCe-sY-sGe">
|
||||
<rect key="frame" x="282" y="8" width="14" height="10"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="NSListViewTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="0qU-ID-kJ8">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="hamburger:" target="-2" id="5Xa-j7-Aod"/>
|
||||
<binding destination="1RI-9K-5qj" name="hidden" keyPath="objectValue.selectedItem.children" id="rY2-0l-0N8">
|
||||
<dictionary key="options">
|
||||
<string key="NSValueTransformerName">NSIsNil</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="hamburgerButton" destination="xCe-sY-sGe" id="5Da-If-Bt4"/>
|
||||
<outlet property="menuButton" destination="zQ8-o3-yBB" id="zZf-nm-tCI"/>
|
||||
<outlet property="textField" destination="qIF-d4-kOf" id="zIF-4n-v1e"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action selector="memoryMenuChanged:" target="-2" id="m1Q-Xj-z22"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.ram" id="UCD-j5-7Bh"/>
|
||||
<outlet property="dataSource" destination="-2" id="OV9-yE-OFp"/>
|
||||
<outlet property="delegate" destination="-2" id="kXs-TN-3VL"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="Ccd-U2-Gx5" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="QI6-Cz-URX">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="v8c-Rp-Mnt">
|
||||
<rect key="frame" x="-2" y="475" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 0:" id="EF7-NX-RMW">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="Ccd-U2-Gx5" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="0KQ-Qt-8KP">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jw1-t7-YyU">
|
||||
<rect key="frame" x="104" y="470" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="8Iv-mH-mEI" id="47g-IO-4Xt">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="nrR-Tr-UaW">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="8Iv-mH-mEI"/>
|
||||
<menuItem title="Item 2" id="Prr-6W-NWp"/>
|
||||
<menuItem title="Item 3" id="xz3-bi-5IM"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="wPZ-cY-9Ir"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl0" id="2aW-3q-Mvt"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="JGU-aq-3uw" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="Y1R-Ob-g2b">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0gP-wH-DVr">
|
||||
<rect key="frame" x="-2" y="439" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 1:" id="bfg-tf-E34">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="JGU-aq-3uw" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="v8q-Rj-E4q">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="bta-RS-JT4">
|
||||
<rect key="frame" x="104" y="434" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="dXO-at-nGw" id="kNn-6b-ysf">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="4ah-BI-RD5">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="dXO-at-nGw"/>
|
||||
<menuItem title="Item 2" id="UZY-8b-qmE"/>
|
||||
<menuItem title="Item 3" id="zxA-OM-BIY"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="hl3-N2-89k"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl1" id="wQI-oy-SYz"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="gVW-Ya-phU" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="tpv-Yc-qii">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EHZ-ol-QVz">
|
||||
<rect key="frame" x="-2" y="403" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 2:" id="FlL-pN-rn7">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="gVW-Ya-phU" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="OzN-rM-Pgi">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="cDU-b1-x5a">
|
||||
<rect key="frame" x="104" y="398" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="vCY-qF-aB3" id="jvL-SH-nvG">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="Hp6-Gt-pVV">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="vCY-qF-aB3"/>
|
||||
<menuItem title="Item 2" id="pbR-nc-itb"/>
|
||||
<menuItem title="Item 3" id="L8Z-vH-OCa"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="T5w-C4-Ohq"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl2" id="uXQ-0A-98q"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="3fP-qp-zmi" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="LbW-TT-AQ7">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zGs-8d-L0S">
|
||||
<rect key="frame" x="-2" y="367" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 3:" id="KZK-h8-8cw">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="3fP-qp-zmi" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="h8H-TB-p2z">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="3" translatesAutoresizingMaskIntoConstraints="NO" id="aSh-cs-0Nn">
|
||||
<rect key="frame" x="104" y="362" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="2yS-4z-8OR" id="HaE-TD-5Wx">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="zka-z5-hPa">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="2yS-4z-8OR"/>
|
||||
<menuItem title="Item 2" id="q4H-Fz-zVr"/>
|
||||
<menuItem title="Item 3" id="HtQ-6y-S25"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="5uS-La-5cM"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl3" id="YgU-fX-fPC"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="86u-5p-UT6" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="hJR-nJ-yYi">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zsX-jd-6ba">
|
||||
<rect key="frame" x="-2" y="331" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 4:" id="WXv-RF-e7f">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="86u-5p-UT6" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="dHu-cL-FyO">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="4" translatesAutoresizingMaskIntoConstraints="NO" id="kU5-cR-hPZ">
|
||||
<rect key="frame" x="104" y="326" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="NaS-CV-XQm" id="rOP-eY-UKe">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="Iwv-z3-oJb">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="NaS-CV-XQm"/>
|
||||
<menuItem title="Item 2" id="ovb-SG-Eg4"/>
|
||||
<menuItem title="Item 3" id="GVh-L4-3Cp"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="I35-wl-YdH"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl4" id="yfx-hj-6Ly"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="Wdg-xb-xQx" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="dsM-t5-8ng">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ANg-c1-hGf">
|
||||
<rect key="frame" x="-2" y="295" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 5:" id="EhN-EV-65V">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="Wdg-xb-xQx" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="ffm-pA-jjo">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="8z4-8f-kLU">
|
||||
<rect key="frame" x="104" y="290" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="gH7-4J-xsg" id="cmc-Gf-Slp">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="Cma-00-qCY">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="gH7-4J-xsg"/>
|
||||
<menuItem title="Item 2" id="meM-WH-GgP"/>
|
||||
<menuItem title="Item 3" id="ILg-Ld-9Ri"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="jSe-j9-QUW"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl5" id="Uo1-Rg-wko"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="ein-Fe-vBw" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="PSw-Jx-eS2">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Cr1-RK-Z7V">
|
||||
<rect key="frame" x="-2" y="259" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 6:" id="uzy-th-5Yc">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="ein-Fe-vBw" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="FsV-vO-KAs">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="6" translatesAutoresizingMaskIntoConstraints="NO" id="GLb-F4-PWe">
|
||||
<rect key="frame" x="104" y="254" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="VaX-M9-Op0" id="CjU-rC-HUT">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="3xq-Hn-icN">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="VaX-M9-Op0"/>
|
||||
<menuItem title="Item 2" id="Fhy-5D-e6z"/>
|
||||
<menuItem title="Item 3" id="9jw-LA-666"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="yZO-kH-P6Q"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl6" id="0ze-xJ-DNX"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="qjB-2w-AWE" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="1WE-Mm-0O3">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3Ia-XB-C6D">
|
||||
<rect key="frame" x="-2" y="223" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Slot 7:" id="32J-6e-nRV">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="qjB-2w-AWE" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="Yvr-uR-Hr5">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="7" translatesAutoresizingMaskIntoConstraints="NO" id="IV2-3M-qfw">
|
||||
<rect key="frame" x="104" y="218" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="8nb-Bq-4R4" id="nKb-Ar-bCb">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="R2a-Mg-LsY">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="8nb-Bq-4R4"/>
|
||||
<menuItem title="Item 2" id="rFT-bC-KE9"/>
|
||||
<menuItem title="Item 3" id="4jB-gp-lYT"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="llh-ab-ayK"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.sl7" id="hT6-pS-WmL"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="EEX-dh-jwn" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="iRl-IX-FSD">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Avf-lX-f2Q">
|
||||
<rect key="frame" x="-2" y="187" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Expansion:" id="PEU-OV-910">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="EEX-dh-jwn" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="Ehv-aA-Llc">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="8" translatesAutoresizingMaskIntoConstraints="NO" id="San-wP-1ez">
|
||||
<rect key="frame" x="104" y="182" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="jtv-Qx-oVD" id="42u-b4-3kx">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="1hM-MS-UEz">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="jtv-Qx-oVD"/>
|
||||
<menuItem title="Item 2" id="UeB-A1-nyv"/>
|
||||
<menuItem title="Item 3" id="GyZ-dv-MS4"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="fi5-WL-lQa"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.exp" id="C88-Gb-QTE"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="OaZ-ZQ-gKK" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="wRB-Wh-7kG">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EMz-7i-H38">
|
||||
<rect key="frame" x="-2" y="151" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Auxiliary:" id="SoV-Qy-h2g">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="OaZ-ZQ-gKK" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="bx6-Rc-x2V">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="3kq-qn-7YR">
|
||||
<rect key="frame" x="104" y="146" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="vWX-Cb-ldP" id="NqP-Uq-Knv">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="7Ef-KS-ulj">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="vWX-Cb-ldP"/>
|
||||
<menuItem title="Item 2" id="Yg1-xZ-vXq"/>
|
||||
<menuItem title="Item 3" id="BwC-w9-hBy"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="uvt-uD-Adn"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.aux" id="KA7-7x-qeJ"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="wQi-Oz-7Ye" column="zpB-Rf-dWg" xPlacement="fill" yPlacement="center" id="KoQ-xV-fQu">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JAG-sJ-u2B">
|
||||
<rect key="frame" x="-2" y="115" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="RS 232:" id="iG2-rY-VDv">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="wQi-Oz-7Ye" column="6Vn-yh-FoQ" xPlacement="fill" yPlacement="center" id="zWk-jd-i0V">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="10" translatesAutoresizingMaskIntoConstraints="NO" id="6ln-U2-0Pi">
|
||||
<rect key="frame" x="104" y="110" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="uu3-rr-iD8" id="daT-eX-4Vu">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="fMw-mh-Qfi">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="uu3-rr-iD8"/>
|
||||
<menuItem title="Item 2" id="f1r-MS-itp"/>
|
||||
<menuItem title="Item 3" id="WhP-Di-CHP"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="gmZ-pW-35n"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.rs232" id="LxA-8b-jb4"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="gr2-eY-995" column="zpB-Rf-dWg" id="xIE-bJ-mzr">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Svb-pu-WPf">
|
||||
<rect key="frame" x="-2" y="79" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Game I/O:" id="2Gc-mV-zCZ">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="gr2-eY-995" column="6Vn-yh-FoQ" id="nhy-Gp-GLL">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="11" translatesAutoresizingMaskIntoConstraints="NO" id="K8G-bZ-6mZ">
|
||||
<rect key="frame" x="104" y="74" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="GOm-Tf-6qc" id="Mig-Nu-gZB">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="faU-zS-LgN">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="GOm-Tf-6qc"/>
|
||||
<menuItem title="Item 2" id="XgG-U0-2G7"/>
|
||||
<menuItem title="Item 3" id="4Ea-aE-sB1"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="o53-71-xuf"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.gameio" id="tJw-AS-RUz"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="1xN-lm-s4l" column="zpB-Rf-dWg" id="vPV-KN-NNp">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="31K-iE-RCe">
|
||||
<rect key="frame" x="-2" y="43" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Printer:" id="QZI-H7-i8m">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="1xN-lm-s4l" column="6Vn-yh-FoQ" id="KRc-Z8-drK">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="12" translatesAutoresizingMaskIntoConstraints="NO" id="sTp-en-8Wd">
|
||||
<rect key="frame" x="104" y="38" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="TU9-ed-ofw" id="1OL-aw-xNL">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="MSP-Iu-ix3">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="TU9-ed-ofw"/>
|
||||
<menuItem title="Item 2" id="7wI-Tn-rE0"/>
|
||||
<menuItem title="Item 3" id="bQc-pc-ccM"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="Fxc-YB-SF9"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.printer" id="3l1-Hn-v47"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
<gridCell row="M2s-qn-SIT" column="zpB-Rf-dWg" id="8R2-aA-mLq">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MH0-Nk-5Py">
|
||||
<rect key="frame" x="-2" y="7" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Modem:" id="HQq-VN-Ju9">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="M2s-qn-SIT" column="6Vn-yh-FoQ" id="idI-pW-e7v">
|
||||
<popUpButton key="contentView" verticalHuggingPriority="750" tag="13" translatesAutoresizingMaskIntoConstraints="NO" id="KHf-kC-BpZ">
|
||||
<rect key="frame" x="104" y="2" width="205" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="CxO-3g-va1" id="jDr-6p-C7y">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="lxi-Z0-ya6">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="CxO-3g-va1"/>
|
||||
<menuItem title="Item 2" id="OpR-vy-iL5"/>
|
||||
<menuItem title="Item 3" id="xvH-9B-ge5"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="pHW-GG-2VQ"/>
|
||||
<binding destination="-2" name="content" keyPath="machine.modem" id="hFa-pj-NnN"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</gridCell>
|
||||
</gridCells>
|
||||
<point key="canvasLocation" x="268" y="71"/>
|
||||
</gridView>
|
||||
<userDefaultsController representsSharedInstance="YES" id="ZGN-Cx-9po"/>
|
||||
</outlineView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="rYF-ld-adB">
|
||||
<rect key="frame" x="-100" y="-100" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="4pL-Dn-e75" customClass="TransparentScroller">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
|
||||
<color key="value" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</scroller>
|
||||
<point key="canvasLocation" x="-100" y="154"/>
|
||||
</scrollView>
|
||||
<viewController id="ziL-Zf-s1k" userLabel="Popover View Controller">
|
||||
<connections>
|
||||
<outlet property="view" destination="uew-UQ-Q25" id="qjB-ya-gFf"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<popover behavior="t" id="QIT-2T-wdy">
|
||||
<connections>
|
||||
<outlet property="contentViewController" destination="ziL-Zf-s1k" id="rj8-2U-9t0"/>
|
||||
</connections>
|
||||
</popover>
|
||||
<customView id="uew-UQ-Q25">
|
||||
<rect key="frame" x="0.0" y="0.0" width="250" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button id="2jh-iq-DV6">
|
||||
<rect key="frame" x="232" y="382" width="14" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="NSStopProgressFreestandingTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="Wp7-Km-kYI">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="performClose:" target="QIT-2T-wdy" id="Q04-24-ZOK"/>
|
||||
</connections>
|
||||
</button>
|
||||
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="27" horizontalPageScroll="10" verticalLineScroll="27" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" id="5gB-oE-Gza">
|
||||
<rect key="frame" x="0.0" y="20" width="250" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" focusRingType="none" drawsBackground="NO" copiesOnScroll="NO" id="X5e-Ka-JLr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="250" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="25" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" autoresizesOutlineColumn="YES" outlineTableColumn="o1K-z1-KVi" id="uM0-Gk-crn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="250" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="230" minWidth="40" maxWidth="1000" id="o1K-z1-KVi">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<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="A12-NQ-gW3">
|
||||
<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"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="MenuCell" id="Mgb-8H-DmI" customClass="SlotTableCellView">
|
||||
<rect key="frame" x="1" y="1" width="230" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ThL-Yz-7Kd">
|
||||
<rect key="frame" x="1" y="0.0" width="229" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" selectedItem="djR-rV-wzX" id="SkW-fW-gwL">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" autoenablesItems="NO" id="7Ib-TL-f6U">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="djR-rV-wzX"/>
|
||||
<menuItem title="Item 2" id="qbC-4D-6t6"/>
|
||||
<menuItem title="Item 3" id="qPv-x5-zpj"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="menuChanged:" target="-2" id="ytA-nD-fIS"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="menuButton" destination="ThL-Yz-7Kd" id="3Oc-hx-qKl"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-2" id="HXP-pH-3Lc"/>
|
||||
<outlet property="delegate" destination="-2" id="nwb-IL-MsP"/>
|
||||
</connections>
|
||||
</outlineView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="Keh-oo-CPO">
|
||||
<rect key="frame" x="-100" y="-100" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="wtc-gL-alh" customClass="TransparentScroller">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="-451" y="61"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSListViewTemplate" width="14" height="10"/>
|
||||
<image name="NSStopProgressFreestandingTemplate" width="14" height="14"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
14
Ample/Bookmark.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// Bookmark.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/7/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Bookmark_h
|
||||
#define Bookmark_h
|
||||
|
||||
#import "Bookmark+CoreDataClass.h"
|
||||
|
||||
#endif /* Bookmark_h */
|
45
Ample/BookmarkManager.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// BookmarkManager.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 6/1/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
@class NSMenu;
|
||||
@class NSMenuItem;
|
||||
@class Bookmark;
|
||||
@class DiskImage;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BookmarkManager : NSObject
|
||||
|
||||
@property (weak) IBOutlet NSMenu *menu;
|
||||
@property (weak) IBOutlet NSMenuItem *updateMenuItem;
|
||||
@property (readonly) NSManagedObjectContext *managedObjectContext;
|
||||
|
||||
@property (nullable) Bookmark *currentBookmark;
|
||||
|
||||
+(instancetype)sharedManager;
|
||||
|
||||
-(NSString *)uniqueBookmarkName: (NSString *)name;
|
||||
|
||||
-(NSError *)saveBookmark: (NSDictionary *)bookmark name: (NSString *)name automatic: (BOOL)automatic;
|
||||
|
||||
//-(NSError *)saveDefault: (NSDictionary *)bookmark;
|
||||
|
||||
-(Bookmark *)defaultBookmark;
|
||||
-(NSDictionary *)loadDefault;
|
||||
|
||||
-(NSError *)setAutomatic: (Bookmark *)bookmark;
|
||||
|
||||
-(BOOL)addDiskImage: (NSObject *)pathOrURL;
|
||||
|
||||
//-(void)convertLegacyBookmarks;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
651
Ample/BookmarkManager.m
Normal file
|
@ -0,0 +1,651 @@
|
|||
//
|
||||
// BookmarkManager.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 6/1/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BookmarkManager.h"
|
||||
#import "Ample.h"
|
||||
|
||||
#import "Bookmark.h"
|
||||
#import "DiskImage.h"
|
||||
#import "Menu.h"
|
||||
|
||||
|
||||
@interface BookmarkManager () {
|
||||
|
||||
NSPersistentStoreCoordinator *_psc;
|
||||
NSManagedObjectContext *_moc;
|
||||
NSManagedObjectModel *_mom;
|
||||
NSPersistentStore *_store;
|
||||
|
||||
NSFetchRequest *_defaultRequest;
|
||||
|
||||
|
||||
NSURL *_bookmarkDirectory;
|
||||
NSArrayController *_items;
|
||||
NSUInteger _newMenuGeneration;
|
||||
NSUInteger _currentMenuGeneration;
|
||||
|
||||
Bookmark *_currentBookmark;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface BookmarkManager (MenuDelegate) <NSMenuDelegate>
|
||||
@end
|
||||
|
||||
@implementation BookmarkManager
|
||||
|
||||
static BookmarkManager *singleton = nil;
|
||||
|
||||
-(void)awakeFromNib {
|
||||
if (!singleton) {
|
||||
singleton = self;
|
||||
if (!_items) [self initMenus];
|
||||
}
|
||||
}
|
||||
|
||||
+(instancetype)sharedManager {
|
||||
if (!singleton) singleton = [BookmarkManager new];
|
||||
return singleton;
|
||||
}
|
||||
|
||||
-(instancetype)init {
|
||||
if (singleton) return singleton;
|
||||
|
||||
|
||||
if ((self = [super init])) {
|
||||
[self initCoreData];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[nc addObserver: self selector: @selector(willTerminate:) name: NSApplicationWillTerminateNotification object: nil];
|
||||
[nc addObserver: self selector: @selector(diskImageAdded:) name: kNotificationDiskImageAdded object: nil];
|
||||
|
||||
|
||||
_newMenuGeneration = 1;
|
||||
_currentMenuGeneration = 0;
|
||||
}
|
||||
|
||||
|
||||
//singleton = self;
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSManagedObjectContext *)managedObjectContext {
|
||||
return _moc;
|
||||
}
|
||||
|
||||
-(void)initCoreData {
|
||||
|
||||
NSError *error;
|
||||
BOOL new = NO;
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSURL *url = [bundle URLForResource: @"Ample" withExtension: @"momd"];
|
||||
_mom = [[NSManagedObjectModel alloc] initWithContentsOfURL: url];
|
||||
|
||||
_psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: _mom];
|
||||
|
||||
_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];
|
||||
[_moc setPersistentStoreCoordinator: _psc];
|
||||
|
||||
//[_moc setMergePolicy: [NSMergePolicy rollbackMergePolicy]];
|
||||
|
||||
url = SupportDirectory();
|
||||
#if 0
|
||||
url = [url URLByAppendingPathComponent: @"Ample.db"];
|
||||
|
||||
if (![url checkResourceIsReachableAndReturnError: &error])
|
||||
new = YES;
|
||||
|
||||
|
||||
_store = [_psc addPersistentStoreWithType: NSSQLiteStoreType
|
||||
configuration: nil
|
||||
URL: url
|
||||
options: nil
|
||||
error: &error];
|
||||
#else
|
||||
|
||||
url = [url URLByAppendingPathComponent: @"Ample.xml"];
|
||||
|
||||
if (![url checkResourceIsReachableAndReturnError: &error])
|
||||
new = YES;
|
||||
|
||||
|
||||
_store = [_psc addPersistentStoreWithType: NSXMLStoreType
|
||||
configuration: nil
|
||||
URL: url
|
||||
options: nil
|
||||
error: &error];
|
||||
|
||||
|
||||
#endif
|
||||
_defaultRequest = [Bookmark fetchRequest];
|
||||
[_defaultRequest setPredicate: [NSPredicate predicateWithFormat: @"automatic == TRUE"]];
|
||||
|
||||
if (new) {
|
||||
[self convertLegacyBookmarks];
|
||||
[self convertLegacyDiskImages];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)willTerminate: (NSNotification *)notification {
|
||||
|
||||
NSError *error;
|
||||
|
||||
if (![_moc save: &error]) {
|
||||
NSLog(@"%@", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)convertLegacyBookmarks {
|
||||
|
||||
//NSEntityDescription *e;
|
||||
|
||||
//e = [NSEntityDescription entityForName: @"Bookmark" inManagedObjectContext: moc];
|
||||
|
||||
NSURL *url = [self bookmarkDirectory];
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
|
||||
NSArray *files = [fm contentsOfDirectoryAtURL: url
|
||||
includingPropertiesForKeys: nil
|
||||
options: NSDirectoryEnumerationSkipsHiddenFiles
|
||||
error: &error];
|
||||
|
||||
NSDate *now = [NSDate date];
|
||||
for (NSURL *url in files) {
|
||||
|
||||
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfURL: url];
|
||||
//NSData *data = [NSPropertyListSerialization dataWithPropertyList: dict format: NSPropertyListBinaryFormat_v1_0 options: 0 error: &error];
|
||||
|
||||
Bookmark *b = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName: @"Bookmark" inManagedObjectContext: _moc];
|
||||
|
||||
[b setName: [url lastPathComponent]];
|
||||
[b setDictionary: dict];
|
||||
//[b setData: data];
|
||||
[b setMachine: [dict objectForKey: @"machine"]];
|
||||
[b setCreated: now];
|
||||
}
|
||||
|
||||
// default...
|
||||
|
||||
url = [url URLByAppendingPathComponent: @".Default"];
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfURL: url];
|
||||
if (dict) {
|
||||
//NSData *data = [NSPropertyListSerialization dataWithPropertyList: dict format: NSPropertyListBinaryFormat_v1_0 options: 0 error: &error];
|
||||
|
||||
NSString *name = [self uniqueBookmarkName: @"Default"];
|
||||
Bookmark *b = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName: @"Bookmark" inManagedObjectContext: _moc];
|
||||
|
||||
[b setName: name];
|
||||
[b setAutomatic: YES];
|
||||
[b setDictionary: dict];
|
||||
//[b setData: data];
|
||||
[b setMachine: [dict objectForKey: @"machine"]];
|
||||
[b setCreated: now];
|
||||
|
||||
}
|
||||
|
||||
if (![_moc save: &error]) {
|
||||
NSLog(@"%@", error);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)convertLegacyDiskImages {
|
||||
|
||||
NSError *error;
|
||||
NSURL *sd = SupportDirectory();
|
||||
NSURL *url = [sd URLByAppendingPathComponent: @"RecentDiskImages.plist"];
|
||||
|
||||
NSArray *array = [NSArray arrayWithContentsOfURL: url];
|
||||
if (!array) return;
|
||||
|
||||
for (NSDictionary *d in array) {
|
||||
|
||||
NSManagedObject *o = [NSEntityDescription insertNewObjectForEntityForName: @"DiskImage" inManagedObjectContext: _moc];
|
||||
[o setValue: [d objectForKey: @"date"] forKey: @"added"];
|
||||
[o setValue: [d objectForKey: @"date"] forKey: @"accessed"];
|
||||
[o setValue: [d objectForKey: @"path"] forKey: @"path"];
|
||||
[o setValue: [d objectForKey: @"size"] forKey: @"size"];
|
||||
}
|
||||
|
||||
if (![_moc save: &error]) {
|
||||
NSLog(@"%@", error);
|
||||
}
|
||||
}
|
||||
|
||||
-(NSURL *)bookmarkDirectory {
|
||||
|
||||
if (_bookmarkDirectory) return _bookmarkDirectory;
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
NSURL *url = SupportDirectory();
|
||||
url = [url URLByAppendingPathComponent: @"Bookmarks"];
|
||||
NSError *error = nil;
|
||||
[fm createDirectoryAtURL: url withIntermediateDirectories: YES attributes: nil error: &error];
|
||||
if (error) NSLog(@"%@", error);
|
||||
_bookmarkDirectory = url;
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
-(Bookmark *)defaultBookmark {
|
||||
|
||||
NSFetchRequest *req;
|
||||
NSError *error;
|
||||
NSArray *array;
|
||||
|
||||
req = [Bookmark fetchRequest];
|
||||
[req setPredicate: [NSPredicate predicateWithFormat: @"automatic == TRUE"]];
|
||||
array = [_moc executeFetchRequest: req error: &error];
|
||||
|
||||
return [array firstObject];
|
||||
}
|
||||
|
||||
-(NSDictionary *)loadDefault {
|
||||
Bookmark *b = [self defaultBookmark];
|
||||
return [b dictionary];
|
||||
}
|
||||
|
||||
/* save as .Default */
|
||||
-(NSError *)saveDefault: (NSDictionary *)bookmark {
|
||||
|
||||
return nil;
|
||||
|
||||
#if 0
|
||||
/* check if it already exists */
|
||||
|
||||
NSFetchRequest *req;
|
||||
NSError *error;
|
||||
NSArray *array;
|
||||
Bookmark *b;
|
||||
NSDate *now = [NSDate date];
|
||||
BOOL ok;
|
||||
|
||||
req = [[NSFetchRequest alloc] initWithEntityName: @"Default"];
|
||||
array = [_moc executeFetchRequest: req error: &error];
|
||||
|
||||
|
||||
b = [array firstObject];
|
||||
if (b) {
|
||||
[b setModified: now];
|
||||
} else {
|
||||
b = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName: @"Default" inManagedObjectContext: _moc];
|
||||
|
||||
[b setName: @"Default"];
|
||||
[b setCreated: now];
|
||||
}
|
||||
[b setDictionary: bookmark];
|
||||
[b setMachine: [bookmark objectForKey: @"machine"]];
|
||||
|
||||
ok = [_moc save: &error];
|
||||
if (!ok) NSLog(@"%@", error);
|
||||
return error;
|
||||
|
||||
#if 0
|
||||
NSURL *url = [self bookmarkDirectory];
|
||||
url = [url URLByAppendingPathComponent: @".Default"];
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL ok = NO;
|
||||
if (@available(macOS 10.13, *)) {
|
||||
ok = [bookmark writeToURL: url error: &error];
|
||||
if (!ok) NSLog(@"%@", error);
|
||||
} else {
|
||||
ok = [bookmark writeToURL: url atomically: YES];
|
||||
}
|
||||
return ok;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
-(NSError *)setAutomatic: (Bookmark *)bookmark {
|
||||
|
||||
NSError *error = nil;
|
||||
NSFetchRequest *req = [Bookmark fetchRequest];
|
||||
[req setPredicate: [NSPredicate predicateWithFormat: @"automatic == TRUE"]];
|
||||
|
||||
NSArray *array = [_moc executeFetchRequest: req error: &error];
|
||||
for (Bookmark *b in array) {
|
||||
if (b != bookmark) [b setAutomatic: NO];
|
||||
}
|
||||
[bookmark setAutomatic: YES];
|
||||
if (error) return error;
|
||||
[_moc save: &error];
|
||||
return error;
|
||||
}
|
||||
|
||||
-(NSError *)saveBookmark: (NSDictionary *)bookmark name: (NSString *)name automatic: (BOOL)automatic {
|
||||
|
||||
NSDate *now = [NSDate date];
|
||||
NSError *error;
|
||||
BOOL ok;
|
||||
|
||||
Bookmark *b = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName: @"Bookmark" inManagedObjectContext: _moc];
|
||||
|
||||
[b setName: name];
|
||||
[b setDictionary: bookmark];
|
||||
[b setMachine: [bookmark objectForKey: @"machine"]];
|
||||
[b setCreated: now];
|
||||
[b setAutomatic: automatic];
|
||||
|
||||
ok = [b validateForInsert: &error];
|
||||
if (!ok) {
|
||||
// will be useful, eg "name is too long"
|
||||
// keys: NSValidationErrorObject, NSLocalizedDescription, NSValidationErrorKey, NSValidationErrorValue
|
||||
//NSLog(@"%@", error);
|
||||
[_moc deleteObject: b];
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
ok = [_moc save: &error];
|
||||
if (!ok) {
|
||||
//NSLog(@"%@", error);
|
||||
[_moc deleteObject: b];
|
||||
error = [NSError errorWithDomain: @"Ample" code: 0 userInfo: @{ NSLocalizedDescriptionKey: @"Duplicate name" }];
|
||||
return error;
|
||||
}
|
||||
|
||||
if (automatic) {
|
||||
[self setAutomatic: b];
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(void)loadBookmarks {
|
||||
|
||||
NSSortDescriptor *s = [NSSortDescriptor sortDescriptorWithKey: @"name" ascending: YES selector: @selector(caseInsensitiveCompare:)];
|
||||
|
||||
|
||||
_items = [NSArrayController new];
|
||||
[_items setManagedObjectContext: _moc];
|
||||
[_items setAvoidsEmptySelection: NO];
|
||||
[_items setAutomaticallyPreparesContent: YES];
|
||||
[_items setAutomaticallyRearrangesObjects: YES];
|
||||
[_items setEntityName: @"Bookmark"];
|
||||
[_items setSortDescriptors: @[ s ]];
|
||||
|
||||
[_items fetch: nil];
|
||||
}
|
||||
|
||||
|
||||
/* extract the number from a trailing " (%d)" */
|
||||
static int extract_number(NSString *s, NSInteger offset) {
|
||||
|
||||
unichar buffer[32];
|
||||
NSInteger len = [s length] - offset;
|
||||
unichar c;
|
||||
int i;
|
||||
int n = 0;
|
||||
|
||||
if (len < 4) return -1; /* " (1)"*/
|
||||
if (len > 8) return -1; /* " (99999)" */
|
||||
|
||||
NSRange r = NSMakeRange(offset, len);
|
||||
[s getCharacters: buffer range: r];
|
||||
|
||||
buffer[len] = 0;
|
||||
i = 0;
|
||||
if (buffer[i++] != ' ') return -1;
|
||||
if (buffer[i++] != '(') return -1;
|
||||
|
||||
c = buffer[i++];
|
||||
if (c < '1' || c > '9') return -1;
|
||||
n = c - '0';
|
||||
|
||||
for (;;) {
|
||||
c = buffer[i];
|
||||
if (c < '0' || c > '9') break;
|
||||
n = n * 10 + (c - '0');
|
||||
++i;
|
||||
}
|
||||
|
||||
if (buffer[i++] != ')') return -1;
|
||||
if (buffer[i++] != 0) return -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
-(NSString *)uniqueBookmarkName: (NSString *)name {
|
||||
|
||||
NSInteger length = [name length];
|
||||
|
||||
NSError *error = nil;
|
||||
NSPredicate *p = [NSPredicate predicateWithFormat: @"name BEGINSWITH %@", name];
|
||||
NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName: @"Bookmark"];
|
||||
[req setPredicate: p];
|
||||
|
||||
NSArray *array = [_moc executeFetchRequest: req error: &error];
|
||||
if (![array count]) return name;
|
||||
|
||||
uint64_t bits = 1; /* mark 0 as unavailable */
|
||||
NSInteger max = 0;
|
||||
BOOL exact = NO;
|
||||
for (Bookmark *b in array) {
|
||||
NSString *s = [b name];
|
||||
if ([name isEqualToString: s]) {
|
||||
exact = YES;
|
||||
continue;
|
||||
}
|
||||
int n = extract_number(s, length);
|
||||
if (n < 1) continue;
|
||||
if (n > max) max = n;
|
||||
if (n < 64)
|
||||
bits |= (1 << n);
|
||||
}
|
||||
if (!exact) return name;
|
||||
|
||||
if (bits == (uint64_t)-1) {
|
||||
return [name stringByAppendingFormat: @" (%u)", (int)(max + 1)];
|
||||
}
|
||||
|
||||
#if 1
|
||||
int ix = 0;
|
||||
while (bits & 0x01) {
|
||||
++ix;
|
||||
bits >>= 1;
|
||||
}
|
||||
#else
|
||||
// this doesn't work correctly.
|
||||
int ix = __builtin_ffsll(~bits);
|
||||
#endif
|
||||
return [name stringByAppendingFormat: @" (%u)", ix];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(BOOL)addDiskImage: (NSObject *)pathOrURL {
|
||||
|
||||
NSError *error;
|
||||
|
||||
NSString *path = nil;
|
||||
NSURL *url = nil;
|
||||
if ([pathOrURL isKindOfClass: [NSString class]]) {
|
||||
path = (NSString *)pathOrURL;
|
||||
} else if ([pathOrURL isKindOfClass: [NSURL class]]){
|
||||
url = (NSURL *)pathOrURL;
|
||||
|
||||
path = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding];
|
||||
}
|
||||
if (!path) return NO;
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
|
||||
NSDictionary *attr = [fm attributesOfItemAtPath: path error: &error];
|
||||
if (error) {
|
||||
NSLog(@"%@ : %@", path, error);
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSNumber *size = [attr objectForKey: NSFileSize];
|
||||
|
||||
NSDate *now = [NSDate date];
|
||||
|
||||
NSPredicate *p = [NSPredicate predicateWithFormat: @"path = %@", path];
|
||||
NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName: @"DiskImage"];
|
||||
[req setPredicate: p];
|
||||
|
||||
|
||||
NSArray *array = [_moc executeFetchRequest: req error: &error];
|
||||
BOOL found = 0;
|
||||
for (NSManagedObject *o in array) {
|
||||
found = YES;
|
||||
[o setValue: now forKey: @"accessed"];
|
||||
}
|
||||
if (found) return NO;
|
||||
|
||||
DiskImage *o = [NSEntityDescription insertNewObjectForEntityForName: @"DiskImage" inManagedObjectContext: _moc];
|
||||
|
||||
|
||||
[o setPath: path];
|
||||
[o setAdded: now];
|
||||
[o setAccessed: now];
|
||||
[o setSize: [size longLongValue]];
|
||||
[o updatePath];
|
||||
|
||||
if (![_moc save: &error]) {
|
||||
NSLog(@"%@", error);
|
||||
[_moc deleteObject: o];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)diskImageAdded: (NSNotification *)notification {
|
||||
|
||||
NSURL *url = [notification object];
|
||||
if (url) [self addDiskImage: url];
|
||||
}
|
||||
|
||||
static NSString *kMenuContext = @"";
|
||||
|
||||
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
|
||||
if (context == (__bridge void * _Nullable)(kMenuContext)) {
|
||||
|
||||
//NSLog(@"observeValueForKeyPath %@", keyPath);
|
||||
|
||||
_newMenuGeneration++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[super observeValueForKeyPath: keyPath ofObject: object change: change context: context];
|
||||
}
|
||||
|
||||
-(void)initMenus {
|
||||
|
||||
if (!_items) {
|
||||
[self loadBookmarks];
|
||||
[_items addObserver: self forKeyPath: @"arrangedObjects.name" options: 0 context: (__bridge void * _Nullable)(kMenuContext)];
|
||||
[_items addObserver: self forKeyPath: @"arrangedObjects.automatic" options: 0 context: (__bridge void * _Nullable)(kMenuContext)];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(IBAction)bookmarkMenu:(id)sender
|
||||
{
|
||||
}
|
||||
|
||||
-(Bookmark *)currentBookmark {
|
||||
return _currentBookmark;
|
||||
}
|
||||
-(void)setCurrentBookmark:(Bookmark *)currentBookmark {
|
||||
if (currentBookmark == _currentBookmark) return;
|
||||
_currentBookmark = currentBookmark;
|
||||
_newMenuGeneration++;
|
||||
}
|
||||
|
||||
-(void)menuNeedsUpdate:(NSMenu *)menu {
|
||||
|
||||
if (_currentMenuGeneration == _newMenuGeneration) return;
|
||||
_currentMenuGeneration = _newMenuGeneration;
|
||||
|
||||
if (_currentBookmark && _updateMenuItem) {
|
||||
NSString *title = [NSString stringWithFormat: @"Update “%@”", [_currentBookmark name]];
|
||||
[_updateMenuItem setHidden: NO];
|
||||
[_updateMenuItem setTitle: title];
|
||||
[_updateMenuItem setRepresentedObject: _currentBookmark];
|
||||
} else {
|
||||
[_updateMenuItem setHidden: YES];
|
||||
[_updateMenuItem setRepresentedObject: nil];
|
||||
}
|
||||
|
||||
|
||||
|
||||
NSArray *menus = [menu itemArray];
|
||||
for (NSMenuItem *item in [menus reverseObjectEnumerator]) {
|
||||
if ([item tag] == 0xdeadbeef) [_menu removeItem: item];
|
||||
}
|
||||
|
||||
NSArray *array = [_items arrangedObjects];
|
||||
for (Bookmark *b in array) {
|
||||
|
||||
NSString *title = [b name];
|
||||
NSMenuItem *item = [menu addItemWithTitle: title action: @selector(bookmarkMenu:) keyEquivalent: @""];
|
||||
[item setRepresentedObject: b];
|
||||
[item setTag: 0xdeadbeef];
|
||||
if ([b automatic]) {
|
||||
|
||||
[item setOnStateImage: [NSImage imageNamed: NSImageNameStatusAvailable]];
|
||||
[item setState: NSOnState];
|
||||
}
|
||||
//if ([b automatic]) [item setAttributedTitle: ItalicMenuString([b name])];
|
||||
//[item setState: [b automatic] ? NSMixedState : NSOffState];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* MacOS 12.1+ doesn't like class clusters in nibs -
|
||||
|
||||
[General] This coder is expecting the replaced object 0x600000938f60 to be returned from
|
||||
NSClassSwapper.initWithCoder instead of <BookmarkManager: 0x600000905da0>
|
||||
|
||||
*/
|
||||
@interface BookmarkManagerProxy : NSProxy {
|
||||
BookmarkManager *_target;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation BookmarkManagerProxy
|
||||
|
||||
-(id)init {
|
||||
_target = [BookmarkManager sharedManager];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
|
||||
return [_target methodSignatureForSelector: sel];
|
||||
}
|
||||
|
||||
+(BOOL)respondsToSelector:(SEL)aSelector {
|
||||
return [BookmarkManager respondsToSelector: aSelector];
|
||||
}
|
||||
-(void)forwardInvocation:(NSInvocation *)invocation {
|
||||
if ([_target respondsToSelector: [invocation selector]]) {
|
||||
[invocation invokeWithTarget: _target];
|
||||
} else {
|
||||
[super forwardInvocation: invocation];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
19
Ample/BookmarkWindowController.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// BookmarkWindowController.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/6/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BookmarkWindowController : NSWindowController
|
||||
|
||||
+(instancetype)sharedInstance;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
170
Ample/BookmarkWindowController.m
Normal file
|
@ -0,0 +1,170 @@
|
|||
//
|
||||
// BookmarkWindowController.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/6/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BookmarkWindowController.h"
|
||||
#import "BookmarkManager.h"
|
||||
#import "Bookmark.h"
|
||||
#import "Ample.h"
|
||||
|
||||
|
||||
|
||||
@interface BookmarkWindowController ()
|
||||
@property (strong) IBOutlet NSArrayController *arrayController;
|
||||
@property (strong) IBOutlet BookmarkManager *bookmarkManager;
|
||||
|
||||
@property (weak) IBOutlet NSTableView *tableView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation BookmarkWindowController
|
||||
|
||||
|
||||
+(instancetype)sharedInstance {
|
||||
static BookmarkWindowController *me = nil;
|
||||
if (!me) {
|
||||
me = [self new];
|
||||
}
|
||||
return me;
|
||||
}
|
||||
|
||||
-(NSString *)windowNibName {
|
||||
return @"BookmarkWindow";
|
||||
}
|
||||
|
||||
|
||||
- (void)windowDidLoad {
|
||||
[super windowDidLoad];
|
||||
|
||||
NSSortDescriptor *s = [NSSortDescriptor sortDescriptorWithKey: @"name" ascending: YES selector: @selector(caseInsensitiveCompare:)];
|
||||
|
||||
[_arrayController setSortDescriptors: @[s]];
|
||||
|
||||
}
|
||||
|
||||
-(BOOL)windowShouldClose: (NSWindow *)sender {
|
||||
|
||||
NSManagedObjectContext *moc = [_arrayController managedObjectContext];
|
||||
NSError *error;
|
||||
|
||||
if (![_arrayController commitEditing]) return NO;
|
||||
|
||||
if ([moc save: &error]) return YES;
|
||||
NSLog(@"%@", error);
|
||||
|
||||
#if 0
|
||||
NSDictionary *dict = [error userInfo];
|
||||
NSArray *array = [dict objectForKey: @"conflictList"];
|
||||
for (NSConstraintConflict *c in array) {
|
||||
|
||||
NSArray * arr = [c conflictingObjects];
|
||||
for (NSManagedObject *o in arr) {
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return YES;
|
||||
|
||||
//[self presentError: error];
|
||||
//return NO;
|
||||
}
|
||||
|
||||
-(void)keyDown:(NSEvent *)event {
|
||||
/* Carbon/Events.h */
|
||||
enum {
|
||||
kVK_Delete = 0x33,
|
||||
kVK_ForwardDelete = 0x75,
|
||||
|
||||
};
|
||||
unsigned short keyCode = [event keyCode];
|
||||
|
||||
if (keyCode == kVK_Delete || keyCode == kVK_ForwardDelete) {
|
||||
|
||||
// arraycontroller selected object / selected index doesn't work right.
|
||||
|
||||
NSInteger row = [_tableView selectedRow];
|
||||
if (row >= 0)
|
||||
[_arrayController removeObjectAtArrangedObjectIndex: row];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-(Bookmark *)clickedItem {
|
||||
|
||||
NSArray *array = [_arrayController arrangedObjects];
|
||||
NSInteger row = [_tableView clickedRow];
|
||||
if (row < 0 || row >= [array count]) return nil;
|
||||
return [array objectAtIndex: row];
|
||||
}
|
||||
|
||||
-(IBAction)doubleClick:(id)sender {
|
||||
|
||||
Bookmark *b = [self clickedItem];
|
||||
if (!b) return;
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[nc postNotificationName: kNotificationBookmarkMagicRoute object: b];
|
||||
}
|
||||
|
||||
-(IBAction)toggleDefault:(id)sender {
|
||||
NSLog(@"%@", sender);
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(IBAction)setDefault:(id)sender {
|
||||
|
||||
Bookmark *b = [self clickedItem];
|
||||
if (!b) return;
|
||||
|
||||
[_bookmarkManager setAutomatic: b];
|
||||
}
|
||||
|
||||
-(IBAction)clearDefault:(id)sender {
|
||||
|
||||
Bookmark *b = [self clickedItem];
|
||||
if (!b) return;
|
||||
|
||||
[b setAutomatic: NO];
|
||||
}
|
||||
|
||||
|
||||
-(IBAction)deleteBookmark:(id)sender {
|
||||
|
||||
//Bookmark *b = [self clickedItem];
|
||||
//if (!b) return;
|
||||
|
||||
NSInteger row = [_tableView clickedRow];
|
||||
if (row >= 0)
|
||||
[_arrayController removeObjectAtArrangedObjectIndex: row];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation BookmarkWindowController (Menu)
|
||||
|
||||
-(BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
||||
|
||||
Bookmark *b = [self clickedItem];
|
||||
|
||||
if (!b) return NO;
|
||||
SEL action = [menuItem action];
|
||||
|
||||
if (action == @selector(clearDefault:)) {
|
||||
return [b automatic];
|
||||
}
|
||||
|
||||
if (action == @selector(setDefault:)) {
|
||||
return ![b automatic];
|
||||
}
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
17
Ample/CheatSheetWindowController.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// CheatSheetWindowController.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 1/14/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CheatSheetWindowController : NSWindowController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
61
Ample/CheatSheetWindowController.m
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// CheatSheetWindowController.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 1/14/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CheatSheetWindowController.h"
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@interface CheatSheetWindowController ()
|
||||
@property (weak) IBOutlet WKWebView *webView;
|
||||
|
||||
@end
|
||||
|
||||
@interface CheatSheetWindowController (NavigationDelegate) <WKNavigationDelegate>
|
||||
@end
|
||||
|
||||
@implementation CheatSheetWindowController
|
||||
|
||||
-(NSString *)windowNibName {
|
||||
return @"CheatSheet";
|
||||
}
|
||||
|
||||
- (void)windowDidLoad {
|
||||
[super windowDidLoad];
|
||||
|
||||
if (!_webView) {
|
||||
WKWebView *webView;
|
||||
NSWindow *window = [self window];
|
||||
CGRect frame = [[window contentView] frame];
|
||||
|
||||
|
||||
webView = [WKWebView new];
|
||||
[webView setFrame: frame];
|
||||
[webView setNavigationDelegate: self];
|
||||
[[window contentView]addSubview: webView];
|
||||
_webView = webView;
|
||||
}
|
||||
|
||||
|
||||
[_webView setHidden: YES];
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSURL *url = [bundle URLForResource: @"CheatSheet" withExtension: @"html"];
|
||||
//[[[_webView configuration] preferences] setValue: @YES forKey: @"developerExtrasEnabled"];
|
||||
[_webView loadFileURL: url allowingReadAccessToURL: url];
|
||||
|
||||
}
|
||||
|
||||
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
|
||||
// delay to prevent flash in dark mode.
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0/8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[webView setHidden: NO];
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15702" systemVersion="18G9323" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="0">
|
||||
<entity name="Bookmark" representedClassName="Bookmark" syncable="YES">
|
||||
<attribute name="automatic" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="comment" optional="YES" attributeType="String"/>
|
||||
<attribute name="created" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="data" attributeType="Binary"/>
|
||||
<attribute name="machine" optional="YES" attributeType="String"/>
|
||||
<attribute name="modified" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="name" attributeType="String" minValueString="1" maxValueString="32"/>
|
||||
<fetchIndex name="Bookmark_name">
|
||||
<fetchIndexElement property="name" type="Binary" order="ascending"/>
|
||||
</fetchIndex>
|
||||
</entity>
|
||||
<entity name="DiskImage" representedClassName="DiskImage" syncable="YES">
|
||||
<attribute name="accessed" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="added" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="name" optional="YES" transient="YES" attributeType="String"/>
|
||||
<attribute name="path" attributeType="String"/>
|
||||
<attribute name="size" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<fetchIndex name="DiskImage_path">
|
||||
<fetchIndexElement property="path" type="Binary" order="ascending"/>
|
||||
</fetchIndex>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Bookmark" positionX="994.5546875" positionY="-404.046875" width="128" height="148"/>
|
||||
<element name="DiskImage" positionX="1242" positionY="-333" width="128" height="118"/>
|
||||
</elements>
|
||||
</model>
|
25
Ample/Core Data/Bookmark+CoreDataClass.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// Bookmark+CoreDataClass.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/6/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface Bookmark : NSManagedObject
|
||||
|
||||
@property NSDictionary *dictionary;
|
||||
|
||||
+(NSString *)uniqueName: (NSString *)name inContext: (NSManagedObjectContext *)context;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#import "Bookmark+CoreDataProperties.h"
|
175
Ample/Core Data/Bookmark+CoreDataClass.m
Normal file
|
@ -0,0 +1,175 @@
|
|||
//
|
||||
// Bookmark+CoreDataClass.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/6/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import "Bookmark+CoreDataClass.h"
|
||||
|
||||
@implementation Bookmark
|
||||
|
||||
/* extract the number from a trailing " (%d)" */
|
||||
static int extract_number(NSString *s, NSInteger offset) {
|
||||
|
||||
unichar buffer[32];
|
||||
NSInteger len = [s length] - offset;
|
||||
unichar c;
|
||||
int i;
|
||||
int n = 0;
|
||||
|
||||
if (len < 4) return -1; /* " (1)"*/
|
||||
if (len > 6) return -1; /* " (999)" */
|
||||
|
||||
NSRange r = NSMakeRange(offset, len);
|
||||
[s getCharacters: buffer range: r];
|
||||
|
||||
buffer[len] = 0;
|
||||
i = 0;
|
||||
if (buffer[i++] != ' ') return -1;
|
||||
if (buffer[i++] != '(') return -1;
|
||||
|
||||
c = buffer[i++];
|
||||
if (c < '1' || c > '9') return -1;
|
||||
n = c - '0';
|
||||
|
||||
for (;;) {
|
||||
c = buffer[i];
|
||||
if (c < '0' || c > '9') break;
|
||||
n = n * 10 + (c - '0');
|
||||
++i;
|
||||
}
|
||||
|
||||
if (buffer[i++] != ')') return -1;
|
||||
if (buffer[i++] != 0) return -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
+(NSString *)uniqueName: (NSString *)name inContext: (NSManagedObjectContext *)context {
|
||||
|
||||
NSInteger length = [name length];
|
||||
|
||||
NSError *error = nil;
|
||||
NSPredicate *p = [NSPredicate predicateWithFormat: @"name BEGINSWITH %@", name];
|
||||
NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName: @"Bookmark"];
|
||||
[req setPredicate: p];
|
||||
|
||||
NSArray *array = [context executeFetchRequest: req error: &error];
|
||||
if (![array count]) return name;
|
||||
|
||||
uint64_t bits = 1; /* mark 0 as unavailable */
|
||||
NSInteger max = 0;
|
||||
BOOL exact = NO;
|
||||
for (Bookmark *b in array) {
|
||||
NSString *s = [b name];
|
||||
if ([name isEqualToString: s]) {
|
||||
exact = YES;
|
||||
continue;
|
||||
}
|
||||
int n = extract_number(s, length);
|
||||
if (n < 1) continue;
|
||||
if (n > max) max = n;
|
||||
if (n < 64)
|
||||
bits |= (1 << n);
|
||||
}
|
||||
if (!exact) return name;
|
||||
|
||||
if (bits == (uint64_t)-1) {
|
||||
if (max == 999) return nil;
|
||||
return [name stringByAppendingFormat: @" (%u)", (int)(max + 1)];
|
||||
}
|
||||
|
||||
#if 1
|
||||
int ix = 0;
|
||||
while (bits) {
|
||||
++ix;
|
||||
bits >>= 1;
|
||||
}
|
||||
#else
|
||||
// this doesn't work correctly.
|
||||
int ix = __builtin_ffsll(~bits);
|
||||
#endif
|
||||
return [name stringByAppendingFormat: @" (%u)", ix];
|
||||
|
||||
}
|
||||
|
||||
-(void)setDictionary:(NSDictionary *)dictionary {
|
||||
|
||||
NSData *data;
|
||||
NSError *error = nil;
|
||||
|
||||
data = [NSPropertyListSerialization dataWithPropertyList: dictionary
|
||||
format: NSPropertyListBinaryFormat_v1_0
|
||||
options: 0
|
||||
error: &error];
|
||||
|
||||
[self setData: data];
|
||||
}
|
||||
|
||||
-(NSDictionary *)dictionary {
|
||||
|
||||
// NSDictionary *dict;
|
||||
NSData *data = [self data];
|
||||
NSError *error = nil;
|
||||
|
||||
return [NSPropertyListSerialization propertyListWithData: data
|
||||
options: 0
|
||||
format: nil
|
||||
error: &error];
|
||||
}
|
||||
|
||||
|
||||
- (NSError *)errorFromOriginalError:(NSError *)originalError error:(NSError*)secondError
|
||||
{
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
NSMutableArray *errors = [NSMutableArray arrayWithObject:secondError];
|
||||
if ([originalError code] == NSValidationMultipleErrorsError) {
|
||||
[userInfo addEntriesFromDictionary:[originalError userInfo]];
|
||||
[errors addObjectsFromArray:[userInfo objectForKey:NSDetailedErrorsKey]];
|
||||
} else {
|
||||
[errors addObject:originalError];
|
||||
}
|
||||
[userInfo setObject:errors forKey:NSDetailedErrorsKey];
|
||||
return [NSError errorWithDomain:NSCocoaErrorDomain code:NSValidationMultipleErrorsError userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (BOOL)validateName:(id*)ioValue error:(NSError**)outError {
|
||||
|
||||
if (!ioValue || !*ioValue) return YES;
|
||||
NSString *name = *ioValue;
|
||||
|
||||
NSFetchRequest *frq = [NSFetchRequest fetchRequestWithEntityName: @"Bookmark"];
|
||||
|
||||
NSPredicate *p = [NSPredicate predicateWithFormat: @"name = %@", name];
|
||||
[frq setPredicate: p];
|
||||
|
||||
NSArray * arr = [[self managedObjectContext] executeFetchRequest: frq error: nil];
|
||||
BOOL dupe = NO;
|
||||
for (Bookmark *b in arr) {
|
||||
if (b == self) continue;
|
||||
dupe = YES;
|
||||
break;
|
||||
}
|
||||
if (dupe && outError) {
|
||||
NSDictionary *dict = @{ NSLocalizedFailureReasonErrorKey: @"duplicate name",
|
||||
NSLocalizedDescriptionKey: @"duplicate name",
|
||||
NSValidationKeyErrorKey: @"name",
|
||||
NSValidationValueErrorKey: name,
|
||||
NSValidationObjectErrorKey: self
|
||||
};
|
||||
NSError *e = [NSError errorWithDomain: @"Ample" code: 1 userInfo: dict];
|
||||
|
||||
if (*outError) {
|
||||
*outError = [self errorFromOriginalError: *outError error: e];
|
||||
} else {
|
||||
*outError = e;
|
||||
}
|
||||
}
|
||||
return !dupe;
|
||||
}
|
||||
|
||||
|
||||
@end
|
28
Ample/Core Data/Bookmark+CoreDataProperties.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// Bookmark+CoreDataProperties.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/6/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import "Bookmark+CoreDataClass.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface Bookmark (CoreDataProperties)
|
||||
|
||||
+ (NSFetchRequest<Bookmark *> *)fetchRequest;
|
||||
|
||||
@property (nullable, nonatomic, copy) NSString *name;
|
||||
@property (nullable, nonatomic, copy) NSString *machine;
|
||||
@property (nullable, nonatomic, retain) NSData *data;
|
||||
@property (nullable, nonatomic, copy) NSDate *created;
|
||||
@property (nullable, nonatomic, copy) NSDate *modified;
|
||||
@property (nullable, nonatomic, copy) NSString *comment;
|
||||
@property (nonatomic) BOOL automatic;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
26
Ample/Core Data/Bookmark+CoreDataProperties.m
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Bookmark+CoreDataProperties.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/6/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import "Bookmark+CoreDataProperties.h"
|
||||
|
||||
@implementation Bookmark (CoreDataProperties)
|
||||
|
||||
+ (NSFetchRequest<Bookmark *> *)fetchRequest {
|
||||
return [NSFetchRequest fetchRequestWithEntityName:@"Bookmark"];
|
||||
}
|
||||
|
||||
@dynamic name;
|
||||
@dynamic machine;
|
||||
@dynamic data;
|
||||
@dynamic created;
|
||||
@dynamic modified;
|
||||
@dynamic comment;
|
||||
@dynamic automatic;
|
||||
|
||||
@end
|
21
Ample/Core Data/DiskImage+CoreDataClass.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// DiskImage+CoreDataClass.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/7/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DiskImage : NSManagedObject
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#import "DiskImage+CoreDataProperties.h"
|
14
Ample/Core Data/DiskImage+CoreDataClass.m
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// DiskImage+CoreDataClass.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/7/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import "DiskImage+CoreDataClass.h"
|
||||
|
||||
@implementation DiskImage
|
||||
|
||||
@end
|
29
Ample/Core Data/DiskImage+CoreDataProperties.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// DiskImage+CoreDataProperties.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/7/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import "DiskImage+CoreDataClass.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DiskImage (CoreDataProperties)
|
||||
|
||||
+ (NSFetchRequest<DiskImage *> *)fetchRequest;
|
||||
|
||||
@property (nullable, nonatomic, copy) NSString *path;
|
||||
@property (nullable, nonatomic, copy) NSDate *added;
|
||||
@property (nonatomic) int64_t size;
|
||||
@property (nullable, nonatomic, copy) NSDate *accessed;
|
||||
@property (nullable, nonatomic, copy) NSString *name;
|
||||
|
||||
-(void)updatePath;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
52
Ample/Core Data/DiskImage+CoreDataProperties.m
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// DiskImage+CoreDataProperties.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/7/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#import "DiskImage+CoreDataProperties.h"
|
||||
|
||||
#if 0
|
||||
@interface DiskImage () {
|
||||
NSString *_name;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation DiskImage (CoreDataProperties)
|
||||
|
||||
+ (NSFetchRequest<DiskImage *> *)fetchRequest {
|
||||
return [NSFetchRequest fetchRequestWithEntityName:@"DiskImage"];
|
||||
}
|
||||
|
||||
@dynamic path;
|
||||
@dynamic added;
|
||||
@dynamic size;
|
||||
@dynamic accessed;
|
||||
@dynamic name;
|
||||
|
||||
-(void)updatePath {
|
||||
|
||||
NSString *path = [self primitiveValueForKey: @"path"];
|
||||
[self setName: [path lastPathComponent]];
|
||||
}
|
||||
|
||||
-(void)awakeFromFetch {
|
||||
[super awakeFromFetch];
|
||||
|
||||
[self updatePath];
|
||||
}
|
||||
|
||||
#if 0
|
||||
-(void)awakeFromInsert {
|
||||
[super awakeFromInsert];
|
||||
|
||||
NSString *path = [self primitiveValueForKey: @"path"];
|
||||
[self setName: [path lastPathComponent]];
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
|
@ -3,12 +3,22 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>MameComponentsDate</key>
|
||||
<date>2020-09-02T16:00:00Z</date>
|
||||
<date>2024-04-25T12:00:00Z</date>
|
||||
<key>UseCustomMame</key>
|
||||
<false/>
|
||||
<key>AutoCloseLogWindow</key>
|
||||
<true/>
|
||||
<key>MamePath</key>
|
||||
<string>/usr/local/bin/mame</string>
|
||||
<key>MameWorkingDirectory</key>
|
||||
<string>/usr/local/share/mame/</string>
|
||||
<key>NSQuitAlwaysKeepsWindows</key>
|
||||
<true/>
|
||||
<key>DefaultDownloadURL</key>
|
||||
<string>https://archive.org/download/mame-merged/mame-merged</string>
|
||||
<key>UseLogWindow</key>
|
||||
<true/>
|
||||
<key>DefaultDownloadExtension</key>
|
||||
<string>zip</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
14
Ample/DiskImage.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// DiskImage.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 2/7/2022.
|
||||
// Copyright © 2022 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef DiskImage_h
|
||||
#define DiskImage_h
|
||||
|
||||
#import "DiskImage+CoreDataClass.h"
|
||||
|
||||
#endif /* DiskImage_h */
|
28
Ample/DiskImagesWindowController.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// DiskImagesWindowController.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 9/13/2020.
|
||||
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DiskImagesWindowController : NSWindowController <NSWindowRestoration>
|
||||
|
||||
+(instancetype)sharedInstance;
|
||||
|
||||
@end
|
||||
|
||||
@interface DiskImagesWindowController (TableView) <NSTableViewDelegate, NSTableViewDataSource>
|
||||
|
||||
@end
|
||||
|
||||
@interface DiskImagesWindowController (Menu) <NSMenuDelegate>
|
||||
|
||||
@end
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
349
Ample/DiskImagesWindowController.m
Normal file
|
@ -0,0 +1,349 @@
|
|||
//
|
||||
// DiskImagesWindowController.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 9/13/2020.
|
||||
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DiskImagesWindowController.h"
|
||||
#import "TableCellView.h"
|
||||
#import "Ample.h"
|
||||
#import "DiskImage.h"
|
||||
|
||||
#import "BookmarkManager.h"
|
||||
|
||||
@interface DiskImagesWindowController ()
|
||||
@property (weak) IBOutlet NSTableView *tableView;
|
||||
@property (strong) IBOutlet NSArrayController *arrayController;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DiskImagesWindowController {
|
||||
NSSet *_extensions;
|
||||
}
|
||||
|
||||
+(instancetype)sharedInstance {
|
||||
static DiskImagesWindowController *me;
|
||||
if (!me) {
|
||||
me = [self new];
|
||||
}
|
||||
return me;
|
||||
}
|
||||
|
||||
+ (void)restoreWindowWithIdentifier:(NSUserInterfaceItemIdentifier)identifier state:(NSCoder *)state completionHandler:(void (^)(NSWindow *, NSError *))completionHandler {
|
||||
NSLog(@"restore disk images window");
|
||||
NSWindowController *controller = [self sharedInstance];
|
||||
NSWindow *w = [controller window];
|
||||
[w restoreStateWithCoder: state];
|
||||
completionHandler(w, nil);
|
||||
}
|
||||
|
||||
-(instancetype)init {
|
||||
|
||||
if ((self = [super init])) {
|
||||
|
||||
//[self loadRecentDiskImages];
|
||||
|
||||
_extensions = [NSSet setWithObjects:
|
||||
@"2img", @"2mg", @"chd", @"dc", @"do", @"dsk", @"hd", @"hdv", @"image", @"nib", @"po", @"wav", @"woz", @"iso", @"raw",
|
||||
// st, etc.
|
||||
@"mfm", @"st", @"msa", @"stx", @"ipf",
|
||||
//
|
||||
@"rom", @"bin",
|
||||
// not supported/relevant.
|
||||
// @"mfi", @"dfi", @"hfe", @"d77" @"d88", @"1dd", @"cqm", @"cqi", @"td0", @"imd",
|
||||
nil
|
||||
];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSString *)windowNibName {
|
||||
return @"DiskImages";
|
||||
}
|
||||
|
||||
- (void)windowDidLoad {
|
||||
|
||||
[super windowDidLoad];
|
||||
NSWindow *window = [self window];
|
||||
[window setRestorable: YES];
|
||||
[window setRestorationClass: [self class]];
|
||||
|
||||
if (@available(macOS 10.13, *)) {
|
||||
[_tableView registerForDraggedTypes: @[NSPasteboardTypeFileURL]];
|
||||
} else {
|
||||
[_tableView registerForDraggedTypes: @[ (NSString *)kUTTypeFileURL ]];
|
||||
}
|
||||
[_tableView setDraggingSourceOperationMask: NSDragOperationCopy forLocal: NO]; // enable drag/drop to othr apps.
|
||||
|
||||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
|
||||
NSSortDescriptor *s = [NSSortDescriptor sortDescriptorWithKey: @"name" ascending: YES selector: @selector(caseInsensitiveCompare:)];
|
||||
[_arrayController setSortDescriptors: @[ s ]];
|
||||
}
|
||||
|
||||
#if 0
|
||||
-(void)loadRecentDiskImages {
|
||||
// NSError *error;
|
||||
|
||||
NSURL *sd = SupportDirectory();
|
||||
NSURL *url = [sd URLByAppendingPathComponent: @"RecentDiskImages.plist"];
|
||||
|
||||
NSData *data = [NSData dataWithContentsOfURL: url];
|
||||
if (data) {
|
||||
_content = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainers format:nil error: nil];
|
||||
|
||||
}
|
||||
if (!_content)
|
||||
_content = [NSMutableArray new];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[nc addObserver: self selector: @selector(diskImageAdded:) name: kNotificationDiskImageAdded object: nil];
|
||||
|
||||
[nc addObserver: self selector: @selector(willTerminate:) name: NSApplicationWillTerminateNotification object: nil];
|
||||
}
|
||||
|
||||
-(void)timerCallback: (NSTimer *)timer {
|
||||
_timer = nil;
|
||||
[self saveFile];
|
||||
}
|
||||
#endif
|
||||
|
||||
-(void)diskImageAdded: (NSNotification *)notification {
|
||||
|
||||
NSURL *url = [notification object];
|
||||
if (!url) return;
|
||||
|
||||
//[self addFile: url];
|
||||
}
|
||||
#if 0
|
||||
-(void)markDirty {
|
||||
_dirty = YES;
|
||||
if (_timer) [_timer invalidate];
|
||||
_timer = [NSTimer scheduledTimerWithTimeInterval: 5 * 60 target: self selector: @selector(timerCallback:) userInfo: nil repeats: NO];
|
||||
#if 0
|
||||
// 10.12+
|
||||
_timer = [NSTimer scheduledTimerWithTimeInterval: 5 * 60 repeats: NO block: ^(NSTimer *t) {
|
||||
|
||||
self->_timer = nil;
|
||||
[self saveFile];
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
-(void)saveFile {
|
||||
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
|
||||
NSURL *sd = SupportDirectory();
|
||||
NSURL *url = [sd URLByAppendingPathComponent: @"RecentDiskImages.plist"];
|
||||
|
||||
if (_content && url) {
|
||||
[_content writeToURL: url atomically: YES];
|
||||
}
|
||||
_dirty = NO;
|
||||
|
||||
}
|
||||
|
||||
-(void)willTerminate: (NSNotification *)notification {
|
||||
// if dirty, write data....
|
||||
|
||||
if (!_dirty) return;
|
||||
|
||||
[self saveFile];
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
-(BOOL)addFile: (NSObject *)pathOrURL {
|
||||
|
||||
NSString *path = nil;
|
||||
NSURL *url = nil;
|
||||
if ([pathOrURL isKindOfClass: [NSString class]]) {
|
||||
path = (NSString *)pathOrURL;
|
||||
} else if ([pathOrURL isKindOfClass: [NSURL class]]){
|
||||
url = (NSURL *)pathOrURL;
|
||||
|
||||
path = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding];
|
||||
}
|
||||
if (!path) return NO;
|
||||
|
||||
// todo -- check if file is in the list already...
|
||||
|
||||
BOOL found = NO;
|
||||
// should really compare the volume id / ino I suppose.
|
||||
for (NSMutableDictionary *d in _content) {
|
||||
NSString *s = [d objectForKey: @"path"];
|
||||
if ([path compare: s] == NSOrderedSame) {
|
||||
found = YES;
|
||||
[d setObject: [NSDate new] forKey: @"date"];
|
||||
[self markDirty];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) return NO;
|
||||
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSError *error;
|
||||
|
||||
NSDictionary *attr = [fm attributesOfItemAtPath: path error: &error];
|
||||
if (error) {
|
||||
NSLog(@"%@ : %@", path, error);
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
NSNumber *size = [attr objectForKey: NSFileSize];
|
||||
|
||||
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
path, @"path",
|
||||
size, @"size",
|
||||
[NSDate new], @"date",
|
||||
nil];
|
||||
|
||||
#if 0
|
||||
@synchronized (self) {
|
||||
if (_arrayController)
|
||||
[_arrayController addObject: d];
|
||||
else
|
||||
[_content addObject: d];
|
||||
}
|
||||
#endif
|
||||
[self markDirty];
|
||||
return YES;
|
||||
}
|
||||
|
||||
#endif
|
||||
-(DiskImage *)clickedItem {
|
||||
|
||||
NSArray *array = [_arrayController arrangedObjects];
|
||||
NSInteger row = [_tableView clickedRow];
|
||||
if (row < 0 || row >= [array count]) return nil;
|
||||
return [array objectAtIndex: row];
|
||||
}
|
||||
#pragma mark - IBActions
|
||||
|
||||
- (IBAction)filter:(id)sender {
|
||||
NSString *text = [sender stringValue];
|
||||
NSPredicate *p = nil;
|
||||
if ([text length]) {
|
||||
p = [NSPredicate predicateWithFormat: @"name CONTAINS[cd] %@",text];
|
||||
}
|
||||
|
||||
[_arrayController setFilterPredicate: p];
|
||||
}
|
||||
|
||||
- (IBAction)showInFinder:(id)sender {
|
||||
|
||||
DiskImage *item = [self clickedItem];
|
||||
if (!item) return;
|
||||
NSString *path = [item path];
|
||||
|
||||
NSURL *url = [NSURL fileURLWithPath: path];
|
||||
if (!url) return;
|
||||
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
[ws activateFileViewerSelectingURLs: @[url]];
|
||||
}
|
||||
|
||||
- (IBAction)eject:(id)sender {
|
||||
|
||||
DiskImage *item = [self clickedItem];
|
||||
if (!item) return;
|
||||
|
||||
[_arrayController removeObject: item];
|
||||
}
|
||||
|
||||
-(IBAction)doubleClick: (id)sender {
|
||||
DiskImage *d = [self clickedItem];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
NSDictionary *userInfo = @{ @"path": [d path] };
|
||||
[nc postNotificationName: kNotificationDiskImageMagicRoute object: nil userInfo: userInfo];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation DiskImagesWindowController (TableView)
|
||||
|
||||
|
||||
-(id<NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row {
|
||||
|
||||
id objects = [_arrayController arrangedObjects];
|
||||
|
||||
DiskImage *d = [objects objectAtIndex: row];
|
||||
if (!d) return nil;
|
||||
NSString *path = [d path];
|
||||
|
||||
NSURL *url = [NSURL fileURLWithPath: path];
|
||||
return url;
|
||||
|
||||
#if 0
|
||||
NSPasteboardItem *item = [NSPasteboardItem new];
|
||||
[item setString: [url absoluteString] forType: NSPasteboardTypeFileURL]; // FileURL
|
||||
[item setString: path forType: NSPasteboardTypeString]; // for Terminal.app
|
||||
|
||||
return item;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id<NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation {
|
||||
|
||||
if ([info draggingSource] == _tableView) return NSDragOperationNone;
|
||||
|
||||
// option key will ignore all filetype restrictions.
|
||||
if ([NSEvent modifierFlags] & NSEventModifierFlagOption) return NSDragOperationCopy;
|
||||
|
||||
// this only checks the first dragged item...
|
||||
NSPasteboard * pb = [info draggingPasteboard];
|
||||
NSURL *url = [NSURL URLFromPasteboard: pb];
|
||||
|
||||
NSString *ext = [url pathExtension];
|
||||
ext = [ext lowercaseString];
|
||||
if ([_extensions containsObject: ext])
|
||||
return NSDragOperationCopy;
|
||||
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation {
|
||||
|
||||
BookmarkManager *bm = [BookmarkManager sharedManager];
|
||||
|
||||
if ([info draggingSource] == _tableView) return NO;
|
||||
|
||||
NSPasteboard * pb = [info draggingPasteboard];
|
||||
|
||||
BOOL ok = NO;
|
||||
for (NSPasteboardItem *item in [pb pasteboardItems]) {
|
||||
|
||||
// need to convert from a string to a url back to a file in case it's a file id url?
|
||||
NSString *s;
|
||||
if (@available(macOS 10.13, *)) {
|
||||
s = [item stringForType: NSPasteboardTypeFileURL];
|
||||
} else {
|
||||
// El Capitan still has kUTTypeFileURL aka public.file-url but doesn't have NSPasteboardTypeFileURL
|
||||
s = [item stringForType: (NSString *)kUTTypeFileURL];
|
||||
}
|
||||
if (!s) continue;
|
||||
NSURL *url = [NSURL URLWithString: s];
|
||||
if (!url) continue;
|
||||
|
||||
ok |= [bm addDiskImage: url];
|
||||
//ok |= [self addFile: url];
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@end
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DownloadWindowController : NSWindowController
|
||||
@interface DownloadWindowController : NSWindowController <NSWindowRestoration>
|
||||
|
||||
@property NSString *currentROM;
|
||||
@property NSInteger currentCount;
|
||||
|
@ -18,22 +18,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property NSInteger errorCount;
|
||||
@property BOOL active;
|
||||
|
||||
+(instancetype)sharedInstance;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@interface DownloadWindowController (URL) <NSURLSessionTaskDelegate, NSURLSessionDownloadDelegate>
|
||||
@end
|
||||
|
||||
@interface DownloadWindowController (Table) <NSTableViewDelegate, NSTableViewDataSource>
|
||||
@end
|
||||
|
||||
@interface DownloadWindowController (Menu) <NSMenuDelegate, NSMenuItemValidation>
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface DownloadTableCellView : NSTableCellView
|
||||
@property (weak) IBOutlet NSTextField *statusTextField;
|
||||
@property (weak) IBOutlet NSProgressIndicator *activity;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -8,6 +8,70 @@
|
|||
|
||||
#import "Ample.h"
|
||||
#import "DownloadWindowController.h"
|
||||
#import "Menu.h"
|
||||
|
||||
|
||||
static NSString *Extensions[] = { @"zip", @"7z" };
|
||||
|
||||
|
||||
enum {
|
||||
kTagZip = 1,
|
||||
kTag7z = 2,
|
||||
};
|
||||
|
||||
@interface DownloadExtensionTransformer: NSValueTransformer
|
||||
@end
|
||||
|
||||
@implementation DownloadExtensionTransformer
|
||||
|
||||
+(void)load {
|
||||
[NSValueTransformer setValueTransformer: [DownloadExtensionTransformer new] forName: @"FormatTransformer"];
|
||||
|
||||
}
|
||||
|
||||
+ (Class)transformedValueClass {
|
||||
return [NSString class];
|
||||
}
|
||||
|
||||
+ (BOOL)allowsReverseTransformation {
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(id)transformedValue:(id)value {
|
||||
// string to number.
|
||||
if ([@"zip" isEqualToString: value])
|
||||
return @(kTagZip);
|
||||
if ([@"7z" isEqualToString: value])
|
||||
return @(kTag7z);
|
||||
return @0;
|
||||
}
|
||||
|
||||
-(id)reverseTransformedValue:(id)value {
|
||||
// number back to string.
|
||||
switch ([value intValue]) {
|
||||
case kTagZip: return @"zip";
|
||||
case kTag7z: return @"7z";
|
||||
default: return @"";
|
||||
}
|
||||
}
|
||||
|
||||
+(unsigned)stringToNumber: (NSString *)string {
|
||||
if ([@"zip" isEqualToString: string])
|
||||
return kTagZip;
|
||||
if ([@"7z" isEqualToString: string])
|
||||
return kTag7z;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+(NSString *)numberToString: (unsigned)number {
|
||||
switch (number) {
|
||||
case kTagZip: return @"zip";
|
||||
case kTag7z: return @"7z";
|
||||
default: return @"";
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
enum {
|
||||
ItemMissing = 0,
|
||||
|
@ -20,6 +84,7 @@ enum {
|
|||
|
||||
@interface DownloadItem : NSObject
|
||||
|
||||
@property NSString *value;
|
||||
@property NSString *name;
|
||||
@property NSError *error;
|
||||
@property NSString *pathName;
|
||||
|
@ -28,136 +93,243 @@ enum {
|
|||
|
||||
@property NSUInteger status;
|
||||
@property NSUInteger index;
|
||||
@property NSUInteger fileSize;
|
||||
|
||||
@property (readonly) NSColor *titleColor;
|
||||
@property (readonly) NSColor *descriptionColor;
|
||||
|
||||
|
||||
-(void)cancelDownload;
|
||||
-(void)beginDownloadWithTask:(NSURLSessionDownloadTask *)task;
|
||||
-(void)completeWithError: (NSError *)error;
|
||||
-(NSString *)statusDescription;
|
||||
|
||||
-(void)refresh: (NSURL *)localURL;
|
||||
@end
|
||||
|
||||
|
||||
@interface DownloadItemArrayController : NSArrayController
|
||||
|
||||
@property(readonly, copy) NSArray<NSString *> *automaticRearrangementKeyPaths;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DownloadItemArrayController
|
||||
|
||||
-(NSArray<NSString *> *)automaticRearrangementKeyPaths {
|
||||
return @[@"localURL"]; // , @"error", @"task", @"statusDescription"];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface DownloadWindowController ()
|
||||
@property (weak) IBOutlet NSTableView *tableView;
|
||||
@property (weak) IBOutlet NSPopUpButton *formatButton;
|
||||
@property (weak) IBOutlet NSTextField *downloadField;
|
||||
@property NSString *downloadExtension;
|
||||
|
||||
/* filter buttons */
|
||||
@property (weak) IBOutlet NSButton *allFilterButton;
|
||||
@property (weak) IBOutlet NSButton *missingFilterButton;
|
||||
|
||||
@property (strong) IBOutlet NSArrayController *arrayController;
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation DownloadWindowController {
|
||||
|
||||
|
||||
NSArray *_items;
|
||||
NSURL *_romFolder;
|
||||
NSURL *_sourceURL;
|
||||
NSURL *_defaultDownloadURL;
|
||||
NSURL *_downloadURL;
|
||||
|
||||
NSURLSession *_session;
|
||||
NSMutableDictionary *_taskIndex;
|
||||
NSUserDefaults *_defaults;
|
||||
|
||||
NSArray<NSButton *> *_filterButtons;
|
||||
}
|
||||
|
||||
+(instancetype)sharedInstance {
|
||||
static DownloadWindowController *me = nil;
|
||||
if (!me) {
|
||||
me = [self new];
|
||||
}
|
||||
return me;
|
||||
}
|
||||
|
||||
+ (void)restoreWindowWithIdentifier:(nonnull NSUserInterfaceItemIdentifier)identifier state:(nonnull NSCoder *)state completionHandler:(nonnull void (^)(NSWindow * _Nullable, NSError * _Nullable))completionHandler {
|
||||
NSLog(@"restore rom manager window");
|
||||
|
||||
NSWindowController *controller = [DownloadWindowController sharedInstance];
|
||||
NSWindow *w = [controller window];
|
||||
[w restoreStateWithCoder: state];
|
||||
completionHandler(w, nil);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
-(NSString *)windowNibName {
|
||||
return @"DownloadWindow";
|
||||
}
|
||||
|
||||
-(void)windowWillLoad {
|
||||
_defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// set here so binding works.
|
||||
NSString *s = [_defaults stringForKey: kDownloadExtension];
|
||||
if (![s length]) s = [_defaults stringForKey: kDefaultDownloadExtension];
|
||||
|
||||
_downloadExtension = s;
|
||||
}
|
||||
|
||||
- (void)windowDidLoad {
|
||||
[super windowDidLoad];
|
||||
|
||||
#if 0
|
||||
NSWindow *window = [self window];
|
||||
// disabled for now ... restoration happens before defaults are loaded.
|
||||
[window setRestorable: YES];
|
||||
[window setRestorationClass: [self class]];
|
||||
#endif
|
||||
|
||||
_filterButtons = @[
|
||||
_allFilterButton,
|
||||
_missingFilterButton
|
||||
];
|
||||
|
||||
|
||||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
|
||||
NSError *error = nil;
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
#ifdef AMPLE_LITE
|
||||
NSURL *url = [bundle URLForResource: @"roms~extra" withExtension: @"plist"];
|
||||
#else
|
||||
NSURL *url = [bundle URLForResource: @"roms" withExtension: @"plist"];
|
||||
|
||||
NSDictionary *d = [NSDictionary dictionaryWithContentsOfURL: url];
|
||||
|
||||
#endif
|
||||
NSArray *roms = [NSArray arrayWithContentsOfURL: url];
|
||||
|
||||
NSURL *sd = SupportDirectory();
|
||||
NSString *romdir = [SupportDirectoryPath() stringByAppendingPathComponent: @"roms"];
|
||||
|
||||
_romFolder = [sd URLByAppendingPathComponent: @"roms"];
|
||||
|
||||
|
||||
[fm createDirectoryAtURL: _romFolder withIntermediateDirectories: YES attributes: nil error: &error];
|
||||
|
||||
// so blank URL isn't overwritten.
|
||||
NSString *s = [_defaults stringForKey: kDefaultDownloadURL];
|
||||
_defaultDownloadURL = [NSURL URLWithString: s];
|
||||
[_downloadField setPlaceholderString: s];
|
||||
|
||||
s = [_defaults stringForKey: kDownloadURL];
|
||||
if ([s length]) {
|
||||
[_downloadField setStringValue: s];
|
||||
_downloadURL = [NSURL URLWithString: s];
|
||||
} else {
|
||||
_downloadURL = _defaultDownloadURL;
|
||||
}
|
||||
|
||||
[self initializeExtensionMenu];
|
||||
|
||||
|
||||
NSArray *roms = [d objectForKey: @"roms"];
|
||||
[self setCurrentROM: @""];
|
||||
[self setCurrentCount: 0];
|
||||
[self setTotalCount: [roms count]];
|
||||
[self setErrorCount: 0];
|
||||
_sourceURL = [NSURL URLWithString: @"https://archive.org/download/mame0224_rom"]; // hardcoded....
|
||||
|
||||
|
||||
|
||||
|
||||
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity: [roms count]];
|
||||
unsigned ix = 0;
|
||||
for (NSString *name in roms) {
|
||||
|
||||
for (NSDictionary *d in roms) {
|
||||
|
||||
DownloadItem *item = [DownloadItem new];
|
||||
[item setName: name];
|
||||
[item setValue: [d objectForKey: @"value"]];
|
||||
[item setName: [d objectForKey: @"description"]];
|
||||
[item setIndex: ix++];
|
||||
|
||||
[tmp addObject: item];
|
||||
|
||||
// check if the file exists.
|
||||
NSString *s = [romdir stringByAppendingPathComponent: name];
|
||||
NSString *path;
|
||||
|
||||
path = [s stringByAppendingPathExtension: @"zip"];
|
||||
if ([fm fileExistsAtPath: path]) {
|
||||
[item setStatus: ItemFound];
|
||||
[item setLocalURL: [NSURL fileURLWithPath: path]];
|
||||
continue;
|
||||
}
|
||||
path = [s stringByAppendingPathExtension: @"7z"];
|
||||
if ([fm fileExistsAtPath: path]) {
|
||||
[item setStatus: ItemFound];
|
||||
[item setLocalURL: [NSURL fileURLWithPath: path]];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_items = tmp;
|
||||
|
||||
[self refreshROMs: nil];
|
||||
[_arrayController setContent: _items];
|
||||
|
||||
//[_tableView reloadData];
|
||||
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
_session = [NSURLSession sessionWithConfiguration: config delegate: self delegateQueue: nil];
|
||||
_taskIndex = [NSMutableDictionary dictionaryWithCapacity: [_items count]];
|
||||
|
||||
|
||||
//[self download];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
-(void)validateURL: (NSString *)url {
|
||||
NSURL *v;
|
||||
|
||||
if (![url length]) {
|
||||
_effectiveURL = [NSURL URLWithString: _downloadURL];
|
||||
[_downloadField setTextColor: nil];
|
||||
return;
|
||||
}
|
||||
|
||||
v = [NSURL URLWithString: url];
|
||||
if (v) {
|
||||
_effectiveURL = v;
|
||||
[_downloadField setTextColor: nil];
|
||||
} else {
|
||||
_effectiveURL = [NSURL URLWithString: _downloadURL];
|
||||
[_downloadField setTextColor: [NSColor systemRedColor]];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
-(void)downloadItem: (DownloadItem *)item {
|
||||
|
||||
if (!_session) {
|
||||
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
_session = [NSURLSession sessionWithConfiguration: config delegate: self delegateQueue: nil];
|
||||
}
|
||||
|
||||
|
||||
NSURLSessionDownloadTask *task;
|
||||
NSString *s = [item name];
|
||||
NSString *path = [s stringByAppendingString: @".7z"]; // hardcoded.
|
||||
NSURL *url = [_sourceURL URLByAppendingPathComponent: path];
|
||||
|
||||
NSString *s = [item value];
|
||||
NSString *path = [s stringByAppendingPathExtension: _downloadExtension];
|
||||
NSURL *url = [_downloadURL URLByAppendingPathComponent: path];
|
||||
|
||||
task = [_session downloadTaskWithURL: url];
|
||||
|
||||
|
||||
[item beginDownloadWithTask: task];
|
||||
[_taskIndex setObject: item forKey: task];
|
||||
|
||||
[task resume];
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)download {
|
||||
|
||||
|
||||
|
||||
// run in thread?
|
||||
//unsigned count = 0;
|
||||
|
||||
for (DownloadItem *item in _items) {
|
||||
|
||||
|
||||
NSURLSessionDownloadTask *task;
|
||||
NSString *s = [item name];
|
||||
NSString *path = [s stringByAppendingString: @".7z"]; // hardcoded.
|
||||
NSURL *url = [_sourceURL URLByAppendingPathComponent: path];
|
||||
|
||||
NSString *s = [item value];
|
||||
NSString *path = [s stringByAppendingPathExtension: _downloadExtension];
|
||||
NSURL *url = [_downloadURL URLByAppendingPathComponent: path];
|
||||
|
||||
task = [_session downloadTaskWithURL: url];
|
||||
[_taskIndex setObject: item forKey: task];
|
||||
|
||||
|
||||
[item setTask: task];
|
||||
|
||||
[task resume];
|
||||
|
@ -166,24 +338,55 @@ enum {
|
|||
//if (count >= 2) break;
|
||||
}
|
||||
[self setActive: YES];
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(DownloadItem *)clickedItem {
|
||||
NSInteger row = [_tableView clickedRow];
|
||||
if (row < 0 || row >= [_items count]) return nil;
|
||||
return [_items objectAtIndex: row];
|
||||
return [[_arrayController arrangedObjects] objectAtIndex: row];
|
||||
//return [_items objectAtIndex: row];
|
||||
}
|
||||
#if 0
|
||||
-(void)redrawRow: (NSUInteger)row {
|
||||
|
||||
|
||||
//NSRect r = [_tableView rectOfRow: row];
|
||||
//[_tableView setNeedsDisplayInRect: r];
|
||||
|
||||
|
||||
NSIndexSet *rIx = [NSIndexSet indexSetWithIndex: row];
|
||||
NSIndexSet *cIx = [NSIndexSet indexSetWithIndex: 0];
|
||||
|
||||
|
||||
[_tableView reloadDataForRowIndexes: rIx columnIndexes: cIx];
|
||||
}
|
||||
#endif
|
||||
|
||||
-(void)initializeExtensionMenu {
|
||||
|
||||
unsigned tag;
|
||||
// mark default download extension.
|
||||
NSString *defaultExt = [_defaults stringForKey: kDefaultDownloadExtension];
|
||||
tag = [DownloadExtensionTransformer stringToNumber: defaultExt];
|
||||
|
||||
NSMenuItem *item = [[_formatButton menu] itemWithTag: tag];
|
||||
if (item) {
|
||||
[item setAttributedTitle: ItalicMenuString([item title])];
|
||||
}
|
||||
|
||||
#if 0
|
||||
// handled via binding.
|
||||
NSString *ext = [_defaults stringForKey: kDownloadExtension];
|
||||
if ([ext length]) {
|
||||
ix = [DownloadExtensionTransformer stringToNumber: ext];
|
||||
}
|
||||
|
||||
[_formatButton selectItemWithTag: tag];
|
||||
#endif
|
||||
}
|
||||
|
||||
-(void) defocus {
|
||||
[[self window] makeFirstResponder: nil];
|
||||
}
|
||||
|
||||
#pragma mark - IBActions
|
||||
|
||||
-(IBAction)cancelAll:(id)sender {
|
||||
|
@ -197,13 +400,11 @@ enum {
|
|||
[_taskIndex removeAllObjects];
|
||||
[self setCurrentCount: 0];
|
||||
[self setActive: NO];
|
||||
|
||||
[_tableView reloadData];
|
||||
//[_tableView setNeedsDisplay: YES]; // doesn't work...
|
||||
}
|
||||
|
||||
- (IBAction)downloadMissing:(id)sender {
|
||||
|
||||
[self defocus];
|
||||
BOOL delta = NO;
|
||||
for (DownloadItem *item in _items) {
|
||||
NSURL *url = [item localURL];
|
||||
|
@ -213,10 +414,43 @@ enum {
|
|||
delta = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (delta) {
|
||||
[self setActive: YES];
|
||||
[_tableView reloadData];
|
||||
}
|
||||
}
|
||||
- (IBAction)showRomFolder:(id)sender {
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
[ws openURL: _romFolder];
|
||||
}
|
||||
|
||||
-(IBAction)refreshROMs: (id)sender {
|
||||
|
||||
NSString *romdir = [SupportDirectoryPath() stringByAppendingPathComponent: @"roms"];
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
for (DownloadItem *item in _items) {
|
||||
NSDictionary *attr = nil;
|
||||
NSString *value = [item value];
|
||||
NSString *s = [romdir stringByAppendingPathComponent: value];
|
||||
NSString *path;
|
||||
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
path = [s stringByAppendingPathExtension: Extensions[i]];
|
||||
attr = [fm attributesOfItemAtPath: path error: nil];
|
||||
if (attr) break;
|
||||
}
|
||||
|
||||
if (attr) {
|
||||
[item setStatus: ItemFound];
|
||||
[item setLocalURL: [NSURL fileURLWithPath: path]];
|
||||
[item setFileSize: [attr fileSize]];
|
||||
} else {
|
||||
[item setStatus: ItemMissing];
|
||||
[item setLocalURL: nil];
|
||||
[item setFileSize: 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,37 +464,125 @@ enum {
|
|||
[ws activateFileViewerSelectingURLs: @[url]];
|
||||
}
|
||||
|
||||
- (IBAction)moveToTrash:(id)sender {
|
||||
NSError *error = nil;
|
||||
|
||||
DownloadItem *item = [self clickedItem];
|
||||
if (!item) return;
|
||||
NSURL *url = [item localURL];
|
||||
if (!url) return;
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
if ([fm trashItemAtURL: url resultingItemURL: NULL error: &error]) {
|
||||
[item refresh: nil];
|
||||
} else {
|
||||
[self presentError: error];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(IBAction)doubleClick:(id)sender {
|
||||
[self download: sender];
|
||||
}
|
||||
|
||||
- (IBAction)download:(id)sender {
|
||||
DownloadItem *item = [self clickedItem];
|
||||
if (!item) return;
|
||||
|
||||
[self defocus];
|
||||
|
||||
[self downloadItem: item];
|
||||
[self setActive: YES];
|
||||
[self redrawRow: [item index]];
|
||||
}
|
||||
- (IBAction)cancel:(id)sender {
|
||||
DownloadItem *item = [self clickedItem];
|
||||
if (!item) return;
|
||||
|
||||
[item cancelDownload];
|
||||
[self redrawRow: [item index]];
|
||||
}
|
||||
|
||||
// binding screws up with placeholder.
|
||||
-(IBAction)downloadURLChanged: (NSTextField *)sender {
|
||||
NSString *value;
|
||||
value = [sender stringValue];
|
||||
if (![value length]) {
|
||||
[_defaults removeObjectForKey: kDownloadURL];
|
||||
_downloadURL = _defaultDownloadURL;
|
||||
return;
|
||||
}
|
||||
// [self validateURL: value];
|
||||
[_defaults setValue: value forKey: kDownloadURL];
|
||||
_downloadURL = [NSURL URLWithString: value];
|
||||
}
|
||||
- (IBAction)downloadExtensionChanged:(id)sender {
|
||||
[_defaults setValue: _downloadExtension forKey: kDownloadExtension];
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)filterButton:(id)sender {
|
||||
|
||||
NSPredicate *p = nil;
|
||||
NSUInteger tag = [sender tag];
|
||||
[sender setState: NSControlStateValueOn];
|
||||
|
||||
|
||||
for (NSButton *b in _filterButtons) {
|
||||
if (b != sender) [b setState: NSControlStateValueOff];
|
||||
}
|
||||
switch (tag) {
|
||||
case 1: // all
|
||||
default:
|
||||
[_arrayController setFilterPredicate: nil];
|
||||
break;
|
||||
case 2: // missing.
|
||||
p = [NSPredicate predicateWithBlock: ^BOOL(DownloadItem *item, NSDictionary *bindings){
|
||||
NSURL *localURL = [item localURL];
|
||||
return localURL == nil;
|
||||
}];
|
||||
|
||||
[_arrayController setFilterPredicate: p];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - NSURLSessionDelegate
|
||||
|
||||
static NSInteger TaskStatusCode(NSURLSessionTask *task) {
|
||||
NSURLResponse *response = [task response];
|
||||
if ([response isKindOfClass: [NSHTTPURLResponse class]]) {
|
||||
return [(NSHTTPURLResponse *)response statusCode];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||
|
||||
|
||||
if (error) NSLog(@"Download error: %@", error);
|
||||
|
||||
NSInteger statusCode = TaskStatusCode(task);
|
||||
if (!error && statusCode != 200) {
|
||||
// treat as an error.
|
||||
NSDictionary *info = @{
|
||||
NSURLErrorKey: [[task originalRequest] URL],
|
||||
NSLocalizedDescriptionKey: [NSHTTPURLResponse localizedStringForStatusCode: statusCode],
|
||||
};
|
||||
error = [NSError errorWithDomain: NSURLErrorDomain code: NSURLErrorFileDoesNotExist userInfo: info];
|
||||
}
|
||||
|
||||
|
||||
// not sure if strictly necessary but this happens in a background thread
|
||||
// and these are used in KVO binding. Also, main thread only
|
||||
// means no race conditions.
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void){
|
||||
if (error)
|
||||
if (error) {
|
||||
[self setErrorCount: self->_errorCount + 1];
|
||||
else
|
||||
} else {
|
||||
[self setCurrentCount: self->_currentCount + 1];
|
||||
|
||||
}
|
||||
NSMutableDictionary *taskIndex = self->_taskIndex;
|
||||
DownloadItem *item = [taskIndex objectForKey: task];
|
||||
[taskIndex removeObjectForKey: task];
|
||||
|
@ -268,119 +590,187 @@ enum {
|
|||
if ([taskIndex count] == 0) {
|
||||
[self setActive: NO];
|
||||
}
|
||||
|
||||
|
||||
if (item) {
|
||||
[item completeWithError: error];
|
||||
NSUInteger row = [item index];
|
||||
|
||||
[self redrawRow: row];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)task didFinishDownloadingToURL:(nonnull NSURL *)location {
|
||||
|
||||
|
||||
// NSLog(@"%@", task);
|
||||
// NSLog(@"%@", [task response]);
|
||||
|
||||
if (TaskStatusCode(task) != 200) return;
|
||||
|
||||
|
||||
// need to move to the destination directory...
|
||||
// file deleted after this function returns, so can't move asynchronously.
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSURL *src = [[task originalRequest] URL];
|
||||
NSURL *dest = [_romFolder URLByAppendingPathComponent: [src lastPathComponent]];
|
||||
NSError *error = nil;
|
||||
|
||||
|
||||
/* just in case ... */
|
||||
[fm removeItemAtURL: dest error: NULL];
|
||||
[fm moveItemAtURL: location toURL: dest error: &error];
|
||||
|
||||
DownloadItem *item = [_taskIndex objectForKey: task];
|
||||
[item setLocalURL: dest];
|
||||
|
||||
/*
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void){
|
||||
NSMutableDictionary *taskIndex = self->_taskIndex;
|
||||
DownloadItem *item = [taskIndex objectForKey: task];
|
||||
|
||||
if (error) [item completeWithError: error];
|
||||
else [item refresh: dest];
|
||||
});
|
||||
|
||||
[item setLocalURL: dest];
|
||||
}
|
||||
*/
|
||||
NSLog(@"%@", src);
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DownloadWindowController (Table)
|
||||
|
||||
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
|
||||
return [_items count];
|
||||
|
||||
-(NSURLCredential *)credentialForChallenge: (NSURLAuthenticationChallenge *)challenge {
|
||||
|
||||
|
||||
//if ([challenge previousFailureCount]) return nil;
|
||||
|
||||
NSURLCredential *credential = nil;
|
||||
NSURLProtectionSpace *space = [challenge protectionSpace];
|
||||
|
||||
|
||||
OSStatus status;
|
||||
NSDictionary *query;
|
||||
CFTypeRef item = nil;
|
||||
|
||||
|
||||
query = @{
|
||||
(id)kSecClass: (id)kSecClassInternetPassword,
|
||||
(id)kSecReturnData: (id)kCFBooleanTrue,
|
||||
(id)kSecReturnAttributes: (id)kCFBooleanTrue,
|
||||
(id)kSecAttrServer: [space host],
|
||||
//(id)kSecAttrProtocol: [space protocol],
|
||||
(id)kSecMatchLimit: (id)kSecMatchLimitOne,
|
||||
};
|
||||
|
||||
status = SecItemCopyMatching((CFDictionaryRef)query, &item);
|
||||
//NSLog(@"%@", query);
|
||||
if (status != 0) return nil;
|
||||
|
||||
NSDictionary *d = (__bridge NSDictionary *)item;
|
||||
//NSLog(@"%@", d);
|
||||
|
||||
NSString *account = [d objectForKey: (id)kSecAttrAccount];
|
||||
NSData *passwordData = [d objectForKey: (id)kSecValueData];
|
||||
NSString *password = [[NSString alloc] initWithData: passwordData encoding: NSUTF8StringEncoding];
|
||||
|
||||
|
||||
credential = [NSURLCredential credentialWithUser: account password: password persistence: NSURLCredentialPersistenceForSession];
|
||||
|
||||
return credential;
|
||||
|
||||
}
|
||||
|
||||
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
|
||||
|
||||
return [_items objectAtIndex: row];
|
||||
}
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
|
||||
|
||||
NSLog(@"challenge: %@", challenge);
|
||||
|
||||
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
|
||||
|
||||
DownloadItem *item = [_items objectAtIndex: row];
|
||||
DownloadTableCellView *v = [tableView makeViewWithIdentifier: @"DownloadCell" owner: self];
|
||||
|
||||
[[v textField] setObjectValue: [item name]];
|
||||
|
||||
NSTextField *tf = [v statusTextField];
|
||||
|
||||
[tf setObjectValue: [item statusDescription]];
|
||||
if ([item error]) {
|
||||
[tf setTextColor: [NSColor redColor]];
|
||||
} else {
|
||||
[tf setTextColor: [NSColor blackColor]];
|
||||
//if ([tableView isRowSelected: row]){
|
||||
//[tf setTextColor: [NSColor whiteColor]];
|
||||
//}
|
||||
if ([challenge previousFailureCount]) {
|
||||
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([item task]) {
|
||||
[[v activity] startAnimation: nil];
|
||||
} else {
|
||||
[[v activity] stopAnimation: nil];
|
||||
NSURLProtectionSpace *space = [challenge protectionSpace];
|
||||
NSString *method = [space authenticationMethod];
|
||||
|
||||
if ([NSURLAuthenticationMethodHTTPBasic isEqualToString: method] ||
|
||||
[NSURLAuthenticationMethodNTLM isEqualToString: method] ||
|
||||
[NSURLAuthenticationMethodHTTPDigest isEqualToString: method]) {
|
||||
|
||||
NSURLCredential *credential = [self credentialForChallenge: challenge];
|
||||
|
||||
if (credential) {
|
||||
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return v;
|
||||
|
||||
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation DownloadTableCellView
|
||||
|
||||
@end
|
||||
|
||||
@implementation DownloadItem
|
||||
|
||||
-(void)beginDownloadWithTask:(NSURLSessionDownloadTask *)task {
|
||||
_task = task;
|
||||
_error = nil;
|
||||
if (task) _status = ItemDownloading;
|
||||
[self setTask: task];
|
||||
[self setError: nil];
|
||||
if (task) [self setStatus: ItemDownloading];
|
||||
}
|
||||
|
||||
-(void)cancelDownload {
|
||||
if (!_task) return;
|
||||
|
||||
[_task cancel];
|
||||
_task = nil;
|
||||
_status = ItemCanceled;
|
||||
[self setTask: nil];
|
||||
[self setStatus: ItemCanceled];
|
||||
}
|
||||
|
||||
-(void)completeWithError: (NSError *)error {
|
||||
_task = nil;
|
||||
[self setTask: nil];
|
||||
if (error) {
|
||||
_error = error;
|
||||
_status = ItemError;
|
||||
[self setError: error];
|
||||
[self setStatus: ItemError];
|
||||
} else {
|
||||
// what if there was an error moving it?
|
||||
_error = nil;
|
||||
_status = ItemDownloaded;
|
||||
[self setError: nil];
|
||||
[self setStatus: ItemDownloaded];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)refresh: (NSURL *)localURL {
|
||||
NSDictionary *attr = nil;
|
||||
NSError * error = nil;
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
if (localURL) {
|
||||
attr = [fm attributesOfItemAtPath: [localURL path] error: &error];
|
||||
} else {
|
||||
NSString *romdir = [SupportDirectoryPath() stringByAppendingPathComponent: @"roms"];
|
||||
NSString *s = [romdir stringByAppendingPathComponent: _value];
|
||||
|
||||
NSString *path = nil;
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
path = [s stringByAppendingPathExtension: Extensions[i]];
|
||||
attr = [fm attributesOfItemAtPath: path error: nil];
|
||||
if (attr) {
|
||||
localURL = [NSURL fileURLWithPath: path];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attr && localURL) {
|
||||
[self setLocalURL: localURL];
|
||||
[self setFileSize: [attr fileSize]];
|
||||
[self setStatus: ItemFound];
|
||||
} else {
|
||||
[self setLocalURL: nil];
|
||||
[self setFileSize: 0];
|
||||
if (_status == ItemFound || _status == ItemDownloaded)
|
||||
[self setStatus: ItemMissing];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+(NSSet *)keyPathsForValuesAffectingStatusDescription {
|
||||
return [NSSet setWithObjects: @"error", @"status", nil];
|
||||
}
|
||||
-(NSString *)statusDescription {
|
||||
|
||||
static NSString *Names[] = {
|
||||
|
@ -391,12 +781,25 @@ enum {
|
|||
@"Canceled",
|
||||
@"Error"
|
||||
};
|
||||
if (_error) return [_error description];
|
||||
if (_error) return [_error localizedDescription];
|
||||
|
||||
if (_status > sizeof(Names)/sizeof(Names[0])) return @"Unknown";
|
||||
return Names[_status];
|
||||
}
|
||||
|
||||
+(NSSet *)keyPathsForValuesAffectingTitleColor {
|
||||
return [NSSet setWithObject: @"localURL"];
|
||||
}
|
||||
-(NSColor *)titleColor {
|
||||
return _localURL ? nil : [NSColor systemRedColor];
|
||||
}
|
||||
+(NSSet *)keyPathsForValuesAffectingDescriptionColor {
|
||||
return [NSSet setWithObject: @"error"];
|
||||
}
|
||||
-(NSColor *)descriptionColor {
|
||||
return _error ? [NSColor systemRedColor] : nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -410,24 +813,34 @@ enum {
|
|||
};
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
||||
|
||||
SEL action = [menuItem action];
|
||||
if (action == @selector(downloadExtensionChanged:)) return YES;
|
||||
|
||||
DownloadItem *item = [self clickedItem];
|
||||
if (!item) return NO;
|
||||
#if 0
|
||||
NSInteger row = [_tableView clickedRow];
|
||||
if (row < 0) return NO;
|
||||
DownloadItem *item = [_items objectAtIndex: row];
|
||||
|
||||
DownloadItem *item = [[_arrayController arrangedObjects] objectAtIndex: row]; //[_items objectAtIndex: row];
|
||||
#endif
|
||||
|
||||
NSUInteger status = [item status];
|
||||
switch([menuItem tag]) {
|
||||
case kOpenInFinder:
|
||||
return status == ItemFound || status == ItemDownloaded;
|
||||
break;
|
||||
case kDownload:
|
||||
return YES;
|
||||
//return status == ItemMissing || status == ItemError || status == ItemCanceled;
|
||||
break;
|
||||
case kCancel:
|
||||
return status == ItemDownloading;
|
||||
break;
|
||||
|
||||
|
||||
if (action == @selector(moveToTrash:)) {
|
||||
return [item localURL] != nil;
|
||||
}
|
||||
if (action == @selector(showInFinder:)) {
|
||||
return [item localURL] != nil;
|
||||
}
|
||||
if (action == @selector(download:)) {
|
||||
return YES;
|
||||
}
|
||||
if (action == @selector(cancel:)) {
|
||||
return status == ItemDownloading;
|
||||
}
|
||||
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
|
17
Ample/EjectButton.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// EjectButton.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 9/7/2020.
|
||||
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EjectButton : NSButton
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
60
Ample/EjectButton.m
Normal file
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// EjectButton.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 9/7/2020.
|
||||
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "EjectButton.h"
|
||||
|
||||
static NSImage *ejectImage = nil;
|
||||
static NSImage *ejectHoverImage = nil;
|
||||
|
||||
@implementation EjectButton {
|
||||
NSTrackingRectTag _tracking;
|
||||
BOOL _mouse;
|
||||
}
|
||||
|
||||
+(void)initialize {
|
||||
// content tint only works with template images.
|
||||
ejectImage = [NSImage imageNamed: @"eject-16x16"];
|
||||
ejectHoverImage = [NSImage imageNamed: @"eject-hover-16x16"];
|
||||
[ejectImage setTemplate: YES];
|
||||
[ejectHoverImage setTemplate: YES];
|
||||
}
|
||||
|
||||
-(void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
[self setButtonType: NSButtonTypeMomentaryPushIn];
|
||||
[self setImage: ejectImage];
|
||||
[self setAlternateImage: ejectHoverImage];
|
||||
// _tracking = [self addTrackingRect: [self bounds] owner: self userData: nil assumeInside: NO];
|
||||
}
|
||||
|
||||
-(void)viewDidMoveToWindow {
|
||||
if (!_tracking)
|
||||
_tracking = [self addTrackingRect: [self bounds] owner: self userData: nil assumeInside: NO];
|
||||
|
||||
}
|
||||
|
||||
-(void)mouseEntered:(NSEvent *)event {
|
||||
_mouse = YES;
|
||||
if ([self isEnabled])
|
||||
[self setImage: ejectHoverImage];
|
||||
}
|
||||
-(void)mouseExited:(NSEvent *)event {
|
||||
_mouse = NO;
|
||||
if ([self isEnabled])
|
||||
[self setImage: ejectImage];
|
||||
}
|
||||
|
||||
-(void)setEnabled:(BOOL)enabled {
|
||||
[super setEnabled: enabled];
|
||||
if (_mouse) {
|
||||
[self setImage: enabled ? ejectHoverImage : ejectImage];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -4,6 +4,33 @@
|
|||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>vgm</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Video Game Music</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>vgz</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Video Game Music</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
|
@ -17,13 +44,15 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>release 4</string>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>4</string>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Kelvin Sherlock. All rights reserved.</string>
|
||||
<string>Copyright © 2020-2023 Kelvin Sherlock. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
@ -31,6 +60,10 @@
|
|||
<key>NSSupportsAutomaticTermination</key>
|
||||
<true/>
|
||||
<key>NSSupportsSuddenTermination</key>
|
||||
<true/>
|
||||
<false/>
|
||||
<key>SUFeedURL</key>
|
||||
<string>https://ample.ksherlock.com/updates/appcast.xml</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>MgYKY5J1nIJ9+C3IabG24ri2M0CuoMqP78fva2GI5BY=</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface LaunchWindowController : NSWindowController <NSBrowserDelegate>
|
||||
@interface LaunchWindowController : NSWindowController <NSBrowserDelegate, NSMenuDelegate>
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -12,8 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@interface LogWindowController : NSWindowController <NSWindowDelegate>
|
||||
|
||||
#if 0
|
||||
+(id)controllerForTask: (NSTask *)task;
|
||||
+(id)controllerForTask: (NSTask *)task close: (BOOL)close;
|
||||
#endif
|
||||
|
||||
+(id)controllerForArgs: (NSArray *)args;
|
||||
+(id)controllerForArgs: (NSArray *)args close: (BOOL)close;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -19,6 +19,10 @@ static NSMutableSet *LogWindows;
|
|||
@implementation LogWindowController {
|
||||
NSTask *_task;
|
||||
NSFileHandle *_handle;
|
||||
NSFont *_font;
|
||||
|
||||
BOOL _close;
|
||||
BOOL _eof;
|
||||
}
|
||||
|
||||
+(void)initialize {
|
||||
|
@ -30,57 +34,154 @@ static NSMutableSet *LogWindows;
|
|||
}
|
||||
|
||||
|
||||
+(id)controllerForTask: (NSTask *)task {
|
||||
+(id)controllerForTask: (NSTask *)task close: (BOOL)close {
|
||||
LogWindowController *controller = [[LogWindowController alloc] initWithWindowNibName: @"LogWindow"];
|
||||
[controller runTask: task];
|
||||
[controller runTask: task close: close];
|
||||
return controller;
|
||||
}
|
||||
|
||||
|
||||
+(id)controllerForArgs: (NSArray *)args close: (BOOL)close {
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
NSURL *url = MameURL();
|
||||
|
||||
if (!url) {
|
||||
NSAlert *alert = [NSAlert new];
|
||||
|
||||
[alert setMessageText: @"Unable to find MAME executable path"];
|
||||
[alert runModal];
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSTask *task = [NSTask new];
|
||||
|
||||
if (@available(macOS 10.13, *)) {
|
||||
[task setExecutableURL: url];
|
||||
[task setCurrentDirectoryURL: MameWorkingDirectory()];
|
||||
} else {
|
||||
[task setLaunchPath: MamePath()];
|
||||
[task setCurrentDirectoryPath: MameWorkingDirectoryPath()];
|
||||
}
|
||||
|
||||
[task setArguments: args];
|
||||
|
||||
if ([defaults boolForKey: kUseLogWindow] == NO) {
|
||||
|
||||
NSAlert *alert = nil;
|
||||
if (@available(macOS 10.13, *)) {
|
||||
NSError *error = nil;
|
||||
|
||||
[task launchAndReturnError: &error];
|
||||
if (error) {
|
||||
alert = [NSAlert alertWithError: error];
|
||||
}
|
||||
} else {
|
||||
@try {
|
||||
[task launch];
|
||||
} @catch (NSException *exception) {
|
||||
|
||||
alert = [NSAlert new];
|
||||
[alert setMessageText: [exception reason]];
|
||||
}
|
||||
}
|
||||
if (alert) [alert runModal];
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
return [LogWindowController controllerForTask: task close: close];
|
||||
|
||||
}
|
||||
|
||||
+(id)controllerForArgs: (NSArray *)args {
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
BOOL close = [defaults boolForKey: kAutoCloseLogWindow];
|
||||
return [self controllerForArgs: args close: close];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad {
|
||||
[super windowDidLoad];
|
||||
|
||||
[LogWindows addObject: self];
|
||||
|
||||
_font = [NSFont userFixedPitchFontOfSize: 0];
|
||||
|
||||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
}
|
||||
|
||||
-(void)appendString: (NSString *)string
|
||||
{
|
||||
if ([string length])
|
||||
{
|
||||
[[[_textView textStorage] mutableString] appendString: string];
|
||||
// needs explicit color attribute for proper dark mode support.
|
||||
NSDictionary *attr = @{
|
||||
NSForegroundColorAttributeName: [NSColor textColor],
|
||||
NSFontAttributeName: _font,
|
||||
};
|
||||
NSAttributedString *astr = [[NSAttributedString alloc] initWithString: string attributes: attr];
|
||||
[[_textView textStorage] appendAttributedString: astr];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSError *)runTask: (NSTask *)task {
|
||||
-(void)appendAttributedString: (NSAttributedString *)string {
|
||||
|
||||
if ([string length]) {
|
||||
[[_textView textStorage] appendAttributedString: string];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSError *)runTask: (NSTask *)task close: (BOOL)close {
|
||||
|
||||
|
||||
if (_task) return nil;
|
||||
_close = close;
|
||||
_eof = NO;
|
||||
|
||||
NSError *error = nil;
|
||||
NSPipe *pipe = [NSPipe pipe];
|
||||
|
||||
// window not yet loaded until [self window] called.
|
||||
|
||||
const char *path = nil;
|
||||
const char *wd = nil;
|
||||
|
||||
|
||||
[task setStandardError: pipe];
|
||||
[task setStandardOutput: pipe];
|
||||
[task launchAndReturnError: &error];
|
||||
|
||||
if (@available(macOS 10.13, *)) {
|
||||
NSError *error = nil;
|
||||
path = [[task executableURL] fileSystemRepresentation];
|
||||
wd = [[task currentDirectoryURL] fileSystemRepresentation];
|
||||
|
||||
if (error) {
|
||||
NSURL *url = [task executableURL];
|
||||
NSString *path = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding];
|
||||
NSLog(@"NSTask error. Path = %@ error = %@", path, error);
|
||||
[self appendString: path];
|
||||
[self appendString: [error description]];
|
||||
return error;
|
||||
[task launchAndReturnError: &error];
|
||||
if (error) {
|
||||
NSLog(@"NSTask error. Path = %s error = %@", path, error);
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
path = [[task launchPath] fileSystemRepresentation];
|
||||
wd = [[task currentDirectoryPath] fileSystemRepresentation];
|
||||
@try {
|
||||
[task launch];
|
||||
} @catch (NSException *exception) {
|
||||
|
||||
NSLog(@"NSTask exception. Path = %s exception = %@", path, exception);
|
||||
return nil; // ?
|
||||
}
|
||||
}
|
||||
|
||||
_task = task;
|
||||
NSString *title = [NSString stringWithFormat: @"Ample Log - %u", [task processIdentifier]];
|
||||
[[self window] setTitle: title];
|
||||
_handle = [pipe fileHandleForReading];
|
||||
|
||||
|
||||
if (path) [self appendString: [NSString stringWithFormat: @"MAME path: %s\n", path]];
|
||||
if (wd) [self appendString: [NSString stringWithFormat: @"Working Directory: %s\n", wd]];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
|
||||
[nc addObserver: self
|
||||
selector: @selector(taskComplete:)
|
||||
name: NSTaskDidTerminateNotification
|
||||
|
@ -91,6 +192,7 @@ static NSMutableSet *LogWindows;
|
|||
object: _handle];
|
||||
|
||||
[_handle readInBackgroundAndNotify];
|
||||
|
||||
[[self window] setDocumentEdited: YES];
|
||||
return nil;
|
||||
}
|
||||
|
@ -103,21 +205,33 @@ static NSMutableSet *LogWindows;
|
|||
// read complete, queue up another.
|
||||
NSDictionary *dict = [notification userInfo];
|
||||
NSData *data = [dict objectForKey: NSFileHandleNotificationDataItem];
|
||||
|
||||
|
||||
if ([data length])
|
||||
{
|
||||
|
||||
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
|
||||
|
||||
[self appendString: string];
|
||||
|
||||
[_handle readInBackgroundAndNotify];
|
||||
} else {
|
||||
[self appendString: @"\n"]; // -listmedia sometimes causes display issues.
|
||||
_eof = YES;
|
||||
//[_textView setNeedsDisplay: YES]; // -listmedia sometimes weird.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)taskCompleteHack {
|
||||
|
||||
}
|
||||
|
||||
/* hask! task complete may occur while output still being processed. add a delay to compensate. */
|
||||
-(void)taskComplete: (NSNotification *)notification
|
||||
{
|
||||
if (!_eof) {
|
||||
[self performSelector: @selector(taskComplete:) withObject: notification afterDelay: 0.5];
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL ok = NO;
|
||||
NSTaskTerminationReason reason;
|
||||
int status;
|
||||
|
@ -131,28 +245,31 @@ static NSMutableSet *LogWindows;
|
|||
|
||||
if (status == 0)
|
||||
{
|
||||
string = @"\n\n[Success]\n\n";
|
||||
//string = @"\n\n[Success]\n\n";
|
||||
ok = YES;
|
||||
}
|
||||
else string = @"\n\n[An error occurred]\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
string = @"\n\n[Caught signal]\n\n";
|
||||
|
||||
string = [NSString stringWithFormat: @"\n\n[Caught signal %d (%s)]\n\n", status, strsignal(status)];
|
||||
}
|
||||
|
||||
[self appendString: string];
|
||||
|
||||
if (string) {
|
||||
NSDictionary *attr = @{
|
||||
NSForegroundColorAttributeName: [NSColor systemRedColor],
|
||||
NSFontAttributeName: _font,
|
||||
};
|
||||
NSAttributedString *astr = [[NSAttributedString alloc] initWithString: string attributes: attr];
|
||||
[self appendAttributedString: astr];
|
||||
}
|
||||
|
||||
_handle = nil;
|
||||
_task = nil;
|
||||
|
||||
[[self window] setDocumentEdited: NO];
|
||||
|
||||
if (ok && [[NSUserDefaults standardUserDefaults] boolForKey: kAutoCloseLogWindow]) {
|
||||
|
||||
if (ok && _close) {
|
||||
[[self window] close];
|
||||
//[LogWindows removeObject: self]; // close sends WindowWillClose notification.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,4 +280,12 @@ static NSMutableSet *LogWindows;
|
|||
[LogWindows removeObject: self];
|
||||
}
|
||||
|
||||
#pragma mark - IBActions
|
||||
|
||||
- (IBAction)clearLog:(id)sender {
|
||||
NSAttributedString *empty = [NSAttributedString new];
|
||||
[[_textView textStorage] setAttributedString: empty];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Ample.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -17,4 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@end
|
||||
|
||||
@interface MachineViewController (Bookmark) <Bookmark>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -20,11 +20,15 @@
|
|||
-(void)awakeFromNib {
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
#ifdef AMPLE_LITE
|
||||
NSString *path = [bundle pathForResource: @"models~extra" ofType: @"plist"];
|
||||
#else
|
||||
NSString *path = [bundle pathForResource: @"models" ofType: @"plist"];
|
||||
#endif
|
||||
_data = [NSArray arrayWithContentsOfFile: path];
|
||||
|
||||
|
||||
/* My Copy of XCode/Interface Builder barfs on NSBrowser. */
|
||||
/* XCode/Interface Builder 11.3 barfs on NSBrowser. */
|
||||
|
||||
NSBrowser *browser;
|
||||
NSRect frame = NSMakeRect(0, 0, 718, 200);
|
||||
|
@ -110,5 +114,67 @@
|
|||
return [data count];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MachineViewController (Bookmark)
|
||||
|
||||
-(BOOL)loadBookmark: (NSDictionary *)bookmark {
|
||||
|
||||
NSBrowser *browser = (NSBrowser *)[self view];
|
||||
NSString *machine = [bookmark objectForKey: @"machine"];
|
||||
|
||||
NSIndexPath *path = nil;
|
||||
NSUInteger ix[2] = {0, 0 };
|
||||
for (NSDictionary *d in _data) {
|
||||
|
||||
NSArray *children = [d objectForKey: @"children"];
|
||||
|
||||
for (NSDictionary *dd in children) {
|
||||
NSString *value = [dd objectForKey: @"value"];
|
||||
|
||||
if ([machine isEqualToString: value]) {
|
||||
path = [NSIndexPath indexPathWithIndexes: ix length: 2];
|
||||
[browser selectRow: ix[0] inColumn: 0];
|
||||
[browser selectRow: ix[1] inColumn: 1];
|
||||
|
||||
//[browser setSelectionIndexPath: path];
|
||||
return YES;
|
||||
}
|
||||
++ix[1];
|
||||
}
|
||||
ix[1] = 0;
|
||||
|
||||
|
||||
// check parent after.
|
||||
NSString *value = [d objectForKey: @"value"];
|
||||
if ([machine isEqualToString: value]) {
|
||||
path = [NSIndexPath indexPathWithIndexes: ix length: 1];
|
||||
[browser selectRow: ix[0] inColumn: 0];
|
||||
// "setSelectionIndexPath: is not supported for browsers with matrix delegates."
|
||||
//[browser setSelectionIndexPath: path];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
++ix[0];
|
||||
|
||||
}
|
||||
NSLog(@"MachineViewController: Unable to find %@", machine);
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(BOOL)saveBookmark: (NSMutableDictionary *)bookmark {
|
||||
// machine saved in parent.
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)willLoadBookmark:(NSDictionary *)bookmark {
|
||||
}
|
||||
|
||||
-(void)didLoadBookmark:(NSDictionary *)bookmark {
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
56
Ample/Media.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// Media.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 3/7/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Media_h
|
||||
#define Media_h
|
||||
|
||||
|
||||
typedef struct Media {
|
||||
unsigned cass;
|
||||
unsigned cdrom;
|
||||
unsigned hard;
|
||||
unsigned floppy_8;
|
||||
unsigned floppy_5_25;
|
||||
unsigned floppy_3_5;
|
||||
unsigned pseudo_disk;
|
||||
unsigned bitbanger;
|
||||
unsigned midiin;
|
||||
unsigned midiout;
|
||||
unsigned picture;
|
||||
unsigned rom;
|
||||
uint64_t floppy_mask_8;
|
||||
uint64_t floppy_mask_5_25;
|
||||
uint64_t floppy_mask_3_5;
|
||||
} Media;
|
||||
|
||||
|
||||
typedef enum {
|
||||
MediaTypeError = -1,
|
||||
MediaTypeUnknown = 0,
|
||||
MediaType_8,
|
||||
MediaType_5_25,
|
||||
MediaType_3_5,
|
||||
MediaType_HardDisk,
|
||||
MediaType_CDROM,
|
||||
MediaType_Cassette,
|
||||
MediaType_Picture,
|
||||
MediaType_MIDI,
|
||||
MediaType_ROM,
|
||||
} MediaType;
|
||||
|
||||
struct Media MediaFromDictionary(NSDictionary *);
|
||||
|
||||
void MediaAdd(Media *dest, const Media *src);
|
||||
|
||||
BOOL MediaEqual(const Media *lhs, const Media *rhs);
|
||||
|
||||
extern const Media EmptyMedia;
|
||||
|
||||
MediaType ClassifyMediaFile(id file);
|
||||
|
||||
#endif /* Media_h */
|
382
Ample/Media.m
Normal file
|
@ -0,0 +1,382 @@
|
|||
//
|
||||
// Media.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 3/7/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Media.h"
|
||||
|
||||
const Media EmptyMedia = { 0 };
|
||||
|
||||
struct Media MediaFromDictionary(NSDictionary *dict) {
|
||||
|
||||
Media m = { 0 };
|
||||
|
||||
#define _(name) m.name = [[dict objectForKey: @ # name] unsignedIntValue]
|
||||
_(cass);
|
||||
_(cdrom);
|
||||
_(hard);
|
||||
_(floppy_3_5);
|
||||
_(floppy_5_25);
|
||||
_(floppy_8);
|
||||
_(pseudo_disk);
|
||||
_(bitbanger);
|
||||
_(midiin);
|
||||
_(midiout);
|
||||
_(picture);
|
||||
_(rom);
|
||||
|
||||
return m;
|
||||
#undef _
|
||||
}
|
||||
|
||||
void MediaAdd(Media *dest, const Media *src) {
|
||||
|
||||
if (!src || !dest) return;
|
||||
|
||||
// could merge from src media but not currently set there.
|
||||
|
||||
//unsigned count;
|
||||
unsigned dest_flops = dest->floppy_8 + dest->floppy_5_25 + dest->floppy_3_5;
|
||||
unsigned src_flops = src->floppy_8 || src->floppy_5_25 || src->floppy_3_5;
|
||||
|
||||
|
||||
#define _(name) dest->name += src->name;
|
||||
_(cass);
|
||||
_(cdrom);
|
||||
_(hard);
|
||||
_(floppy_3_5);
|
||||
_(floppy_5_25);
|
||||
_(floppy_8);
|
||||
_(pseudo_disk);
|
||||
_(bitbanger);
|
||||
_(midiin);
|
||||
_(midiout);
|
||||
_(picture);
|
||||
_(rom);
|
||||
#undef _
|
||||
|
||||
|
||||
// this assumes any device that supports more than 1 floppy size
|
||||
// the order is 8" < 5.25" < 3.5"
|
||||
|
||||
if (src_flops) {
|
||||
uint64_t bits = 1 << dest_flops;
|
||||
for (unsigned i = 0; i < src->floppy_8; ++i) {
|
||||
dest->floppy_mask_8 |= bits;
|
||||
bits <<= 1;
|
||||
}
|
||||
for (unsigned i = 0; i < src->floppy_5_25; ++i) {
|
||||
dest->floppy_mask_5_25 |= bits;
|
||||
bits <<= 1;
|
||||
}
|
||||
for (unsigned i = 0; i < src->floppy_3_5; ++i) {
|
||||
dest->floppy_mask_3_5 |= bits;
|
||||
bits <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL MediaEqual(const Media *lhs, const Media *rhs) {
|
||||
if (lhs == rhs) return YES;
|
||||
if (!lhs || !rhs) return NO;
|
||||
|
||||
|
||||
#define _(name) if (lhs->name != rhs->name) return NO;
|
||||
_(cass);
|
||||
_(cdrom);
|
||||
_(hard);
|
||||
_(floppy_3_5);
|
||||
_(floppy_5_25);
|
||||
_(floppy_8);
|
||||
_(pseudo_disk);
|
||||
_(bitbanger);
|
||||
_(midiin);
|
||||
_(midiout);
|
||||
_(picture);
|
||||
_(rom);
|
||||
|
||||
_(floppy_mask_8);
|
||||
_(floppy_mask_5_25);
|
||||
_(floppy_mask_3_5);
|
||||
|
||||
return YES;
|
||||
#undef _
|
||||
}
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
|
||||
#define _x2(a,b) (a | (b << 8))
|
||||
#define _x3(a,b,c) (a | (b << 8) | (c << 16))
|
||||
#define _x4(a,b,c, d) (a | (b << 8) | (c << 16) | (d << 24))
|
||||
static unsigned hash(const char *cp) {
|
||||
unsigned rv = 0;
|
||||
int i, shift;
|
||||
if (!cp) return 0;
|
||||
for (i = 0, shift = 0; i < 4; ++i, shift += 8) {
|
||||
unsigned c = cp[i];
|
||||
if (!c) break;
|
||||
c = tolower(c);
|
||||
rv |= (c << shift);
|
||||
}
|
||||
//if (i > 4) return 0; // .image is 5....
|
||||
return rv;
|
||||
}
|
||||
|
||||
const char *extname(const char *path) {
|
||||
|
||||
const char *rv = NULL;
|
||||
if (!path) return path;
|
||||
for(unsigned i = 0; ; ++i) {
|
||||
unsigned c = path[i];
|
||||
if (c == 0) break;
|
||||
if (c == '/') rv = NULL;
|
||||
if (c == '.') rv = path + i + 1;
|
||||
}
|
||||
if (rv && !*rv) rv = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* MAME cares deeply about file extensions. LIST NOT EXHAUSTIVE
|
||||
*
|
||||
* Hard Disk: .chd .hd .hdv .2mg .hdi
|
||||
* CD-ROM: .chd .cue .toc .nrg .gdi .iso .cdr
|
||||
* 5.25: .dsk .do .po .edd .woz .nib .mfi .dfi .rti
|
||||
* 3.5: .dc42 .woz .2mg .mfi .dfi .hfe .mfm .td0 .imd
|
||||
.d77 .d88 .1dd .cqm .cqi .dsk .ima .img .ufi
|
||||
.360 .ipf [also .po and .hdv]
|
||||
* Midi in: .mid
|
||||
* Midi out: .mid
|
||||
* Picture: .png
|
||||
* Cassette: .wav
|
||||
*/
|
||||
|
||||
static bool is_raw_525(size_t disk_size) {
|
||||
if (disk_size & 255) return NO;
|
||||
size_t blocks = disk_size >> 8;
|
||||
|
||||
return blocks == 560 || blocks == 640;
|
||||
}
|
||||
|
||||
static BOOL is_raw_35(size_t disk_size) {
|
||||
if (disk_size & 511) return NO;
|
||||
size_t blocks = disk_size >> 9;
|
||||
|
||||
// atari st has 360 (single sided) and 720 (double-sided) disks..
|
||||
return blocks == 800 || blocks == 1600 || blocks == 1440 || blocks == 2880 || blocks == 720 || blocks == 360;
|
||||
}
|
||||
|
||||
static MediaType is_woz(const uint8_t *buffer, size_t file_size) {
|
||||
|
||||
/* woz 1/2 ? */
|
||||
if (!memcmp(buffer, "WOZ1\xff\x0a\x0d\x0a", 8) || !memcmp(buffer, "WOZ2\xff\x0a\x0d\x0a", 8)) {
|
||||
|
||||
if (!memcmp(buffer + 12, "INFO", 4)) {
|
||||
unsigned type = buffer[21]; // 1 = 5.25, 2 = 3.5
|
||||
if (type == 1) return MediaType_5_25;
|
||||
if (type == 2) return MediaType_3_5;
|
||||
}
|
||||
return MediaTypeUnknown;
|
||||
}
|
||||
return MediaTypeError;
|
||||
}
|
||||
|
||||
static MediaType is_dc42(const uint8_t *buffer, size_t file_size) {
|
||||
|
||||
if (buffer[0x52] == 0x01 && buffer[0x53] == 0x00 && buffer[0] >= 1 && buffer[0] <= 0x3f) {
|
||||
int dsize = OSReadBigInt32(buffer, 0x40);
|
||||
int tsize = OSReadBigInt32(buffer, 0x44);
|
||||
if (dsize + tsize + 0x54 == file_size) {
|
||||
if (is_raw_35(dsize)) return MediaType_3_5;
|
||||
return MediaType_HardDisk;
|
||||
}
|
||||
}
|
||||
|
||||
return MediaTypeError;
|
||||
}
|
||||
|
||||
static MediaType is_2img(const uint8_t *buffer, size_t file_size) {
|
||||
|
||||
if (!memcmp(buffer, "2IMG", 4)) {
|
||||
int format = OSReadLittleInt32(buffer, 0x0c); // 0 - dos order, 1 = prodos order, 2 = nib data
|
||||
int blocks = OSReadLittleInt32(buffer, 0x14); // prodos only.
|
||||
//int bytes = OSReadLittleInt32(buffer, 0x1c);
|
||||
|
||||
if (format == 2 || format == 0) return MediaType_5_25; // nib and dos order
|
||||
if (is_raw_525(blocks * 512)) return MediaType_5_25;
|
||||
if (is_raw_35(blocks * 512)) return MediaType_3_5;
|
||||
return MediaType_HardDisk; //
|
||||
//return MediaTypeUnknown;
|
||||
}
|
||||
|
||||
return MediaTypeError;
|
||||
}
|
||||
|
||||
static MediaType is_chd(const uint8_t *buffer, size_t file_size) {
|
||||
if (!memcmp(buffer, "MComprHD", 8)) {
|
||||
static int offsets[] = { 0, 0, 0, 28, 28, 32}; // offset for logival bytes.
|
||||
int version = OSReadBigInt32(buffer, 12);
|
||||
|
||||
if (version >= 3 && version <= 5) {
|
||||
long bytes = OSReadBigInt64(buffer, offsets[version]);
|
||||
if (is_raw_525(bytes)) return MediaType_5_25;
|
||||
if (is_raw_35(bytes)) return MediaType_3_5;
|
||||
return MediaType_HardDisk; // iso?
|
||||
}
|
||||
return MediaTypeUnknown;
|
||||
}
|
||||
return MediaTypeError;
|
||||
}
|
||||
|
||||
static MediaType is_ipf(const uint8_t *buffer, size_t file_size) {
|
||||
// http://justsolve.archiveteam.org/wiki/IPF
|
||||
if (!memcmp(buffer, "CAPS\x00\x00\x00", 7)) return MediaType_3_5;
|
||||
return MediaTypeUnknown;
|
||||
}
|
||||
|
||||
static MediaType is_hxcf(const uint8_t *buffer, size_t file_size) {
|
||||
// HxCFloppyEmulator
|
||||
if (!memcmp(buffer, "HXCMFM", 6)) return MediaType_3_5;
|
||||
return MediaTypeUnknown;
|
||||
}
|
||||
|
||||
static MediaType is_msa(const uint8_t *buffer, size_t file_size) {
|
||||
// Atari MSA
|
||||
if (!memcmp(buffer, "\x0x\x0f", 2)) return MediaType_3_5;
|
||||
return MediaTypeUnknown;
|
||||
}
|
||||
|
||||
static MediaType is_pasti(const uint8_t *buffer, size_t file_size) {
|
||||
// Atari STX/Pasti
|
||||
if (!memcmp(buffer, "RSY\x00\x03\x00", 6)) return MediaType_3_5;
|
||||
return MediaTypeUnknown;
|
||||
}
|
||||
|
||||
MediaType ClassifyMediaFile(id file) {
|
||||
|
||||
struct stat st;
|
||||
ssize_t size;
|
||||
unsigned char buffer[128];
|
||||
int fd;
|
||||
const char *path = [file fileSystemRepresentation]; // or URL
|
||||
const char *ext = extname(path);
|
||||
unsigned ext_hash = hash(ext);
|
||||
|
||||
memset(&st, 0, sizeof(st));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) return MediaTypeError;
|
||||
fstat(fd, &st);
|
||||
|
||||
size = read(fd, buffer, sizeof(buffer));
|
||||
close(fd);
|
||||
if (size <= 0) return MediaTypeError;
|
||||
|
||||
// 13 sector support ? not on an event 512 block boundary.
|
||||
// = 116480 bytes.
|
||||
|
||||
switch(ext_hash) {
|
||||
case _x3('w', 'o', 'z'):
|
||||
return is_woz(buffer, st.st_size);
|
||||
|
||||
case _x3('2', 'm', 'g'):
|
||||
case _x4('2', 'i', 'm', 'g'):
|
||||
return is_2img(buffer, st.st_size);
|
||||
|
||||
case _x3('c', 'h', 'd'):
|
||||
return is_chd(buffer, st.st_size);
|
||||
|
||||
// dc42 - dc,dc42,dsk,img,image
|
||||
case _x2('d', 'c'): // n.b. as of .233, allowed for mac, not for apple2
|
||||
case _x4('d', 'c', '4', '2'):
|
||||
return is_dc42(buffer, st.st_size);
|
||||
|
||||
// dsk, image, img may also be raw or disk copy.
|
||||
case _x3('d', 's', 'k'):
|
||||
case _x3('i', 'm', 'g'):
|
||||
case _x4('i', 'm', 'a', 'g'):
|
||||
|
||||
if (is_raw_525(st.st_size)) return MediaType_5_25;
|
||||
if (is_raw_35(st.st_size)) return MediaType_3_5;
|
||||
return is_dc42(buffer, st.st_size);
|
||||
|
||||
case _x2('d', 'o'):
|
||||
case _x2('p', 'o'):
|
||||
if (is_raw_525(st.st_size)) return MediaType_5_25;
|
||||
if (is_raw_35(st.st_size)) return MediaType_3_5;
|
||||
return MediaTypeUnknown;
|
||||
|
||||
// hdv - 3.5 or hard drive.
|
||||
case _x3('h', 'd', 'v'):
|
||||
case _x3('r', 'a', 'w'):
|
||||
if (is_raw_35(st.st_size)) return MediaType_3_5;
|
||||
if ((st.st_size & 511) == 0) return MediaType_HardDisk;
|
||||
return MediaTypeUnknown;
|
||||
|
||||
case _x3('n', 'i', 'b'):
|
||||
return MediaType_5_25;
|
||||
|
||||
case _x3('w', 'a', 'v'):
|
||||
return MediaType_Cassette;
|
||||
|
||||
// cd-rom
|
||||
case _x3('i', 's', 'o'):
|
||||
case _x3('c', 'u', 'e'):
|
||||
case _x3('c', 'd', 'r'):
|
||||
return MediaType_CDROM;
|
||||
|
||||
case _x3('p', 'n', 'g'):
|
||||
return MediaType_Picture;
|
||||
|
||||
case _x3('m', 'i', 'd'):
|
||||
return MediaType_MIDI;
|
||||
|
||||
|
||||
// atari st, etc, 3.5 disk?
|
||||
// http://justsolve.archiveteam.org/wiki/Disk_Image_Formats
|
||||
|
||||
case _x3('i', 'p', 'f'):
|
||||
return is_ipf(buffer, st.st_size);
|
||||
|
||||
case _x3('m', 'f', 'm'):
|
||||
return is_hxcf(buffer, st.st_size);
|
||||
|
||||
case _x3('m', 's', 'a'):
|
||||
return is_msa(buffer, st.st_size);
|
||||
|
||||
case _x2('s', 't'):
|
||||
if (is_raw_35(st.st_size)) return MediaType_3_5;
|
||||
return MediaTypeUnknown;
|
||||
|
||||
case _x3('s', 't', 'x'): // pasti
|
||||
return is_pasti(buffer, st.st_size);
|
||||
|
||||
//case _x3('m', 'f', 'i'): // mame/mess floppy image [???]
|
||||
//case _x3('d', 'f', 'i'): // disc ferret image
|
||||
//case _x3('h', 'f', 'e'): // ???
|
||||
//case _x3('t', 'd', '0'): // teledisk - may be split across multiple files (.td1, .td2, ...)
|
||||
//case _x3('i', 'm', 'd'): // imagedisk
|
||||
//case _x3('d', '7', '7'): //pc-88, may have multiple disk images
|
||||
//case _x3('d', '8', '8'): //fm-77, may have multiple disk images.
|
||||
//case _x3('1', 'd', 'd'): // related?
|
||||
//case _x3('c', 'q', 'm'): // copyQM
|
||||
//case _x3('c', 'q', 'i'): // copyQM
|
||||
|
||||
case _x3('r', 'o', 'm'):
|
||||
case _x3('b', 'i', 'n'):
|
||||
return MediaType_ROM;
|
||||
}
|
||||
|
||||
return MediaTypeUnknown;
|
||||
|
||||
}
|
|
@ -7,29 +7,31 @@
|
|||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Media.h"
|
||||
#import "Ample.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MediaViewController : NSViewController <NSOutlineViewDelegate, NSOutlineViewDataSource>
|
||||
|
||||
@property (weak) IBOutlet NSOutlineView *outlineView;
|
||||
@property (nonatomic) NSDictionary *media;
|
||||
@property (nonatomic) Media media;
|
||||
@property NSArray *args;
|
||||
|
||||
- (IBAction)deleteAction:(id)sender;
|
||||
- (IBAction)ejectAction:(id)sender;
|
||||
- (IBAction)pathAction:(id)sender;
|
||||
|
||||
-(IBAction)resetMedia:(id)sender;
|
||||
|
||||
//-(void)setMedia: (NSDictionary *)media;
|
||||
-(BOOL)smartRouteURL: (NSURL *)url;
|
||||
-(BOOL)smartRouteFile: (NSString *)file;
|
||||
|
||||
@end
|
||||
|
||||
@interface MediaViewController (Bookmark) <Bookmark>
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface TablePathView : NSTableCellView
|
||||
@property (weak) IBOutlet NSPathControl *pathControl;
|
||||
@property (weak) IBOutlet NSButton *deleteButton;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
15
Ample/Menu.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Menu.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 10/3/2020.
|
||||
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Menu_h
|
||||
#define Menu_h
|
||||
|
||||
NSFont *ItalicMenuFont(void);
|
||||
NSAttributedString *ItalicMenuString(NSString *s);
|
||||
|
||||
#endif /* Menu_h */
|
27
Ample/Menu.m
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Menu.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 10/3/2020.
|
||||
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NSFont *ItalicMenuFont(void) {
|
||||
NSFont *font = [NSFont menuFontOfSize: 0];
|
||||
NSFontDescriptor *fd = [font fontDescriptor];
|
||||
NSFontDescriptor *fd2 = [fd fontDescriptorWithSymbolicTraits: NSFontDescriptorTraitItalic];
|
||||
return [NSFont fontWithDescriptor: fd2 size: [font pointSize]];
|
||||
}
|
||||
|
||||
NSAttributedString *ItalicMenuString(NSString *s) {
|
||||
static NSDictionary *attr = nil;
|
||||
if (!attr) {
|
||||
attr = @{
|
||||
NSFontAttributeName: ItalicMenuFont()
|
||||
};
|
||||
}
|
||||
return [[NSAttributedString alloc] initWithString: s attributes: attr];
|
||||
}
|
25
Ample/MidiManager.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// MidiManager.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 8/6/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef MidiManager_h
|
||||
#define MidiManager_h
|
||||
|
||||
|
||||
extern NSString *kMidiSourcesChangedNotification;
|
||||
extern NSString *kMidiDestinationsChangedNotification;
|
||||
|
||||
@interface MidiManager : NSObject
|
||||
|
||||
@property NSArray *sources;
|
||||
@property NSArray *destinations;
|
||||
|
||||
+(instancetype)sharedManager;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MidiManager_h */
|
153
Ample/MidiManager.m
Normal file
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// Midi.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 8/6/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreMIDI/CoreMIDI.h>
|
||||
|
||||
#import "MidiManager.h"
|
||||
|
||||
static NSArray *MidiSources(void) {
|
||||
|
||||
ItemCount count = MIDIGetNumberOfSources();
|
||||
if (count <= 0) return @[];
|
||||
|
||||
NSMutableArray *rv = [NSMutableArray arrayWithCapacity: count + 1];
|
||||
|
||||
MIDIEndpointRef ep;
|
||||
for(int i = 0; i < count; ++i) {
|
||||
ep = MIDIGetSource(i);
|
||||
if (!ep) continue;
|
||||
|
||||
// https://developer.apple.com/library/archive/qa/qa1374/_index.html
|
||||
CFStringRef str = NULL;
|
||||
MIDIObjectGetStringProperty(ep, kMIDIPropertyDisplayName, &str);
|
||||
|
||||
if (str) {
|
||||
[rv addObject: (__bridge id _Nonnull)(str)];
|
||||
CFRelease(str);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static NSArray *MidiDestinations(void) {
|
||||
|
||||
ItemCount count = MIDIGetNumberOfDestinations();
|
||||
if (count <= 0) return @[];
|
||||
|
||||
NSMutableArray *rv = [NSMutableArray arrayWithCapacity: count + 1];
|
||||
|
||||
MIDIEndpointRef ep;
|
||||
for(int i = 0; i < count; ++i) {
|
||||
ep = MIDIGetDestination(i);
|
||||
if (!ep) continue;
|
||||
|
||||
// https://developer.apple.com/library/archive/qa/qa1374/_index.html
|
||||
CFStringRef str = NULL;
|
||||
MIDIObjectGetStringProperty(ep, kMIDIPropertyDisplayName, &str);
|
||||
|
||||
if (str) {
|
||||
[rv addObject: (__bridge id _Nonnull)(str)];
|
||||
CFRelease(str);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NSString *kMidiSourcesChangedNotification = @"Midi Sources Changed";
|
||||
NSString *kMidiDestinationsChangedNotification = @"Midi Destinations Changed";
|
||||
|
||||
|
||||
@interface MidiManager () {
|
||||
MIDIClientRef _client;
|
||||
}
|
||||
|
||||
-(void)objectAddRemove: (const MIDIObjectAddRemoveNotification *)message;
|
||||
-(void)objectPropertyChanged: (const MIDIObjectPropertyChangeNotification *)message;
|
||||
@end
|
||||
|
||||
|
||||
static MidiManager *singleton = nil;
|
||||
@implementation MidiManager
|
||||
|
||||
-(void)awakeFromNib {
|
||||
if (!singleton) singleton = self;
|
||||
}
|
||||
|
||||
+(instancetype)sharedManager {
|
||||
if (!singleton) singleton = [MidiManager new];
|
||||
return singleton;
|
||||
}
|
||||
|
||||
-(instancetype)init {
|
||||
|
||||
if (singleton) return singleton;
|
||||
|
||||
OSStatus status;
|
||||
|
||||
|
||||
status = MIDIClientCreateWithBlock(
|
||||
CFSTR("serial_midi"),
|
||||
&_client,
|
||||
^(const MIDINotification *message){
|
||||
switch(message->messageID) {
|
||||
case kMIDIMsgObjectAdded:
|
||||
case kMIDIMsgObjectRemoved:
|
||||
[self objectAddRemove: (const MIDIObjectAddRemoveNotification *)message];
|
||||
break;
|
||||
case kMIDIMsgPropertyChanged:
|
||||
[self objectPropertyChanged: (const MIDIObjectPropertyChangeNotification *)message];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
_sources = MidiSources();
|
||||
_destinations = MidiDestinations();
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)objectAddRemove: (const MIDIObjectAddRemoveNotification *)message {
|
||||
|
||||
const MIDIObjectAddRemoveNotification *m = (const MIDIObjectAddRemoveNotification *)message;
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
if (m->childType == kMIDIObjectType_Source) {
|
||||
[self setSources: MidiSources()];
|
||||
[nc postNotificationName: kMidiSourcesChangedNotification object: self];
|
||||
}
|
||||
|
||||
if (m->childType == kMIDIObjectType_Destination) {
|
||||
[self setDestinations: MidiDestinations()];
|
||||
[nc postNotificationName: kMidiDestinationsChangedNotification object: self];
|
||||
}
|
||||
|
||||
}
|
||||
-(void)objectPropertyChanged: (const MIDIObjectPropertyChangeNotification *)message {
|
||||
|
||||
const MIDIObjectPropertyChangeNotification *m = (const MIDIObjectPropertyChangeNotification *)message;
|
||||
if (m->propertyName == kMIDIPropertyDisplayName) {
|
||||
[self setSources: MidiSources()];
|
||||
[self setDestinations: MidiDestinations()];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc postNotificationName: kMidiSourcesChangedNotification object: self];
|
||||
[nc postNotificationName: kMidiDestinationsChangedNotification object: self];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)dealloc {
|
||||
|
||||
if (_client)
|
||||
MIDIClientDispose(_client);
|
||||
}
|
||||
@end
|
||||
|
30
Ample/NewMachineViewController.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// NewMachineViewController.h
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 6/8/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Ample.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NewMachineViewController : NSViewController
|
||||
|
||||
@property (nullable) NSString *machine;
|
||||
|
||||
-(void)reset;
|
||||
|
||||
@end
|
||||
|
||||
@interface NewMachineViewController (Table) <NSOutlineViewDelegate, NSOutlineViewDataSource>
|
||||
|
||||
@end
|
||||
|
||||
@interface NewMachineViewController (Bookmark) <Bookmark>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
238
Ample/NewMachineViewController.m
Normal file
|
@ -0,0 +1,238 @@
|
|||
//
|
||||
// NewMachineViewController.m
|
||||
// Ample
|
||||
//
|
||||
// Created by Kelvin Sherlock on 6/8/2021.
|
||||
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NewMachineViewController.h"
|
||||
|
||||
@interface NewMachineViewController () {
|
||||
|
||||
NSArray *_data;
|
||||
}
|
||||
|
||||
@property (weak) IBOutlet NSOutlineView *outlineView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NewMachineViewController
|
||||
|
||||
-(void)awakeFromNib {
|
||||
|
||||
static unsigned first = 0;
|
||||
|
||||
if (first) return;
|
||||
first++;
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
#ifdef AMPLE_LITE
|
||||
NSString *path = [bundle pathForResource: @"models~extra" ofType: @"plist"];
|
||||
#else
|
||||
NSString *path = [bundle pathForResource: @"models" ofType: @"plist"];
|
||||
#endif
|
||||
_data = [NSArray arrayWithContentsOfFile: path];
|
||||
|
||||
}
|
||||
|
||||
-(void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
//[_outlineView reloadData];
|
||||
//[_outlineView setAutosaveExpandedItems: YES];
|
||||
//[_outlineView expandItem: nil expandChildren: YES];
|
||||
}
|
||||
|
||||
#pragma mark - IBActions
|
||||
- (IBAction)clickAction:(id)sender {
|
||||
|
||||
NSInteger row = [_outlineView clickedRow];
|
||||
if (row < 0) return;
|
||||
NSDictionary *item = [_outlineView itemAtRow: row];
|
||||
if (!item) return;
|
||||
|
||||
NSString *value = [item objectForKey: @"value"];
|
||||
NSArray *children = [item objectForKey: @"children"];
|
||||
|
||||
if (value) {
|
||||
[self setMachine: value];
|
||||
} else if (children) {
|
||||
id ap = [_outlineView animator];
|
||||
[_outlineView isItemExpanded: item] ? [ap collapseItem: item] : [ap expandItem: item];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)reset {
|
||||
|
||||
[_outlineView deselectAll: nil];
|
||||
[self setMachine: nil];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation NewMachineViewController (Table)
|
||||
|
||||
#if 0
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldCollapseItem:(id)item {
|
||||
return NO;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item {
|
||||
// disclosure triangle.
|
||||
if (!item) return YES;
|
||||
NSArray *children = [(NSDictionary *)item objectForKey: @"children"];
|
||||
return [children count] > 0;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
|
||||
if (!item) return YES;
|
||||
NSArray *children = [(NSDictionary *)item objectForKey: @"children"];
|
||||
return [children count] > 0;
|
||||
}
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
|
||||
|
||||
#if 0
|
||||
NSArray *children = [(NSDictionary *)item objectForKey: @"children"];
|
||||
return [children count] > 0;
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
|
||||
|
||||
#if 0
|
||||
NSArray *children = [(NSDictionary *)item objectForKey: @"children"];
|
||||
if ([children count]) {
|
||||
return [outlineView makeViewWithIdentifier: @"HeaderCell" owner: self];
|
||||
}
|
||||
#endif
|
||||
NSTableCellView *v = [outlineView makeViewWithIdentifier: @"DataCell" owner: self];
|
||||
//[v setObjectValue: item];
|
||||
return v;
|
||||
}
|
||||
|
||||
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
|
||||
if (!item) return [_data count];
|
||||
NSArray *children = [(NSDictionary *)item objectForKey: @"children"];
|
||||
return [children count];
|
||||
}
|
||||
|
||||
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
|
||||
|
||||
if (item == nil) {
|
||||
return [_data objectAtIndex: index];
|
||||
}
|
||||
NSArray *children = [(NSDictionary *)item objectForKey: @"children"];
|
||||
return [children objectAtIndex: index];
|
||||
}
|
||||
|
||||
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item {
|
||||
if (!item) return NO;
|
||||
return [(NSDictionary *)item objectForKey: @"value"] != nil;
|
||||
}
|
||||
|
||||
|
||||
// saving/restoring expanded items
|
||||
- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item {
|
||||
|
||||
return [item objectForKey: @"description"];
|
||||
}
|
||||
|
||||
- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object {
|
||||
|
||||
if ([object isKindOfClass: [NSString class]]) {
|
||||
|
||||
for(NSDictionary *d in _data) {
|
||||
if ([(NSString *)object isEqualToString: [d objectForKey: @"description"]])
|
||||
return d;
|
||||
}
|
||||
|
||||
}
|
||||
return nil;
|
||||
//return object;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NewMachineViewController (Bookmark)
|
||||
|
||||
|
||||
- (void)didLoadBookmark:(NSDictionary *)bookmark {
|
||||
}
|
||||
|
||||
- (BOOL)loadBookmark:(NSDictionary *)bookmark {
|
||||
NSString *machine = [bookmark objectForKey: @"machine"];
|
||||
|
||||
|
||||
|
||||
//NSInteger row = [_outlineView selectedRow];
|
||||
if (!machine) {
|
||||
[self setMachine: nil];
|
||||
[_outlineView deselectAll: nil];
|
||||
return NO;
|
||||
}
|
||||
|
||||
for (NSDictionary *parent in _data) {
|
||||
NSArray *children = [parent objectForKey: @"children"];
|
||||
|
||||
for (NSDictionary *child in children) {
|
||||
if ([machine isEqualToString: [child objectForKey: @"value"]]) {
|
||||
|
||||
id ap = [_outlineView animator];
|
||||
[ap expandItem: parent];
|
||||
NSInteger row = [_outlineView rowForItem: child];
|
||||
if (row >= 0) {
|
||||
NSIndexSet *set = [NSIndexSet indexSetWithIndex: row];
|
||||
[_outlineView selectRowIndexes: set byExtendingSelection: NO];
|
||||
[_outlineView scrollRowToVisible: row];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// could also match parent.
|
||||
if ([machine isEqualToString: [parent objectForKey: @"value"]]) {
|
||||
NSInteger row = [_outlineView rowForItem: parent];
|
||||
if (row >= 0) {
|
||||
NSIndexSet *set = [NSIndexSet indexSetWithIndex: row];
|
||||
[_outlineView selectRowIndexes: set byExtendingSelection: NO];
|
||||
[_outlineView scrollRowToVisible: row];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)saveBookmark:(NSMutableDictionary *)bookmark {
|
||||
// machine saved in parent.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)willLoadBookmark:(NSDictionary *)bookmark {
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -9,8 +9,13 @@
|
|||
#import "Ample.h"
|
||||
#import "PreferencesWindowController.h"
|
||||
|
||||
#import <Security/Security.h>
|
||||
|
||||
|
||||
@interface PreferencesWindowController ()
|
||||
@property (weak) IBOutlet NSTextField *pathField;
|
||||
@property (weak) IBOutlet NSTextField *wdField;
|
||||
@property (weak) IBOutlet NSButton *fixButton;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -27,19 +32,41 @@
|
|||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
|
||||
[self validateMamePath: [defaults stringForKey: kMamePath]];
|
||||
[self validateMameWD: [defaults stringForKey: kMameWorkingDirectory]];
|
||||
|
||||
/* check vmnet_helper permissions */
|
||||
|
||||
int needs_fixin = [self checkHelperPermissions: nil];
|
||||
[_fixButton setEnabled: needs_fixin > 0];
|
||||
}
|
||||
|
||||
-(void)validateMamePath: (NSString *)path {
|
||||
NSFileManager * fm = [NSFileManager defaultManager];
|
||||
|
||||
if ([path length] == 0 || [fm isExecutableFileAtPath: path]) {
|
||||
[_pathField setTextColor: [NSColor blackColor]];
|
||||
[_pathField setTextColor: nil];
|
||||
} else {
|
||||
[_pathField setTextColor: [NSColor redColor]];
|
||||
[_pathField setTextColor: [NSColor systemRedColor]];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)validateMameWD: (NSString *)path {
|
||||
NSFileManager * fm = [NSFileManager defaultManager];
|
||||
BOOL directory = YES;
|
||||
|
||||
if ([path length] == 0) {
|
||||
[_wdField setTextColor: nil];
|
||||
return;
|
||||
}
|
||||
|
||||
if ([fm fileExistsAtPath: path isDirectory: &directory] && directory) {
|
||||
[_wdField setTextColor: nil];
|
||||
return;
|
||||
|
||||
}
|
||||
[_wdField setTextColor: [NSColor systemRedColor]];
|
||||
}
|
||||
|
||||
- (IBAction)pathChanged:(id)sender {
|
||||
|
||||
NSString *path = [sender stringValue];
|
||||
|
@ -47,6 +74,126 @@
|
|||
[self validateMamePath: path];
|
||||
|
||||
}
|
||||
- (IBAction)wdChanged:(id)sender {
|
||||
|
||||
NSString *path = [sender stringValue];
|
||||
|
||||
[self validateMameWD: path];
|
||||
}
|
||||
|
||||
// -1 - error
|
||||
// 1 - needs help
|
||||
// 0 - a-ok
|
||||
-(int)checkHelperPermissions: (NSString *)path {
|
||||
|
||||
static const unsigned Mask = S_ISUID | S_ISGID;
|
||||
if (!path) {
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
path = [bundle pathForAuxiliaryExecutable: @"vmnet_helper"];
|
||||
}
|
||||
if (!path) return -1;
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
NSDictionary *attr = [fm attributesOfItemAtPath: path error: &error];
|
||||
|
||||
if (error) return -1;
|
||||
|
||||
NSNumber *owner = [attr objectForKey: NSFileOwnerAccountID];
|
||||
NSNumber *perm = [attr objectForKey: NSFilePosixPermissions];
|
||||
if ([owner longValue] == 0 && ([perm unsignedIntValue] & Mask) == Mask) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (IBAction)fixPerms:(id)sender {
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSString *path = [bundle pathForAuxiliaryExecutable: @"vmnet_helper"];
|
||||
if (!path) return;
|
||||
|
||||
|
||||
#if 0
|
||||
// this requires an entitlement and sanboxing and Apple's permission.
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
[ws requestAuthorizationOfType:NSWorkspaceAuthorizationTypeSetAttributes
|
||||
completionHandler: ^(NSWorkspaceAuthorization *a, NSError *e){
|
||||
if (e || !a) return;
|
||||
|
||||
NSError *error = nil;
|
||||
NSDictionary *attr = @{
|
||||
NSFileOwnerAccountID: @0, /* root */
|
||||
NSFileGroupOwnerAccountID: @20, /* staff */
|
||||
// NSFilePosixPermissions: @0106755 /* 755 + setuid + setgid */
|
||||
};
|
||||
|
||||
|
||||
|
||||
NSFileManager *fm = [NSFileManager fileManagerWithAuthorization: a];
|
||||
[fm setAttributes: attr ofItemAtPath: path error: &error];
|
||||
if (error) {
|
||||
NSLog(@"%@", error);
|
||||
// NSAlert *a = [NSAlert alertWithError: error];
|
||||
// [a runModal];
|
||||
}
|
||||
else {
|
||||
[self->_fixButton setEnabled: NO];
|
||||
}
|
||||
|
||||
}];
|
||||
#endif
|
||||
|
||||
// AuthorizationExecuteWithPrivileges - deprecated in 10.7
|
||||
// https://github.com/sveinbjornt/STPrivilegedTask
|
||||
// XMJobBless + launchd stuff - the preferred way to do it...
|
||||
// https://developer.apple.com/library/archive/samplecode/BetterAuthorizationSample/Introduction/Intro.html
|
||||
// https://developer.apple.com/library/archive/samplecode/SMJobBless/Listings/ReadMe_txt.html#//apple_ref/doc/uid/DTS40010071-ReadMe_txt-DontLinkElementID_3
|
||||
//
|
||||
// really should be a launchd service but that's for another time...
|
||||
|
||||
AuthorizationRef myAuthorizationRef = 0;
|
||||
OSStatus myStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &myAuthorizationRef);
|
||||
if (myStatus) return;
|
||||
|
||||
AuthorizationItem myItems[1] = {{0}};
|
||||
myItems[0].name = kAuthorizationRightExecute;
|
||||
myItems[0].valueLength = 0;
|
||||
myItems[0].value = NULL;
|
||||
myItems[0].flags = 0;
|
||||
AuthorizationRights myRights = {0};
|
||||
myRights.count = sizeof(myItems) / sizeof(myItems[0]);
|
||||
myRights.items = myItems;
|
||||
AuthorizationFlags myFlags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize;
|
||||
myStatus = AuthorizationCopyRights(myAuthorizationRef, &myRights,
|
||||
kAuthorizationEmptyEnvironment, myFlags, NULL);
|
||||
|
||||
if (!myStatus) {
|
||||
FILE *fp = NULL;
|
||||
static char buffer[4096];
|
||||
const char *cp = [path fileSystemRepresentation];
|
||||
const char* args_chown[] = {"root", cp , NULL};
|
||||
const char* args_chmod[] = {"+s", cp, NULL};
|
||||
|
||||
// well ... the second command executes a lot more consistently when the (optional) fp is provided and the we fgets the buffer.
|
||||
// textmate does a wait() to wait for a child to exit. Using the fp (which is popened()?) and reading until EOF
|
||||
// accomplishes the same thing.
|
||||
myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/usr/sbin/chown", kAuthorizationFlagDefaults, (char**)args_chown, &fp);
|
||||
while (fgets(buffer, sizeof(buffer), fp));
|
||||
fclose(fp);
|
||||
// fprintf(stderr, "myStatus = %d\ndata: %s\n", myStatus, buffer);
|
||||
|
||||
myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/bin/chmod", kAuthorizationFlagDefaults, (char**)args_chmod, &fp);
|
||||
while (fgets(buffer, sizeof(buffer), fp));
|
||||
fclose(fp);
|
||||
// fprintf(stderr, "myStatus = %d\ndata: %s\n", myStatus, buffer);
|
||||
|
||||
}
|
||||
AuthorizationFree(myAuthorizationRef, kAuthorizationFlagDestroyRights);
|
||||
|
||||
int needs_fixin = [self checkHelperPermissions: path];
|
||||
[_fixButton setEnabled: needs_fixin > 0];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
231
Ample/Resources/CheatSheet.html
Normal file
|
@ -0,0 +1,231 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Keyboard Cheat Sheet</title>
|
||||
<style type="text/css">
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
font-family: -apple-system, 'HelveticaNeue' ;
|
||||
font: -apple-system-body;
|
||||
}
|
||||
|
||||
body {
|
||||
user-select: none;
|
||||
|
||||
background-color: rgb(236, 236, 236);
|
||||
color: rgb(38, 38, 38);
|
||||
}
|
||||
h1, h2 {
|
||||
text-align: center;
|
||||
font-size: 150%;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
kbd {
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
padding-left: .5em;
|
||||
padding-right: .5em;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 2px;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 5px;
|
||||
margin-left: 4px;
|
||||
|
||||
border: solid 1px black;
|
||||
box-shadow: 1px 1px 2px 0px rgba(0,0,0,0.75), inset 1px 1px 2px 0px white;
|
||||
text-shadow: 0px 1px 0px rgb(255, 255, 255);
|
||||
background-color: rgb(225, 225, 225);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: rgb(50, 50, 50);
|
||||
color: rgb(225, 225, 225);
|
||||
}
|
||||
|
||||
kbd {
|
||||
border: solid 1px black;
|
||||
text-shadow: 0px 1px 0px black;
|
||||
box-shadow: 1px 1px 2px 0px rgba(0,0,0,0.75);
|
||||
background-color: rgb(101, 101, 101);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
/* os x 10.11 */
|
||||
if (window.NodeList && !NodeList.prototype.forEach) {
|
||||
NodeList.prototype.forEach = Array.prototype.forEach;
|
||||
}
|
||||
|
||||
function macbook(onoff) {
|
||||
var nodes = document.querySelectorAll("[data-macbook]");
|
||||
nodes.forEach( function(e) {
|
||||
var m = (e.dataset.macbook == "true");
|
||||
e.hidden = m ^ onoff;
|
||||
});
|
||||
}
|
||||
window.addEventListener('load', function(event) {
|
||||
macbook(false);
|
||||
|
||||
var e = document.getElementById('macbook');
|
||||
if (e) {
|
||||
e.checked = false;
|
||||
e.addEventListener('click', function (event) {
|
||||
macbook(e.checked);
|
||||
});
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
MacBook: <input type="checkbox" id="macbook" />
|
||||
</div>
|
||||
<h1>Full UI Mode</h1>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 14em;" />
|
||||
<col />
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-macbook=false><kbd>Delete</kbd></span>
|
||||
<span data-macbook=true><kbd>Fn</kbd>+<kbd>Delete</kbd></span>
|
||||
</td>
|
||||
<td>Toggle partial UI mode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Option</kbd>+<kbd>Enter</kbd></td>
|
||||
<td>Toggle full screen mode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-macbook=false><kbd>F12</kbd></span>
|
||||
<span data-macbook=true><kbd>Fn</kbd>+<kbd>F12</kbd></span>
|
||||
</td>
|
||||
<td>Reset Key</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1>Partial UI Mode</h1>
|
||||
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 14em;" />
|
||||
<col />
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-macbook=false><kbd>Delete</kbd></span>
|
||||
<span data-macbook=true><kbd>Fn</kbd>+<kbd>Delete</kbd></span>
|
||||
</td>
|
||||
<td>Toggle full UI mode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Option</kbd>+<kbd>Enter</kbd></td>
|
||||
<td>Toggle full screen mode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Tab</kbd></td>
|
||||
<td>Config menu</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Esc</kbd></td>
|
||||
<td>Quit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>F5</kbd></td>
|
||||
<td>Pause</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>~</kbd></td>
|
||||
<td>Debugger break (when active)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<span data-macbook=false><kbd>Page Down</kbd></span>
|
||||
<span data-macbook=true><kbd>Fn</kbd>+<kbd>Down Arrow</kbd></span>
|
||||
</td>
|
||||
<td>Fast forward (while pressed)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>F3</kbd></td>
|
||||
<td>Soft reset</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd>+<kbd>F3</kbd></td>
|
||||
<td>Hard reset</td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td><kbd>F5</kbd></td>
|
||||
<td>Toggle debugger</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd>+<kbd>F5</kbd></td>
|
||||
<td>Toggle graphic filters</td>
|
||||
</tr>
|
||||
-->
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd>+<kbd>F6</kbd></td>
|
||||
<td>Create save state</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>F7</kbd></td>
|
||||
<td>Load save state</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><kbd>F10</kbd></td>
|
||||
<td>Toggle throttle</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>F11</kbd></td>
|
||||
<td>Show FPS</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd>+<kbd>F11</kbd></td>
|
||||
<td>Show profiler</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>F12</kbd></td>
|
||||
<td>Save snapshot</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd>+<kbd>F12</kbd></td>
|
||||
<td>Record MNG video</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Control</kbd>+<kbd>Shift</kbd>+<kbd>F12</kbd></td>
|
||||
<td>Record AVI video</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Option</kbd>+<kbd>Shift</kbd>+<kbd>F12</kbd></td>
|
||||
<td>Record rendered AVI video</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Note</h2>
|
||||
<ul class="note">
|
||||
<li><kbd>F</kbd> keys may require <kbd>Fn</kbd> key depending on keyboard and system settings.</li>
|
||||
<li><kbd>Shift</kbd>, <kbd>Control</kbd>, and <kbd>Option</kbd> assume left-key unless otherwise specified.</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
875
Ample/Resources/a1000.plist
Normal file
|
@ -0,0 +1,875 @@
|
|||
<?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>value</key>
|
||||
<string>a1000</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 (PAL)</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>resolution</key>
|
||||
<array>
|
||||
<integer>724</integer>
|
||||
<integer>567</integer>
|
||||
</array>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>description</key>
|
||||
<string>Disk Drives</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string></string>
|
||||
<key>devname</key>
|
||||
<string>smartport</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>rs232</string>
|
||||
<key>description</key>
|
||||
<string>Serial</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>ie15_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>devname</key>
|
||||
<string>scorpion_ic</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>pseudo_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>rs_serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>devname</key>
|
||||
<string>dec_rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>devname</key>
|
||||
<string>null_modem</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_patch_box</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>devname</key>
|
||||
<string>serial_keyboard</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>serial_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>devname</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>devname</key>
|
||||
<string>mockingboardd</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>swtpc8212_terminal</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>centronics</string>
|
||||
<key>description</key>
|
||||
<string>Printer</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Centronics Printer</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>centronics_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pl80</string>
|
||||
<key>description</key>
|
||||
<string>COMX PL-80</string>
|
||||
<key>devname</key>
|
||||
<string>comx_pl80</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>covox_stereo</string>
|
||||
<key>description</key>
|
||||
<string>Covox (Stereo-in-1)</string>
|
||||
<key>devname</key>
|
||||
<string>covox_stereo</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>covox</string>
|
||||
<key>description</key>
|
||||
<string>Covox Speech Thing</string>
|
||||
<key>devname</key>
|
||||
<string>covox</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>digiblst</string>
|
||||
<key>description</key>
|
||||
<string>Digiblaster (DIY)</string>
|
||||
<key>devname</key>
|
||||
<string>cpcdigiblst</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ap2000</string>
|
||||
<key>description</key>
|
||||
<string>Epson ActionPrinter 2000</string>
|
||||
<key>devname</key>
|
||||
<string>ap2000</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ex800</string>
|
||||
<key>description</key>
|
||||
<string>Epson EX-800</string>
|
||||
<key>devname</key>
|
||||
<string>ex800</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>lx800</string>
|
||||
<key>description</key>
|
||||
<string>Epson LX-800</string>
|
||||
<key>devname</key>
|
||||
<string>lx800</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>lx810l</string>
|
||||
<key>description</key>
|
||||
<string>Epson LX-810L</string>
|
||||
<key>devname</key>
|
||||
<string>lx810l</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>p72</string>
|
||||
<key>description</key>
|
||||
<string>NEC PinWriter P72</string>
|
||||
<key>devname</key>
|
||||
<string>p72</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>samdac</string>
|
||||
<key>description</key>
|
||||
<string>SAMDAC</string>
|
||||
<key>devname</key>
|
||||
<string>centronics_samdac</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nlq401</string>
|
||||
<key>description</key>
|
||||
<string>Schneider NLQ 401 Matrix Printer</string>
|
||||
<key>devname</key>
|
||||
<string>nlq401</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>chessmec</string>
|
||||
<key>description</key>
|
||||
<string>Tasc ChessMachine EC Interface</string>
|
||||
<key>devname</key>
|
||||
<string>centronics_chessmec</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>smartboard</string>
|
||||
<key>description</key>
|
||||
<string>Tasc SmartBoard SB30 Interface</string>
|
||||
<key>devname</key>
|
||||
<string>centronics_smartboard</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>kbd</string>
|
||||
<key>description</key>
|
||||
<string>Keyboard</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_dk</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Denmark)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_dk</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_fr</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (France/Belgium)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_fr</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_de</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Germany/Austria)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_de</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_it</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Italy)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_it</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_se</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Sweden/Finland)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_se</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (U.S./Canada)</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_us</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_gb</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (UK)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_gb</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1200_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1200 Keyboard Rev B</string>
|
||||
<key>devname</key>
|
||||
<string>a1200kbd_rb</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_dk</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - Denmark)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_dk</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_de</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - Germany/Austria)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_de</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_se</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - Sweden/Finland)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_se</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - U.S./Canada)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_us</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_gb</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - UK)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_gb</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_dk</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Denmark)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_dk</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_fr</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (France/Belgium)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_fr</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_de</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Germany/Austria)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_de</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_it</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Italy)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_it</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_no</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Norway)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_no</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_es</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Spain)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_es</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_se</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Sweden/Finland)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_se</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_ch</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Switzerland)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_ch</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (U.S./Canada)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_us</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_gb</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (UK)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_gb</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>devices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:2</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:3</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>rs232_patch_box</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:dce</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:keyboard</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type3hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 3 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type4hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 4 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5gbhle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Great Britain - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5jphle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Japan - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5sehle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Sweden - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (U.S.A. - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>software</key>
|
||||
<array>
|
||||
<string>amiga_workbench.xml</string>
|
||||
<string>amiga_hardware.xml</string>
|
||||
<string>amiga_apps.xml</string>
|
||||
<string>amiga_flop.xml</string>
|
||||
<string>amigaocs_flop.xml</string>
|
||||
<string>amiga_demos.xml</string>
|
||||
<string>amiga_a1000.xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
875
Ample/Resources/a1000n.plist
Normal file
|
@ -0,0 +1,875 @@
|
|||
<?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>value</key>
|
||||
<string>a1000n</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 (NTSC)</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>resolution</key>
|
||||
<array>
|
||||
<integer>724</integer>
|
||||
<integer>483</integer>
|
||||
</array>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>description</key>
|
||||
<string>Disk Drives</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string></string>
|
||||
<key>devname</key>
|
||||
<string>smartport</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>rs232</string>
|
||||
<key>description</key>
|
||||
<string>Serial</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>ie15_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>devname</key>
|
||||
<string>scorpion_ic</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>pseudo_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>rs_serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>devname</key>
|
||||
<string>dec_rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>devname</key>
|
||||
<string>null_modem</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_patch_box</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>devname</key>
|
||||
<string>serial_keyboard</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>serial_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>devname</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>devname</key>
|
||||
<string>mockingboardd</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>swtpc8212_terminal</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>centronics</string>
|
||||
<key>description</key>
|
||||
<string>Printer</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Centronics Printer</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>centronics_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pl80</string>
|
||||
<key>description</key>
|
||||
<string>COMX PL-80</string>
|
||||
<key>devname</key>
|
||||
<string>comx_pl80</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>covox_stereo</string>
|
||||
<key>description</key>
|
||||
<string>Covox (Stereo-in-1)</string>
|
||||
<key>devname</key>
|
||||
<string>covox_stereo</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>covox</string>
|
||||
<key>description</key>
|
||||
<string>Covox Speech Thing</string>
|
||||
<key>devname</key>
|
||||
<string>covox</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>digiblst</string>
|
||||
<key>description</key>
|
||||
<string>Digiblaster (DIY)</string>
|
||||
<key>devname</key>
|
||||
<string>cpcdigiblst</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ap2000</string>
|
||||
<key>description</key>
|
||||
<string>Epson ActionPrinter 2000</string>
|
||||
<key>devname</key>
|
||||
<string>ap2000</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ex800</string>
|
||||
<key>description</key>
|
||||
<string>Epson EX-800</string>
|
||||
<key>devname</key>
|
||||
<string>ex800</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>lx800</string>
|
||||
<key>description</key>
|
||||
<string>Epson LX-800</string>
|
||||
<key>devname</key>
|
||||
<string>lx800</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>lx810l</string>
|
||||
<key>description</key>
|
||||
<string>Epson LX-810L</string>
|
||||
<key>devname</key>
|
||||
<string>lx810l</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>p72</string>
|
||||
<key>description</key>
|
||||
<string>NEC PinWriter P72</string>
|
||||
<key>devname</key>
|
||||
<string>p72</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>samdac</string>
|
||||
<key>description</key>
|
||||
<string>SAMDAC</string>
|
||||
<key>devname</key>
|
||||
<string>centronics_samdac</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nlq401</string>
|
||||
<key>description</key>
|
||||
<string>Schneider NLQ 401 Matrix Printer</string>
|
||||
<key>devname</key>
|
||||
<string>nlq401</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>chessmec</string>
|
||||
<key>description</key>
|
||||
<string>Tasc ChessMachine EC Interface</string>
|
||||
<key>devname</key>
|
||||
<string>centronics_chessmec</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>smartboard</string>
|
||||
<key>description</key>
|
||||
<string>Tasc SmartBoard SB30 Interface</string>
|
||||
<key>devname</key>
|
||||
<string>centronics_smartboard</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>kbd</string>
|
||||
<key>description</key>
|
||||
<string>Keyboard</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_dk</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Denmark)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_dk</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_fr</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (France/Belgium)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_fr</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_de</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Germany/Austria)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_de</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_it</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Italy)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_it</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_se</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (Sweden/Finland)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_se</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (U.S./Canada)</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_us</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1000_gb</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1000 Keyboard (UK)</string>
|
||||
<key>devname</key>
|
||||
<string>a1000kbd_gb</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a1200_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 1200 Keyboard Rev B</string>
|
||||
<key>devname</key>
|
||||
<string>a1200kbd_rb</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_dk</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - Denmark)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_dk</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_de</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - Germany/Austria)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_de</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_se</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - Sweden/Finland)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_se</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - U.S./Canada)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_us</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_g80_gb</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000 Keyboard (Cherry - UK)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_g80_gb</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_dk</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Denmark)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_dk</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_fr</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (France/Belgium)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_fr</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_de</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Germany/Austria)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_de</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_it</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Italy)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_it</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_no</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Norway)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_no</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_es</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Spain)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_es</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_se</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Sweden/Finland)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_se</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_ch</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (Switzerland)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_ch</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_us</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (U.S./Canada)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_us</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a2000_gb</string>
|
||||
<key>description</key>
|
||||
<string>Amiga 2000/3000/4000 Keyboard (UK)</string>
|
||||
<key>devname</key>
|
||||
<string>a2000kbd_gb</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>devices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:2</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>fdc:3</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>35dd</string>
|
||||
<key>description</key>
|
||||
<string>3.5" DD</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_3_5</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>rs232_patch_box</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:dce</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:keyboard</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type3hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 3 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type4hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 4 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5gbhle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Great Britain - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5jphle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Japan - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5sehle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Sweden - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (U.S.A. - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>software</key>
|
||||
<array>
|
||||
<string>amiga_workbench.xml</string>
|
||||
<string>amiga_hardware.xml</string>
|
||||
<string>amiga_apps.xml</string>
|
||||
<string>amiga_flop.xml</string>
|
||||
<string>amigaocs_flop.xml</string>
|
||||
<string>amiga_demos.xml</string>
|
||||
<string>amiga_a1000.xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
3002
Ample/Resources/a2000.plist
Normal file
3002
Ample/Resources/a2000n.plist
Normal file
1255
Ample/Resources/a500.plist
Normal file
1255
Ample/Resources/a500n.plist
Normal file
7851
Ample/Resources/ace1000.plist
Normal file
8141
Ample/Resources/ace2200.plist
Normal file
575
Ample/Resources/ace500.plist
Normal file
|
@ -0,0 +1,575 @@
|
|||
<?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>value</key>
|
||||
<string>ace500</string>
|
||||
<key>description</key>
|
||||
<string>Franklin ACE 500</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>resolution</key>
|
||||
<array>
|
||||
<integer>560</integer>
|
||||
<integer>192</integer>
|
||||
</array>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>ramsize</string>
|
||||
<key>description</key>
|
||||
<string>RAM</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>131072</integer>
|
||||
<key>description</key>
|
||||
<string>128K</string>
|
||||
<key>value</key>
|
||||
<string>128K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>description</key>
|
||||
<string>Disk Drives</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string></string>
|
||||
<key>devname</key>
|
||||
<string>smartport</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>gameio</string>
|
||||
<key>description</key>
|
||||
<string>Game I/O</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>joy</string>
|
||||
<key>description</key>
|
||||
<string>Apple II Analog Joysticks</string>
|
||||
<key>devname</key>
|
||||
<string>a2joy</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>paddles</string>
|
||||
<key>description</key>
|
||||
<string>Apple II Paddles</string>
|
||||
<key>devname</key>
|
||||
<string>a2pdls</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>compeyes</string>
|
||||
<key>description</key>
|
||||
<string>Digital Vision ComputerEyes</string>
|
||||
<key>devname</key>
|
||||
<string>a2ceyes</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>picture</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>gizmo</string>
|
||||
<key>description</key>
|
||||
<string>HAL Labs Gizmo</string>
|
||||
<key>devname</key>
|
||||
<string>a2gizmo</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>modem</string>
|
||||
<key>description</key>
|
||||
<string>Modem</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>ie15_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>devname</key>
|
||||
<string>scorpion_ic</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nss_tvi</string>
|
||||
<key>description</key>
|
||||
<string>Novag Super System TV Interface</string>
|
||||
<key>devname</key>
|
||||
<string>nss_tvinterface</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>pseudo_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>rs_serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>devname</key>
|
||||
<string>dec_rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>devname</key>
|
||||
<string>null_modem</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_patch_box</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>devname</key>
|
||||
<string>serial_keyboard</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>serial_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>devname</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>devname</key>
|
||||
<string>mockingboardd</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>swtpc8212_terminal</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>devices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sl6:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525</string>
|
||||
<key>description</key>
|
||||
<string>5.25"</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_5_25</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sl6:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525</string>
|
||||
<key>description</key>
|
||||
<string>5.25"</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_5_25</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>rs232_patch_box</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:dce</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nss_tvi</string>
|
||||
<key>description</key>
|
||||
<string>Novag Super System TV Interface</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:keyboard</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type3hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 3 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type4hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 4 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5gbhle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Great Britain - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5jphle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Japan - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5sehle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Sweden - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (U.S.A. - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>software</key>
|
||||
<array>
|
||||
<string>apple2_flop_clcracked.xml</string>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>apple2_flop_orig.xml</string>
|
||||
<key>filter</key>
|
||||
<string>A2C</string>
|
||||
</dict>
|
||||
<string>apple2_flop_misc.xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -6,348 +6,661 @@
|
|||
<string>agat7</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7</string>
|
||||
<key>ram</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>32768</integer>
|
||||
<key>description</key>
|
||||
<string>32K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>flop_5_25</key>
|
||||
<integer>2</integer>
|
||||
<key>cass</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>resolution</key>
|
||||
<array>
|
||||
<integer>512</integer>
|
||||
<integer>512</integer>
|
||||
<integer>256</integer>
|
||||
</array>
|
||||
<key>sl2</key>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>name</key>
|
||||
<string>ramsize</string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>RAM</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>32768</integer>
|
||||
<key>description</key>
|
||||
<string>32K</string>
|
||||
<key>value</key>
|
||||
<string>32K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>name</key>
|
||||
<string>bios</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>ROM</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—Default—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>v1</string>
|
||||
<key>description</key>
|
||||
<string>Version 1</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>v2</string>
|
||||
<key>description</key>
|
||||
<string>Version 2</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>debug</string>
|
||||
<key>description</key>
|
||||
<string>Debug</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>name</key>
|
||||
<string>sl2</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy controller card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Slot 2</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat840k_hle</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Controller Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat_fdc</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat7_flop</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>a7lang</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ram</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ports</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>name</key>
|
||||
<string>sl3</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>flop_5_25</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
<string>Slot 3</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat840k_hle</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Controller Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat_fdc</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K Floppy Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>agat7_flop</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7lang</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ram</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ports</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>name</key>
|
||||
<string>sl4</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<string>Slot 4</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat840k_hle</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Controller Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat_fdc</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat7_flop</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7lang</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ram</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>a7ports</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>name</key>
|
||||
<string>sl5</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Slot 5</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat840k_hle</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Controller Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat_fdc</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat7_flop</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7lang</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ram</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ports</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>name</key>
|
||||
<string>sl6</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Slot 6</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat840k_hle</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K Floppy Controller Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat_fdc</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K Floppy Card</string>
|
||||
<key>devname</key>
|
||||
<string>agat7_flop</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7lang</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>a7ram</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>devname</key>
|
||||
<string>a7ports</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>sl3</key>
|
||||
<key>devices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy controller card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K floppy card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>flop_5_25</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<key>name</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:centronics</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Centronics Printer</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pl80</string>
|
||||
<key>description</key>
|
||||
<string>COMX PL-80</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>covox_stereo</string>
|
||||
<key>description</key>
|
||||
<string>Covox (Stereo-in-1)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>covox</string>
|
||||
<key>description</key>
|
||||
<string>Covox Speech Thing</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>digiblst</string>
|
||||
<key>description</key>
|
||||
<string>Digiblaster (DIY)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ap2000</string>
|
||||
<key>description</key>
|
||||
<string>Epson ActionPrinter 2000</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ex800</string>
|
||||
<key>description</key>
|
||||
<string>Epson EX-800</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>lx800</string>
|
||||
<key>description</key>
|
||||
<string>Epson LX-800</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>lx810l</string>
|
||||
<key>description</key>
|
||||
<string>Epson LX-810L</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>p72</string>
|
||||
<key>description</key>
|
||||
<string>NEC PinWriter P72</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>samdac</string>
|
||||
<key>description</key>
|
||||
<string>SAMDAC</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nlq401</string>
|
||||
<key>description</key>
|
||||
<string>Schneider NLQ 401 Matrix Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>chessmec</string>
|
||||
<key>description</key>
|
||||
<string>Tasc ChessMachine EC Interface</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>smartboard</string>
|
||||
<key>description</key>
|
||||
<string>Tasc SmartBoard SB30 Interface</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>agat7_flop</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525</string>
|
||||
<key>description</key>
|
||||
<string>5.25"</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_5_25</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525</string>
|
||||
<key>description</key>
|
||||
<string>5.25"</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_5_25</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>agat_fdc</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525dsqd</string>
|
||||
<key>description</key>
|
||||
<string>5.25" quad density floppy drive</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525dsqd</string>
|
||||
<key>description</key>
|
||||
<string>5.25" quad density floppy drive</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>sl4</key>
|
||||
<key>software</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy controller card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>flop_5_25</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>sl5</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy controller card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>flop_5_25</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>sl6</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdchle</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a9fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat 840K floppy controller card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7fdc</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 140K floppy card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>flop_5_25</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7lang</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K Language Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ram</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 32K RAM Card</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>a7ports</string>
|
||||
<key>description</key>
|
||||
<string>Agat-7 Ports Card</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -6,151 +6,329 @@
|
|||
<string>apple1</string>
|
||||
<key>description</key>
|
||||
<string>Apple I</string>
|
||||
<key>ram</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>4096</integer>
|
||||
<key>description</key>
|
||||
<string>4K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>8192</integer>
|
||||
<key>description</key>
|
||||
<string>8K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>12288</integer>
|
||||
<key>description</key>
|
||||
<string>12K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>16384</integer>
|
||||
<key>description</key>
|
||||
<string>16K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>20480</integer>
|
||||
<key>description</key>
|
||||
<string>20K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>24576</integer>
|
||||
<key>description</key>
|
||||
<string>24K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>28672</integer>
|
||||
<key>description</key>
|
||||
<string>28K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>32768</integer>
|
||||
<key>description</key>
|
||||
<string>32K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>36864</integer>
|
||||
<key>description</key>
|
||||
<string>36K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>40960</integer>
|
||||
<key>description</key>
|
||||
<string>40K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>45056</integer>
|
||||
<key>description</key>
|
||||
<string>44K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>49152</integer>
|
||||
<key>description</key>
|
||||
<string>48K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>cass</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>resolution</key>
|
||||
<array>
|
||||
<integer>560</integer>
|
||||
<integer>384</integer>
|
||||
<integer>192</integer>
|
||||
</array>
|
||||
<key>exp</key>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>name</key>
|
||||
<string>ramsize</string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>RAM</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>4096</integer>
|
||||
<key>description</key>
|
||||
<string>4K</string>
|
||||
<key>value</key>
|
||||
<string>4K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>8192</integer>
|
||||
<key>description</key>
|
||||
<string>8K</string>
|
||||
<key>value</key>
|
||||
<string>8K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>12288</integer>
|
||||
<key>description</key>
|
||||
<string>12K</string>
|
||||
<key>value</key>
|
||||
<string>12K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>16384</integer>
|
||||
<key>description</key>
|
||||
<string>16K</string>
|
||||
<key>value</key>
|
||||
<string>16K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>20480</integer>
|
||||
<key>description</key>
|
||||
<string>20K</string>
|
||||
<key>value</key>
|
||||
<string>20K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>24576</integer>
|
||||
<key>description</key>
|
||||
<string>24K</string>
|
||||
<key>value</key>
|
||||
<string>24K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>28672</integer>
|
||||
<key>description</key>
|
||||
<string>28K</string>
|
||||
<key>value</key>
|
||||
<string>28K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>32768</integer>
|
||||
<key>description</key>
|
||||
<string>32K</string>
|
||||
<key>value</key>
|
||||
<string>32K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>36864</integer>
|
||||
<key>description</key>
|
||||
<string>36K</string>
|
||||
<key>value</key>
|
||||
<string>36K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>40960</integer>
|
||||
<key>description</key>
|
||||
<string>40K</string>
|
||||
<key>value</key>
|
||||
<string>40K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>45056</integer>
|
||||
<key>description</key>
|
||||
<string>44K</string>
|
||||
<key>value</key>
|
||||
<string>44K</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>49152</integer>
|
||||
<key>description</key>
|
||||
<string>48K</string>
|
||||
<key>value</key>
|
||||
<string>48K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cassette</string>
|
||||
<key>name</key>
|
||||
<string>exp</string>
|
||||
<key>description</key>
|
||||
<string>Apple I cassette board</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>cass</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<string>Expansion</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cassette</string>
|
||||
<key>description</key>
|
||||
<string>Apple I Cassette Board</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>devname</key>
|
||||
<string>a1cass</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>cass</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cffa</string>
|
||||
<key>description</key>
|
||||
<string>CFFA Compact Flash For Apple I</string>
|
||||
<key>devname</key>
|
||||
<string>cffa1</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>devices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cffa</string>
|
||||
<key>description</key>
|
||||
<string>CFFA Compact Flash for Apple I</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>hard</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>cffa1</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:cffa_ata:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cdrom</string>
|
||||
<key>description</key>
|
||||
<string>CD-ROM</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>cdrom</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>hdd</string>
|
||||
<key>description</key>
|
||||
<string>Hard Disk</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>hard</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>zip100</string>
|
||||
<key>description</key>
|
||||
<string>Iomega Zip 100MB IDE Drive</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cr589</string>
|
||||
<key>description</key>
|
||||
<string>Matsushita CR589 CD-ROM Drive</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>xm3301</string>
|
||||
<key>description</key>
|
||||
<string>Toshiba XM-3301 CD-ROM Drive</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:cffa_ata:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cdrom</string>
|
||||
<key>description</key>
|
||||
<string>CD-ROM</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>cdrom</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>hdd</string>
|
||||
<key>description</key>
|
||||
<string>Hard Disk</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>hard</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>zip100</string>
|
||||
<key>description</key>
|
||||
<string>Iomega Zip 100MB IDE Drive</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>cr589</string>
|
||||
<key>description</key>
|
||||
<string>Matsushita CR589 CD-ROM Drive</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>xm3301</string>
|
||||
<key>description</key>
|
||||
<string>Toshiba XM-3301 CD-ROM Drive</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>software</key>
|
||||
<array>
|
||||
<string>apple1.xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -6,241 +6,725 @@
|
|||
<string>apple2c</string>
|
||||
<key>description</key>
|
||||
<string>Apple //c</string>
|
||||
<key>ram</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<integer>131072</integer>
|
||||
<key>description</key>
|
||||
<string>128K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>resolution</key>
|
||||
<array>
|
||||
<integer>560</integer>
|
||||
<integer>384</integer>
|
||||
<integer>192</integer>
|
||||
</array>
|
||||
<key>gameio</key>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>name</key>
|
||||
<string>ramsize</string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<string>RAM</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>intValue</key>
|
||||
<integer>131072</integer>
|
||||
<key>description</key>
|
||||
<string>128K</string>
|
||||
<key>value</key>
|
||||
<string>128K</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>joy</string>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>description</key>
|
||||
<string>Apple II analog joysticks</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Disk Drives</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string></string>
|
||||
<key>devname</key>
|
||||
<string>smartport</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>paddles</string>
|
||||
<key>name</key>
|
||||
<string>gameio</string>
|
||||
<key>description</key>
|
||||
<string>Apple II paddles</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Game I/O</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>joy</string>
|
||||
<key>description</key>
|
||||
<string>Apple II Analog Joysticks</string>
|
||||
<key>devname</key>
|
||||
<string>a2joy</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>paddles</string>
|
||||
<key>description</key>
|
||||
<string>Apple II Paddles</string>
|
||||
<key>devname</key>
|
||||
<string>a2pdls</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>compeyes</string>
|
||||
<key>description</key>
|
||||
<string>Digital Vision ComputerEyes</string>
|
||||
<key>devname</key>
|
||||
<string>a2ceyes</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>picture</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>gizmo</string>
|
||||
<key>description</key>
|
||||
<string>HAL Labs Gizmo</string>
|
||||
<key>devname</key>
|
||||
<string>a2gizmo</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>compeyes</string>
|
||||
<key>description</key>
|
||||
<string>Digital Vision ComputerEyes</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>printer</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS232 Loopback</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS232 Null Modem</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<key>name</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Printer</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>ie15_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>devname</key>
|
||||
<string>scorpion_ic</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nss_tvi</string>
|
||||
<key>description</key>
|
||||
<string>Novag Super System TV Interface</string>
|
||||
<key>devname</key>
|
||||
<string>nss_tvinterface</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>pseudo_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>rs_serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>devname</key>
|
||||
<string>dec_rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>devname</key>
|
||||
<string>null_modem</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_patch_box</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>devname</key>
|
||||
<string>serial_keyboard</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>serial_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>devname</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>devname</key>
|
||||
<string>mockingboardd</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>swtpc8212_terminal</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>name</key>
|
||||
<string>modem</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<string>Modem</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>ie15_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>devname</key>
|
||||
<string>scorpion_ic</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nss_tvi</string>
|
||||
<key>description</key>
|
||||
<string>Novag Super System TV Interface</string>
|
||||
<key>devname</key>
|
||||
<string>nss_tvinterface</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>pseudo_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>rs_serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>devname</key>
|
||||
<string>dec_rs232_loopback</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>devname</key>
|
||||
<string>null_modem</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_patch_box</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>devname</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>devname</key>
|
||||
<string>serial_keyboard</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>devname</key>
|
||||
<string>serial_printer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>serial_terminal</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>devname</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>devname</key>
|
||||
<string>mockingboardd</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>devname</key>
|
||||
<string>swtpc8212_terminal</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>modem</key>
|
||||
<key>devices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>name</key>
|
||||
<string>smartport</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sl6:0</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525</string>
|
||||
<key>description</key>
|
||||
<string>5.25"</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_5_25</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>sl6:1</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>525</string>
|
||||
<key>description</key>
|
||||
<string>5.25"</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>floppy_5_25</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>name</key>
|
||||
<string>rs232_patch_box</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:dce</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>ie15</string>
|
||||
<key>description</key>
|
||||
<string>IE15 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>scorpion</string>
|
||||
<key>description</key>
|
||||
<string>Micro-Robotics Scorpion Intelligent Controller</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>nss_tvi</string>
|
||||
<key>description</key>
|
||||
<string>Novag Super System TV Interface</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs_printer</string>
|
||||
<key>description</key>
|
||||
<string>Radio Shack Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Null Modem</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>patch</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Patch Box</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>rs232_sync_io</string>
|
||||
<key>description</key>
|
||||
<string>RS-232 Synchronous I/O</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>media</key>
|
||||
<dict>
|
||||
<key>bitbanger</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>mockingboard</string>
|
||||
<key>description</key>
|
||||
<string>Sweet Micro Systems Mockingboard D</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>pty</string>
|
||||
<key>description</key>
|
||||
<string>Pseudo terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>name</key>
|
||||
<string>sunkbd_adaptor</string>
|
||||
<key>slots</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>:keyboard</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string></string>
|
||||
<key>description</key>
|
||||
<string>—None—</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type3hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 3 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type4hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 4 Keyboard (HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5gbhle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Great Britain - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5jphle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Japan - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5sehle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (Sweden - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>type5hle</string>
|
||||
<key>description</key>
|
||||
<string>Sun Type 5 Keyboard (U.S.A. - HLE)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>software</key>
|
||||
<array>
|
||||
<string>apple2_flop_clcracked.xml</string>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS232 Loopback</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>dec_loopback</string>
|
||||
<key>description</key>
|
||||
<string>RS232 Loopback (DEC 12-15336-00)</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>null_modem</string>
|
||||
<key>description</key>
|
||||
<string>RS232 Null Modem</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>keyboard</string>
|
||||
<key>description</key>
|
||||
<string>Serial Keyboard</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>printer</string>
|
||||
<key>description</key>
|
||||
<string>Serial Printer</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>terminal</string>
|
||||
<key>description</key>
|
||||
<string>Serial Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>sunkbd</string>
|
||||
<key>description</key>
|
||||
<string>Sun Keyboard Adaptor</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>value</key>
|
||||
<string>swtpc8212</string>
|
||||
<key>description</key>
|
||||
<string>SWTPC8212 Terminal</string>
|
||||
<key>default</key>
|
||||
<false/>
|
||||
<key>name</key>
|
||||
<string>apple2_flop_orig.xml</string>
|
||||
<key>filter</key>
|
||||
<string>A2C</string>
|
||||
</dict>
|
||||
<string>apple2_flop_misc.xml</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|