ample/Ample/NewSlotViewController.m

285 lines
6.1 KiB
Mathematica
Raw Normal View History

2020-09-11 02:06:41 +00:00
//
// NewSlotViewController.m
// Ample
//
// Created by Kelvin Sherlock on 9/9/2020.
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
//
#import "Ample.h"
2020-09-11 02:06:41 +00:00
#import "NewSlotViewController.h"
#import "Menu.h"
#import "Slot.h"
#import "Media.h"
2020-09-11 02:06:41 +00:00
2021-01-17 06:05:02 +00:00
/* number of slot types. bitmask used so should be < sizeof(unsigned *8) */
2021-01-18 20:46:07 +00:00
#define SLOT_COUNT 21
static_assert(SLOT_COUNT <= sizeof(unsigned) * 8, "too many slot types");
2020-09-11 02:06:41 +00:00
#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
2020-09-11 02:06:41 +00:00
@interface NewSlotViewController ()
@property (weak) IBOutlet NSOutlineView *outlineView;
@end
@implementation NewSlotViewController {
NSArray *_root;
2020-09-11 02:06:41 +00:00
unsigned _slots_explicit;
unsigned _slots_valid;
unsigned _slots_default;
Slot *_slot_object[SLOT_COUNT];
2021-01-18 20:46:07 +00:00
NSString *_slot_value[SLOT_COUNT]; // when explicitely set.
Media _slot_media[SLOT_COUNT];
Media _machine_media;
2020-09-11 02:06:41 +00:00
NSDictionary *_machine_data;
2020-09-11 02:06:41 +00:00
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
2020-09-12 22:00:09 +00:00
_root = @[];
[_outlineView setIndentationPerLevel: 2.0];
2020-09-11 02:06:41 +00:00
}
-(void)resetMachine {
_root = @[];
2020-09-11 02:06:41 +00:00
[_outlineView reloadData];
_slots_valid = 0;
_slots_explicit = 0;
_slots_default = 0;
_machine_media = EmptyMedia;
2020-09-11 02:06:41 +00:00
_machine_data = nil;
2021-01-18 20:46:07 +00:00
for (unsigned i = 0; i < SLOT_COUNT; ++i) {
_slot_media[i] = EmptyMedia;
2020-09-11 02:06:41 +00:00
_slot_object[i] = nil;
_slot_value[i] = nil;
}
[self setResolution: NSMakeSize(0, 0)];
[self setArgs: @[]];
[self setMedia: EmptyMedia];
2020-09-11 02:06:41 +00:00
}
2020-09-11 02:06:41 +00:00
-(void)loadMachine {
NSDictionary *d = MameMachine(_machine);
2020-09-11 02:06:41 +00:00
if (!d) {
[self resetMachine];
return;
}
NSArray *r = [d objectForKey: @"resolution"];
NSSize res = NSMakeSize(0, 0);
if (r) {
res.width = [(NSNumber *)[r objectAtIndex: 0 /*@"width"*/] doubleValue];
res.height = [(NSNumber *)[r objectAtIndex: 1 /*@"height"*/] doubleValue];
}
[self setResolution: res];
_slots_valid = 0;
//_slots_explicit = 0;
_slots_default = 0;
_machine_media = MediaFromDictionary([d objectForKey: @"media"]);
2020-09-11 02:06:41 +00:00
_machine_data = d;
for (unsigned i = 0; i < SLOT_COUNT; ++i) {
_slot_media[i] = EmptyMedia;
2020-09-11 02:06:41 +00:00
_slot_object[i] = nil;
}
2020-09-11 02:06:41 +00:00
extern NSArray *BuildSlots(NSString *name, NSDictionary *data);
_root = BuildSlots(_machine, d);
for (Slot *item in _root) {
NSInteger index = [item index];
if (index < 0) continue;
unsigned mask = 1 << index;
2020-09-11 02:06:41 +00:00
_slots_valid |= mask;
if ([item defaultIndex] >= 0)
2020-09-11 02:06:41 +00:00
_slots_default |= mask;
if (_slot_value[index])
[item selectValue: _slot_value[index]];
_slot_media[index] = [item selectedMedia];
_slot_object[index] = item;
2020-09-11 02:06:41 +00:00
}
2020-09-11 02:06:41 +00:00
[_outlineView reloadData];
[self rebuildMedia];
[self rebuildArgs];
}
-(void)setMachine: (NSString *)machine {
if (_machine == machine) return;
if (_machine && machine && [machine compare: _machine] == NSOrderedSame) return;
_machine = machine;
if (!machine) {
[self resetMachine];
return;
}
[self loadMachine];
}
-(void)rebuildMedia {
Media media = _machine_media;
2020-09-11 02:06:41 +00:00
unsigned mask = 1;
2021-01-18 20:46:07 +00:00
for (unsigned i = 0; i < SLOT_COUNT; ++i, mask <<= 1) {
2020-09-11 02:06:41 +00:00
if (_slots_valid & mask) {
MediaAdd(&media, &_slot_media[i]);
2020-09-11 02:06:41 +00:00
}
}
[self setMedia: media];
2020-09-11 02:06:41 +00:00
}
2020-09-11 02:06:41 +00:00
-(void)rebuildArgs {
NSMutableArray *args = [NSMutableArray new];
for (Slot *item in _root) {
2020-09-11 02:06:41 +00:00
NSArray *x = [item args];
if (x) [args addObjectsFromArray: x];
2020-09-11 02:06:41 +00:00
}
2020-09-11 02:06:41 +00:00
[self setArgs: args];
}
- (IBAction)menuChanged:(NSPopUpButton *)sender {
BOOL direct = YES;
NSInteger index = [sender tag];
if (index < 0) return; //
if (index >= 0 && index < SLOT_COUNT) {
direct = YES;
} else {
direct = NO;
index &= ~0x10000;
}
if (index >= SLOT_COUNT) return; //
2020-09-11 02:06:41 +00:00
unsigned mask = 1 << index;
// index 0 = ram = special case...
SlotOption *o = [[sender selectedItem] representedObject];
Slot *item = _slot_object[index];
2020-09-11 02:06:41 +00:00
if (direct) {
_slots_explicit |= mask;
_slot_value[index] = [o value];
//_slots_default &= ~mask;
}
2020-09-11 02:06:41 +00:00
Media media = [item selectedMedia];
if (!MediaEqual(&media, &_slot_media[index])) {
_slot_media[index] = media;
2020-09-11 02:06:41 +00:00
[self rebuildMedia];
2020-09-11 02:06:41 +00:00
}
// needs to reload children if expanded.
if (direct) {
BOOL rc = ([_outlineView isItemExpanded: item]);
[_outlineView reloadItem: item reloadChildren: rc];
}
2020-09-11 02:06:41 +00:00
[self rebuildArgs];
}
-(IBAction)resetSlots:(id)sender {
_slots_explicit = 0;
2021-01-18 20:46:07 +00:00
for (unsigned i = 0; i < SLOT_COUNT; ++i) {
_slot_media[i] = EmptyMedia;
2020-09-11 02:06:41 +00:00
_slot_value[i] = nil;
}
for (Slot *item in _root) {
2020-09-11 02:06:41 +00:00
[item reset];
// if children, reset them too...
NSInteger index = [item index];
if (index < 0) continue;
2020-09-11 02:06:41 +00:00
_slot_media[index] = [item selectedMedia];
}
[_outlineView reloadData];
2020-09-11 02:06:41 +00:00
[self rebuildMedia];
[self rebuildArgs];
}
@end
@implementation NewSlotViewController (OutlineView)
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
if (!item) return [_root count];
NSArray *tmp = [(Slot *)item selectedChildren];
return [tmp count];
// return 0;
2020-09-11 02:06:41 +00:00
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
if (!item) return [_root objectAtIndex: index];
NSArray *tmp = [(Slot *)item selectedChildren];
return [tmp objectAtIndex: index];
2020-09-11 02:06:41 +00:00
return nil;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
if (!item) return NO;
NSArray *tmp = [(Slot *)item selectedChildren];
return [tmp count] > 0;
2020-09-11 02:06:41 +00:00
}
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(Slot *)item {
2020-09-11 02:06:41 +00:00
SlotTableCellView *v = [outlineView makeViewWithIdentifier: @"MenuCell" owner: self];
[item prepareView: v];
return v;
}
@end