Compare commits
No commits in common. "master" and "gh-pages" have entirely different histories.
36
.gitignore
vendored
36
.gitignore
vendored
@ -1,36 +0,0 @@
|
||||
# Mac OS X Finder and whatnot
|
||||
.DS_Store
|
||||
|
||||
# Sparkle distribution Private Key (Don't check me in!)
|
||||
dsa_priv.pem
|
||||
|
||||
# XCode (and ancestors) per-user config (very noisy, and not relevant)
|
||||
*.mode1
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.perspective
|
||||
*.perspectivev3
|
||||
*.pbxuser
|
||||
*.xcworkspace
|
||||
xcuserdata
|
||||
|
||||
# Generated files
|
||||
VersionX-revision.h
|
||||
|
||||
# build products
|
||||
build/
|
||||
*.[oa]
|
||||
|
||||
# Other source repository archive directories (protects when importing)
|
||||
.hg
|
||||
.svn
|
||||
CVS
|
||||
|
||||
# automatic backup files
|
||||
*~.nib
|
||||
*.swp
|
||||
*~
|
||||
*(Autosaved).rtfd/
|
||||
Backup[ ]of[ ]*.pages/
|
||||
Backup[ ]of[ ]*.key/
|
||||
Backup[ ]of[ ]*.numbers/
|
||||
@ -1,40 +0,0 @@
|
||||
//
|
||||
// IJInventoryItem.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/7/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
// See: http://www.minecraftwiki.net/wiki/Data_values
|
||||
#define IJInventorySlotQuickFirst (0)
|
||||
#define IJInventorySlotQuickLast (8)
|
||||
#define IJInventorySlotNormalFirst (9)
|
||||
#define IJInventorySlotNormalLast (35)
|
||||
#define IJInventorySlotArmorLast (103) // head
|
||||
#define IJInventorySlotArmorFirst (100) // feet
|
||||
|
||||
|
||||
@interface IJInventoryItem : NSObject <NSCoding> {
|
||||
int16_t itemId;
|
||||
int16_t damage;
|
||||
uint8_t count;
|
||||
int8_t slot;
|
||||
}
|
||||
@property (nonatomic, assign) int16_t itemId;
|
||||
@property (nonatomic, assign) int16_t damage;
|
||||
@property (nonatomic, assign) uint8_t count;
|
||||
@property (nonatomic, assign) int8_t slot;
|
||||
|
||||
@property (nonatomic, readonly) NSString *itemName;
|
||||
@property (nonatomic, readonly) NSImage *image;
|
||||
|
||||
+ (id)emptyItemWithSlot:(uint8_t)slot;
|
||||
|
||||
+ (NSDictionary *)itemIdLookup;
|
||||
|
||||
+ (NSImage *)imageForItemId:(uint16_t)itemId;
|
||||
|
||||
@end
|
||||
@ -1,173 +0,0 @@
|
||||
//
|
||||
// IJInventoryItem.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/7/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJInventoryItem.h"
|
||||
|
||||
|
||||
@implementation IJInventoryItem
|
||||
|
||||
@synthesize itemId, slot, damage, count;
|
||||
|
||||
+ (id)emptyItemWithSlot:(uint8_t)slot
|
||||
{
|
||||
IJInventoryItem *obj = [[[[self class] alloc] init] autorelease];
|
||||
obj.slot = slot;
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
itemId = [decoder decodeIntForKey:@"itemId"];
|
||||
slot = [decoder decodeIntForKey:@"slot"];
|
||||
damage = [decoder decodeIntForKey:@"damage"];
|
||||
count = [decoder decodeIntForKey:@"count"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)coder
|
||||
{
|
||||
[coder encodeInt:itemId forKey:@"itemId"];
|
||||
[coder encodeInt:slot forKey:@"slot"];
|
||||
[coder encodeInt:damage forKey:@"damage"];
|
||||
[coder encodeInt:count forKey:@"count"];
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@ %p itemId=%d name=%@ count=%d slot=%d damage=%d",
|
||||
NSStringFromClass([self class]), self, itemId, self.itemName, count, slot, damage];
|
||||
}
|
||||
|
||||
- (NSString *)itemName
|
||||
{
|
||||
NSString *name = [[IJInventoryItem itemIdLookup] objectForKey:[NSNumber numberWithShort:self.itemId]];
|
||||
if (name)
|
||||
return name;
|
||||
else
|
||||
return [NSString stringWithFormat:@"%d", self.itemId];
|
||||
}
|
||||
|
||||
+ (NSImage *)imageForItemId:(uint16_t)itemId
|
||||
{
|
||||
NSSize itemImageSize = NSMakeSize(32, 32);
|
||||
NSPoint atlasOffset;
|
||||
NSUInteger itemsPerRow = 9;
|
||||
NSUInteger pixelsPerColumn = 36;
|
||||
NSUInteger pixelsPerRow = 56;
|
||||
NSImage *atlas;
|
||||
BOOL notFound = FALSE;
|
||||
|
||||
int index = 0;
|
||||
|
||||
if (itemId <= 94)
|
||||
{
|
||||
if (itemId <= 17){
|
||||
index = itemId - 1; // first item is 1
|
||||
}
|
||||
else if (itemId <= 34 ){
|
||||
index = itemId + 1;
|
||||
}
|
||||
else if (itemId == 35 ){
|
||||
index = itemId - 8;
|
||||
}
|
||||
else if (itemId >= 37){
|
||||
index = itemId + 6;
|
||||
}
|
||||
atlasOffset = NSMakePoint(36, 75);
|
||||
}
|
||||
else if (itemId >= 256 && itemId <= 351)
|
||||
{
|
||||
index = itemId - 256;
|
||||
atlasOffset = NSMakePoint(445, 75);
|
||||
}
|
||||
else if (itemId >= 352 && itemId <= 356)
|
||||
{
|
||||
index = itemId - 241;
|
||||
atlasOffset = NSMakePoint(445, 75);
|
||||
}
|
||||
else if (itemId == 2256)
|
||||
{
|
||||
index = 0;
|
||||
atlasOffset = NSMakePoint(445+pixelsPerColumn*8, pixelsPerRow*13 + 18);
|
||||
}
|
||||
else if (itemId == 2257)
|
||||
{
|
||||
index = 0;
|
||||
atlasOffset = NSMakePoint(445, pixelsPerRow*14+18);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"%s error: unrecognized item id %d", __PRETTY_FUNCTION__, itemId);
|
||||
index = 0;
|
||||
atlasOffset = NSMakePoint(1, 30);
|
||||
notFound = TRUE;
|
||||
}
|
||||
|
||||
atlasOffset.x += pixelsPerColumn * (index % itemsPerRow);
|
||||
atlasOffset.y += pixelsPerRow * (index / itemsPerRow);
|
||||
|
||||
NSRect atlasRect = NSMakeRect(atlasOffset.x, atlasOffset.y, itemImageSize.width, itemImageSize.height);
|
||||
|
||||
if (notFound != TRUE) {
|
||||
atlas = [NSImage imageNamed:@"DataValuesV110Transparent.png"];
|
||||
}else {
|
||||
atlas = [NSImage imageNamed:@"blockNotFound.png"];
|
||||
}
|
||||
|
||||
NSImage *output = [[NSImage alloc] initWithSize:itemImageSize];
|
||||
|
||||
atlasRect.origin.y = atlas.size.height - atlasRect.origin.y;
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
|
||||
[output lockFocus];
|
||||
|
||||
[atlas drawInRect:NSMakeRect(0, 0, itemImageSize.width, itemImageSize.height)
|
||||
fromRect:atlasRect
|
||||
operation:NSCompositeCopy
|
||||
fraction:1.0];
|
||||
|
||||
[output unlockFocus];
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
return [output autorelease];
|
||||
}
|
||||
|
||||
- (NSImage *)image
|
||||
{
|
||||
return [IJInventoryItem imageForItemId:itemId];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)itemIdLookup
|
||||
{
|
||||
static NSDictionary *lookup = nil;
|
||||
if (!lookup)
|
||||
{
|
||||
NSError *error = nil;
|
||||
NSString *lines = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Items" withExtension:@"csv"]
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:&error];
|
||||
NSMutableDictionary *building = [NSMutableDictionary dictionary];
|
||||
[lines enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
|
||||
if ([line hasPrefix:@"#"]) // ignore lines with a # prefix
|
||||
return;
|
||||
NSArray *components = [line componentsSeparatedByString:@","];
|
||||
NSNumber *itemId = [NSNumber numberWithShort:[[components objectAtIndex:0] intValue]];
|
||||
NSString *name = [components objectAtIndex:1];
|
||||
[building setObject:name forKey:itemId];
|
||||
}];
|
||||
lookup = [[NSDictionary alloc] initWithDictionary:building];
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,44 +0,0 @@
|
||||
//
|
||||
// IJInventoryView.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/9/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
extern NSString * const IJPasteboardTypeInventoryItem;
|
||||
|
||||
@protocol IJInventoryViewDelegate;
|
||||
@class IJInventoryItem;
|
||||
|
||||
@interface IJInventoryView : NSView {
|
||||
int rows;
|
||||
int cols;
|
||||
|
||||
BOOL invert;
|
||||
|
||||
NSEvent *mouseDownEvent;
|
||||
|
||||
NSArray *items;
|
||||
|
||||
id<IJInventoryViewDelegate> delegate;
|
||||
|
||||
BOOL dragging;
|
||||
}
|
||||
@property (nonatomic, assign) id<IJInventoryViewDelegate> delegate;
|
||||
|
||||
- (void)setRows:(int)numberOfRows columns:(int)numberOfColumns invert:(BOOL)invert;
|
||||
- (void)setItems:(NSArray *)theItems;
|
||||
- (NSPoint)pointForItemAtIndex:(int)index;
|
||||
- (void)reloadItemAtIndex:(int)itemIndex;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@protocol IJInventoryViewDelegate <NSObject>
|
||||
- (void)inventoryView:(IJInventoryView *)inventoryView removeItemAtIndex:(int)itemIndex;
|
||||
- (void)inventoryView:(IJInventoryView *)inventoryView setItem:(IJInventoryItem *)item atIndex:(int)itemIndex;
|
||||
- (void)inventoryView:(IJInventoryView *)inventoryView selectedItemAtIndex:(int)itemIndex;
|
||||
@end
|
||||
@ -1,358 +0,0 @@
|
||||
//
|
||||
// IJInventoryView.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/9/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJInventoryView.h"
|
||||
#import "IJInventoryItem.h"
|
||||
#import "MAAttachedWindow.h"
|
||||
#import "NSColor+Additions.h"
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
NSString * const IJPasteboardTypeInventoryItem = @"net.adampreble.insidejob.inventoryitem";
|
||||
|
||||
const static CGFloat cellSize = 36;
|
||||
const static CGFloat cellOffset = 40;
|
||||
|
||||
@implementation IJInventoryView
|
||||
|
||||
@synthesize delegate;
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if (self = [super initWithFrame:frameRect])
|
||||
{
|
||||
// Initialization code here.
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:IJPasteboardTypeInventoryItem, nil]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[items release];
|
||||
[mouseDownEvent release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (CGColorRef)borderColor
|
||||
{
|
||||
return [[NSColor colorWithCalibratedWhite:0.5 alpha:1.0] CGColor];
|
||||
}
|
||||
- (CGColorRef)highlightedBorderColor
|
||||
{
|
||||
return [[NSColor colorWithCalibratedWhite:0 alpha:1.0] CGColor];
|
||||
}
|
||||
|
||||
// For use by external stuff, since it flips the coordinates and our layer uses flipped geometry.
|
||||
- (NSPoint)pointForItemAtIndex:(int)index
|
||||
{
|
||||
int x = index % cols;
|
||||
int y = index / cols;
|
||||
if (invert)
|
||||
y = rows - 1 - y;
|
||||
return NSMakePoint(x * cellOffset, self.bounds.size.height - y * cellOffset);
|
||||
}
|
||||
|
||||
- (void)setRows:(int)numberOfRows columns:(int)numberOfColumns invert:(BOOL)inv
|
||||
{
|
||||
invert = inv;
|
||||
|
||||
CALayer *layer = [CALayer layer];
|
||||
|
||||
layer.bounds = NSRectToCGRect(self.bounds);
|
||||
layer.anchorPoint = CGPointZero;
|
||||
layer.position = CGPointZero; //CGPointMake(NSMidX(self.bounds), NSMidY(self.bounds));
|
||||
layer.geometryFlipped = YES;
|
||||
|
||||
[self setLayer:layer];
|
||||
[self setWantsLayer:YES];
|
||||
|
||||
|
||||
rows = numberOfRows;
|
||||
cols = numberOfColumns;
|
||||
|
||||
// reset the layers
|
||||
|
||||
for (CALayer *layer in self.layer.sublayers)
|
||||
{
|
||||
[layer removeFromSuperlayer];
|
||||
}
|
||||
|
||||
for (int y = 0; y < rows; y++)
|
||||
{
|
||||
for (int x = 0; x < cols; x++)
|
||||
{
|
||||
CALayer *layer = [CALayer layer];
|
||||
layer.anchorPoint = CGPointZero;
|
||||
|
||||
if (invert)
|
||||
layer.position = CGPointMake(x * cellOffset, (rows - 1 - y) * cellOffset);
|
||||
else
|
||||
layer.position = CGPointMake(x * cellOffset, y * cellOffset);
|
||||
|
||||
layer.bounds = CGRectMake(0, 0, cellSize, cellSize);
|
||||
layer.borderWidth = 1.0;
|
||||
layer.borderColor = [self borderColor];
|
||||
layer.backgroundColor = [[NSColor colorWithCalibratedWhite:0.7 alpha:1.0] CGColor];
|
||||
layer.cornerRadius = 2.0;
|
||||
|
||||
CALayer *imageLayer = [CALayer layer];
|
||||
imageLayer.position = CGPointMake(cellSize/2.0, cellSize/2.0);
|
||||
imageLayer.bounds = CGRectMake(0, 0, 32, 32);
|
||||
[layer addSublayer:imageLayer];
|
||||
|
||||
CATextLayer *textLayer = [CATextLayer layer];
|
||||
textLayer.bounds = CGRectMake(0, 0, cellSize-2, 18);
|
||||
textLayer.position = CGPointMake(cellSize/2.0, cellSize/2.0 + 18/2 + 1);
|
||||
textLayer.foregroundColor = CGColorGetConstantColor(kCGColorWhite);
|
||||
textLayer.fontSize = 18;
|
||||
textLayer.shadowOpacity = 1.0;
|
||||
textLayer.shadowRadius = 0.5;
|
||||
textLayer.shadowOffset = CGSizeMake(0, 1);
|
||||
textLayer.alignmentMode = @"right";
|
||||
[layer addSublayer:textLayer];
|
||||
|
||||
[self.layer addSublayer:layer];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reloadItemAtIndex:(int)itemIndex
|
||||
{
|
||||
IJInventoryItem *item = nil;
|
||||
|
||||
if (itemIndex < items.count)
|
||||
item = [items objectAtIndex:itemIndex];
|
||||
|
||||
CALayer *layer = [self.layer.sublayers objectAtIndex:itemIndex];
|
||||
|
||||
CALayer *imageLayer = [layer.sublayers objectAtIndex:0];
|
||||
imageLayer.contents = item.image;
|
||||
|
||||
CATextLayer *textLayer = [layer.sublayers objectAtIndex:1];
|
||||
if (item.count <= 1) // for 1 and 0, show no number.
|
||||
textLayer.string = @"";
|
||||
else
|
||||
textLayer.string = [NSString stringWithFormat:@"%d", item.count];
|
||||
}
|
||||
|
||||
- (void)setItems:(NSArray *)theItems
|
||||
{
|
||||
[items autorelease];
|
||||
[theItems retain];
|
||||
items = theItems;
|
||||
|
||||
for (int i = 0; i < rows * cols; i++)
|
||||
[self reloadItemAtIndex:i];
|
||||
}
|
||||
|
||||
- (int)itemIndexForPoint:(NSPoint)point
|
||||
{
|
||||
point.y = self.bounds.size.height - point.y;
|
||||
point.x /= cellOffset;
|
||||
point.y /= cellOffset;
|
||||
if (invert)
|
||||
point.y = rows - 1 - floor(point.y);
|
||||
int index = floor(point.y) * cols + floor(point.x); // flip y
|
||||
return index;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Drag & Drop: Source
|
||||
|
||||
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
|
||||
{
|
||||
// NSLog(@"%s", __PRETTY_FUNCTION__);
|
||||
// if (propertiesWindow) // take the first mouse while the properties window is up.
|
||||
// return YES;
|
||||
// else
|
||||
// return NO;
|
||||
// the above doesn't work since the window has already been dismissed by the time we get here
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
[theEvent retain];
|
||||
[mouseDownEvent release];
|
||||
mouseDownEvent = theEvent;
|
||||
dragging = NO;
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
NSPoint mouseDownPoint = [mouseDownEvent locationInWindow];
|
||||
NSPoint mouseDragPoint = [theEvent locationInWindow];
|
||||
float dragDistance = hypot(mouseDownPoint.x - mouseDragPoint.x, mouseDownPoint.y - mouseDragPoint.y);
|
||||
if (dragDistance < 3)
|
||||
return;
|
||||
|
||||
dragging = YES;
|
||||
|
||||
// Find the IJInventoryItem:
|
||||
NSPoint pointInView = [self convertPoint:mouseDownPoint fromView:nil];
|
||||
int itemIndex = [self itemIndexForPoint:pointInView];
|
||||
if (itemIndex >= items.count)
|
||||
return;
|
||||
|
||||
IJInventoryItem *item = [items objectAtIndex:itemIndex];
|
||||
if (item.itemId == 0)
|
||||
return; // can't drag nothing
|
||||
|
||||
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
|
||||
|
||||
[pasteboard declareTypes:[NSArray arrayWithObjects:IJPasteboardTypeInventoryItem, nil] owner:nil];
|
||||
|
||||
[pasteboard setData:[NSKeyedArchiver archivedDataWithRootObject:item]
|
||||
forType:IJPasteboardTypeInventoryItem];
|
||||
|
||||
NSImage *image = item.image;
|
||||
|
||||
// Now clear out item, if the option key isn't down (option for copy):
|
||||
if (([theEvent modifierFlags] & NSAlternateKeyMask) == 0)
|
||||
[delegate inventoryView:self removeItemAtIndex:itemIndex];
|
||||
|
||||
NSPoint dragPoint = NSMakePoint(pointInView.x - image.size.width*0.5, pointInView.y - image.size.height*0.5);
|
||||
|
||||
[self dragImage:image
|
||||
at:dragPoint
|
||||
offset:NSZeroSize
|
||||
event:mouseDownEvent
|
||||
pasteboard:pasteboard
|
||||
source:self
|
||||
slideBack:NO];
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
if (!dragging)
|
||||
{
|
||||
NSPoint mouseDownPoint = [mouseDownEvent locationInWindow];
|
||||
NSPoint pointInView = [self convertPoint:mouseDownPoint fromView:nil];
|
||||
|
||||
int itemIndex = [self itemIndexForPoint:pointInView];
|
||||
[delegate inventoryView:self selectedItemAtIndex:itemIndex];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
|
||||
{
|
||||
if (isLocal)
|
||||
return NSDragOperationEvery;
|
||||
else
|
||||
return NSDragOperationDelete;
|
||||
}
|
||||
//- (void)draggedImage:(NSImage *)image beganAt:(NSPoint)screenPoint
|
||||
//{
|
||||
// NSLog(@"%s", __PRETTY_FUNCTION__);
|
||||
//}
|
||||
- (void)draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
NSLog(@"%s operation=%d", __PRETTY_FUNCTION__, operation);
|
||||
|
||||
if (operation == NSDragOperationNone)
|
||||
{
|
||||
// If the mouse has stopped outside of our bounds, we consider the item to have been removed; show an animation:
|
||||
if (!NSMouseInRect([[self window] convertScreenToBase:screenPoint], [self bounds], NO))
|
||||
{
|
||||
NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, [NSEvent mouseLocation], NSZeroSize, nil, nil, nil);
|
||||
}
|
||||
}
|
||||
}
|
||||
//- (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint
|
||||
//{
|
||||
// NSLog(@"%s", __PRETTY_FUNCTION__);
|
||||
//}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Drag & Drop: Destination
|
||||
|
||||
- (void)moveHighlightToLayerAtIndex:(int)index
|
||||
{
|
||||
[self.layer.sublayers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||
CALayer *layer = obj;
|
||||
if (idx == index)
|
||||
layer.borderColor = [self highlightedBorderColor];
|
||||
else
|
||||
layer.borderColor = [self borderColor];
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
// TODO: Detect and ignore same slot.
|
||||
int index = [self itemIndexForPoint:[self convertPoint:[sender draggingLocation] fromView:nil]];
|
||||
|
||||
if (index >= items.count) // this could happen if this is an invalid world
|
||||
return NSDragOperationNone;
|
||||
|
||||
[self moveHighlightToLayerAtIndex:index];
|
||||
|
||||
if ([[sender draggingSource] isKindOfClass:[self class]])
|
||||
return NSDragOperationMove; // moving between inventories
|
||||
else
|
||||
return NSDragOperationCopy; // copying from the item selector, presumably
|
||||
}
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
// TODO: Detect and ignore same slot.
|
||||
int index = [self itemIndexForPoint:[self convertPoint:[sender draggingLocation] fromView:nil]];
|
||||
|
||||
if (index >= items.count) // this could happen if this is an invalid world
|
||||
return NSDragOperationNone;
|
||||
|
||||
[self moveHighlightToLayerAtIndex:index];
|
||||
|
||||
if ([[sender draggingSource] isKindOfClass:[self class]])
|
||||
return NSDragOperationMove; // moving between inventories
|
||||
else
|
||||
return NSDragOperationCopy; // copying from the item selector, presumably
|
||||
}
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
[self moveHighlightToLayerAtIndex:-1];
|
||||
}
|
||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
//NSLog(@"%s operation=%d", __PRETTY_FUNCTION__, sender.draggingSourceOperationMask);
|
||||
|
||||
int index = [self itemIndexForPoint:[self convertPoint:[sender draggingLocation] fromView:nil]];
|
||||
|
||||
NSData *itemData = [[sender draggingPasteboard] dataForType:IJPasteboardTypeInventoryItem];
|
||||
IJInventoryItem *item = [NSKeyedUnarchiver unarchiveObjectWithData:itemData];
|
||||
|
||||
IJInventoryItem *existingItem = [items objectAtIndex:index];
|
||||
|
||||
if (existingItem.itemId == item.itemId)
|
||||
{
|
||||
item.count = MIN(64, item.count + existingItem.count);
|
||||
}
|
||||
[delegate inventoryView:self setItem:item atIndex:index];
|
||||
return YES;
|
||||
}
|
||||
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
[self moveHighlightToLayerAtIndex:-1];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@ -1,80 +0,0 @@
|
||||
//
|
||||
// IJInventoryWindowController.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/7/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "IJInventoryView.h"
|
||||
|
||||
@class IJInventoryView;
|
||||
@class IJMinecraftLevel;
|
||||
@class MAAttachedWindow;
|
||||
@class IJItemPropertiesViewController;
|
||||
|
||||
@interface IJInventoryWindowController : NSWindowController <NSWindowDelegate, IJInventoryViewDelegate> {
|
||||
IJMinecraftLevel *level;
|
||||
IJMinecraftLevel *player; /***< SMP Player.dat file use same format as level.dat */
|
||||
NSArray *inventory;
|
||||
|
||||
NSPopUpButton *worldSelectionControl;
|
||||
NSTextField *statusTextField;
|
||||
|
||||
IJInventoryView *inventoryView;
|
||||
IJInventoryView *quickView;
|
||||
IJInventoryView *armorView;
|
||||
|
||||
NSMutableArray *armorInventory;
|
||||
NSMutableArray *quickInventory;
|
||||
NSMutableArray *normalInventory;
|
||||
|
||||
// Search/Item List
|
||||
NSSearchField *itemSearchField;
|
||||
NSTableView *itemTableView;
|
||||
NSArray *allItemIds;
|
||||
NSArray *filteredItemIds;
|
||||
|
||||
//
|
||||
IJItemPropertiesViewController *propertiesViewController;
|
||||
MAAttachedWindow *propertiesWindow;
|
||||
id observerObject;
|
||||
|
||||
// Document
|
||||
int64_t sessionLockValue;
|
||||
int loadedWorldIndex;
|
||||
NSString *loadedWorldFolder;
|
||||
NSString *attemptedLoadWorldFolder;
|
||||
NSString *loadedPlayer;
|
||||
NSPopUpButton *playerSelectionControl;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) IBOutlet NSPopUpButton *worldSelectionControl;
|
||||
@property (nonatomic, assign) IBOutlet NSTextField *statusTextField;
|
||||
@property (nonatomic, assign) IBOutlet IJInventoryView *inventoryView;
|
||||
@property (nonatomic, assign) IBOutlet IJInventoryView *quickView;
|
||||
@property (nonatomic, assign) IBOutlet IJInventoryView *armorView;
|
||||
@property (nonatomic, assign) IBOutlet NSSearchField *itemSearchField;
|
||||
@property (nonatomic, assign) IBOutlet NSTableView *itemTableView;
|
||||
@property (nonatomic, retain) NSNumber *worldTime;
|
||||
@property (nonatomic, assign) IBOutlet NSPopUpButton *playerSelectionControl;
|
||||
|
||||
- (IBAction)menuSelectWorldFromPath:(id)sender;
|
||||
- (IBAction)menuSelectWorld:(id)sender;
|
||||
- (IBAction)worldSelectionChanged:(id)sender;
|
||||
- (IBAction)updateItemSearchFilter:(id)sender;
|
||||
- (IBAction)makeSearchFieldFirstResponder:(id)sender;
|
||||
- (IBAction)itemTableViewDoubleClicked:(id)sender;
|
||||
|
||||
- (IBAction)setNextDay:(id)sender;
|
||||
- (IBAction)setNextNight:(id)sender;
|
||||
- (IBAction)setNextNoon:(id)sender;
|
||||
- (IBAction)setNextMidnight:(id)sender;
|
||||
|
||||
- (IBAction)emptyInventory:(id)sender;
|
||||
- (IBAction)saveInventoryItems:(id)sender;
|
||||
- (IBAction)loadInventoryItems:(id)sender;
|
||||
- (IBAction)playerSelectionChanged:(id)sender;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
//
|
||||
// IJItemPropertiesViewController.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/9/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class IJInventoryItem;
|
||||
|
||||
@interface IJItemPropertiesViewController : NSViewController {
|
||||
IJInventoryItem *item;
|
||||
IBOutlet NSButton *checkIndestructible;
|
||||
}
|
||||
@property (nonatomic, retain) IJInventoryItem *item;
|
||||
|
||||
- (void)setState:(bool)enabel;
|
||||
- (IBAction)closeButton:(id)sender;
|
||||
- (IBAction)makeIndestructible:(id)sender;
|
||||
@end
|
||||
@ -1,36 +0,0 @@
|
||||
//
|
||||
// IJItemPropertiesViewController.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/9/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJItemPropertiesViewController.h"
|
||||
#import "IJInventoryItem.h"
|
||||
|
||||
@implementation IJItemPropertiesViewController
|
||||
|
||||
@synthesize item;
|
||||
|
||||
- (IBAction)closeButton:(id)sender
|
||||
{
|
||||
[self.view.window.parentWindow makeKeyWindow];
|
||||
[self commitEditing];
|
||||
self.item = nil; // Hack to prevent this item as coming up as 'lastItem' if they click again.
|
||||
}
|
||||
|
||||
- (IBAction)makeIndestructible:(id)sender
|
||||
{
|
||||
if ([checkIndestructible state] == NSOnState) {
|
||||
self.item.damage = -1000;
|
||||
|
||||
}else {
|
||||
self.item.damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setState:(bool)enabel{
|
||||
[checkIndestructible setState:enabel];
|
||||
}
|
||||
@end
|
||||
@ -1,30 +0,0 @@
|
||||
//
|
||||
// IJMinecraftLevel.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/7/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
// Changes for opening folder Copyright 2011 Manoel Trapier
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "NBTContainer.h"
|
||||
|
||||
@interface IJMinecraftLevel : NBTContainer {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSArray *inventory; // Array of IJInventoryItem objects.
|
||||
@property (nonatomic, readonly) NBTContainer *worldTimeContainer;
|
||||
|
||||
+ (NSString *)pathForWorldAtIndex:(int)worldIndex;
|
||||
+ (BOOL)worldExistsAtFolder:(NSString *)worldPath;
|
||||
+ (NSString *)pathForLevelDatAtFolder:(NSString *)worldPath;
|
||||
+ (NSString *)pathForSessionLockAtFolder:(NSString *)worldPath;
|
||||
+ (NSString *)pathForPlayer:(NSString *)loadedPlayer withWorld:(NSString *)worldPath;
|
||||
|
||||
+ (int64_t)writeToSessionLockAtFolder:(NSString *)worldPath;
|
||||
+ (BOOL)checkSessionLockAtFolder:(NSString *)worldPath value:(int64_t)checkValue;
|
||||
|
||||
|
||||
@end
|
||||
@ -1,184 +0,0 @@
|
||||
//
|
||||
// IJMinecraftLevel.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/7/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
// Changes for opening folder Copyright 2011 Manoel Trapier
|
||||
//
|
||||
|
||||
#import "IJMinecraftLevel.h"
|
||||
#import "IJInventoryItem.h"
|
||||
|
||||
@implementation IJMinecraftLevel
|
||||
|
||||
- (NBTContainer *)containerWithName:(NSString *)theName inArray:(NSArray *)array
|
||||
{
|
||||
for (NBTContainer *container in array)
|
||||
{
|
||||
if ([container.name isEqual:theName])
|
||||
return container;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NBTContainer *)inventoryList
|
||||
{
|
||||
// Inventory is found in:
|
||||
// - compound "Data"
|
||||
// - compound "Player"
|
||||
// - list "Inventory"
|
||||
// *
|
||||
// SMP Player have not the same structure, there is no "DATA" compound, nor "player"
|
||||
NBTContainer *playerCompound;
|
||||
NBTContainer *dataCompound = [self childNamed:@"Data"];
|
||||
if (dataCompound != nil)
|
||||
{
|
||||
playerCompound = [dataCompound childNamed:@"Player"];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Player file is from a SMP file, not level.dat one");
|
||||
playerCompound = self;
|
||||
}
|
||||
|
||||
NBTContainer *inventoryList = [playerCompound childNamed:@"Inventory"];
|
||||
// TODO: Check for error conditions here.
|
||||
return inventoryList;
|
||||
}
|
||||
|
||||
- (NSArray *)inventory
|
||||
{
|
||||
NSMutableArray *output = [NSMutableArray array];
|
||||
for (NSArray *listItems in [self inventoryList].children)
|
||||
{
|
||||
IJInventoryItem *invItem = [[IJInventoryItem alloc] init];
|
||||
|
||||
invItem.itemId = [[self containerWithName:@"id" inArray:listItems].numberValue shortValue];
|
||||
invItem.count = [[self containerWithName:@"Count" inArray:listItems].numberValue unsignedCharValue];
|
||||
invItem.damage = [[self containerWithName:@"Damage" inArray:listItems].numberValue shortValue];
|
||||
invItem.slot = [[self containerWithName:@"Slot" inArray:listItems].numberValue unsignedCharValue];
|
||||
[output addObject:invItem];
|
||||
[invItem release];
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
- (void)setInventory:(NSArray *)newInventory
|
||||
{
|
||||
NSMutableArray *newChildren = [NSMutableArray array];
|
||||
NBTContainer *inventoryList = [self inventoryList];
|
||||
|
||||
if (inventoryList.listType != NBTTypeCompound)
|
||||
{
|
||||
// There appears to be a bug in the way Minecraft writes empty inventory lists; it appears to
|
||||
// set the list type to 'byte', so we will correct it here.
|
||||
NSLog(@"%s Fixing inventory list type; was %d.", __PRETTY_FUNCTION__, inventoryList.listType);
|
||||
inventoryList.listType = NBTTypeCompound;
|
||||
}
|
||||
|
||||
for (IJInventoryItem *invItem in newInventory)
|
||||
{
|
||||
NSArray *listItems = [NSArray arrayWithObjects:
|
||||
[NBTContainer containerWithName:@"id" type:NBTTypeShort numberValue:[NSNumber numberWithShort:invItem.itemId]],
|
||||
[NBTContainer containerWithName:@"Damage" type:NBTTypeShort numberValue:[NSNumber numberWithShort:invItem.damage]],
|
||||
[NBTContainer containerWithName:@"Count" type:NBTTypeByte numberValue:[NSNumber numberWithShort:invItem.count]],
|
||||
[NBTContainer containerWithName:@"Slot" type:NBTTypeByte numberValue:[NSNumber numberWithShort:invItem.slot]],
|
||||
nil];
|
||||
[newChildren addObject:listItems];
|
||||
}
|
||||
inventoryList.children = newChildren;
|
||||
}
|
||||
|
||||
- (NBTContainer *)worldTimeContainer
|
||||
{
|
||||
return [[self childNamed:@"Data"] childNamed:@"Time"];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Helpers
|
||||
|
||||
+ (NSString *)pathForWorldAtIndex:(int)worldIndex
|
||||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
NSString *path = [paths objectAtIndex:0];
|
||||
path = [path stringByAppendingPathComponent:@"minecraft"];
|
||||
path = [path stringByAppendingPathComponent:@"saves"];
|
||||
path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"World%d", worldIndex]];
|
||||
return path;
|
||||
}
|
||||
|
||||
+ (NSData *)dataWithInt64:(int64_t)v
|
||||
{
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
uint32_t v0 = htonl(v >> 32);
|
||||
uint32_t v1 = htonl(v);
|
||||
[data appendBytes:&v0 length:4];
|
||||
[data appendBytes:&v1 length:4];
|
||||
return data;
|
||||
}
|
||||
+ (int64_t)int64FromData:(NSData *)data
|
||||
{
|
||||
uint8_t *bytes = (uint8_t *)[data bytes];
|
||||
uint64_t n = ntohl(*((uint32_t *)(bytes + 0)));
|
||||
n <<= 32;
|
||||
n += ntohl(*((uint32_t *)(bytes + 4)));
|
||||
return n;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
+ (NSString *)pathForLevelDatAtFolder:(NSString *)worldPath
|
||||
{
|
||||
return [worldPath stringByAppendingPathComponent:@"level.dat"];
|
||||
}
|
||||
|
||||
+ (NSString *)pathForSessionLockAtFolder:(NSString *)worldPath
|
||||
{
|
||||
return [worldPath stringByAppendingPathComponent:@"session.lock"];
|
||||
}
|
||||
|
||||
+ (NSString *)pathForPlayer:(NSString *)loadedPlayer withWorld:(NSString *)worldPath;
|
||||
{
|
||||
/* loadedPlayer == nil, we use level.dat, or else we use the name */
|
||||
if (loadedPlayer == nil)
|
||||
return [self pathForLevelDatAtFolder:worldPath];
|
||||
|
||||
return [[[worldPath stringByAppendingPathComponent:@"players"] stringByAppendingPathComponent:loadedPlayer] stringByAppendingPathExtension:@"dat"];
|
||||
}
|
||||
|
||||
+ (BOOL)worldExistsAtFolder:(NSString *)worldPath
|
||||
{
|
||||
return [[NSFileManager defaultManager] fileExistsAtPath:[[self class] pathForLevelDatAtFolder:worldPath]];
|
||||
}
|
||||
|
||||
+ (int64_t)writeToSessionLockAtFolder:(NSString *)worldPath
|
||||
{
|
||||
NSString *path = [IJMinecraftLevel pathForSessionLockAtFolder:worldPath];
|
||||
NSDate *now = [NSDate date];
|
||||
NSTimeInterval interval = [now timeIntervalSince1970];
|
||||
int64_t milliseconds = (int64_t)(interval * 1000.0);
|
||||
// write as number of milliseconds
|
||||
|
||||
NSData *data = [IJMinecraftLevel dataWithInt64:milliseconds];
|
||||
[data writeToFile:path atomically:YES];
|
||||
|
||||
return milliseconds;
|
||||
}
|
||||
|
||||
+ (BOOL)checkSessionLockAtFolder:(NSString *)worldPath value:(int64_t)checkValue
|
||||
{
|
||||
NSString *path = [IJMinecraftLevel pathForSessionLockAtFolder:worldPath];
|
||||
NSData *data = [NSData dataWithContentsOfFile:path];
|
||||
|
||||
if (!data)
|
||||
{
|
||||
NSLog(@"Failed to read session lock at %@", path);
|
||||
return NO;
|
||||
}
|
||||
|
||||
int64_t milliseconds = [IJMinecraftLevel int64FromData:data];
|
||||
return checkValue == milliseconds;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@ -1,16 +0,0 @@
|
||||
//
|
||||
// IJTableView.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 12/14/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface IJTableView : NSTableView {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,25 +0,0 @@
|
||||
//
|
||||
// IJTableView.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 12/14/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IJTableView.h"
|
||||
|
||||
|
||||
@implementation IJTableView
|
||||
|
||||
- (void)keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
unichar ch = [[theEvent characters] characterAtIndex:0];
|
||||
if (ch == '\r') // return key
|
||||
{
|
||||
[self sendAction:[self doubleAction] to:[self target]];
|
||||
return;
|
||||
}
|
||||
[super keyDown:theEvent];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,19 +0,0 @@
|
||||
//
|
||||
// InsideJobAppDelegate.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class IJInventoryWindowController;
|
||||
|
||||
@interface InsideJobAppDelegate : NSObject <NSApplicationDelegate> {
|
||||
IJInventoryWindowController *inventoryWindowController;
|
||||
}
|
||||
|
||||
@property (assign) IBOutlet IJInventoryWindowController *inventoryWindowController;
|
||||
|
||||
@end
|
||||
@ -1,28 +0,0 @@
|
||||
//
|
||||
// InsideJobAppDelegate.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import "InsideJobAppDelegate.h"
|
||||
#import "IJInventoryWindowController.h"
|
||||
|
||||
@implementation InsideJobAppDelegate
|
||||
|
||||
@synthesize inventoryWindowController;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
[inventoryWindowController worldSelectionChanged:nil];
|
||||
}
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
BOOL shouldClose = [inventoryWindowController windowShouldClose:nil];
|
||||
if (shouldClose)
|
||||
return NSTerminateNow;
|
||||
else
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,184 +0,0 @@
|
||||
//
|
||||
// MAAttachedWindow.h
|
||||
//
|
||||
// Created by Matt Gemmell on 27/09/2007.
|
||||
// Copyright 2007 Magic Aubergine.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
/*
|
||||
Below are the positions the attached window can be displayed at.
|
||||
|
||||
Note that these positions are relative to the point passed to the constructor,
|
||||
e.g. MAPositionBottomRight will put the window below the point and towards the right,
|
||||
MAPositionTop will horizontally center the window above the point,
|
||||
MAPositionRightTop will put the window to the right and above the point,
|
||||
and so on.
|
||||
|
||||
You can also pass MAPositionAutomatic (or use an initializer which omits the 'onSide:'
|
||||
argument) and the attached window will try to position itself sensibly, based on
|
||||
available screen-space.
|
||||
|
||||
Notes regarding automatically-positioned attached windows:
|
||||
|
||||
(a) The window prefers to position itself horizontally centered below the specified point.
|
||||
This gives a certain enhanced visual sense of an attachment/relationship.
|
||||
|
||||
(b) The window will try to align itself with its parent window (if any); i.e. it will
|
||||
attempt to stay within its parent window's frame if it can.
|
||||
|
||||
(c) The algorithm isn't perfect. :) If in doubt, do your own calculations and then
|
||||
explicitly request that the window attach itself to a particular side.
|
||||
*/
|
||||
|
||||
typedef enum _MAWindowPosition {
|
||||
// The four primary sides are compatible with the preferredEdge of NSDrawer.
|
||||
MAPositionLeft = NSMinXEdge, // 0
|
||||
MAPositionRight = NSMaxXEdge, // 2
|
||||
MAPositionTop = NSMaxYEdge, // 3
|
||||
MAPositionBottom = NSMinYEdge, // 1
|
||||
MAPositionLeftTop = 4,
|
||||
MAPositionLeftBottom = 5,
|
||||
MAPositionRightTop = 6,
|
||||
MAPositionRightBottom = 7,
|
||||
MAPositionTopLeft = 8,
|
||||
MAPositionTopRight = 9,
|
||||
MAPositionBottomLeft = 10,
|
||||
MAPositionBottomRight = 11,
|
||||
MAPositionAutomatic = 12
|
||||
} MAWindowPosition;
|
||||
|
||||
@interface MAAttachedWindow : NSWindow {
|
||||
NSColor *borderColor;
|
||||
float borderWidth;
|
||||
float viewMargin;
|
||||
float arrowBaseWidth;
|
||||
float arrowHeight;
|
||||
BOOL hasArrow;
|
||||
float cornerRadius;
|
||||
BOOL drawsRoundCornerBesideArrow;
|
||||
|
||||
@private
|
||||
NSColor *_MABackgroundColor;
|
||||
__weak NSView *_view;
|
||||
__weak NSWindow *_window;
|
||||
NSPoint _point;
|
||||
MAWindowPosition _side;
|
||||
float _distance;
|
||||
NSRect _viewFrame;
|
||||
BOOL _resizing;
|
||||
}
|
||||
|
||||
/*
|
||||
Initialization methods
|
||||
|
||||
Parameters:
|
||||
|
||||
view The view to display in the attached window. Must not be nil.
|
||||
|
||||
point The point to which the attached window should be attached. If you
|
||||
are also specifying a parent window, the point should be in the
|
||||
coordinate system of that parent window. If you are not specifying
|
||||
a window, the point should be in the screen's coordinate space.
|
||||
This value is required.
|
||||
|
||||
window The parent window to attach this one to. Note that no actual
|
||||
relationship is created (particularly, this window is not made
|
||||
a childWindow of the parent window).
|
||||
Default: nil.
|
||||
|
||||
side The side of the specified point on which to attach this window.
|
||||
Default: MAPositionAutomatic.
|
||||
|
||||
distance How far from the specified point this window should be.
|
||||
Default: 0.
|
||||
*/
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view // designated initializer
|
||||
attachedToPoint:(NSPoint)point
|
||||
inWindow:(NSWindow *)window
|
||||
onSide:(MAWindowPosition)side
|
||||
atDistance:(float)distance;
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
inWindow:(NSWindow *)window
|
||||
atDistance:(float)distance;
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
onSide:(MAWindowPosition)side
|
||||
atDistance:(float)distance;
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
atDistance:(float)distance;
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
inWindow:(NSWindow *)window;
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
onSide:(MAWindowPosition)side;
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point;
|
||||
|
||||
// Accessor methods
|
||||
- (void)setPoint:(NSPoint)point side:(MAWindowPosition)side;
|
||||
- (NSColor *)borderColor;
|
||||
- (void)setBorderColor:(NSColor *)value;
|
||||
- (float)borderWidth;
|
||||
- (void)setBorderWidth:(float)value; // See note 1 below.
|
||||
- (float)viewMargin;
|
||||
- (void)setViewMargin:(float)value; // See note 2 below.
|
||||
- (float)arrowBaseWidth;
|
||||
- (void)setArrowBaseWidth:(float)value; // See note 2 below.
|
||||
- (float)arrowHeight;
|
||||
- (void)setArrowHeight:(float)value; // See note 2 below.
|
||||
- (float)hasArrow;
|
||||
- (void)setHasArrow:(float)value;
|
||||
- (float)cornerRadius;
|
||||
- (void)setCornerRadius:(float)value; // See note 2 below.
|
||||
- (float)drawsRoundCornerBesideArrow; // See note 3 below.
|
||||
- (void)setDrawsRoundCornerBesideArrow:(float)value; // See note 2 below.
|
||||
- (void)setBackgroundImage:(NSImage *)value;
|
||||
- (NSColor *)windowBackgroundColor; // See note 4 below.
|
||||
- (void)setBackgroundColor:(NSColor *)value;
|
||||
|
||||
/*
|
||||
Notes regarding accessor methods:
|
||||
|
||||
1. The border is drawn inside the viewMargin area, expanding inwards; it does not
|
||||
increase the width/height of the window. You can use the -setBorderWidth: and
|
||||
-setViewMargin: methods together to achieve the exact look/geometry you want.
|
||||
(viewMargin is the distance between the edge of the view and the window edge.)
|
||||
|
||||
2. The specified setter methods are primarily intended to be used _before_ the window
|
||||
is first shown. If you use them while the window is already visible, be aware
|
||||
that they may cause the window to move and/or resize, in order to stay anchored
|
||||
to the point specified in the initializer. They may also cause the view to move
|
||||
within the window, in order to remain centered there.
|
||||
|
||||
Note that the -setHasArrow: method can safely be used at any time, and will not
|
||||
cause moving/resizing of the window. This is for convenience, in case you want
|
||||
to add or remove the arrow in response to user interaction. For example, you
|
||||
could make the attached window movable by its background, and if the user dragged
|
||||
it away from its initial point, the arrow could be removed. This would duplicate
|
||||
how Aperture's attached windows behave.
|
||||
|
||||
3. drawsRoundCornerBesideArrow takes effect when the arrow is being drawn at a corner,
|
||||
i.e. when it's not at one of the four primary compass directions. In this situation,
|
||||
if drawsRoundCornerBesideArrow is YES (the default), then that corner of the window
|
||||
will be rounded just like the other three corners, thus the arrow will be inset
|
||||
slightly from the edge of the window to allow room for the rounded corner. If this
|
||||
value is NO, the corner beside the arrow will be a square corner, and the other
|
||||
three corners will be rounded.
|
||||
|
||||
This is useful when you want to attach a window very near the edge of another window,
|
||||
and don't want the attached window's edge to be visually outside the frame of the
|
||||
parent window.
|
||||
|
||||
4. Note that to retrieve the background color of the window, you should use the
|
||||
-windowBackgroundColor method, instead of -backgroundColor. This is because we draw
|
||||
the entire background of the window (rounded path, arrow, etc) in an NSColor pattern
|
||||
image, and set it as the backgroundColor of the window.
|
||||
*/
|
||||
|
||||
@end
|
||||
@ -1,951 +0,0 @@
|
||||
//
|
||||
// MAAttachedWindow.m
|
||||
//
|
||||
// Created by Matt Gemmell on 27/09/2007.
|
||||
// Copyright 2007 Magic Aubergine.
|
||||
//
|
||||
|
||||
#import "MAAttachedWindow.h"
|
||||
|
||||
#define MAATTACHEDWINDOW_DEFAULT_BACKGROUND_COLOR [NSColor colorWithCalibratedWhite:0.1 alpha:0.75]
|
||||
#define MAATTACHEDWINDOW_DEFAULT_BORDER_COLOR [NSColor whiteColor]
|
||||
#define MAATTACHEDWINDOW_SCALE_FACTOR [[NSScreen mainScreen] userSpaceScaleFactor]
|
||||
|
||||
@interface MAAttachedWindow (MAPrivateMethods)
|
||||
|
||||
// Geometry
|
||||
- (void)_updateGeometry;
|
||||
- (MAWindowPosition)_bestSideForAutomaticPosition;
|
||||
- (float)_arrowInset;
|
||||
|
||||
// Drawing
|
||||
- (void)_updateBackground;
|
||||
- (NSColor *)_backgroundColorPatternImage;
|
||||
- (NSBezierPath *)_backgroundPath;
|
||||
- (void)_appendArrowToPath:(NSBezierPath *)path;
|
||||
- (void)_redisplay;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAAttachedWindow
|
||||
|
||||
|
||||
#pragma mark Initializers
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
inWindow:(NSWindow *)window
|
||||
onSide:(MAWindowPosition)side
|
||||
atDistance:(float)distance
|
||||
{
|
||||
// Insist on having a valid view.
|
||||
if (!view) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Create dummy initial contentRect for window.
|
||||
NSRect contentRect = NSZeroRect;
|
||||
contentRect.size = [view frame].size;
|
||||
|
||||
if ((self = [super initWithContentRect:contentRect
|
||||
styleMask:NSBorderlessWindowMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO])) {
|
||||
_view = view;
|
||||
_window = window;
|
||||
_point = point;
|
||||
_side = side;
|
||||
_distance = distance;
|
||||
|
||||
// Configure window characteristics.
|
||||
[super setBackgroundColor:[NSColor clearColor]];
|
||||
[self setMovableByWindowBackground:NO];
|
||||
[self setExcludedFromWindowsMenu:YES];
|
||||
[self setAlphaValue:1.0];
|
||||
[self setOpaque:NO];
|
||||
[self setHasShadow:YES];
|
||||
[self useOptimizedDrawing:YES];
|
||||
|
||||
// Set up some sensible defaults for display.
|
||||
_MABackgroundColor = [MAATTACHEDWINDOW_DEFAULT_BACKGROUND_COLOR copy];
|
||||
borderColor = [MAATTACHEDWINDOW_DEFAULT_BORDER_COLOR copy];
|
||||
borderWidth = 2.0;
|
||||
viewMargin = 2.0;
|
||||
arrowBaseWidth = 20.0;
|
||||
arrowHeight = 16.0;
|
||||
hasArrow = YES;
|
||||
cornerRadius = 8.0;
|
||||
drawsRoundCornerBesideArrow = YES;
|
||||
_resizing = NO;
|
||||
|
||||
// Work out what side to put the window on if it's "automatic".
|
||||
if (_side == MAPositionAutomatic) {
|
||||
_side = [self _bestSideForAutomaticPosition];
|
||||
}
|
||||
|
||||
// Configure our initial geometry.
|
||||
[self _updateGeometry];
|
||||
|
||||
// Update the background.
|
||||
[self _updateBackground];
|
||||
|
||||
// Add view as subview of our contentView.
|
||||
[[self contentView] addSubview:_view];
|
||||
|
||||
// Subscribe to notifications for when we change size.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowDidResize:)
|
||||
name:NSWindowDidResizeNotification
|
||||
object:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
inWindow:(NSWindow *)window
|
||||
atDistance:(float)distance
|
||||
{
|
||||
return [self initWithView:view attachedToPoint:point
|
||||
inWindow:window onSide:MAPositionAutomatic
|
||||
atDistance:distance];
|
||||
}
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
onSide:(MAWindowPosition)side
|
||||
atDistance:(float)distance
|
||||
{
|
||||
return [self initWithView:view attachedToPoint:point
|
||||
inWindow:nil onSide:side
|
||||
atDistance:distance];
|
||||
}
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
atDistance:(float)distance
|
||||
{
|
||||
return [self initWithView:view attachedToPoint:point
|
||||
inWindow:nil onSide:MAPositionAutomatic
|
||||
atDistance:distance];
|
||||
}
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
inWindow:(NSWindow *)window
|
||||
{
|
||||
return [self initWithView:view attachedToPoint:point
|
||||
inWindow:window onSide:MAPositionAutomatic
|
||||
atDistance:0];
|
||||
}
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
onSide:(MAWindowPosition)side
|
||||
{
|
||||
return [self initWithView:view attachedToPoint:point
|
||||
inWindow:nil onSide:side
|
||||
atDistance:0];
|
||||
}
|
||||
|
||||
|
||||
- (MAAttachedWindow *)initWithView:(NSView *)view
|
||||
attachedToPoint:(NSPoint)point
|
||||
{
|
||||
return [self initWithView:view attachedToPoint:point
|
||||
inWindow:nil onSide:MAPositionAutomatic
|
||||
atDistance:0];
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[borderColor release];
|
||||
[_MABackgroundColor release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Geometry
|
||||
|
||||
|
||||
- (void)_updateGeometry
|
||||
{
|
||||
NSRect contentRect = NSZeroRect;
|
||||
contentRect.size = [_view frame].size;
|
||||
|
||||
// Account for viewMargin.
|
||||
_viewFrame = NSMakeRect(viewMargin * MAATTACHEDWINDOW_SCALE_FACTOR,
|
||||
viewMargin * MAATTACHEDWINDOW_SCALE_FACTOR,
|
||||
[_view frame].size.width, [_view frame].size.height);
|
||||
contentRect = NSInsetRect(contentRect,
|
||||
-viewMargin * MAATTACHEDWINDOW_SCALE_FACTOR,
|
||||
-viewMargin * MAATTACHEDWINDOW_SCALE_FACTOR);
|
||||
|
||||
// Account for arrowHeight in new window frame.
|
||||
// Note: we always leave room for the arrow, even if it currently set to
|
||||
// not be shown. This is so it can easily be toggled whilst the window
|
||||
// is visible, without altering the window's frame origin point.
|
||||
float scaledArrowHeight = arrowHeight * MAATTACHEDWINDOW_SCALE_FACTOR;
|
||||
switch (_side) {
|
||||
case MAPositionLeft:
|
||||
case MAPositionLeftTop:
|
||||
case MAPositionLeftBottom:
|
||||
contentRect.size.width += scaledArrowHeight;
|
||||
break;
|
||||
case MAPositionRight:
|
||||
case MAPositionRightTop:
|
||||
case MAPositionRightBottom:
|
||||
_viewFrame.origin.x += scaledArrowHeight;
|
||||
contentRect.size.width += scaledArrowHeight;
|
||||
break;
|
||||
case MAPositionTop:
|
||||
case MAPositionTopLeft:
|
||||
case MAPositionTopRight:
|
||||
_viewFrame.origin.y += scaledArrowHeight;
|
||||
contentRect.size.height += scaledArrowHeight;
|
||||
break;
|
||||
case MAPositionBottom:
|
||||
case MAPositionBottomLeft:
|
||||
case MAPositionBottomRight:
|
||||
contentRect.size.height += scaledArrowHeight;
|
||||
break;
|
||||
default:
|
||||
break; // won't happen, but this satisfies gcc with -Wall
|
||||
}
|
||||
|
||||
// Position frame origin appropriately for _side, accounting for arrow-inset.
|
||||
contentRect.origin = (_window) ? [_window convertBaseToScreen:_point] : _point;
|
||||
float arrowInset = [self _arrowInset];
|
||||
float halfWidth = contentRect.size.width / 2.0;
|
||||
float halfHeight = contentRect.size.height / 2.0;
|
||||
switch (_side) {
|
||||
case MAPositionTopLeft:
|
||||
contentRect.origin.x -= contentRect.size.width - arrowInset;
|
||||
break;
|
||||
case MAPositionTop:
|
||||
contentRect.origin.x -= halfWidth;
|
||||
break;
|
||||
case MAPositionTopRight:
|
||||
contentRect.origin.x -= arrowInset;
|
||||
break;
|
||||
case MAPositionBottomLeft:
|
||||
contentRect.origin.y -= contentRect.size.height;
|
||||
contentRect.origin.x -= contentRect.size.width - arrowInset;
|
||||
break;
|
||||
case MAPositionBottom:
|
||||
contentRect.origin.y -= contentRect.size.height;
|
||||
contentRect.origin.x -= halfWidth;
|
||||
break;
|
||||
case MAPositionBottomRight:
|
||||
contentRect.origin.x -= arrowInset;
|
||||
contentRect.origin.y -= contentRect.size.height;
|
||||
break;
|
||||
case MAPositionLeftTop:
|
||||
contentRect.origin.x -= contentRect.size.width;
|
||||
contentRect.origin.y -= arrowInset;
|
||||
break;
|
||||
case MAPositionLeft:
|
||||
contentRect.origin.x -= contentRect.size.width;
|
||||
contentRect.origin.y -= halfHeight;
|
||||
break;
|
||||
case MAPositionLeftBottom:
|
||||
contentRect.origin.x -= contentRect.size.width;
|
||||
contentRect.origin.y -= contentRect.size.height - arrowInset;
|
||||
break;
|
||||
case MAPositionRightTop:
|
||||
contentRect.origin.y -= arrowInset;
|
||||
break;
|
||||
case MAPositionRight:
|
||||
contentRect.origin.y -= halfHeight;
|
||||
break;
|
||||
case MAPositionRightBottom:
|
||||
contentRect.origin.y -= contentRect.size.height - arrowInset;
|
||||
break;
|
||||
default:
|
||||
break; // won't happen, but this satisfies gcc with -Wall
|
||||
}
|
||||
|
||||
// Account for _distance in new window frame.
|
||||
switch (_side) {
|
||||
case MAPositionLeft:
|
||||
case MAPositionLeftTop:
|
||||
case MAPositionLeftBottom:
|
||||
contentRect.origin.x -= _distance;
|
||||
break;
|
||||
case MAPositionRight:
|
||||
case MAPositionRightTop:
|
||||
case MAPositionRightBottom:
|
||||
contentRect.origin.x += _distance;
|
||||
break;
|
||||
case MAPositionTop:
|
||||
case MAPositionTopLeft:
|
||||
case MAPositionTopRight:
|
||||
contentRect.origin.y += _distance;
|
||||
break;
|
||||
case MAPositionBottom:
|
||||
case MAPositionBottomLeft:
|
||||
case MAPositionBottomRight:
|
||||
contentRect.origin.y -= _distance;
|
||||
break;
|
||||
default:
|
||||
break; // won't happen, but this satisfies gcc with -Wall
|
||||
}
|
||||
|
||||
// Reconfigure window and view frames appropriately.
|
||||
[self setFrame:contentRect display:NO];
|
||||
[_view setFrame:_viewFrame];
|
||||
}
|
||||
|
||||
|
||||
- (MAWindowPosition)_bestSideForAutomaticPosition
|
||||
{
|
||||
// Get all relevant geometry in screen coordinates.
|
||||
NSRect screenFrame;
|
||||
if (_window && [_window screen]) {
|
||||
screenFrame = [[_window screen] visibleFrame];
|
||||
} else {
|
||||
screenFrame = [[NSScreen mainScreen] visibleFrame];
|
||||
}
|
||||
NSPoint pointOnScreen = (_window) ? [_window convertBaseToScreen:_point] : _point;
|
||||
NSSize viewSize = [_view frame].size;
|
||||
viewSize.width += (viewMargin * MAATTACHEDWINDOW_SCALE_FACTOR) * 2.0;
|
||||
viewSize.height += (viewMargin * MAATTACHEDWINDOW_SCALE_FACTOR) * 2.0;
|
||||
MAWindowPosition side = MAPositionBottom; // By default, position us centered below.
|
||||
float scaledArrowHeight = (arrowHeight * MAATTACHEDWINDOW_SCALE_FACTOR) + _distance;
|
||||
|
||||
// We'd like to display directly below the specified point, since this gives a
|
||||
// sense of a relationship between the point and this window. Check there's room.
|
||||
if (pointOnScreen.y - viewSize.height - scaledArrowHeight < NSMinY(screenFrame)) {
|
||||
// We'd go off the bottom of the screen. Try the right.
|
||||
if (pointOnScreen.x + viewSize.width + scaledArrowHeight >= NSMaxX(screenFrame)) {
|
||||
// We'd go off the right of the screen. Try the left.
|
||||
if (pointOnScreen.x - viewSize.width - scaledArrowHeight < NSMinX(screenFrame)) {
|
||||
// We'd go off the left of the screen. Try the top.
|
||||
if (pointOnScreen.y + viewSize.height + scaledArrowHeight < NSMaxY(screenFrame)) {
|
||||
side = MAPositionTop;
|
||||
}
|
||||
} else {
|
||||
side = MAPositionLeft;
|
||||
}
|
||||
} else {
|
||||
side = MAPositionRight;
|
||||
}
|
||||
}
|
||||
|
||||
float halfWidth = viewSize.width / 2.0;
|
||||
float halfHeight = viewSize.height / 2.0;
|
||||
|
||||
NSRect parentFrame = (_window) ? [_window frame] : screenFrame;
|
||||
float arrowInset = [self _arrowInset];
|
||||
|
||||
// We're currently at a primary side.
|
||||
// Try to avoid going outwith the parent area in the secondary dimension,
|
||||
// by checking to see if an appropriate corner side would be better.
|
||||
switch (side) {
|
||||
case MAPositionBottom:
|
||||
case MAPositionTop:
|
||||
// Check to see if we go beyond the left edge of the parent area.
|
||||
if (pointOnScreen.x - halfWidth < NSMinX(parentFrame)) {
|
||||
// We go beyond the left edge. Try using right position.
|
||||
if (pointOnScreen.x + viewSize.width - arrowInset < NSMaxX(screenFrame)) {
|
||||
// We'd still be on-screen using right, so use it.
|
||||
if (side == MAPositionBottom) {
|
||||
side = MAPositionBottomRight;
|
||||
} else {
|
||||
side = MAPositionTopRight;
|
||||
}
|
||||
}
|
||||
} else if (pointOnScreen.x + halfWidth >= NSMaxX(parentFrame)) {
|
||||
// We go beyond the right edge. Try using left position.
|
||||
if (pointOnScreen.x - viewSize.width + arrowInset >= NSMinX(screenFrame)) {
|
||||
// We'd still be on-screen using left, so use it.
|
||||
if (side == MAPositionBottom) {
|
||||
side = MAPositionBottomLeft;
|
||||
} else {
|
||||
side = MAPositionTopLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MAPositionRight:
|
||||
case MAPositionLeft:
|
||||
// Check to see if we go beyond the bottom edge of the parent area.
|
||||
if (pointOnScreen.y - halfHeight < NSMinY(parentFrame)) {
|
||||
// We go beyond the bottom edge. Try using top position.
|
||||
if (pointOnScreen.y + viewSize.height - arrowInset < NSMaxY(screenFrame)) {
|
||||
// We'd still be on-screen using top, so use it.
|
||||
if (side == MAPositionRight) {
|
||||
side = MAPositionRightTop;
|
||||
} else {
|
||||
side = MAPositionLeftTop;
|
||||
}
|
||||
}
|
||||
} else if (pointOnScreen.y + halfHeight >= NSMaxY(parentFrame)) {
|
||||
// We go beyond the top edge. Try using bottom position.
|
||||
if (pointOnScreen.y - viewSize.height + arrowInset >= NSMinY(screenFrame)) {
|
||||
// We'd still be on-screen using bottom, so use it.
|
||||
if (side == MAPositionRight) {
|
||||
side = MAPositionRightBottom;
|
||||
} else {
|
||||
side = MAPositionLeftBottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break; // won't happen, but this satisfies gcc with -Wall
|
||||
}
|
||||
|
||||
return side;
|
||||
}
|
||||
|
||||
|
||||
- (float)_arrowInset
|
||||
{
|
||||
float cornerInset = (drawsRoundCornerBesideArrow) ? cornerRadius : 0;
|
||||
return (cornerInset + (arrowBaseWidth / 2.0)) * MAATTACHEDWINDOW_SCALE_FACTOR;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Drawing
|
||||
|
||||
|
||||
- (void)_updateBackground
|
||||
{
|
||||
// Call NSWindow's implementation of -setBackgroundColor: because we override
|
||||
// it in this class to let us set the entire background image of the window
|
||||
// as an NSColor patternImage.
|
||||
NSDisableScreenUpdates();
|
||||
[super setBackgroundColor:[self _backgroundColorPatternImage]];
|
||||
if ([self isVisible]) {
|
||||
[self display];
|
||||
[self invalidateShadow];
|
||||
}
|
||||
NSEnableScreenUpdates();
|
||||
}
|
||||
|
||||
|
||||
- (NSColor *)_backgroundColorPatternImage
|
||||
{
|
||||
NSImage *bg = [[NSImage alloc] initWithSize:[self frame].size];
|
||||
NSRect bgRect = NSZeroRect;
|
||||
bgRect.size = [bg size];
|
||||
|
||||
[bg lockFocus];
|
||||
NSBezierPath *bgPath = [self _backgroundPath];
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[bgPath addClip];
|
||||
|
||||
// Draw background.
|
||||
[_MABackgroundColor set];
|
||||
[bgPath fill];
|
||||
|
||||
// Draw border if appropriate.
|
||||
if (borderWidth > 0) {
|
||||
// Double the borderWidth since we're drawing inside the path.
|
||||
[bgPath setLineWidth:(borderWidth * 2.0) * MAATTACHEDWINDOW_SCALE_FACTOR];
|
||||
[borderColor set];
|
||||
[bgPath stroke];
|
||||
}
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
[bg unlockFocus];
|
||||
|
||||
return [NSColor colorWithPatternImage:[bg autorelease]];
|
||||
}
|
||||
|
||||
|
||||
- (NSBezierPath *)_backgroundPath
|
||||
{
|
||||
/*
|
||||
Construct path for window background, taking account of:
|
||||
1. hasArrow
|
||||
2. _side
|
||||
3. drawsRoundCornerBesideArrow
|
||||
4. arrowBaseWidth
|
||||
5. arrowHeight
|
||||
6. cornerRadius
|
||||
*/
|
||||
|
||||
float scaleFactor = MAATTACHEDWINDOW_SCALE_FACTOR;
|
||||
float scaledRadius = cornerRadius * scaleFactor;
|
||||
float scaledArrowWidth = arrowBaseWidth * scaleFactor;
|
||||
float halfArrowWidth = scaledArrowWidth / 2.0;
|
||||
NSRect contentArea = NSInsetRect(_viewFrame,
|
||||
-viewMargin * scaleFactor,
|
||||
-viewMargin * scaleFactor);
|
||||
float minX = ceilf(NSMinX(contentArea) * scaleFactor + 0.5f);
|
||||
float midX = NSMidX(contentArea) * scaleFactor;
|
||||
float maxX = floorf(NSMaxX(contentArea) * scaleFactor - 0.5f);
|
||||
float minY = ceilf(NSMinY(contentArea) * scaleFactor + 0.5f);
|
||||
float midY = NSMidY(contentArea) * scaleFactor;
|
||||
float maxY = floorf(NSMaxY(contentArea) * scaleFactor - 0.5f);
|
||||
|
||||
NSBezierPath *path = [NSBezierPath bezierPath];
|
||||
[path setLineJoinStyle:NSRoundLineJoinStyle];
|
||||
|
||||
// Begin at top-left. This will be either after the rounded corner, or
|
||||
// at the top-left point if cornerRadius is zero and/or we're drawing
|
||||
// the arrow at the top-left or left-top without a rounded corner.
|
||||
NSPoint currPt = NSMakePoint(minX, maxY);
|
||||
if (scaledRadius > 0 &&
|
||||
(drawsRoundCornerBesideArrow ||
|
||||
(_side != MAPositionBottomRight && _side != MAPositionRightBottom))
|
||||
) {
|
||||
currPt.x += scaledRadius;
|
||||
}
|
||||
|
||||
NSPoint endOfLine = NSMakePoint(maxX, maxY);
|
||||
BOOL shouldDrawNextCorner = NO;
|
||||
if (scaledRadius > 0 &&
|
||||
(drawsRoundCornerBesideArrow ||
|
||||
(_side != MAPositionBottomLeft && _side != MAPositionLeftBottom))
|
||||
) {
|
||||
endOfLine.x -= scaledRadius;
|
||||
shouldDrawNextCorner = YES;
|
||||
}
|
||||
|
||||
[path moveToPoint:currPt];
|
||||
|
||||
// If arrow should be drawn at top-left point, draw it.
|
||||
if (_side == MAPositionBottomRight) {
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionBottom) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(midX - halfArrowWidth, maxY)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionBottomLeft) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(endOfLine.x - scaledArrowWidth, maxY)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
}
|
||||
|
||||
// Line to end of this side.
|
||||
[path lineToPoint:endOfLine];
|
||||
|
||||
// Rounded corner on top-right.
|
||||
if (shouldDrawNextCorner) {
|
||||
[path appendBezierPathWithArcFromPoint:NSMakePoint(maxX, maxY)
|
||||
toPoint:NSMakePoint(maxX, maxY - scaledRadius)
|
||||
radius:scaledRadius];
|
||||
}
|
||||
|
||||
|
||||
// Draw the right side, beginning at the top-right.
|
||||
endOfLine = NSMakePoint(maxX, minY);
|
||||
shouldDrawNextCorner = NO;
|
||||
if (scaledRadius > 0 &&
|
||||
(drawsRoundCornerBesideArrow ||
|
||||
(_side != MAPositionTopLeft && _side != MAPositionLeftTop))
|
||||
) {
|
||||
endOfLine.y += scaledRadius;
|
||||
shouldDrawNextCorner = YES;
|
||||
}
|
||||
|
||||
// If arrow should be drawn at right-top point, draw it.
|
||||
if (_side == MAPositionLeftBottom) {
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionLeft) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(maxX, midY + halfArrowWidth)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionLeftTop) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(maxX, endOfLine.y + scaledArrowWidth)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
}
|
||||
|
||||
// Line to end of this side.
|
||||
[path lineToPoint:endOfLine];
|
||||
|
||||
// Rounded corner on bottom-right.
|
||||
if (shouldDrawNextCorner) {
|
||||
[path appendBezierPathWithArcFromPoint:NSMakePoint(maxX, minY)
|
||||
toPoint:NSMakePoint(maxX - scaledRadius, minY)
|
||||
radius:scaledRadius];
|
||||
}
|
||||
|
||||
|
||||
// Draw the bottom side, beginning at the bottom-right.
|
||||
endOfLine = NSMakePoint(minX, minY);
|
||||
shouldDrawNextCorner = NO;
|
||||
if (scaledRadius > 0 &&
|
||||
(drawsRoundCornerBesideArrow ||
|
||||
(_side != MAPositionTopRight && _side != MAPositionRightTop))
|
||||
) {
|
||||
endOfLine.x += scaledRadius;
|
||||
shouldDrawNextCorner = YES;
|
||||
}
|
||||
|
||||
// If arrow should be drawn at bottom-right point, draw it.
|
||||
if (_side == MAPositionTopLeft) {
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionTop) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(midX + halfArrowWidth, minY)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionTopRight) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(endOfLine.x + scaledArrowWidth, minY)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
}
|
||||
|
||||
// Line to end of this side.
|
||||
[path lineToPoint:endOfLine];
|
||||
|
||||
// Rounded corner on bottom-left.
|
||||
if (shouldDrawNextCorner) {
|
||||
[path appendBezierPathWithArcFromPoint:NSMakePoint(minX, minY)
|
||||
toPoint:NSMakePoint(minX, minY + scaledRadius)
|
||||
radius:scaledRadius];
|
||||
}
|
||||
|
||||
|
||||
// Draw the left side, beginning at the bottom-left.
|
||||
endOfLine = NSMakePoint(minX, maxY);
|
||||
shouldDrawNextCorner = NO;
|
||||
if (scaledRadius > 0 &&
|
||||
(drawsRoundCornerBesideArrow ||
|
||||
(_side != MAPositionRightBottom && _side != MAPositionBottomRight))
|
||||
) {
|
||||
endOfLine.y -= scaledRadius;
|
||||
shouldDrawNextCorner = YES;
|
||||
}
|
||||
|
||||
// If arrow should be drawn at left-bottom point, draw it.
|
||||
if (_side == MAPositionRightTop) {
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionRight) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(minX, midY - halfArrowWidth)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
} else if (_side == MAPositionRightBottom) {
|
||||
// Line to relevant point before arrow.
|
||||
[path lineToPoint:NSMakePoint(minX, endOfLine.y - scaledArrowWidth)];
|
||||
// Draw arrow.
|
||||
[self _appendArrowToPath:path];
|
||||
}
|
||||
|
||||
// Line to end of this side.
|
||||
[path lineToPoint:endOfLine];
|
||||
|
||||
// Rounded corner on top-left.
|
||||
if (shouldDrawNextCorner) {
|
||||
[path appendBezierPathWithArcFromPoint:NSMakePoint(minX, maxY)
|
||||
toPoint:NSMakePoint(minX + scaledRadius, maxY)
|
||||
radius:scaledRadius];
|
||||
}
|
||||
|
||||
[path closePath];
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
- (void)_appendArrowToPath:(NSBezierPath *)path
|
||||
{
|
||||
if (!hasArrow) {
|
||||
return;
|
||||
}
|
||||
|
||||
float scaleFactor = MAATTACHEDWINDOW_SCALE_FACTOR;
|
||||
float scaledArrowWidth = arrowBaseWidth * scaleFactor;
|
||||
float halfArrowWidth = scaledArrowWidth / 2.0;
|
||||
float scaledArrowHeight = arrowHeight * scaleFactor;
|
||||
NSPoint currPt = [path currentPoint];
|
||||
NSPoint tipPt = currPt;
|
||||
NSPoint endPt = currPt;
|
||||
|
||||
// Note: we always build the arrow path in a clockwise direction.
|
||||
switch (_side) {
|
||||
case MAPositionLeft:
|
||||
case MAPositionLeftTop:
|
||||
case MAPositionLeftBottom:
|
||||
// Arrow points towards right. We're starting from the top.
|
||||
tipPt.x += scaledArrowHeight;
|
||||
tipPt.y -= halfArrowWidth;
|
||||
endPt.y -= scaledArrowWidth;
|
||||
break;
|
||||
case MAPositionRight:
|
||||
case MAPositionRightTop:
|
||||
case MAPositionRightBottom:
|
||||
// Arrow points towards left. We're starting from the bottom.
|
||||
tipPt.x -= scaledArrowHeight;
|
||||
tipPt.y += halfArrowWidth;
|
||||
endPt.y += scaledArrowWidth;
|
||||
break;
|
||||
case MAPositionTop:
|
||||
case MAPositionTopLeft:
|
||||
case MAPositionTopRight:
|
||||
// Arrow points towards bottom. We're starting from the right.
|
||||
tipPt.y -= scaledArrowHeight;
|
||||
tipPt.x -= halfArrowWidth;
|
||||
endPt.x -= scaledArrowWidth;
|
||||
break;
|
||||
case MAPositionBottom:
|
||||
case MAPositionBottomLeft:
|
||||
case MAPositionBottomRight:
|
||||
// Arrow points towards top. We're starting from the left.
|
||||
tipPt.y += scaledArrowHeight;
|
||||
tipPt.x += halfArrowWidth;
|
||||
endPt.x += scaledArrowWidth;
|
||||
break;
|
||||
default:
|
||||
break; // won't happen, but this satisfies gcc with -Wall
|
||||
}
|
||||
|
||||
[path lineToPoint:tipPt];
|
||||
[path lineToPoint:endPt];
|
||||
}
|
||||
|
||||
|
||||
- (void)_redisplay
|
||||
{
|
||||
if (_resizing) {
|
||||
return;
|
||||
}
|
||||
|
||||
_resizing = YES;
|
||||
NSDisableScreenUpdates();
|
||||
[self _updateGeometry];
|
||||
[self _updateBackground];
|
||||
NSEnableScreenUpdates();
|
||||
_resizing = NO;
|
||||
}
|
||||
|
||||
|
||||
# pragma mark Window Behaviour
|
||||
|
||||
|
||||
- (BOOL)canBecomeMainWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isExcludedFromWindowsMenu
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if (_window) {
|
||||
return [_window validateMenuItem:item];
|
||||
}
|
||||
return [super validateMenuItem:item];
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)performClose:(id)sender
|
||||
{
|
||||
if (_window) {
|
||||
[_window performClose:sender];
|
||||
} else {
|
||||
[super performClose:sender];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# pragma mark Notification handlers
|
||||
|
||||
|
||||
- (void)windowDidResize:(NSNotification *)note
|
||||
{
|
||||
[self _redisplay];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Accessors
|
||||
|
||||
|
||||
- (void)setPoint:(NSPoint)point side:(MAWindowPosition)side
|
||||
{
|
||||
// Thanks to Martin Redington.
|
||||
_point = point;
|
||||
_side = side;
|
||||
NSDisableScreenUpdates();
|
||||
[self _updateGeometry];
|
||||
[self _updateBackground];
|
||||
NSEnableScreenUpdates();
|
||||
}
|
||||
|
||||
|
||||
- (NSColor *)windowBackgroundColor {
|
||||
return [[_MABackgroundColor retain] autorelease];
|
||||
}
|
||||
|
||||
|
||||
- (void)setBackgroundColor:(NSColor *)value {
|
||||
if (_MABackgroundColor != value) {
|
||||
[_MABackgroundColor release];
|
||||
_MABackgroundColor = [value copy];
|
||||
|
||||
[self _updateBackground];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (NSColor *)borderColor {
|
||||
return [[borderColor retain] autorelease];
|
||||
}
|
||||
|
||||
|
||||
- (void)setBorderColor:(NSColor *)value {
|
||||
if (borderColor != value) {
|
||||
[borderColor release];
|
||||
borderColor = [value copy];
|
||||
|
||||
[self _updateBackground];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (float)borderWidth {
|
||||
return borderWidth;
|
||||
}
|
||||
|
||||
|
||||
- (void)setBorderWidth:(float)value {
|
||||
if (borderWidth != value) {
|
||||
float maxBorderWidth = viewMargin;
|
||||
if (value <= maxBorderWidth) {
|
||||
borderWidth = value;
|
||||
} else {
|
||||
borderWidth = maxBorderWidth;
|
||||
}
|
||||
|
||||
[self _updateBackground];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (float)viewMargin {
|
||||
return viewMargin;
|
||||
}
|
||||
|
||||
|
||||
- (void)setViewMargin:(float)value {
|
||||
if (viewMargin != value) {
|
||||
viewMargin = MAX(value, 0.0);
|
||||
|
||||
// Adjust cornerRadius appropriately (which will also adjust arrowBaseWidth).
|
||||
[self setCornerRadius:cornerRadius];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (float)arrowBaseWidth {
|
||||
return arrowBaseWidth;
|
||||
}
|
||||
|
||||
|
||||
- (void)setArrowBaseWidth:(float)value {
|
||||
float maxWidth = (MIN(_viewFrame.size.width, _viewFrame.size.height) +
|
||||
(viewMargin * 2.0)) - cornerRadius;
|
||||
if (drawsRoundCornerBesideArrow) {
|
||||
maxWidth -= cornerRadius;
|
||||
}
|
||||
if (value <= maxWidth) {
|
||||
arrowBaseWidth = value;
|
||||
} else {
|
||||
arrowBaseWidth = maxWidth;
|
||||
}
|
||||
|
||||
[self _redisplay];
|
||||
}
|
||||
|
||||
|
||||
- (float)arrowHeight {
|
||||
return arrowHeight;
|
||||
}
|
||||
|
||||
|
||||
- (void)setArrowHeight:(float)value {
|
||||
if (arrowHeight != value) {
|
||||
arrowHeight = value;
|
||||
|
||||
[self _redisplay];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (float)hasArrow {
|
||||
return hasArrow;
|
||||
}
|
||||
|
||||
|
||||
- (void)setHasArrow:(float)value {
|
||||
if (hasArrow != value) {
|
||||
hasArrow = value;
|
||||
|
||||
[self _updateBackground];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (float)cornerRadius {
|
||||
return cornerRadius;
|
||||
}
|
||||
|
||||
|
||||
- (void)setCornerRadius:(float)value {
|
||||
float maxRadius = ((MIN(_viewFrame.size.width, _viewFrame.size.height) +
|
||||
(viewMargin * 2.0)) - arrowBaseWidth) / 2.0;
|
||||
if (value <= maxRadius) {
|
||||
cornerRadius = value;
|
||||
} else {
|
||||
cornerRadius = maxRadius;
|
||||
}
|
||||
cornerRadius = MAX(cornerRadius, 0.0);
|
||||
|
||||
// Adjust arrowBaseWidth appropriately.
|
||||
[self setArrowBaseWidth:arrowBaseWidth];
|
||||
}
|
||||
|
||||
|
||||
- (float)drawsRoundCornerBesideArrow {
|
||||
return drawsRoundCornerBesideArrow;
|
||||
}
|
||||
|
||||
|
||||
- (void)setDrawsRoundCornerBesideArrow:(float)value {
|
||||
if (drawsRoundCornerBesideArrow != value) {
|
||||
drawsRoundCornerBesideArrow = value;
|
||||
|
||||
[self _redisplay];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setBackgroundImage:(NSImage *)value
|
||||
{
|
||||
if (value) {
|
||||
[self setBackgroundColor:[NSColor colorWithPatternImage:value]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@ -1,45 +0,0 @@
|
||||
//
|
||||
// NBTFile.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
typedef enum {
|
||||
NBTTypeEnd = 0,
|
||||
NBTTypeByte = 1,
|
||||
NBTTypeShort = 2,
|
||||
NBTTypeInt = 3,
|
||||
NBTTypeLong = 4,
|
||||
NBTTypeFloat = 5,
|
||||
NBTTypeDouble = 6,
|
||||
NBTTypeByteArray = 7,
|
||||
NBTTypeString = 8,
|
||||
NBTTypeList = 9,
|
||||
NBTTypeCompound = 10,
|
||||
} NBTType;
|
||||
|
||||
@interface NBTContainer : NSObject {
|
||||
NSString *name;
|
||||
NSMutableArray *children;
|
||||
NBTType type;
|
||||
NSString *stringValue;
|
||||
NSNumber *numberValue;
|
||||
NBTType listType;
|
||||
}
|
||||
@property (nonatomic, copy) NSString *name;
|
||||
@property (nonatomic, retain) NSMutableArray *children;
|
||||
@property (nonatomic, assign) NBTType type;
|
||||
@property (nonatomic, retain) NSString *stringValue;
|
||||
@property (nonatomic, retain) NSNumber *numberValue;
|
||||
@property (nonatomic, assign) NBTType listType;
|
||||
|
||||
+ (NBTContainer *)containerWithName:(NSString *)theName type:(NBTType)theType numberValue:(NSNumber *)theNumber;
|
||||
+ (id)nbtContainerWithData:(NSData *)data;
|
||||
- (void)readFromData:(NSData *)data;
|
||||
- (NSData *)writeData;
|
||||
- (NBTContainer *)childNamed:(NSString *)theName;
|
||||
@end
|
||||
@ -1,408 +0,0 @@
|
||||
//
|
||||
// NBTFile.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
// Spec for the Named Binary Tag format: http://www.minecraft.net/docs/NBT.txt
|
||||
|
||||
#import "NBTContainer.h"
|
||||
#import "NSData+CocoaDevAdditions.h"
|
||||
|
||||
|
||||
#ifndef NBT_LOGGING
|
||||
#define NBT_LOGGING 0
|
||||
#endif
|
||||
|
||||
#if NBT_LOGGING
|
||||
#define NBTLog(format, ...) NSLog(format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define NBTLog(format, ...) while(0)
|
||||
#endif
|
||||
|
||||
|
||||
@interface NBTContainer ()
|
||||
- (void)populateWithBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
|
||||
- (uint8_t)byteFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
|
||||
- (uint16_t)shortFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
|
||||
- (uint32_t)intFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
|
||||
- (uint64_t)longFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
|
||||
- (NSString *)stringFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
|
||||
|
||||
- (void)appendString:(NSString *)str toData:(NSMutableData *)data;
|
||||
- (void)appendByte:(uint8_t)v toData:(NSMutableData *)data;
|
||||
- (void)appendShort:(uint16_t)v toData:(NSMutableData *)data;
|
||||
- (void)appendInt:(uint32_t)v toData:(NSMutableData *)data;
|
||||
- (void)appendLong:(uint64_t)v toData:(NSMutableData *)data;
|
||||
- (void)appendFloat:(float)v toData:(NSMutableData *)data;
|
||||
- (void)appendDouble:(double)v toData:(NSMutableData *)data;
|
||||
|
||||
- (NSData *)data;
|
||||
@end
|
||||
|
||||
|
||||
@implementation NBTContainer
|
||||
@synthesize name, children, type;
|
||||
@synthesize stringValue, numberValue, listType;
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)dealloc
|
||||
{
|
||||
[name release];
|
||||
[children release];
|
||||
[stringValue release];
|
||||
[numberValue release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (NBTContainer *)containerWithName:(NSString *)theName type:(NBTType)theType numberValue:(NSNumber *)theNumber
|
||||
{
|
||||
NBTContainer *cont = [[[NBTContainer alloc] init] autorelease];
|
||||
cont.name = theName;
|
||||
cont.type = theType;
|
||||
cont.numberValue = theNumber;
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
+ (id)nbtContainerWithData:(NSData *)data;
|
||||
{
|
||||
id obj = [[[self class] alloc] init];
|
||||
[obj readFromData:data];
|
||||
return [obj autorelease];
|
||||
}
|
||||
|
||||
- (void)readFromData:(NSData *)data
|
||||
{
|
||||
data = [data gzipInflate];
|
||||
|
||||
const uint8_t *bytes = (const uint8_t *)[data bytes];
|
||||
|
||||
uint32_t offset = 0;
|
||||
[self populateWithBytes:bytes offset:&offset];
|
||||
}
|
||||
|
||||
- (NSData *)writeData
|
||||
{
|
||||
return [[self data] gzipDeflate];
|
||||
}
|
||||
|
||||
- (NBTContainer *)childNamed:(NSString *)theName
|
||||
{
|
||||
if (self.type != NBTTypeCompound)
|
||||
{
|
||||
NSLog(@"ERROR: Cannot find children inside a non-compound NBTContainer.");
|
||||
return nil;
|
||||
}
|
||||
for (NBTContainer *container in self.children)
|
||||
{
|
||||
if ([container.name isEqual:theName])
|
||||
return container;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Private I/O API
|
||||
|
||||
- (void)populateWithBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
|
||||
{
|
||||
uint32_t offset = *offsetPointer;
|
||||
self.type = [self byteFromBytes:bytes offset:&offset];
|
||||
self.name = [self stringFromBytes:bytes offset:&offset];
|
||||
|
||||
if (self.type == NBTTypeCompound)
|
||||
{
|
||||
NBTLog(@">> start compound named %@", self.name);
|
||||
self.children = [NSMutableArray array];
|
||||
|
||||
while (1)
|
||||
{
|
||||
NBTType childType = bytes[offset]; // peek
|
||||
if (childType == NBTTypeEnd)
|
||||
{
|
||||
offset += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
NBTContainer *child = [[NBTContainer alloc] init];
|
||||
[child populateWithBytes:bytes offset:&offset];
|
||||
[self.children addObject:child];
|
||||
[child release];
|
||||
}
|
||||
NBTLog(@"<< end compound %@", self.name);
|
||||
}
|
||||
else if (self.type == NBTTypeList)
|
||||
{
|
||||
listType = [self byteFromBytes:bytes offset:&offset];
|
||||
uint32_t listLength = [self intFromBytes:bytes offset:&offset];
|
||||
|
||||
NBTLog(@">> start list named %@ with type=%d length=%d", self.name, listType, listLength);
|
||||
|
||||
self.children = [NSMutableArray array];
|
||||
while (listLength > 0)
|
||||
{
|
||||
if (listType == NBTTypeFloat)
|
||||
{
|
||||
uint32_t i = [self intFromBytes:bytes offset:&offset];
|
||||
float f = *((float*)&i);
|
||||
NSNumber *num = [NSNumber numberWithFloat:f];
|
||||
[self.children addObject:num];
|
||||
}
|
||||
else if (listType == NBTTypeDouble)
|
||||
{
|
||||
uint64_t l = [self longFromBytes:bytes offset:&offset];
|
||||
double d = *((double*)&l);
|
||||
NSNumber *num = [NSNumber numberWithDouble:d];
|
||||
[self.children addObject:num];
|
||||
}
|
||||
else if (listType == NBTTypeCompound)
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
while (1)
|
||||
{
|
||||
NBTType childType = bytes[offset]; // peek
|
||||
if (childType == NBTTypeEnd)
|
||||
{
|
||||
offset += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
NBTContainer *child = [[NBTContainer alloc] init];
|
||||
[child populateWithBytes:bytes offset:&offset];
|
||||
[array addObject:child];
|
||||
[child release];
|
||||
}
|
||||
[self.children addObject:array];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Unhandled list type: %d", listType);
|
||||
}
|
||||
listLength--;
|
||||
}
|
||||
|
||||
NBTLog(@"<< end list %@", self.name);
|
||||
}
|
||||
else if (self.type == NBTTypeString)
|
||||
{
|
||||
self.stringValue = [self stringFromBytes:bytes offset:&offset];
|
||||
NBTLog(@" name=%@ string=%@", self.name, self.stringValue);
|
||||
}
|
||||
else if (self.type == NBTTypeLong)
|
||||
{
|
||||
self.numberValue = [NSNumber numberWithUnsignedLongLong:[self longFromBytes:bytes offset:&offset]];
|
||||
NBTLog(@" name=%@ long=%qu", self.name, [self.numberValue unsignedLongLongValue]);
|
||||
}
|
||||
else if (self.type == NBTTypeInt)
|
||||
{
|
||||
self.numberValue = [NSNumber numberWithUnsignedInt:[self intFromBytes:bytes offset:&offset]];
|
||||
NBTLog(@" name=%@ int=0x%x", self.name, [self.numberValue unsignedIntValue]);
|
||||
}
|
||||
else if (self.type == NBTTypeShort)
|
||||
{
|
||||
self.numberValue = [NSNumber numberWithUnsignedShort:[self shortFromBytes:bytes offset:&offset]];
|
||||
NBTLog(@" name=%@ short=0x%x", self.name, [self.numberValue unsignedShortValue]);
|
||||
}
|
||||
else if (self.type == NBTTypeByte)
|
||||
{
|
||||
self.numberValue = [NSNumber numberWithUnsignedChar:[self byteFromBytes:bytes offset:&offset]];
|
||||
NBTLog(@" name=%@ byte=0x%x", self.name, [self.numberValue unsignedCharValue]);
|
||||
}
|
||||
else if (self.type == NBTTypeFloat)
|
||||
{
|
||||
uint32_t i = [self intFromBytes:bytes offset:&offset];
|
||||
float f = *((float *)&i);
|
||||
self.numberValue = [NSNumber numberWithFloat:f];
|
||||
NBTLog(@" name=%@ float=%f", self.name, [self.numberValue floatValue]);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Unhandled type: %d", self.type);
|
||||
}
|
||||
|
||||
*offsetPointer = offset;
|
||||
}
|
||||
|
||||
|
||||
- (NSData *)data
|
||||
{
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[self appendByte:self.type toData:data];
|
||||
[self appendString:self.name toData:data];
|
||||
|
||||
if (self.type == NBTTypeCompound)
|
||||
{
|
||||
for (NBTContainer *child in self.children)
|
||||
{
|
||||
[data appendData:[child data]];
|
||||
}
|
||||
uint8_t t = NBTTypeEnd;
|
||||
[data appendBytes:&t length:1];
|
||||
}
|
||||
else if (self.type == NBTTypeList)
|
||||
{
|
||||
[self appendByte:self.listType toData:data];
|
||||
[self appendInt:self.children.count toData:data];
|
||||
for (id item in self.children)
|
||||
{
|
||||
if (listType == NBTTypeCompound)
|
||||
{
|
||||
for (NBTContainer *i in item)
|
||||
{
|
||||
[data appendData:[i data]];
|
||||
}
|
||||
uint8_t t = NBTTypeEnd;
|
||||
[data appendBytes:&t length:1];
|
||||
}
|
||||
else if (listType == NBTTypeFloat)
|
||||
{
|
||||
[self appendFloat:[item floatValue] toData:data];
|
||||
}
|
||||
else if (listType == NBTTypeDouble)
|
||||
{
|
||||
[self appendDouble:[item doubleValue] toData:data];
|
||||
}
|
||||
else if (listType == NBTTypeByte)
|
||||
{
|
||||
[self appendByte:[item unsignedCharValue] toData:data];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Unhandled list type: %d", listType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (self.type == NBTTypeString)
|
||||
{
|
||||
[self appendString:self.stringValue toData:data];
|
||||
}
|
||||
else if (self.type == NBTTypeLong)
|
||||
{
|
||||
[self appendLong:[self.numberValue unsignedLongLongValue] toData:data];
|
||||
}
|
||||
else if (self.type == NBTTypeShort)
|
||||
{
|
||||
[self appendShort:[self.numberValue unsignedShortValue] toData:data];
|
||||
}
|
||||
else if (self.type == NBTTypeInt)
|
||||
{
|
||||
[self appendInt:[self.numberValue unsignedIntValue] toData:data];
|
||||
}
|
||||
else if (self.type == NBTTypeByte)
|
||||
{
|
||||
[self appendByte:[self.numberValue unsignedCharValue] toData:data];
|
||||
}
|
||||
else if (self.type == NBTTypeDouble)
|
||||
{
|
||||
[self appendDouble:[self.numberValue doubleValue] toData:data];
|
||||
}
|
||||
else if (self.type == NBTTypeFloat)
|
||||
{
|
||||
[self appendFloat:[self.numberValue floatValue] toData:data];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Unhandled type: %d", self.type);
|
||||
}
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Data Helpers
|
||||
|
||||
|
||||
- (NSString *)stringFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
|
||||
{
|
||||
uint32_t offset = *offsetPointer;
|
||||
uint16_t length = (bytes[offset] << 8) | bytes[offset + 1];
|
||||
*offsetPointer += 2 + length;
|
||||
return [[[NSString alloc] initWithBytes:bytes + offset + 2 length:length encoding:NSUTF8StringEncoding] autorelease];
|
||||
}
|
||||
- (uint8_t)byteFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
|
||||
{
|
||||
uint32_t offset = *offsetPointer;
|
||||
uint8_t n = bytes[offset];
|
||||
*offsetPointer += 1;
|
||||
return n;
|
||||
}
|
||||
- (uint16_t)shortFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
|
||||
{
|
||||
uint32_t offset = *offsetPointer;
|
||||
uint16_t n = (bytes[offset + 0] << 8) | bytes[offset + 1];
|
||||
*offsetPointer += 2;
|
||||
return n;
|
||||
}
|
||||
- (uint32_t)intFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
|
||||
{
|
||||
uint32_t offset = *offsetPointer;
|
||||
uint32_t n = ntohl(*((uint32_t *)(bytes + offset)));
|
||||
*offsetPointer += 4;
|
||||
return n;
|
||||
}
|
||||
- (uint64_t)longFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
|
||||
{
|
||||
uint32_t offset = *offsetPointer;
|
||||
uint64_t n = ntohl(*((uint32_t *)(bytes + offset)));
|
||||
n <<= 32;
|
||||
offset += 4;
|
||||
n += ntohl(*((uint32_t *)(bytes + offset)));
|
||||
*offsetPointer += 8;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
- (void)appendString:(NSString *)str toData:(NSMutableData *)data
|
||||
{
|
||||
[self appendShort:str.length toData:data];
|
||||
[data appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
}
|
||||
- (void)appendByte:(uint8_t)v toData:(NSMutableData *)data
|
||||
{
|
||||
[data appendBytes:&v length:1];
|
||||
}
|
||||
- (void)appendShort:(uint16_t)v toData:(NSMutableData *)data
|
||||
{
|
||||
v = htons(v);
|
||||
[data appendBytes:&v length:2];
|
||||
}
|
||||
- (void)appendInt:(uint32_t)v toData:(NSMutableData *)data
|
||||
{
|
||||
v = htonl(v);
|
||||
[data appendBytes:&v length:4];
|
||||
}
|
||||
- (void)appendLong:(uint64_t)v toData:(NSMutableData *)data
|
||||
{
|
||||
uint32_t v0 = htonl(v >> 32);
|
||||
uint32_t v1 = htonl(v);
|
||||
[data appendBytes:&v0 length:4];
|
||||
[data appendBytes:&v1 length:4];
|
||||
}
|
||||
- (void)appendFloat:(float)v toData:(NSMutableData *)data
|
||||
{
|
||||
uint32_t vi = *((uint32_t *)&v);
|
||||
vi = htonl(vi);
|
||||
[data appendBytes:&vi length:4];
|
||||
}
|
||||
- (void)appendDouble:(double)v toData:(NSMutableData *)data
|
||||
{
|
||||
uint64_t vl = *((uint64_t *)&v);
|
||||
uint32_t v0 = htonl(vl >> 32);
|
||||
uint32_t v1 = htonl(vl);
|
||||
[data appendBytes:&v0 length:4];
|
||||
[data appendBytes:&v1 length:4];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@ -1,16 +0,0 @@
|
||||
//
|
||||
// NSColor+Additions.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/10/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface NSColor (Additions)
|
||||
|
||||
- (CGColorRef)CGColor;
|
||||
|
||||
@end
|
||||
@ -1,27 +0,0 @@
|
||||
//
|
||||
// NSColor+Additions.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/10/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSColor+Additions.h"
|
||||
|
||||
|
||||
@implementation NSColor (Additions)
|
||||
|
||||
- (CGColorRef)CGColor
|
||||
{
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
NSColor *deviceColor = [self colorUsingColorSpaceName:NSDeviceRGBColorSpace];
|
||||
|
||||
CGFloat components[4];
|
||||
[deviceColor getRed: &components[0] green: &components[1] blue:&components[2] alpha: &components[3]];
|
||||
|
||||
CGColorRef output = CGColorCreate(colorSpace, components);
|
||||
CGColorSpaceRelease (colorSpace);
|
||||
return (CGColorRef)[(id)output autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,16 +0,0 @@
|
||||
//
|
||||
// NSData+CocoaDevAdditions.h
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface NSData (CocoaDevAdditions)
|
||||
|
||||
- (NSData *)gzipInflate;
|
||||
- (NSData *)gzipDeflate;
|
||||
|
||||
@end
|
||||
@ -1,100 +0,0 @@
|
||||
//
|
||||
// NSData+CocoaDevAdditions.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
//
|
||||
// Source: http://www.cocoadev.com/index.pl?NSDataCategory
|
||||
|
||||
|
||||
#import "NSData+CocoaDevAdditions.h"
|
||||
#import <zlib.h>
|
||||
|
||||
@implementation NSData (CocoaDevAdditions)
|
||||
|
||||
|
||||
- (NSData *)gzipInflate
|
||||
{
|
||||
if ([self length] == 0) return self;
|
||||
|
||||
unsigned full_length = [self length];
|
||||
unsigned half_length = [self length] / 2;
|
||||
|
||||
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
|
||||
BOOL done = NO;
|
||||
int status;
|
||||
|
||||
z_stream strm;
|
||||
strm.next_in = (Bytef *)[self bytes];
|
||||
strm.avail_in = [self length];
|
||||
strm.total_out = 0;
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
|
||||
if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
|
||||
while (!done)
|
||||
{
|
||||
// Make sure we have enough room and reset the lengths.
|
||||
if (strm.total_out >= [decompressed length])
|
||||
[decompressed increaseLengthBy: half_length];
|
||||
strm.next_out = [decompressed mutableBytes] + strm.total_out;
|
||||
strm.avail_out = [decompressed length] - strm.total_out;
|
||||
|
||||
// Inflate another chunk.
|
||||
status = inflate (&strm, Z_SYNC_FLUSH);
|
||||
if (status == Z_STREAM_END) done = YES;
|
||||
else if (status != Z_OK) break;
|
||||
}
|
||||
if (inflateEnd (&strm) != Z_OK) return nil;
|
||||
|
||||
// Set real length.
|
||||
if (done)
|
||||
{
|
||||
[decompressed setLength: strm.total_out];
|
||||
return [NSData dataWithData: decompressed];
|
||||
}
|
||||
else return nil;
|
||||
}
|
||||
|
||||
- (NSData *)gzipDeflate
|
||||
{
|
||||
if ([self length] == 0) return self;
|
||||
|
||||
z_stream strm;
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.total_out = 0;
|
||||
strm.next_in=(Bytef *)[self bytes];
|
||||
strm.avail_in = [self length];
|
||||
|
||||
// Compresssion Levels:
|
||||
// Z_NO_COMPRESSION
|
||||
// Z_BEST_SPEED
|
||||
// Z_BEST_COMPRESSION
|
||||
// Z_DEFAULT_COMPRESSION
|
||||
|
||||
if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
|
||||
|
||||
NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion
|
||||
|
||||
do {
|
||||
|
||||
if (strm.total_out >= [compressed length])
|
||||
[compressed increaseLengthBy: 16384];
|
||||
|
||||
strm.next_out = [compressed mutableBytes] + strm.total_out;
|
||||
strm.avail_out = [compressed length] - strm.total_out;
|
||||
|
||||
deflate(&strm, Z_FINISH);
|
||||
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
deflateEnd(&strm);
|
||||
|
||||
[compressed setLength: strm.total_out];
|
||||
return [NSData dataWithData:compressed];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,27 +0,0 @@
|
||||
//
|
||||
// NSFileManager+DirectoryLocations.h
|
||||
//
|
||||
// Created by Matt Gallagher on 06 May 2010
|
||||
//
|
||||
// Permission is given to use this source code file, free of charge, in any
|
||||
// project, commercial or otherwise, entirely at your risk, with the condition
|
||||
// that any redistribution (in part or whole) of source code must retain
|
||||
// this copyright and permission notice. Attribution in compiled projects is
|
||||
// appreciated but not required.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//
|
||||
// DirectoryLocations is a set of global methods for finding the fixed location
|
||||
// directoriess.
|
||||
//
|
||||
@interface NSFileManager (DirectoryLocations)
|
||||
|
||||
- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
|
||||
inDomain:(NSSearchPathDomainMask)domainMask
|
||||
appendPathComponent:(NSString *)appendComponent
|
||||
error:(NSError **)errorOut;
|
||||
- (NSString *)applicationSupportDirectory;
|
||||
|
||||
@end
|
||||
@ -1,179 +0,0 @@
|
||||
//
|
||||
// NSFileManager+DirectoryLocations.m
|
||||
//
|
||||
// Created by Matt Gallagher on 06 May 2010
|
||||
//
|
||||
// Permission is given to use this source code file, free of charge, in any
|
||||
// project, commercial or otherwise, entirely at your risk, with the condition
|
||||
// that any redistribution (in part or whole) of source code must retain
|
||||
// this copyright and permission notice. Attribution in compiled projects is
|
||||
// appreciated but not required.
|
||||
//
|
||||
|
||||
#import "NSFileManager+DirectoryLocations.h"
|
||||
|
||||
enum
|
||||
{
|
||||
DirectoryLocationErrorNoPathFound,
|
||||
DirectoryLocationErrorFileExistsAtLocation
|
||||
};
|
||||
|
||||
NSString * const DirectoryLocationDomain = @"DirectoryLocationDomain";
|
||||
|
||||
@implementation NSFileManager (DirectoryLocations)
|
||||
|
||||
//
|
||||
// findOrCreateDirectory:inDomain:appendPathComponent:error:
|
||||
//
|
||||
// Method to tie together the steps of:
|
||||
// 1) Locate a standard directory by search path and domain mask
|
||||
// 2) Select the first path in the results
|
||||
// 3) Append a subdirectory to that path
|
||||
// 4) Create the directory and intermediate directories if needed
|
||||
// 5) Handle errors by emitting a proper NSError object
|
||||
//
|
||||
// Parameters:
|
||||
// searchPathDirectory - the search path passed to NSSearchPathForDirectoriesInDomains
|
||||
// domainMask - the domain mask passed to NSSearchPathForDirectoriesInDomains
|
||||
// appendComponent - the subdirectory appended
|
||||
// errorOut - any error from file operations
|
||||
//
|
||||
// returns the path to the directory (if path found and exists), nil otherwise
|
||||
//
|
||||
- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
|
||||
inDomain:(NSSearchPathDomainMask)domainMask
|
||||
appendPathComponent:(NSString *)appendComponent
|
||||
error:(NSError **)errorOut
|
||||
{
|
||||
//
|
||||
// Search for the path
|
||||
//
|
||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(
|
||||
searchPathDirectory,
|
||||
domainMask,
|
||||
YES);
|
||||
if ([paths count] == 0)
|
||||
{
|
||||
if (errorOut)
|
||||
{
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTable(
|
||||
@"No path found for directory in domain.",
|
||||
@"Errors",
|
||||
nil),
|
||||
NSLocalizedDescriptionKey,
|
||||
[NSNumber numberWithInteger:searchPathDirectory],
|
||||
@"NSSearchPathDirectory",
|
||||
[NSNumber numberWithInteger:domainMask],
|
||||
@"NSSearchPathDomainMask",
|
||||
nil];
|
||||
*errorOut =
|
||||
[NSError
|
||||
errorWithDomain:DirectoryLocationDomain
|
||||
code:DirectoryLocationErrorNoPathFound
|
||||
userInfo:userInfo];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
// Normally only need the first path returned
|
||||
//
|
||||
NSString *resolvedPath = [paths objectAtIndex:0];
|
||||
|
||||
//
|
||||
// Append the extra path component
|
||||
//
|
||||
if (appendComponent)
|
||||
{
|
||||
resolvedPath = [resolvedPath
|
||||
stringByAppendingPathComponent:appendComponent];
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the path exists
|
||||
//
|
||||
BOOL exists;
|
||||
BOOL isDirectory;
|
||||
exists = [self
|
||||
fileExistsAtPath:resolvedPath
|
||||
isDirectory:&isDirectory];
|
||||
if (!exists || !isDirectory)
|
||||
{
|
||||
if (exists)
|
||||
{
|
||||
if (errorOut)
|
||||
{
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedStringFromTable(
|
||||
@"File exists at requested directory location.",
|
||||
@"Errors",
|
||||
nil),
|
||||
NSLocalizedDescriptionKey,
|
||||
[NSNumber numberWithInteger:searchPathDirectory],
|
||||
@"NSSearchPathDirectory",
|
||||
[NSNumber numberWithInteger:domainMask],
|
||||
@"NSSearchPathDomainMask",
|
||||
nil];
|
||||
*errorOut =
|
||||
[NSError
|
||||
errorWithDomain:DirectoryLocationDomain
|
||||
code:DirectoryLocationErrorFileExistsAtLocation
|
||||
userInfo:userInfo];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the path if it doesn't exist
|
||||
//
|
||||
NSError *error = nil;
|
||||
BOOL success = [self
|
||||
createDirectoryAtPath:resolvedPath
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:&error];
|
||||
if (!success)
|
||||
{
|
||||
if (errorOut)
|
||||
{
|
||||
*errorOut = error;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorOut)
|
||||
{
|
||||
*errorOut = nil;
|
||||
}
|
||||
return resolvedPath;
|
||||
}
|
||||
|
||||
//
|
||||
// applicationSupportDirectory
|
||||
//
|
||||
// Returns the path to the applicationSupportDirectory (creating it if it doesn't
|
||||
// exist).
|
||||
//
|
||||
- (NSString *)applicationSupportDirectory
|
||||
{
|
||||
NSString *executableName =
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
|
||||
NSError *error;
|
||||
NSString *result =
|
||||
[self
|
||||
findOrCreateDirectory:NSApplicationSupportDirectory
|
||||
inDomain:NSUserDomainMask
|
||||
appendPathComponent:executableName
|
||||
error:&error];
|
||||
if (!result)
|
||||
{
|
||||
NSLog(@"Unable to find or create application support directory:\n%@", error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
28
Credits.rtf
28
Credits.rtf
@ -1,28 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
|
||||
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\paperw12240\paperh15840\vieww9000\viewh8400\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
|
||||
|
||||
\f0\fs20 \cf0 A Minecraft Inventory Editor - SMP Friendly Version\
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
|
||||
{\field{\*\fldinst{HYPERLINK "http://github.com/godzil/InsideJob"}}{\fldrslt \cf0 http://github.com/godzil/InsideJob}}\
|
||||
\
|
||||
Changes merged from Nickloose fork:\
|
||||
{\field{\*\fldinst{HYPERLINK "http://github.com/preble/InsideJob"}}{\fldrslt http://github.com/nickloose/InsideJob}}\
|
||||
\
|
||||
Forked from original version by Adam Preble:\
|
||||
{\field{\*\fldinst{HYPERLINK "http://adampreble.net"}}{\fldrslt http://adampreble.net}}\
|
||||
{\field{\*\fldinst{HYPERLINK "http://github.com/preble/InsideJob"}}{\fldrslt http://github.com/preble/InsideJob}}\
|
||||
\
|
||||
{\field{\*\fldinst{HYPERLINK "http://www.minecraftwiki.net/wiki/File:DataValuesV110.png"}}{\fldrslt Item Images}}\
|
||||
Copyright Mojang Specifications\
|
||||
Compiled by Trojam\
|
||||
and the Minecraft Community\
|
||||
\
|
||||
Uses MAAttachedWindow\
|
||||
by {\field{\*\fldinst{HYPERLINK "http://mattgemmell.com/"}}{\fldrslt Matt Gemmell}}\
|
||||
\
|
||||
Uses NSFileManager\
|
||||
by Matt Gallagher}
|
||||
@ -1,5 +0,0 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
"No world loaded." = "No world loaded.";
|
||||
"No world exists in that slot." = "No world exists in that slot.";
|
||||
"Dismiss" = "Dismiss";
|
||||
"Please create a new single player world in this slot using Minecraft and try again." = "Please create a new single player world in this slot using Minecraft and try again.";
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 153 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 203 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 4.7 KiB |
@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array/>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>InsideJob</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.godzil.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.2-smp</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array/>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright 2011 Adam Preble and Contributors - SMP mod by Manoel Trapier</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSServices</key>
|
||||
<array/>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array/>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
InsideJob.png
Normal file
BIN
InsideJob.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
@ -1,449 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 45;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; };
|
||||
256AC3DA0F4B6AC300CF3369 /* InsideJobAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */; };
|
||||
668B2556125D5A3E0060BF71 /* NBTContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B2555125D5A3E0060BF71 /* NBTContainer.m */; };
|
||||
668B255C125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */; };
|
||||
668B2560125D5C1C0060BF71 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 668B255F125D5C1C0060BF71 /* libz.dylib */; };
|
||||
668B27AF125D8EFD0060BF71 /* IJMinecraftLevel.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B27AE125D8EFD0060BF71 /* IJMinecraftLevel.m */; };
|
||||
668B27B2125D8F8E0060BF71 /* IJInventoryItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B27B1125D8F8E0060BF71 /* IJInventoryItem.m */; };
|
||||
668B27F2125D963F0060BF71 /* IJInventoryWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B27F1125D963F0060BF71 /* IJInventoryWindowController.m */; };
|
||||
668B290F125E40560060BF71 /* Items.csv in Resources */ = {isa = PBXBuildFile; fileRef = 668B28D8125E370A0060BF71 /* Items.csv */; };
|
||||
66BC00031260215C005A23F4 /* IJInventoryView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BC00021260215C005A23F4 /* IJInventoryView.m */; };
|
||||
66BC000E12602359005A23F4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66BC000D12602359005A23F4 /* QuartzCore.framework */; };
|
||||
66BC033B1260CC59005A23F4 /* MAAttachedWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BC033A1260CC59005A23F4 /* MAAttachedWindow.m */; };
|
||||
66BC03621260D095005A23F4 /* IJItemPropertiesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BC03611260D095005A23F4 /* IJItemPropertiesViewController.m */; };
|
||||
66BC04F812619072005A23F4 /* NSColor+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BC04F712619072005A23F4 /* NSColor+Additions.m */; };
|
||||
66BC077312628257005A23F4 /* ItemPropertiesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 66BC077212628257005A23F4 /* ItemPropertiesView.xib */; };
|
||||
66BCFC2B125E9A51005A23F4 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 66BCFC2A125E9A51005A23F4 /* Credits.rtf */; };
|
||||
66BCFC36125EA53E005A23F4 /* InsideJob.icns in Resources */ = {isa = PBXBuildFile; fileRef = 66BCFC35125EA53E005A23F4 /* InsideJob.icns */; };
|
||||
66BCFE62125FCEC6005A23F4 /* DataValuesV110Transparent.png in Resources */ = {isa = PBXBuildFile; fileRef = 66BCFE61125FCEC6005A23F4 /* DataValuesV110Transparent.png */; };
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
|
||||
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||
BA24598B1297428900F8B9C2 /* blockNotFound.png in Resources */ = {isa = PBXBuildFile; fileRef = BA24598A1297428900F8B9C2 /* blockNotFound.png */; };
|
||||
BA3329A9129889860079447B /* NSFileManager+DirectoryLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = BA3329A8129889860079447B /* NSFileManager+DirectoryLocations.m */; };
|
||||
BA9186CB1328C1C600769DEC /* IJTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = BA9186CA1328C1C600769DEC /* IJTableView.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
256AC3D80F4B6AC300CF3369 /* InsideJobAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsideJobAppDelegate.h; sourceTree = "<group>"; };
|
||||
256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InsideJobAppDelegate.m; sourceTree = "<group>"; };
|
||||
256AC3F00F4B6AF500CF3369 /* InsideJob_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsideJob_Prefix.pch; sourceTree = "<group>"; };
|
||||
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
|
||||
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
668B2554125D5A3E0060BF71 /* NBTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NBTContainer.h; sourceTree = "<group>"; };
|
||||
668B2555125D5A3E0060BF71 /* NBTContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NBTContainer.m; sourceTree = "<group>"; };
|
||||
668B255A125D5BCA0060BF71 /* NSData+CocoaDevAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+CocoaDevAdditions.h"; sourceTree = "<group>"; };
|
||||
668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+CocoaDevAdditions.m"; sourceTree = "<group>"; };
|
||||
668B255F125D5C1C0060BF71 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
|
||||
668B27AD125D8EFD0060BF71 /* IJMinecraftLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJMinecraftLevel.h; sourceTree = "<group>"; };
|
||||
668B27AE125D8EFD0060BF71 /* IJMinecraftLevel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJMinecraftLevel.m; sourceTree = "<group>"; };
|
||||
668B27B0125D8F8E0060BF71 /* IJInventoryItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJInventoryItem.h; sourceTree = "<group>"; };
|
||||
668B27B1125D8F8E0060BF71 /* IJInventoryItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJInventoryItem.m; sourceTree = "<group>"; };
|
||||
668B27F0125D963F0060BF71 /* IJInventoryWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJInventoryWindowController.h; sourceTree = "<group>"; };
|
||||
668B27F1125D963F0060BF71 /* IJInventoryWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJInventoryWindowController.m; sourceTree = "<group>"; };
|
||||
668B28D8125E370A0060BF71 /* Items.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Items.csv; sourceTree = "<group>"; };
|
||||
6697AD7012B86762001890C6 /* IJTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJTableView.h; sourceTree = "<group>"; };
|
||||
6697AD7112B86762001890C6 /* IJTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJTableView.m; sourceTree = "<group>"; };
|
||||
6697ADA812B86A07001890C6 /* README.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.markdown; sourceTree = "<group>"; wrapsLines = 1; };
|
||||
66BC00011260215C005A23F4 /* IJInventoryView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJInventoryView.h; sourceTree = "<group>"; };
|
||||
66BC00021260215C005A23F4 /* IJInventoryView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJInventoryView.m; sourceTree = "<group>"; };
|
||||
66BC000D12602359005A23F4 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
66BC03391260CC59005A23F4 /* MAAttachedWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAAttachedWindow.h; sourceTree = "<group>"; };
|
||||
66BC033A1260CC59005A23F4 /* MAAttachedWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAAttachedWindow.m; sourceTree = "<group>"; };
|
||||
66BC03601260D095005A23F4 /* IJItemPropertiesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJItemPropertiesViewController.h; sourceTree = "<group>"; };
|
||||
66BC03611260D095005A23F4 /* IJItemPropertiesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJItemPropertiesViewController.m; sourceTree = "<group>"; };
|
||||
66BC03631260D0B3005A23F4 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/ItemPropertiesView.xib; sourceTree = "<group>"; };
|
||||
66BC04F612619072005A23F4 /* NSColor+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+Additions.h"; sourceTree = "<group>"; };
|
||||
66BC04F712619072005A23F4 /* NSColor+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+Additions.m"; sourceTree = "<group>"; };
|
||||
66BCFC2A125E9A51005A23F4 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||
66BCFC35125EA53E005A23F4 /* InsideJob.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = InsideJob.icns; sourceTree = "<group>"; };
|
||||
66BCFE61125FCEC6005A23F4 /* DataValuesV110Transparent.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DataValuesV110Transparent.png; sourceTree = "<group>"; };
|
||||
8D1107310486CEB800E47090 /* InsideJob-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "InsideJob-Info.plist"; sourceTree = "<group>"; };
|
||||
8D1107320486CEB800E47090 /* Inside Job.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Inside Job.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BA24598A1297428900F8B9C2 /* blockNotFound.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blockNotFound.png; sourceTree = "<group>"; };
|
||||
BA3329A7129889860079447B /* NSFileManager+DirectoryLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileManager+DirectoryLocations.h"; sourceTree = "<group>"; };
|
||||
BA3329A8129889860079447B /* NSFileManager+DirectoryLocations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+DirectoryLocations.m"; sourceTree = "<group>"; };
|
||||
BA9186C91328C1C600769DEC /* IJTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJTableView.h; sourceTree = "<group>"; };
|
||||
BA9186CA1328C1C600769DEC /* IJTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJTableView.m; sourceTree = "<group>"; };
|
||||
D13FDB481322757D00D318D1 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8D11072E0486CEB800E47090 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
|
||||
668B2560125D5C1C0060BF71 /* libz.dylib in Frameworks */,
|
||||
66BC000E12602359005A23F4 /* QuartzCore.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
256AC3D80F4B6AC300CF3369 /* InsideJobAppDelegate.h */,
|
||||
256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */,
|
||||
668B27F3125D96470060BF71 /* Interface */,
|
||||
668B2551125D59BF0060BF71 /* Model */,
|
||||
66BC033E1260CC68005A23F4 /* Views & Windows */,
|
||||
668B2559125D5BB90060BF71 /* Categories */,
|
||||
);
|
||||
path = Classes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
66BC000D12602359005A23F4 /* QuartzCore.framework */,
|
||||
668B255F125D5C1C0060BF71 /* libz.dylib */,
|
||||
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
|
||||
);
|
||||
name = "Linked Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
29B97324FDCFA39411CA2CEA /* AppKit.framework */,
|
||||
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
|
||||
29B97325FDCFA39411CA2CEA /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
19C28FACFE9D520D11CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D1107320486CEB800E47090 /* Inside Job.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29B97314FDCFA39411CA2CEA /* InsideJob */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6697ADA812B86A07001890C6 /* README.markdown */,
|
||||
080E96DDFE201D6D7F000001 /* Classes */,
|
||||
29B97315FDCFA39411CA2CEA /* Other Sources */,
|
||||
29B97317FDCFA39411CA2CEA /* Resources */,
|
||||
29B97323FDCFA39411CA2CEA /* Frameworks */,
|
||||
19C28FACFE9D520D11CA2CBB /* Products */,
|
||||
);
|
||||
name = InsideJob;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
256AC3F00F4B6AF500CF3369 /* InsideJob_Prefix.pch */,
|
||||
29B97316FDCFA39411CA2CEA /* main.m */,
|
||||
);
|
||||
name = "Other Sources";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29B97317FDCFA39411CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
66BC07711262823E005A23F4 /* Images */,
|
||||
8D1107310486CEB800E47090 /* InsideJob-Info.plist */,
|
||||
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
|
||||
1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
|
||||
66BC077212628257005A23F4 /* ItemPropertiesView.xib */,
|
||||
668B28D8125E370A0060BF71 /* Items.csv */,
|
||||
66BCFC2A125E9A51005A23F4 /* Credits.rtf */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
|
||||
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
668B2551125D59BF0060BF71 /* Model */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
668B27AD125D8EFD0060BF71 /* IJMinecraftLevel.h */,
|
||||
668B27AE125D8EFD0060BF71 /* IJMinecraftLevel.m */,
|
||||
668B27B0125D8F8E0060BF71 /* IJInventoryItem.h */,
|
||||
668B27B1125D8F8E0060BF71 /* IJInventoryItem.m */,
|
||||
668B2554125D5A3E0060BF71 /* NBTContainer.h */,
|
||||
668B2555125D5A3E0060BF71 /* NBTContainer.m */,
|
||||
);
|
||||
name = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
668B2559125D5BB90060BF71 /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
668B255A125D5BCA0060BF71 /* NSData+CocoaDevAdditions.h */,
|
||||
668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */,
|
||||
66BC04F612619072005A23F4 /* NSColor+Additions.h */,
|
||||
66BC04F712619072005A23F4 /* NSColor+Additions.m */,
|
||||
BA3329A7129889860079447B /* NSFileManager+DirectoryLocations.h */,
|
||||
BA3329A8129889860079447B /* NSFileManager+DirectoryLocations.m */,
|
||||
);
|
||||
name = Categories;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
668B27F3125D96470060BF71 /* Interface */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
668B27F0125D963F0060BF71 /* IJInventoryWindowController.h */,
|
||||
668B27F1125D963F0060BF71 /* IJInventoryWindowController.m */,
|
||||
66BC00011260215C005A23F4 /* IJInventoryView.h */,
|
||||
66BC00021260215C005A23F4 /* IJInventoryView.m */,
|
||||
66BC03601260D095005A23F4 /* IJItemPropertiesViewController.h */,
|
||||
66BC03611260D095005A23F4 /* IJItemPropertiesViewController.m */,
|
||||
);
|
||||
name = Interface;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
66BC033E1260CC68005A23F4 /* Views & Windows */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BA9186C91328C1C600769DEC /* IJTableView.h */,
|
||||
BA9186CA1328C1C600769DEC /* IJTableView.m */,
|
||||
66BC03391260CC59005A23F4 /* MAAttachedWindow.h */,
|
||||
66BC033A1260CC59005A23F4 /* MAAttachedWindow.m */,
|
||||
6697AD7012B86762001890C6 /* IJTableView.h */,
|
||||
6697AD7112B86762001890C6 /* IJTableView.m */,
|
||||
);
|
||||
name = "Views & Windows";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
66BC07711262823E005A23F4 /* Images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BA24598A1297428900F8B9C2 /* blockNotFound.png */,
|
||||
66BCFE61125FCEC6005A23F4 /* DataValuesV110Transparent.png */,
|
||||
66BCFC35125EA53E005A23F4 /* InsideJob.icns */,
|
||||
);
|
||||
path = Images;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8D1107260486CEB800E47090 /* Inside Job-SMP */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Inside Job-SMP" */;
|
||||
buildPhases = (
|
||||
8D1107290486CEB800E47090 /* Resources */,
|
||||
8D11072C0486CEB800E47090 /* Sources */,
|
||||
8D11072E0486CEB800E47090 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Inside Job-SMP";
|
||||
productInstallPath = "$(HOME)/Applications";
|
||||
productName = InsideJob;
|
||||
productReference = 8D1107320486CEB800E47090 /* Inside Job.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
ORGANIZATIONNAME = "Adam Preble";
|
||||
};
|
||||
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "InsideJob" */;
|
||||
compatibilityVersion = "Xcode 3.1";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
English,
|
||||
Japanese,
|
||||
French,
|
||||
German,
|
||||
fr,
|
||||
);
|
||||
mainGroup = 29B97314FDCFA39411CA2CEA /* InsideJob */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8D1107260486CEB800E47090 /* Inside Job-SMP */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
8D1107290486CEB800E47090 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
|
||||
1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */,
|
||||
668B290F125E40560060BF71 /* Items.csv in Resources */,
|
||||
66BCFC2B125E9A51005A23F4 /* Credits.rtf in Resources */,
|
||||
66BCFC36125EA53E005A23F4 /* InsideJob.icns in Resources */,
|
||||
66BCFE62125FCEC6005A23F4 /* DataValuesV110Transparent.png in Resources */,
|
||||
66BC077312628257005A23F4 /* ItemPropertiesView.xib in Resources */,
|
||||
BA24598B1297428900F8B9C2 /* blockNotFound.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8D11072C0486CEB800E47090 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D11072D0486CEB800E47090 /* main.m in Sources */,
|
||||
256AC3DA0F4B6AC300CF3369 /* InsideJobAppDelegate.m in Sources */,
|
||||
668B2556125D5A3E0060BF71 /* NBTContainer.m in Sources */,
|
||||
668B255C125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m in Sources */,
|
||||
668B27AF125D8EFD0060BF71 /* IJMinecraftLevel.m in Sources */,
|
||||
668B27B2125D8F8E0060BF71 /* IJInventoryItem.m in Sources */,
|
||||
668B27F2125D963F0060BF71 /* IJInventoryWindowController.m in Sources */,
|
||||
66BC00031260215C005A23F4 /* IJInventoryView.m in Sources */,
|
||||
66BC033B1260CC59005A23F4 /* MAAttachedWindow.m in Sources */,
|
||||
66BC03621260D095005A23F4 /* IJItemPropertiesViewController.m in Sources */,
|
||||
66BC04F812619072005A23F4 /* NSColor+Additions.m in Sources */,
|
||||
BA3329A9129889860079447B /* NSFileManager+DirectoryLocations.m in Sources */,
|
||||
BA9186CB1328C1C600769DEC /* IJTableView.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
089C165DFE840E0CC02AAC07 /* English */,
|
||||
D13FDB481322757D00D318D1 /* fr */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
1DDD58150DA1D0A300B32029 /* English */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
66BC077212628257005A23F4 /* ItemPropertiesView.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
66BC03631260D0B3005A23F4 /* English */,
|
||||
);
|
||||
name = ItemPropertiesView.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
C01FCF4B08A954540054247B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = InsideJob_Prefix.pch;
|
||||
INFOPLIST_FILE = "InsideJob-Info.plist";
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
PRODUCT_NAME = "Inside Job";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C01FCF4C08A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = InsideJob_Prefix.pch;
|
||||
INFOPLIST_FILE = "InsideJob-Info.plist";
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
PRODUCT_NAME = "Inside Job";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C01FCF4F08A954540054247B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = macosx10.6;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C01FCF5008A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = macosx10.6;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Inside Job-SMP" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C01FCF4B08A954540054247B /* Debug */,
|
||||
C01FCF4C08A954540054247B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "InsideJob" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C01FCF4F08A954540054247B /* Debug */,
|
||||
C01FCF5008A954540054247B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'InsideJob' target in the 'InsideJob' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
209
Items.csv
209
Items.csv
@ -1,209 +0,0 @@
|
||||
1,Stone
|
||||
2,Grass
|
||||
3,Dirt
|
||||
4,Cobblestone
|
||||
5,Wood
|
||||
6,Sapling
|
||||
7,Bedrock
|
||||
8,Water
|
||||
9,Stationary Water
|
||||
10,Lava
|
||||
11,Stationary Lava
|
||||
12,Sand
|
||||
13,Gravel
|
||||
14,Gold Ore
|
||||
15,Iron Ore
|
||||
16,Coal Ore
|
||||
17,Log
|
||||
18,Leaves
|
||||
19,Sponge
|
||||
20,Glass
|
||||
21,Lapis Lazuli Ore
|
||||
22,Lapis Lazuli Block
|
||||
23,Dispenser
|
||||
24,Sandstone
|
||||
25,Note Block
|
||||
35,Wool
|
||||
37,Yellow Flower
|
||||
38,Red Rose
|
||||
39,Brown Mushroom
|
||||
40,Red Mushroom
|
||||
41,Gold Block
|
||||
42,Iron Block
|
||||
43,Double Step
|
||||
44,Step
|
||||
# 44,Stone Step, 0
|
||||
# 44,Sandstone Step, 1
|
||||
# 44,Wodden Step, 2
|
||||
# 44,Cobblestone Step, 3
|
||||
45,Brick
|
||||
46,TNT
|
||||
47,Bookcase
|
||||
48,Mossy Cobblestone
|
||||
49,Obsidian
|
||||
50,Torch
|
||||
51,Fire
|
||||
52,Mob Spawner
|
||||
53,Wooden Stairs
|
||||
54,Chest
|
||||
55,Redstone Wire
|
||||
56,Diamond Ore
|
||||
57,Diamond Block
|
||||
58,Workbench
|
||||
59,Crops
|
||||
60,Soil
|
||||
61,Furnace
|
||||
62,Burning Furnace
|
||||
63,Sign Post
|
||||
64,Wooden Door
|
||||
65,Ladder
|
||||
66,Minecart Tracks
|
||||
67,Cobblestone Stairs
|
||||
68,Wall Sign
|
||||
69,Lever
|
||||
70,Stone Pressure Plate
|
||||
71,Iron Door
|
||||
72,Wooden Pressure Plate
|
||||
73,Redstone Ore
|
||||
74,Glowing Redstone Ore
|
||||
75,Redstone Torch (Off)
|
||||
76,Redstone Torch (On)
|
||||
77,Stone Button
|
||||
78,Snow
|
||||
79,Ice
|
||||
80,Snow Block
|
||||
81,Cactus
|
||||
82,Clay
|
||||
83,Reed
|
||||
84,Jukebox
|
||||
85,Fence
|
||||
86,Pumpkin
|
||||
87,Netherrack
|
||||
88,Soul Sand
|
||||
89,Glowstone
|
||||
90,Portal
|
||||
91,Jack-O-Lantern
|
||||
92,Cake Block
|
||||
93,Redstone Repeater (off)
|
||||
94,Redstone Repeater (on)
|
||||
256,Iron Spade
|
||||
257,Iron Pickaxe
|
||||
258,Iron Axe
|
||||
259,Flint and Steel
|
||||
260,Apple
|
||||
261,Bow
|
||||
262,Arrow
|
||||
263,Coal
|
||||
264,Diamond
|
||||
265,Iron Ingot
|
||||
266,Gold Ingot
|
||||
267,Iron Sword
|
||||
268,Wooden Sword
|
||||
269,Wooden Spade
|
||||
270,Wooden Pickaxe
|
||||
271,Wooden Axe
|
||||
272,Stone Sword
|
||||
273,Stone Spade
|
||||
274,Stone Pickaxe
|
||||
275,Stone Axe
|
||||
276,Diamond Sword
|
||||
277,Diamond Spade
|
||||
278,Diamond Pickaxe
|
||||
279,Diamond Axe
|
||||
280,Stick
|
||||
281,Bowl
|
||||
282,Mushroom Soup
|
||||
283,Gold Sword
|
||||
284,Gold Spade
|
||||
285,Gold Pickaxe
|
||||
286,Gold Axe
|
||||
287,String
|
||||
288,Feather
|
||||
289,Gunpowder
|
||||
290,Wooden Hoe
|
||||
291,Stone Hoe
|
||||
292,Iron Hoe
|
||||
293,Diamond Hoe
|
||||
294,Gold Hoe
|
||||
295,Seeds
|
||||
296,Wheat
|
||||
297,Bread
|
||||
298,Leather Helmet
|
||||
299,Leather Chestplate
|
||||
300,Leather Pants
|
||||
301,Leather Boots
|
||||
302,Chainmail Helmet
|
||||
303,Chainmail Chestplate
|
||||
304,Chainmail Pants
|
||||
305,Chainmail Boots
|
||||
306,Iron Helmet
|
||||
307,Iron Chestplate
|
||||
308,Iron Pants
|
||||
309,Iron Boots
|
||||
310,Diamond Helmet
|
||||
311,Diamond Chestplate
|
||||
312,Diamond Pants
|
||||
313,Diamond Boots
|
||||
314,Gold Helmet
|
||||
315,Gold Chestplate
|
||||
316,Gold Pants
|
||||
317,Gold Boots
|
||||
318,Flint
|
||||
319,Pork
|
||||
320,Grilled Pork
|
||||
321,Paintings
|
||||
322,Golden Apple
|
||||
323,Sign
|
||||
324,Wooden Door
|
||||
325,Bucket
|
||||
326,Water Bucket
|
||||
327,Lava Bucket
|
||||
328,Mine Cart
|
||||
329,Saddle
|
||||
330,Iron Door
|
||||
331,Redstone
|
||||
332,Snowball
|
||||
333,Boat
|
||||
334,Leather
|
||||
335,Milk Bucket
|
||||
336,Clay Brick
|
||||
337,Clay Balls
|
||||
338,Sugar Cane
|
||||
339,Paper
|
||||
340,Book
|
||||
341,Slime Ball
|
||||
342,Storage Minecart
|
||||
343,Powered Minecart
|
||||
344,Egg
|
||||
345,Compass
|
||||
346,Fishing Rod
|
||||
347,Watch
|
||||
348,Glowstone Dust
|
||||
349,Raw Fish
|
||||
350,Cooked Fish
|
||||
#Dye
|
||||
#351,Ink sack,0
|
||||
#351,Rose Red,1
|
||||
#351,Cactus Green,2
|
||||
#351,Brown,3
|
||||
#351,Lapis Lazuli Dye,4
|
||||
#351,Purple Dye,5
|
||||
#351,Cyan Dye,6
|
||||
#351,Light Gray Dye,7
|
||||
#351,Gray Dye,8
|
||||
#351,Pink Dye,9
|
||||
#351,Lime Dye,10
|
||||
#351,Dandelion Yellow Dye,11
|
||||
#351,Light Blue Dye,12
|
||||
#351,Magenta Dye,13
|
||||
#351,Orange Dye,14
|
||||
#351,Bone Meal,15
|
||||
351,Dye
|
||||
#Dye End
|
||||
352,Bone
|
||||
353,Sugar
|
||||
354,Cake
|
||||
355,Bed
|
||||
356,Redstone Repeater
|
||||
2256,Gold Record
|
||||
2257,Green Record
|
||||
|
Can't render this file because it has a wrong number of fields in line 35.
|
@ -1,96 +0,0 @@
|
||||
## Inside Job - SMP
|
||||
|
||||
### A Minecraft Alpha Inventory Editor for Mac OS X
|
||||
|
||||

|
||||
|
||||
Inside Job was written in early October 2010 by [Adam Preble](http://adampreble.net).
|
||||
|
||||
Management of SMP world added by [Manoel Trapier](http://www.godzil.net).
|
||||
|
||||
Features include:
|
||||
|
||||
- Native Cocoa interface.
|
||||
- Drag and drop inventory editing with item images.
|
||||
- Item list searchable by name or item number.
|
||||
- Experimental "time of day" editing.
|
||||
- Opening world from a folder
|
||||
|
||||
The goal of this fork of this application is to add support for SMP World, and by the way add support of new Beta 1.3 named worlds. This will never be the official version of InsideJobs, I have no pretention to add new functionnality other than the support of named world and edit SMP player.
|
||||
|
||||
### System Requirements
|
||||
|
||||
Mac OS X 10.6 Snow Leopard.
|
||||
|
||||
### Instructions
|
||||
|
||||
Inside Job operates on Minecraft's level.dat files, located in _~/Library/Application Support/minecraft/saves/*_. While Inside Job was written to interact with Minecraft's data as safely as possible, it's entirely possible that it will destroy it completely. Please back up your Minecraft saves folder before using Inside Job.
|
||||
|
||||
Inside Job-SMP have the particularity to automaticaly detect if the world have been used on a minecraft server, and allow you to select the differents players found on the server (and you can select too the default player found in the world "level.dat")
|
||||
|
||||
Be sure to save and exit any open Minecraft worlds before running Inside Job. Once run, Inside Job will open the first world and display your inventory. You can change worlds using Command-1 thru 5, or using the segmented control at the top of the main window. Note that Inside Job can only edit existing worlds.
|
||||
|
||||
To alter your inventory, use the item list at right to find the item you desire, then drag it into an inventory slot. Rearrange items by dragging them to different slots. To copy an item, including its quantity, hold the Option key when you start dragging.
|
||||
|
||||
Note that Inside Job works differently from the Minecraft inventory screen in that it does not "swap" items when dropping an item onto another. Instead, it replaces the item completely. If you drag an item into a slot already containing that item, the quantity will be increased accordingly, up to 64.
|
||||
|
||||
To alter the quantity or damage of a particular item, click on its inventory slot. To accept the changes, hit escape or click outside of the popup window.
|
||||
|
||||
After changing your inventory you will need to save the currently open world using the World menu, or Command-S. Once you have saved the world you can open it in Minecraft. Note that if a world is opened in Minecraft while it is open in Inside Job, you will need to re-open it by switching to another world before switching back. This is because Minecraft's file locking system gives write access to the last program to open it.
|
||||
|
||||
### Release Notes
|
||||
|
||||
#### 1.0.2-smp - March 11, 2011
|
||||
|
||||
- Now players .dat file are correctly listed and selectable, we even can save it!
|
||||
- Merges changes from Nickloose, we are now able to list SSP worlds and open them.
|
||||
- Minor other changes
|
||||
|
||||
#### 1.0.2-smp - March 5, 2011
|
||||
|
||||
- Major changes on world internal selection, we no longuer use World Index as ID, but the world path. We currently still have "slots" on the interface, but it should be changed soon to use a popup button with the list of worlds.
|
||||
- Now we have separated level.dat from player.dat for beeing SMP friendly.
|
||||
- Add missing Redstone repeater
|
||||
- Forked from official version
|
||||
|
||||
#### 1.0.2 - February 25, 2011
|
||||
|
||||
- Inside Job presently only supports worlds named "World1" thru "World5". Support for worlds with other names will be added in a future release.
|
||||
- Added 1.3 and 1.2 beta items, as well as "unknown item" image, thanks to Nick Loose!
|
||||
- Inside Job now allows negative damage values (such as -1000) to create indestructible items.
|
||||
- Streamlined keyboard item-adding: search with Command-F, down arrow to navigate to item, then return adds it to the first available inventory slot.
|
||||
|
||||
#### 1.0.1 - November 2, 2010
|
||||
|
||||
- Added Halloween update items (thanks to nickloose)
|
||||
- Improved safety of world saving
|
||||
- Now prompts to save when closing or moving away from an unsaved world
|
||||
|
||||
### Credits
|
||||
|
||||
Inside Job uses [Matt Gemmell](http://mattgemmell.com/)'s MAAttachedWindow. Item graphics were originally created by Mojang Specifications and compiled by Trojam and the Minecraft community.
|
||||
|
||||
### License
|
||||
|
||||
Inside Job is made available under the [MIT License](http://www.opensource.org/licenses/mit-license.html). Its source code can be found on GitHub: [http://github.com/godzil/InsideJob](). Original work can be found on GitHub: [http://github.com/preble/InsideJob]().
|
||||
|
||||
Copyright (c) 2010-2011 Adam Preble
|
||||
Parts Copyright (c) 2011 Manoël Trapier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@ -1,5 +0,0 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
"No world loaded." = "Aucun monde chargé.";
|
||||
"No world exists in that slot." = "Aucun mode dans ce slot";
|
||||
"Dismiss" = "Annuler";
|
||||
"Please create a new single player world in this slot using Minecraft and try again." = "Veuillez creer un monde en mode un joueur utilisant ce slot dans Minecraft, et essayez a nouveau.";
|
||||
86
index.css
Normal file
86
index.css
Normal file
@ -0,0 +1,86 @@
|
||||
body
|
||||
{
|
||||
margin-top: 1.0em;
|
||||
background-color: #fff;
|
||||
font-family: Lucida Grande,FreeSans,sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
color: #444;
|
||||
}
|
||||
|
||||
#container
|
||||
{
|
||||
margin: 0 auto;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
text-align: center;
|
||||
font-size: 2.5em;
|
||||
color: #000;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
h1 .small
|
||||
{
|
||||
font-size: 0.4em;
|
||||
}
|
||||
|
||||
h1 a
|
||||
{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h2
|
||||
{
|
||||
font-size: 1.5em;
|
||||
color: #444;
|
||||
letter-spacing: 4px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
h3
|
||||
{
|
||||
text-align: center;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.download a
|
||||
{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.description
|
||||
{
|
||||
font-size: 1.0em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 15px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
background: #000;
|
||||
color: #ccc;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: 0;
|
||||
width: 80%;
|
||||
border-bottom: 1px solid #aaa
|
||||
}
|
||||
|
||||
.footer
|
||||
{
|
||||
text-align: center;
|
||||
font-size: 0.8em;
|
||||
padding-top: 30px;
|
||||
font-style: italic;
|
||||
color: #aaa;
|
||||
}
|
||||
86
index.html
Normal file
86
index.html
Normal file
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
<title>godzil/InsideJob @ GitHub</title>
|
||||
|
||||
<style type="text/css"media="screen">
|
||||
@import url("index.css");
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-22057036-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a href="http://github.com/godzil/InsideJob"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<h1><a href="http://github.com/godzil/InsideJob">Inside Job - SMP</a></h1>
|
||||
|
||||
<div class="description">
|
||||
Inside Job is a Minecraft inventory editor for Mac OS X 10.6 written by <a href="http://adampreble.net/">Adam Preble</a>.
|
||||
</div>
|
||||
<div class="description">
|
||||
Management of SMP world added by <a href="http://www.godzil.net">Manoel Trapier</a>.
|
||||
</div>
|
||||
|
||||
<img src="InsideJob.png" />
|
||||
|
||||
<p>
|
||||
Instructions, release notes, and the full license text (MIT License) are available <a href="http://github.com/godzil/InsideJob/blob/master/README.markdown">here</a>.
|
||||
</p>
|
||||
|
||||
<h2>Download Inside Job</h2>
|
||||
<div class="download">
|
||||
<table border="0" cellspacing="10">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/downloads/Godzil/InsideJob/Inside%20Job.zip">
|
||||
<img border="0" width="90" src="http://github.com/images/modules/download/zip.png"><br/>v1.0.2-SMP</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Source Code</h2>
|
||||
<p>
|
||||
The source code to Inside Job is made available under the MIT License.
|
||||
You can download this project in either
|
||||
<a href="http://github.com/godzil/InsideJob/zipball/master">zip</a> or
|
||||
<a href="http://github.com/godzil/InsideJob/tarball/master">tar</a> formats.
|
||||
</p>
|
||||
<p>You can also clone the project with <a href="http://git-scm.com">Git</a> by running:
|
||||
<pre>$ git clone git://github.com/godzil/InsideJob</pre>
|
||||
</p>
|
||||
|
||||
<h2>Support</h2>
|
||||
<p>
|
||||
Please report issues with Inside Job by <a href="http://github.com/godzil/InsideJob/issues">creating an issue on GitHub</a>.
|
||||
</p>
|
||||
|
||||
<div class="footer">
|
||||
get the source code on GitHub : <a href="http://github.com/godzil/InsideJob">godzil/InsideJob</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
14
main.m
14
main.m
@ -1,14 +0,0 @@
|
||||
//
|
||||
// main.m
|
||||
// InsideJob
|
||||
//
|
||||
// Created by Adam Preble on 10/6/10.
|
||||
// Copyright 2010 Adam Preble. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, (const char **) argv);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user