#import "Document.h" #import "PieceView.h" @interface Document (Private) - adjacent; - dragCluster:(BTree *)cluster offs:(float *)delta superview:(NSView *)sv; - (BOOL)loadError:(NSString *)msg; - (NSWindow*)makeWindow; @end static NSArray *types = nil; @implementation Document static NSMenu *_action_menu = nil; + actionMenu { if(_action_menu==nil){ NSMenu *menu = [[NSMenu alloc] initWithTitle:_(@"Action")]; [[menu addItemWithTitle: _(@"Scramble") action: @selector (scramble:) keyEquivalent: @""] setTag:MENU_SCRAMBLE]; [[menu addItemWithTitle: _(@"Verify") action: @selector (verify:) keyEquivalent: @""] setTag:MENU_VERIFY]; [[menu addItemWithTitle: _(@"Solve") action: @selector (solve:) keyEquivalent: @""] setTag:MENU_SOLVE]; _action_menu = menu; RETAIN(_action_menu); } return _action_menu; } static NSPanel *_stopper_panel = nil; #define STOP_WIDTH 150 #define STOP_HEIGHT 30 + stopperForDocument:(Document *)doc { if(_stopper_panel==nil){ _stopper_panel = [[NSPanel alloc] initWithContentRect: NSMakeRect(0, 0, STOP_WIDTH, STOP_HEIGHT) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; [_stopper_panel setReleasedWhenClosed:NO]; NSButton *_stopper; _stopper = [NSButton new]; // [_stopper setTransparent:YES]; [_stopper setTitle:@"Stop"]; [_stopper setAction:@selector(stopSolve:)]; [_stopper_panel setContentView:_stopper]; } [[_stopper_panel contentView] setTarget:doc]; NSRect wframe = [[[[doc windowControllers] objectAtIndex:0] window] frame]; NSPoint sorigin = NSMakePoint (wframe.origin.x+wframe.size.width/2 - STOP_WIDTH/2, wframe.origin.y+wframe.size.height/2 - STOP_HEIGHT/2); [_stopper_panel setFrameOrigin:sorigin]; return _stopper_panel; } - init { if(types==nil){ types = [NSArray arrayWithObjects:@"tiff", @"TIFF", @"png", @"PNG", @"jpg", @"JPG", @"jpeg", @"JPEG", nil]; RETAIN(types); } solving = NO; done = NO; [super init]; return self; } - (void) dealloc { [super dealloc]; } - (int)setDone:(int)flag { int prev = done; if(prev!=flag){ int c, ccount = [clusters count]; for(c=0; c 1){ unsigned c[2]; BTree *cl1 = [processed objectAtIndex:0], *cl2 = [processed objectAtIndex:1], *newCluster; // clusters are already adjacent newCluster = [[BTree alloc] initWithPairFirst:cl1 andSecond:cl2]; // prepend [processed removeObjectAtIndex:0]; [processed replaceObjectAtIndex:0 withObject:newCluster]; } all = [processed objectAtIndex:0]; [all inorderWithPointer:(void *)all sel:@selector(setCluster:)]; [clusters replaceObjectsInRange: NSMakeRange(0, pc) withObjectsFromArray:processed]; if(complete==YES){ [self setDone:YES]; [sv setNeedsDisplay:YES]; }; solving = NO; [sender setTitle:_(@"Solve")]; [self updateChangeCount:NSChangeDone]; // [[view window] setDocumentEdited:YES]; return self; } - (NSMutableArray *)clusters { return clusters; } - (NSData *)dataRepresentationOfType:(NSString *)aType { NSString *msg; if([aType isEqualToString:DOCTYPE]){ NSString *trees = @"", *pieces = @"", *all; int clind, pind; BTree *cluster; PieceView *piece; NSMutableArray *leaves; for(clind=0; clind<[clusters count]; clind++){ cluster = [clusters objectAtIndex:clind]; trees = [trees stringByAppendingString: [cluster toString]]; leaves = [cluster leaves]; for(pind=0; pind<[leaves count]; pind++){ piece = [leaves objectAtIndex:pind]; pieces = [pieces stringByAppendingString: [piece toString]]; } } [[view window] saveFrameUsingName:[self fileName]]; all = [NSString stringWithFormat:@"%@\n%d %d %d %d %d\n", nameOfImageFile, piece_width, piece_height, px, py, [clusters count]]; all = [all stringByAppendingString:trees]; all = [all stringByAppendingString:pieces]; return [all dataUsingEncoding:NSASCIIStringEncoding]; } else{ msg = [NSString stringWithFormat: @"Unknown type: %@", [aType uppercaseString]]; NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil); return nil; } } - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType { NSString *msg; NSSize size; int x, y; PieceView *piece; BTree *cluster; int horizontal[DIM_MAX][DIM_MAX]; int vertical[DIM_MAX][DIM_MAX]; if([aType isEqualToString:DOCTYPE]){ NSArray *lines = [[NSString stringWithCString:[data bytes] length:[data length]] componentsSeparatedByString:@"\n"]; NSEnumerator *en = [lines objectEnumerator]; NSString *line; NSScanner *scanner; int clcount, clind, lind; NSMutableDictionary *pdict; int x, y, ktag, posx, posy; NSPoint *loc; PTYPE left, right, lower, upper; image = nil; clusters = nil; if((line = [en nextObject])==nil){ return [self loadError:@"File name is missing"]; } if ((image = [[NSImage alloc] initWithContentsOfFile:line])==nil){ msg = [NSString stringWithFormat: @"Load failed (IMAGE)", data]; return [self loadError:msg]; } nameOfImageFile = [line copy]; size = [image size]; if((line = [en nextObject])==nil){ return [self loadError:@"Image dimensions missing"]; } scanner = [NSScanner scannerWithString:line]; if([scanner scanInt:&piece_width]==NO || [scanner scanInt:&piece_height]==NO || [scanner scanInt:&px]==NO || [scanner scanInt:&py]==NO || [scanner scanInt:&clcount]==NO || pxDIM_MAX-1 || pyDIM_MAX-1 || clcount<1 || clcount>px*py){ return [self loadError: @"Image dimensions/clusters out of range"]; } clusters = [NSMutableArray arrayWithCapacity:clcount]; for(clind=0; clindDIM_MAX-1 || py>DIM_MAX-1){ [image dealloc]; NSRunAlertPanel(@"Alert", @"Image too large (IMAGE)", @"Ok", nil, nil); return NO; } // horizontal for(y=0; y0 ? (_v) : -(_v)) if(ABSF(delta[0])>ABSF(delta[1])){ if(delta[0]<0){ steps = -delta[0]; dx = -1; } else{ steps = delta[0]; dx = 1; } dy = delta[1]/(float)steps; } else{ if(delta[1]<0){ steps = -delta[1]; dy = -1; } else{ steps = delta[1]; dy = 1; } dx = delta[0]/(float)steps; } [sv lockFocus]; for(step = 0; step < steps; step+=TICK){ if(first==NO){ [win restoreCachedImage]; } first = NO; cur[0] = step*dx; cur[1] = step*dy; bbox.origin.x = orig.x + cur[0]; bbox.origin.y = orig.y + cur[1]; wbbox = [sv convertRect:bbox toView:nil]; [win cacheImageInRect:wbbox]; [cluster inorderWithPointer:cur sel:@selector(outline:)]; [win flushWindow]; } [win restoreCachedImage]; [win flushWindow]; [sv unlockFocus]; return self; } - (NSWindow*)makeWindow { NSWindow *window; NSRect frame; int m = (NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask); int clind, pieceind; BTree *cluster; NSScrollView *scroller; NSSize scrollSize, desktop; NSString *fname; frame.origin.x = 0; frame.origin.y = 0; frame.size = [image size]; frame.size.width += 2*(BOUNDARY+DESKTOPEXTRA); frame.size.height += 2*(BOUNDARY+DESKTOPEXTRA); desktop = frame.size; view = [[NSView alloc] initWithFrame:frame]; for(clind=0; clind<[clusters count]; clind++){ cluster = [clusters objectAtIndex:clind]; [cluster inorderWithTarget:view sel:@selector(addSubview:)]; } [view setMenu:[Document actionMenu]]; NSSize initialSize = NSMakeSize((desktop.width