From 376f808d29d0870870da31752573332e4a6f6c38 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 13 Sep 2020 22:48:55 -0400 Subject: [PATCH 01/10] disk images window [WIP]. uses bound nsarray controller. --- Ample.xcodeproj/project.pbxproj | 38 +++++++++ Ample/AppDelegate.m | 14 ++- Ample/Base.lproj/DiskImages.xib | 133 +++++++++++++++++++++++++++++ Ample/Base.lproj/MainMenu.xib | 8 +- Ample/DiskImagesWindowController.h | 22 +++++ Ample/DiskImagesWindowController.m | 80 +++++++++++++++++ Ample/MediaViewController.h | 6 -- Ample/MediaViewController.m | 39 +-------- Ample/TableCellView.h | 22 +++++ Ample/TableCellView.m | 47 ++++++++++ Ample/Transformers.h | 24 ++++++ Ample/Transformers.m | 68 +++++++++++++++ 12 files changed, 455 insertions(+), 46 deletions(-) create mode 100644 Ample/Base.lproj/DiskImages.xib create mode 100644 Ample/DiskImagesWindowController.h create mode 100644 Ample/DiskImagesWindowController.m create mode 100644 Ample/TableCellView.h create mode 100644 Ample/TableCellView.m create mode 100644 Ample/Transformers.h create mode 100644 Ample/Transformers.m diff --git a/Ample.xcodeproj/project.pbxproj b/Ample.xcodeproj/project.pbxproj index bea00b1..bebcd7e 100644 --- a/Ample.xcodeproj/project.pbxproj +++ b/Ample.xcodeproj/project.pbxproj @@ -79,6 +79,14 @@ B63C1BA8250192E600511A71 /* zijini.plist in Resources */ = {isa = PBXBuildFile; fileRef = B63C1BA7250192E600511A71 /* zijini.plist */; }; B63C1BA9250192E600511A71 /* zijini.plist in Resources */ = {isa = PBXBuildFile; fileRef = B63C1BA7250192E600511A71 /* zijini.plist */; }; B64979C224EF6703008ABD20 /* MediaViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64979C124EF6703008ABD20 /* MediaViewController.m */; }; + B64AF1EE250EC35B00A09B9B /* DiskImages.xib in Resources */ = {isa = PBXBuildFile; fileRef = B64AF1EC250EC35B00A09B9B /* DiskImages.xib */; }; + B64AF1EF250EC35B00A09B9B /* DiskImages.xib in Resources */ = {isa = PBXBuildFile; fileRef = B64AF1EC250EC35B00A09B9B /* DiskImages.xib */; }; + B64AF1F2250ECB2E00A09B9B /* DiskImagesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64AF1F1250ECB2E00A09B9B /* DiskImagesWindowController.m */; }; + B64AF1F3250ECB2E00A09B9B /* DiskImagesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64AF1F1250ECB2E00A09B9B /* DiskImagesWindowController.m */; }; + B64AF1F6250ED5E400A09B9B /* TableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = B64AF1F5250ED5E400A09B9B /* TableCellView.m */; }; + B64AF1F7250ED5E400A09B9B /* TableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = B64AF1F5250ED5E400A09B9B /* TableCellView.m */; }; + B64AF1FA250EF6A500A09B9B /* Transformers.m in Sources */ = {isa = PBXBuildFile; fileRef = B64AF1F9250EF6A500A09B9B /* Transformers.m */; }; + B64AF1FB250EF6A500A09B9B /* Transformers.m in Sources */ = {isa = PBXBuildFile; fileRef = B64AF1F9250EF6A500A09B9B /* Transformers.m */; }; B64E15A924EA1D5300E8AD3D /* MachineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64E15A824EA1D5300E8AD3D /* MachineViewController.m */; }; B66236A924FD9A34006CABD7 /* PreferencesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B66236A824FD9A34006CABD7 /* PreferencesWindowController.m */; }; B66236B524FDA527006CABD7 /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B66236B224FDA522006CABD7 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -282,6 +290,13 @@ B63C1BA7250192E600511A71 /* zijini.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = zijini.plist; sourceTree = ""; }; B64979C024EF6703008ABD20 /* MediaViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaViewController.h; sourceTree = ""; }; B64979C124EF6703008ABD20 /* MediaViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MediaViewController.m; sourceTree = ""; }; + B64AF1ED250EC35B00A09B9B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/DiskImages.xib; sourceTree = ""; }; + B64AF1F0250ECB2E00A09B9B /* DiskImagesWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DiskImagesWindowController.h; sourceTree = ""; }; + B64AF1F1250ECB2E00A09B9B /* DiskImagesWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DiskImagesWindowController.m; sourceTree = ""; }; + B64AF1F4250ED5E400A09B9B /* TableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TableCellView.h; sourceTree = ""; }; + B64AF1F5250ED5E400A09B9B /* TableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TableCellView.m; sourceTree = ""; }; + B64AF1F8250EF6A500A09B9B /* Transformers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Transformers.h; sourceTree = ""; }; + B64AF1F9250EF6A500A09B9B /* Transformers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Transformers.m; sourceTree = ""; }; B64E15A724EA1D5300E8AD3D /* MachineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MachineViewController.h; sourceTree = ""; }; B64E15A824EA1D5300E8AD3D /* MachineViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MachineViewController.m; sourceTree = ""; }; B65593AF24ECB61800722E0C /* SlotViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SlotViewController.h; sourceTree = ""; }; @@ -450,6 +465,8 @@ B6BA257D24E99BE9005FB8FF /* Ample */ = { isa = PBXGroup; children = ( + B64AF1F4250ED5E400A09B9B /* TableCellView.h */, + B64AF1F5250ED5E400A09B9B /* TableCellView.m */, B6E9A17E25088B1B005E7525 /* NewSlotViewController.h */, B6E9A17F25088B1B005E7525 /* NewSlotViewController.m */, B63C1B9125008A2700511A71 /* DownloadWindowController.h */, @@ -476,6 +493,10 @@ B66236A824FD9A34006CABD7 /* PreferencesWindowController.m */, B6B9EA652506A5550080E70D /* EjectButton.h */, B6B9EA642506A5550080E70D /* EjectButton.m */, + B64AF1F0250ECB2E00A09B9B /* DiskImagesWindowController.h */, + B64AF1F1250ECB2E00A09B9B /* DiskImagesWindowController.m */, + B64AF1F8250EF6A500A09B9B /* Transformers.h */, + B64AF1F9250EF6A500A09B9B /* Transformers.m */, B6BA258124E99BEB005FB8FF /* Assets.xcassets */, B64E15AF24EA365E00E8AD3D /* Resources */, B6BA258624E99BEB005FB8FF /* Info.plist */, @@ -500,6 +521,7 @@ B61099E524F5F230005CB652 /* MediaView.xib */, B6D6DE3724FAC8B500661A5F /* Preferences.xib */, B61099E324F5F230005CB652 /* SlotView.xib */, + B64AF1EC250EC35B00A09B9B /* DiskImages.xib */, ); name = Nibs; sourceTree = ""; @@ -648,6 +670,7 @@ B6109A2B24F5F377005CB652 /* elppa.plist in Resources */, B63C1B8E25004C6D00511A71 /* mame-data.tgz in Resources */, B6DDECCE2505A86E0093587A /* eject-16x16@3x.png in Resources */, + B64AF1EE250EC35B00A09B9B /* DiskImages.xib in Resources */, B6109A3B24F5F377005CB652 /* apple2gsr1.plist in Resources */, B63C1B9625008A2700511A71 /* DownloadWindow.xib in Resources */, B6D6DE3B24FACF4F00661A5F /* Defaults.plist in Resources */, @@ -691,6 +714,7 @@ B6E4B5C424FDE2670094A35C /* LogWindow.xib in Resources */, B6E4B5C524FDE2670094A35C /* Assets.xcassets in Resources */, B6E4B5C624FDE2670094A35C /* apple2e.plist in Resources */, + B64AF1EF250EC35B00A09B9B /* DiskImages.xib in Resources */, B63C1BA2250192D800511A71 /* cecg.plist in Resources */, B6E4B5C724FDE2670094A35C /* am100.plist in Resources */, B6E4B5C824FDE2670094A35C /* laser2c.plist in Resources */, @@ -768,7 +792,10 @@ B6BA258024E99BE9005FB8FF /* AppDelegate.m in Sources */, B6004DF024FB05D600D38596 /* LogWindowController.m in Sources */, B66236A924FD9A34006CABD7 /* PreferencesWindowController.m in Sources */, + B64AF1F2250ECB2E00A09B9B /* DiskImagesWindowController.m in Sources */, + B64AF1F6250ED5E400A09B9B /* TableCellView.m in Sources */, B63C1B9425008A2700511A71 /* DownloadWindowController.m in Sources */, + B64AF1FA250EF6A500A09B9B /* Transformers.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -777,12 +804,15 @@ buildActionMask = 2147483647; files = ( B608E1802502FE0C00D53465 /* TransparentScroller.m in Sources */, + B64AF1FB250EF6A500A09B9B /* Transformers.m in Sources */, B6E4B5B024FDE2670094A35C /* main.m in Sources */, B63C1B8C24FF4BF700511A71 /* Ample.m in Sources */, + B64AF1F3250ECB2E00A09B9B /* DiskImagesWindowController.m in Sources */, B6B9EA672506A5550080E70D /* EjectButton.m in Sources */, B6E4B5B124FDE2670094A35C /* LaunchWindowController.m in Sources */, B6E4B5B224FDE2670094A35C /* MachineViewController.m in Sources */, B6E4B5B324FDE2670094A35C /* MediaViewController.m in Sources */, + B64AF1F7250ED5E400A09B9B /* TableCellView.m in Sources */, B6E4B5B424FDE2670094A35C /* FlippedView.m in Sources */, B6E4B5B524FDE2670094A35C /* AppDelegate.m in Sources */, B6E4B5B624FDE2670094A35C /* LogWindowController.m in Sources */, @@ -810,6 +840,14 @@ name = MediaView.xib; sourceTree = ""; }; + B64AF1EC250EC35B00A09B9B /* DiskImages.xib */ = { + isa = PBXVariantGroup; + children = ( + B64AF1ED250EC35B00A09B9B /* Base */, + ); + name = DiskImages.xib; + sourceTree = ""; + }; B66236BF24FDB7A6006CABD7 /* Credits.rtf */ = { isa = PBXVariantGroup; children = ( diff --git a/Ample/AppDelegate.m b/Ample/AppDelegate.m index b12e677..7be75cd 100644 --- a/Ample/AppDelegate.m +++ b/Ample/AppDelegate.m @@ -10,6 +10,8 @@ #import "LaunchWindowController.h" #import "PreferencesWindowController.h" #import "DownloadWindowController.h" +#import "DiskImagesWindowController.h" +#import "Transformers.h" @interface AppDelegate () @property (weak) IBOutlet NSWindow *installWindow; @@ -20,6 +22,7 @@ NSWindowController *_prefs; NSWindowController *_launcher; NSWindowController *_downloader; + NSWindowController *_diskImages; } @@ -31,6 +34,8 @@ NSDictionary *dict; + RegisterTransformers(); + path = [bundle pathForResource: @"Defaults" ofType: @"plist"]; dict = [NSDictionary dictionaryWithContentsOfFile: path]; @@ -143,12 +148,17 @@ } -- (IBAction)downloadROMS:(id)sender { - +- (IBAction)displayROMS:(id)sender { if (!_downloader) { _downloader = [DownloadWindowController new]; } [_downloader showWindow: sender]; } +- (IBAction)displayRecentDiskImages:(id)sender { + if (!_diskImages) { + _diskImages = [DiskImagesWindowController new]; + } + [_diskImages showWindow: sender]; +} @end diff --git a/Ample/Base.lproj/DiskImages.xib b/Ample/Base.lproj/DiskImages.xib new file mode 100644 index 0000000..b499c46 --- /dev/null +++ b/Ample/Base.lproj/DiskImages.xib @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FilePathTransformer + + + + + + + + + + + + + + + + FileSizeTransformer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ample/Base.lproj/MainMenu.xib b/Ample/Base.lproj/MainMenu.xib index b6f6835..286bd61 100644 --- a/Ample/Base.lproj/MainMenu.xib +++ b/Ample/Base.lproj/MainMenu.xib @@ -402,7 +402,13 @@ - + + + + + + + diff --git a/Ample/DiskImagesWindowController.h b/Ample/DiskImagesWindowController.h new file mode 100644 index 0000000..8d8bb76 --- /dev/null +++ b/Ample/DiskImagesWindowController.h @@ -0,0 +1,22 @@ +// +// DiskImagesWindowController.h +// Ample +// +// Created by Kelvin Sherlock on 9/13/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DiskImagesWindowController : NSWindowController + +@end + +@interface DiskImagesWindowController (TableView) + +@end + + +NS_ASSUME_NONNULL_END diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m new file mode 100644 index 0000000..0d212a1 --- /dev/null +++ b/Ample/DiskImagesWindowController.m @@ -0,0 +1,80 @@ +// +// DiskImagesWindowController.m +// Ample +// +// Created by Kelvin Sherlock on 9/13/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import "DiskImagesWindowController.h" +#import "TableCellView.h" + +@interface DiskImagesWindowController () +@property (weak) IBOutlet NSTableView *tableView; +@property (strong) IBOutlet NSArrayController *arrayController; +@property NSMutableArray *content; +@end + +@implementation DiskImagesWindowController { + //NSArray *_data; + +} + +-(NSString *)windowNibName { + return @"DiskImages"; +} + +- (void)windowDidLoad { + //_data = [NSMutableArray new]; + [self setContent: + [NSMutableArray arrayWithObject: + [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"/path/to/a/file.2mg", @"path", + @(12345), @"size", + nil] + ]]; + [super windowDidLoad]; + + // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. +} + +@end + +@implementation DiskImagesWindowController (TableView) + +#if 0 +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { + return 5; //[_data count]; +} + +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { + + NSTableCellView *v = [tableView makeViewWithIdentifier: @"PathCell" owner: self]; + + return v; +} +#endif + + +- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { + +// if ([rowIndexes count] > 1) return NO; // ? + + id objects = [_arrayController arrangedObjects]; + [pboard declareTypes: @[NSPasteboardTypeURL] owner: nil]; + // NSURLPboardType deprecated + [rowIndexes enumerateIndexesUsingBlock: ^(NSUInteger index, BOOL *stop) { + + NSDictionary *d = [objects objectAtIndex: index]; + NSString *path = [d objectForKey: @"path"]; + + NSURL *url = [NSURL fileURLWithPath: path]; + [url writeToPasteboard: pboard]; + }]; + // NSFilenamesPboardType -- old way of handling it ... + + return YES; +} + + +@end diff --git a/Ample/MediaViewController.h b/Ample/MediaViewController.h index 36103ce..df9b61f 100644 --- a/Ample/MediaViewController.h +++ b/Ample/MediaViewController.h @@ -26,10 +26,4 @@ NS_ASSUME_NONNULL_BEGIN -@interface TablePathView : NSTableCellView -@property (weak) IBOutlet NSPathControl *pathControl; -@property (weak) IBOutlet NSButton *ejectButton; -@property (weak) IBOutlet NSImageView *dragHandle; -@end - NS_ASSUME_NONNULL_END diff --git a/Ample/MediaViewController.m b/Ample/MediaViewController.m index e8c7360..4a3e178 100644 --- a/Ample/MediaViewController.m +++ b/Ample/MediaViewController.m @@ -7,42 +7,7 @@ // #import "MediaViewController.h" - - -@implementation TablePathView { - NSTrackingRectTag _trackingRect; -} - -#if 0 --(void)awakeFromNib { - - // this is apparently necessary for setTintColor to work. - NSImage *img; - img = [_ejectButton image]; - [img setTemplate: YES]; - img = [_ejectButton alternateImage]; - [img setTemplate: YES]; -} -#endif - --(void)viewDidMoveToSuperview { - return; - if (_trackingRect) { - [self removeTrackingRect: _trackingRect]; - } - NSRect rect = [_dragHandle frame]; - _trackingRect = [self addTrackingRect: rect owner: self userData: NULL assumeInside:NO]; -} - --(void)mouseEntered:(NSEvent *)event { - [_dragHandle setHidden: NO]; -} - --(void)mouseExited:(NSEvent *)event { - [_dragHandle setHidden: YES]; -} - -@end +#import "TableCellView.h" @protocol MediaNode @@ -526,7 +491,7 @@ static NSString *kDragType = @"private.ample.media"; NSInteger indexes[2] = { 0, 0 }; indexes[0] = [cat index]; indexes[1] = [item index]; - NSData *data =[NSData dataWithBytes: indexes length: sizeof(indexes)]; + NSData *data = [NSData dataWithBytes: indexes length: sizeof(indexes)]; [pasteboard setData: data forType: kDragType]; return YES; diff --git a/Ample/TableCellView.h b/Ample/TableCellView.h new file mode 100644 index 0000000..d115eb2 --- /dev/null +++ b/Ample/TableCellView.h @@ -0,0 +1,22 @@ +// +// TableCellView.h +// Ample +// +// Created by Kelvin Sherlock on 9/13/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import + +//NS_ASSUME_NONNULL_BEGIN + + + +@interface TablePathView : NSTableCellView +@property (weak) IBOutlet NSPathControl *pathControl; +@property (weak) IBOutlet NSButton *ejectButton; +@property (weak) IBOutlet NSImageView *dragHandle; +@property BOOL movable; +@end + +//NS_ASSUME_NONNULL_END diff --git a/Ample/TableCellView.m b/Ample/TableCellView.m new file mode 100644 index 0000000..d90c7fa --- /dev/null +++ b/Ample/TableCellView.m @@ -0,0 +1,47 @@ +// +// TableCellView.m +// Ample +// +// Created by Kelvin Sherlock on 9/13/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import "TableCellView.h" + + + +@implementation TablePathView { + NSTrackingRectTag _trackingRect; +} + +#if 0 +-(void)awakeFromNib { + + // this is apparently necessary for setTintColor to work. + NSImage *img; + img = [_ejectButton image]; + [img setTemplate: YES]; + img = [_ejectButton alternateImage]; + [img setTemplate: YES]; +} +#endif + +-(void)viewDidMoveToSuperview { + return; + if (_trackingRect) { + [self removeTrackingRect: _trackingRect]; + } + NSRect rect = [_dragHandle frame]; + _trackingRect = [self addTrackingRect: rect owner: self userData: NULL assumeInside:NO]; +} + +-(void)mouseEntered:(NSEvent *)event { + [_dragHandle setHidden: NO]; +} + +-(void)mouseExited:(NSEvent *)event { + [_dragHandle setHidden: YES]; +} + +@end + diff --git a/Ample/Transformers.h b/Ample/Transformers.h new file mode 100644 index 0000000..5831fb1 --- /dev/null +++ b/Ample/Transformers.h @@ -0,0 +1,24 @@ +// +// Transformers.h +// Ample +// +// Created by Kelvin Sherlock on 9/13/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import + +void RegisterTransformers(void); + +NS_ASSUME_NONNULL_BEGIN + +@interface FilePathTransformer : NSValueTransformer + +@end + +@interface FileSizeTransformer : NSValueTransformer + +@end + + +NS_ASSUME_NONNULL_END diff --git a/Ample/Transformers.m b/Ample/Transformers.m new file mode 100644 index 0000000..db07232 --- /dev/null +++ b/Ample/Transformers.m @@ -0,0 +1,68 @@ +// +// Transformers.m +// Ample +// +// Created by Kelvin Sherlock on 9/13/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import "Transformers.h" + +@implementation FilePathTransformer + ++ (Class)transformedValueClass { + return [NSString class]; +} + ++ (BOOL)allowsReverseTransformation { + return NO; +} + +- (id)transformedValue:(id)value { + if (!value) return value; + + return [(NSString *)value lastPathComponent]; +} + +@end + +@implementation FileSizeTransformer + ++ (Class)transformedValueClass { + return [NSString class]; +} + ++ (BOOL)allowsReverseTransformation { + return NO; +} + +- (id)transformedValue:(id)value { + if (!value) return value; + if (![value respondsToSelector: @selector(integerValue)]) { + [NSException raise: NSInternalInconsistencyException + format: @"Value (%@) does not respond to -integerValue.", + [value class]]; + } + NSInteger size = [(NSNumber *)value integerValue]; + + if (size < 0) return nil; + if (size < 1024*1024) return [NSString stringWithFormat: @"%.1fKB", (float)size / 1024]; + if (size < 1024*1024*1024) return [NSString stringWithFormat: @"%.1fMB", (float)size / (1024*1024)]; + + return [NSString stringWithFormat: @"%.1fGB", (float)size / (1024*1024*1024)]; +} + +@end + + + +void RegisterTransformers(void) { + + NSValueTransformer *t; + t = [FileSizeTransformer new]; + [NSValueTransformer setValueTransformer: t forName: @"FileSizeTransformer"]; + + t = [FilePathTransformer new]; + [NSValueTransformer setValueTransformer: t forName: @"FilePathTransformer"]; + +} From 531c3096e9216284884683122e39f2e9248d791e Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 14 Sep 2020 18:11:50 -0400 Subject: [PATCH 02/10] drag-n-drop files to the recent disk images list. --- Ample/DiskImagesWindowController.m | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index 0d212a1..c5f68e6 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -33,8 +33,11 @@ @(12345), @"size", nil] ]]; + [super windowDidLoad]; + [_tableView registerForDraggedTypes: @[NSPasteboardTypeURL]]; + // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. } @@ -76,5 +79,39 @@ return YES; } +-(NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation { + + return NSDragOperationCopy; +} + +-(BOOL)tableView:(NSTableView *)tableView acceptDrop:(id)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { + + + NSPasteboard * pb = [info draggingPasteboard]; + NSURL *url = [NSURL URLFromPasteboard: pb]; + if (!url) return NO; + + NSFileManager *fm = [NSFileManager defaultManager]; + + NSString *path = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding]; + if (!path) return NO; + + NSError *error = nil; + 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" + , nil]; + + [_arrayController addObject: d]; + return YES; +} @end From 4ca9d2caafe8f7eabfa6bf0ca03394099b110923 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 15 Sep 2020 18:03:05 -0400 Subject: [PATCH 03/10] fix casette spelling --- Ample/MediaViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ample/MediaViewController.m b/Ample/MediaViewController.m index 4a3e178..b8df390 100644 --- a/Ample/MediaViewController.m +++ b/Ample/MediaViewController.m @@ -251,7 +251,7 @@ b = [[MediaCategory alloc] initWithTitle: @"3.5\" Floppies"]; c = [[MediaCategory alloc] initWithTitle: @"Hard Drives"]; d = [[MediaCategory alloc] initWithTitle: @"CD-ROMs"]; - e = [[MediaCategory alloc] initWithTitle: @"Casettes"]; + e = [[MediaCategory alloc] initWithTitle: @"Cassettes"]; _data[0] = a; From 0d88e3e93a217efe36b10af810f5df460c23a723 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 15 Sep 2020 21:39:14 -0400 Subject: [PATCH 04/10] put all recent disk image logic in the recent disk image window controller. --- Ample/AppDelegate.m | 2 + Ample/DiskImagesWindowController.m | 138 ++++++++++++++++++++++------- Ample/MediaViewController.m | 8 ++ 3 files changed, 118 insertions(+), 30 deletions(-) diff --git a/Ample/AppDelegate.m b/Ample/AppDelegate.m index 7be75cd..3a2344c 100644 --- a/Ample/AppDelegate.m +++ b/Ample/AppDelegate.m @@ -50,6 +50,8 @@ [self displayLaunchWindow]; } + _diskImages = [DiskImagesWindowController new]; + } -(void)displayLaunchWindow { diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index c5f68e6..f727d6f 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -8,31 +8,38 @@ #import "DiskImagesWindowController.h" #import "TableCellView.h" +#import "Ample.h" @interface DiskImagesWindowController () @property (weak) IBOutlet NSTableView *tableView; @property (strong) IBOutlet NSArrayController *arrayController; -@property NSMutableArray *content; +@property (strong) NSMutableArray *content; + @end @implementation DiskImagesWindowController { - //NSArray *_data; + BOOL _dirty; } + +-(instancetype)init { + + if ((self = [super init])) { + + [self loadRecentDiskImages]; + } + return self; +} + -(NSString *)windowNibName { return @"DiskImages"; } - (void)windowDidLoad { - //_data = [NSMutableArray new]; - [self setContent: - [NSMutableArray arrayWithObject: - [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"/path/to/a/file.2mg", @"path", - @(12345), @"size", - nil] - ]]; + + if (!_content) + [self setContent: [NSMutableArray new]]; [super windowDidLoad]; @@ -41,6 +48,96 @@ // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. } +-(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: @"DiskImageAdded" object: nil]; + + [nc addObserver: self selector: @selector(willTerminate:) name: NSApplicationWillTerminateNotification object: nil]; +} + +-(void)diskImageAdded: (NSNotification *)notification { + + NSURL *url = [notification object]; + if (!url) return; + + [self addFile: url]; +} + +-(void)willTerminate: (NSNotification *)notification { + // if dirty, write data.... + + if (!_dirty) return; + + NSURL *sd = SupportDirectory(); + NSURL *url = [sd URLByAppendingPathComponent: @"RecentDiskImages.plist"]; + + if (_content && url) { + [_content writeToURL: url atomically: YES]; + } + + +} + + +-(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... + + + 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]; + + @synchronized (self) { + if (_arrayController) + [_arrayController addObject: d]; + else + [_content addObject: d]; + } + + _dirty = YES; + return YES; +} + @end @implementation DiskImagesWindowController (TableView) @@ -91,27 +188,8 @@ NSURL *url = [NSURL URLFromPasteboard: pb]; if (!url) return NO; - NSFileManager *fm = [NSFileManager defaultManager]; - - NSString *path = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding]; - if (!path) return NO; + return [self addFile: url]; - NSError *error = nil; - 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" - , nil]; - - [_arrayController addObject: d]; - return YES; } @end diff --git a/Ample/MediaViewController.m b/Ample/MediaViewController.m index b8df390..5e1f2c1 100644 --- a/Ample/MediaViewController.m +++ b/Ample/MediaViewController.m @@ -611,6 +611,14 @@ static NSString *kDragType = @"private.ample.media"; - (IBAction)pathAction:(id)sender { // need to update the eject button... + + NSURL *url = [(NSPathControl *)sender URL]; + + if (url) { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc postNotificationName: @"DiskImageAdded" object: url]; + } + [self rebuildArgs]; } @end From 59ce93bbc06c2c900412d081bb75f05515050bec Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 15 Sep 2020 21:56:10 -0400 Subject: [PATCH 05/10] add some duplicate filtering when adding a disk image to the recent list. --- Ample/DiskImagesWindowController.m | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index f727d6f..0fc0311 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -108,6 +108,19 @@ // 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"]; + _dirty = YES; // ? + break; + } + } + if (found) return NO; + NSFileManager *fm = [NSFileManager defaultManager]; NSError *error; From d5d869a4077cdfc7fe6b672cad7f46e97edd89c9 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 15 Sep 2020 23:11:20 -0400 Subject: [PATCH 06/10] check filetypes when drag-n-dropping to the recent window. alt skips filetype check. --- Ample/DiskImagesWindowController.m | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index 0fc0311..80492ea 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -19,6 +19,7 @@ @implementation DiskImagesWindowController { BOOL _dirty; + NSSet *_extensions; } @@ -28,6 +29,10 @@ if ((self = [super init])) { [self loadRecentDiskImages]; + + _extensions = [NSSet setWithObjects: + @"2img", @"2mg", @"chd", @"dc", @"do", @"dsk", @"hd", @"hdv", @"image", @"nib", @"po", @"wav", @"woz", @"iso", nil + ]; } return self; } @@ -190,8 +195,19 @@ } -(NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation { + + // option key will ignore all filetype restrictions. + if ([NSEvent modifierFlags] & NSEventModifierFlagOption) return NSDragOperationCopy; + + NSPasteboard * pb = [info draggingPasteboard]; + NSURL *url = [NSURL URLFromPasteboard: pb]; - return NSDragOperationCopy; + NSString *ext = [url pathExtension]; + ext = [ext lowercaseString]; + if ([_extensions containsObject: ext]) + return NSDragOperationCopy; + + return NSDragOperationNone; } -(BOOL)tableView:(NSTableView *)tableView acceptDrop:(id)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { From bf619da42d716b1204566d804a214ce44b5cf049 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 15 Sep 2020 23:44:24 -0400 Subject: [PATCH 07/10] eject / show in finder menu for disk images. --- Ample/Base.lproj/DiskImages.xib | 29 ++++++++++++++++++--- Ample/DiskImagesWindowController.h | 4 +++ Ample/DiskImagesWindowController.m | 41 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Ample/Base.lproj/DiskImages.xib b/Ample/Base.lproj/DiskImages.xib index b499c46..7956ea5 100644 --- a/Ample/Base.lproj/DiskImages.xib +++ b/Ample/Base.lproj/DiskImages.xib @@ -24,14 +24,14 @@ - + - + @@ -64,19 +64,19 @@ - FilePathTransformer + - + @@ -103,6 +103,7 @@ + @@ -129,5 +130,25 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Ample/DiskImagesWindowController.h b/Ample/DiskImagesWindowController.h index 8d8bb76..b792240 100644 --- a/Ample/DiskImagesWindowController.h +++ b/Ample/DiskImagesWindowController.h @@ -18,5 +18,9 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface DiskImagesWindowController (Menu) + +@end + NS_ASSUME_NONNULL_END diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index 80492ea..b9a44c1 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -156,6 +156,47 @@ return YES; } + +-(NSMutableDictionary *)clickedItem { + + NSInteger row = [_tableView clickedRow]; + if (row < 0) return nil; + + NSTableCellView *v = [_tableView viewAtColumn: 0 row: row makeIfNecessary: NO]; + return [v objectValue]; +} +#pragma mark - IBActions + +- (IBAction)showInFinder:(id)sender { + + NSMutableDictionary *item = [self clickedItem]; + if (!item) return; + NSString *path = [item objectForKey: @"path"]; + + NSURL *url = [NSURL fileURLWithPath: path]; + if (!url) return; + + NSWorkspace *ws = [NSWorkspace sharedWorkspace]; + [ws activateFileViewerSelectingURLs: @[url]]; +} + +- (IBAction)eject:(id)sender { + + NSMutableDictionary *item = [self clickedItem]; + if (!item) return; + + @synchronized (self) { + + if (_arrayController) { + [_arrayController removeObject: item]; + } else { + [_content removeObject: item]; + } + _dirty = YES; + } + +} + @end @implementation DiskImagesWindowController (TableView) From 7a085301cf962947ca39ecaba8147428f9f38705 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Fri, 18 Sep 2020 00:33:02 -0400 Subject: [PATCH 08/10] drag-and-drop - export urls to other applications. --- Ample/DiskImagesWindowController.m | 93 ++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index b9a44c1..5c15939 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -20,6 +20,7 @@ @implementation DiskImagesWindowController { BOOL _dirty; NSSet *_extensions; + NSTimer *_timer; } @@ -48,8 +49,9 @@ [super windowDidLoad]; - [_tableView registerForDraggedTypes: @[NSPasteboardTypeURL]]; - + [_tableView registerForDraggedTypes: @[NSPasteboardTypeFileURL]]; + [_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. } @@ -81,11 +83,20 @@ [self addFile: url]; } +-(void)markDirty { + _dirty = YES; + if (_timer) [_timer invalidate]; + _timer = [NSTimer scheduledTimerWithTimeInterval: 5 * 60 repeats: NO block: ^(NSTimer *t) { + + self->_timer = nil; + [self saveFile]; + }]; +} --(void)willTerminate: (NSNotification *)notification { - // if dirty, write data.... +-(void)saveFile { - if (!_dirty) return; + [_timer invalidate]; + _timer = nil; NSURL *sd = SupportDirectory(); NSURL *url = [sd URLByAppendingPathComponent: @"RecentDiskImages.plist"]; @@ -93,11 +104,22 @@ if (_content && url) { [_content writeToURL: url atomically: YES]; } + _dirty = NO; +} + +-(void)willTerminate: (NSNotification *)notification { + // if dirty, write data.... + + if (!_dirty) return; + + [self saveFile]; } + + -(BOOL)addFile: (NSObject *)pathOrURL { NSString *path = nil; @@ -120,7 +142,7 @@ if ([path compare: s] == NSOrderedSame) { found = YES; [d setObject: [NSDate new] forKey: @"date"]; - _dirty = YES; // ? + [self markDirty]; break; } } @@ -151,8 +173,7 @@ else [_content addObject: d]; } - - _dirty = YES; + [self markDirty]; return YES; } @@ -192,7 +213,7 @@ } else { [_content removeObject: item]; } - _dirty = YES; + [self markDirty]; } } @@ -215,31 +236,36 @@ #endif -- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { - -// if ([rowIndexes count] > 1) return NO; // ? - +-(id)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row { + id objects = [_arrayController arrangedObjects]; - [pboard declareTypes: @[NSPasteboardTypeURL] owner: nil]; - // NSURLPboardType deprecated - [rowIndexes enumerateIndexesUsingBlock: ^(NSUInteger index, BOOL *stop) { - - NSDictionary *d = [objects objectAtIndex: index]; - NSString *path = [d objectForKey: @"path"]; + + NSDictionary *d = [objects objectAtIndex: row]; + + NSString *path = [d objectForKey: @"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 - NSURL *url = [NSURL fileURLWithPath: path]; - [url writeToPasteboard: pboard]; - }]; - // NSFilenamesPboardType -- old way of handling it ... - - return YES; + return item; +#endif } + + -(NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id)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]; @@ -253,13 +279,22 @@ -(BOOL)tableView:(NSTableView *)tableView acceptDrop:(id)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { + if ([info draggingSource] == _tableView) return NO; NSPasteboard * pb = [info draggingPasteboard]; - NSURL *url = [NSURL URLFromPasteboard: pb]; - if (!url) return NO; - return [self addFile: url]; - + 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 = [item stringForType: NSPasteboardTypeFileURL]; + if (!s) continue; + NSURL *url = [NSURL URLWithString: s]; + if (!url) continue; + + ok |= [self addFile: url]; + } + return ok; } @end From ecfd5fb7a8be31503e65c3c43b6f82133c84d6b9 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Fri, 18 Sep 2020 13:35:04 -0400 Subject: [PATCH 09/10] adjust window positions, add frame auto-save --- Ample/Base.lproj/DiskImages.xib | 6 +++--- Ample/Base.lproj/DownloadWindow.xib | 2 +- Ample/Base.lproj/LaunchWindow.xib | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Ample/Base.lproj/DiskImages.xib b/Ample/Base.lproj/DiskImages.xib index 7956ea5..9820552 100644 --- a/Ample/Base.lproj/DiskImages.xib +++ b/Ample/Base.lproj/DiskImages.xib @@ -15,10 +15,10 @@ - + - - + + diff --git a/Ample/Base.lproj/DownloadWindow.xib b/Ample/Base.lproj/DownloadWindow.xib index b86f454..fd3de9b 100644 --- a/Ample/Base.lproj/DownloadWindow.xib +++ b/Ample/Base.lproj/DownloadWindow.xib @@ -14,7 +14,7 @@ - + diff --git a/Ample/Base.lproj/LaunchWindow.xib b/Ample/Base.lproj/LaunchWindow.xib index af7c17a..e8d55ec 100644 --- a/Ample/Base.lproj/LaunchWindow.xib +++ b/Ample/Base.lproj/LaunchWindow.xib @@ -19,7 +19,7 @@ - + From f90f5a6bf32aa061dc3ae7aeedf0bfdf9301f3e1 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Fri, 25 Sep 2020 20:46:25 -0400 Subject: [PATCH 10/10] window restoration support. only applies if you option quit (quit and save windows) or quit unexpectedly. --- Ample.xcodeproj/project.pbxproj | 36 ++++++++++++++++++------------ Ample/AppDelegate.m | 11 +++++---- Ample/Defaults.plist | 2 ++ Ample/DiskImagesWindowController.h | 4 +++- Ample/DiskImagesWindowController.m | 19 ++++++++++++++++ Ample/DownloadWindowController.h | 5 ++++- Ample/DownloadWindowController.m | 27 ++++++++++++++++++++++ 7 files changed, 84 insertions(+), 20 deletions(-) diff --git a/Ample.xcodeproj/project.pbxproj b/Ample.xcodeproj/project.pbxproj index bebcd7e..acb95cc 100644 --- a/Ample.xcodeproj/project.pbxproj +++ b/Ample.xcodeproj/project.pbxproj @@ -465,18 +465,14 @@ B6BA257D24E99BE9005FB8FF /* Ample */ = { isa = PBXGroup; children = ( - B64AF1F4250ED5E400A09B9B /* TableCellView.h */, - B64AF1F5250ED5E400A09B9B /* TableCellView.m */, - B6E9A17E25088B1B005E7525 /* NewSlotViewController.h */, - B6E9A17F25088B1B005E7525 /* NewSlotViewController.m */, - B63C1B9125008A2700511A71 /* DownloadWindowController.h */, - B63C1B9225008A2700511A71 /* DownloadWindowController.m */, B6BA257E24E99BE9005FB8FF /* AppDelegate.h */, B6BA257F24E99BE9005FB8FF /* AppDelegate.m */, B63C1B8924FF4B7100511A71 /* Ample.h */, B63C1B8A24FF4BF700511A71 /* Ample.m */, - B6D6DE3F24FADFAC00661A5F /* LaunchWindowController.h */, - B6D6DE4024FADFAC00661A5F /* LaunchWindowController.m */, + B64AF1F4250ED5E400A09B9B /* TableCellView.h */, + B64AF1F5250ED5E400A09B9B /* TableCellView.m */, + B6E9A17E25088B1B005E7525 /* NewSlotViewController.h */, + B6E9A17F25088B1B005E7525 /* NewSlotViewController.m */, B65593B024ECB61800722E0C /* SlotViewController.m */, B65593AF24ECB61800722E0C /* SlotViewController.h */, B64979C024EF6703008ABD20 /* MediaViewController.h */, @@ -487,14 +483,9 @@ B60A6E1224EE0AE2004B7EEF /* FlippedView.h */, B608E17D2502FE0C00D53465 /* TransparentScroller.h */, B608E17E2502FE0C00D53465 /* TransparentScroller.m */, - B6004DED24FB05D600D38596 /* LogWindowController.h */, - B6004DEE24FB05D600D38596 /* LogWindowController.m */, - B66236A724FD9A34006CABD7 /* PreferencesWindowController.h */, - B66236A824FD9A34006CABD7 /* PreferencesWindowController.m */, + B6BA563A251685DA00B0C47D /* Window Controllers */, B6B9EA652506A5550080E70D /* EjectButton.h */, B6B9EA642506A5550080E70D /* EjectButton.m */, - B64AF1F0250ECB2E00A09B9B /* DiskImagesWindowController.h */, - B64AF1F1250ECB2E00A09B9B /* DiskImagesWindowController.m */, B64AF1F8250EF6A500A09B9B /* Transformers.h */, B64AF1F9250EF6A500A09B9B /* Transformers.m */, B6BA258124E99BEB005FB8FF /* Assets.xcassets */, @@ -509,6 +500,23 @@ path = Ample; sourceTree = ""; }; + B6BA563A251685DA00B0C47D /* Window Controllers */ = { + isa = PBXGroup; + children = ( + B64AF1F0250ECB2E00A09B9B /* DiskImagesWindowController.h */, + B64AF1F1250ECB2E00A09B9B /* DiskImagesWindowController.m */, + B63C1B9125008A2700511A71 /* DownloadWindowController.h */, + B63C1B9225008A2700511A71 /* DownloadWindowController.m */, + B6D6DE3F24FADFAC00661A5F /* LaunchWindowController.h */, + B6D6DE4024FADFAC00661A5F /* LaunchWindowController.m */, + B6004DED24FB05D600D38596 /* LogWindowController.h */, + B6004DEE24FB05D600D38596 /* LogWindowController.m */, + B66236A724FD9A34006CABD7 /* PreferencesWindowController.h */, + B66236A824FD9A34006CABD7 /* PreferencesWindowController.m */, + ); + name = "Window Controllers"; + sourceTree = ""; + }; B6D6DE4224FAEE8900661A5F /* Nibs */ = { isa = PBXGroup; children = ( diff --git a/Ample/AppDelegate.m b/Ample/AppDelegate.m index 3a2344c..0f502a8 100644 --- a/Ample/AppDelegate.m +++ b/Ample/AppDelegate.m @@ -46,12 +46,13 @@ + _diskImages = [DiskImagesWindowController sharedInstance]; //[DiskImagesWindowController new]; + if ([self installMameComponents]) { + [self displayLaunchWindow]; } - _diskImages = [DiskImagesWindowController new]; - } -(void)displayLaunchWindow { @@ -119,6 +120,7 @@ } [win close]; [self displayLaunchWindow]; + [self displayROMS: nil]; }); }]; @@ -152,15 +154,16 @@ - (IBAction)displayROMS:(id)sender { if (!_downloader) { - _downloader = [DownloadWindowController new]; + _downloader = [DownloadWindowController sharedInstance]; } [_downloader showWindow: sender]; } - (IBAction)displayRecentDiskImages:(id)sender { if (!_diskImages) { - _diskImages = [DiskImagesWindowController new]; + _diskImages = [DiskImagesWindowController sharedInstance]; } [_diskImages showWindow: sender]; } + @end diff --git a/Ample/Defaults.plist b/Ample/Defaults.plist index 3a4e96d..4414f9d 100644 --- a/Ample/Defaults.plist +++ b/Ample/Defaults.plist @@ -10,5 +10,7 @@ MamePath /usr/local/bin/mame + NSQuitAlwaysKeepsWindows + diff --git a/Ample/DiskImagesWindowController.h b/Ample/DiskImagesWindowController.h index b792240..37562cd 100644 --- a/Ample/DiskImagesWindowController.h +++ b/Ample/DiskImagesWindowController.h @@ -10,7 +10,9 @@ NS_ASSUME_NONNULL_BEGIN -@interface DiskImagesWindowController : NSWindowController +@interface DiskImagesWindowController : NSWindowController + ++(instancetype)sharedInstance; @end diff --git a/Ample/DiskImagesWindowController.m b/Ample/DiskImagesWindowController.m index 5c15939..9ef7d98 100644 --- a/Ample/DiskImagesWindowController.m +++ b/Ample/DiskImagesWindowController.m @@ -24,6 +24,21 @@ } ++(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 { @@ -48,6 +63,10 @@ [self setContent: [NSMutableArray new]]; [super windowDidLoad]; + NSWindow *window = [self window]; + [window setRestorable: YES]; + [window setRestorationClass: [self class]]; + [_tableView registerForDraggedTypes: @[NSPasteboardTypeFileURL]]; [_tableView setDraggingSourceOperationMask: NSDragOperationCopy forLocal: NO]; // enable drag/drop to othr apps. diff --git a/Ample/DownloadWindowController.h b/Ample/DownloadWindowController.h index 80c1ec3..65103e1 100644 --- a/Ample/DownloadWindowController.h +++ b/Ample/DownloadWindowController.h @@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface DownloadWindowController : NSWindowController +@interface DownloadWindowController : NSWindowController @property NSString *currentROM; @property NSInteger currentCount; @@ -18,6 +18,9 @@ NS_ASSUME_NONNULL_BEGIN @property NSInteger errorCount; @property BOOL active; ++(instancetype)sharedInstance; + + @end @interface DownloadWindowController (URL) diff --git a/Ample/DownloadWindowController.m b/Ample/DownloadWindowController.m index 956e008..ecc6a63 100644 --- a/Ample/DownloadWindowController.m +++ b/Ample/DownloadWindowController.m @@ -52,12 +52,38 @@ enum { NSMutableDictionary *_taskIndex; } ++(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)windowDidLoad { [super windowDidLoad]; + NSWindow *window = [self window]; + [window setRestorable: YES]; + [window setRestorationClass: [self class]]; // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. @@ -303,6 +329,7 @@ enum { */ NSLog(@"%@", src); } + @end @implementation DownloadWindowController (Table)