// // logo.m // LOGOSX // // Created by Micah Acinapura on Fri May 23 2003. // Copyright (c) 2003 __MyCompanyName__. All rights reserved. // #import "logo.h" #import #import "logosxBezelDisplay.h" @implementation logo //window/initilization stuff - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code. turtle.size.height = 16.0; turtle.size.width = 16.0; turtle.origin.x = 120.0; turtle.origin.y = 100.0; //init turtle picture NSString *filePath = [[NSBundle mainBundle] pathForResource:@"turtle" ofType:@"gif"]; turtlePic = [[NSImage alloc] initWithContentsOfFile:filePath]; //[turtlePic initWithContentsOfFile:@"turtle.gif"]; if(!colorBeenSet) { //initial colors turtle_color = [[NSColor whiteColor] retain]; line_color = [[NSColor redColor] retain]; background = [[NSColor blueColor] retain]; } //init arrays legnths = [[NSMutableArray alloc] init]; pen_states = [[NSMutableArray alloc] init]; turns = [[NSMutableArray alloc] init]; //initialize the variables angle = 90; noTurtle = FALSE; noBackground = FALSE; pen_down = TRUE; step = 0; level = 0; //bezier path initilization [NSBezierPath setDefaultLineCapStyle:NSRoundLineCapStyle]; [NSBezierPath setDefaultLineJoinStyle:NSRoundLineJoinStyle]; [turtlePoo setWindingRule: NSNonZeroWindingRule]; [turtlePoo setLineWidth:5]; turtlePoo = [[NSBezierPath bezierPath] retain]; [turtlePoo moveToPoint:turtle.origin]; } return self; } -(void)showBezel { bezel = [[logosxBezelDisplay alloc] init]; [bezel displayNotification]; } - (void)drawRect:(NSRect)rect { if (!noBackground) { //draw background [background set]; [[NSBezierPath bezierPathWithRect:[self bounds]] fill]; } if (!noTurtle) { //draw turtle [turtle_color set]; //[[NSBezierPath bezierPathWithRect:turtle] fill]; [turtlePic compositeToPoint:turtle.origin operation:NSCompositeSourceOver]; } //draw lines [line_color set]; [turtlePoo stroke]; } //constant functions - (int)get_step { return step; } //modifying functions - (void)forward:(id)sender { //Determine new point NSPoint tmp; tmp.x = turtle.origin.x + (legnth * cos( (angle*3.14159)/180) ); tmp.y = turtle.origin.y + (legnth * sin( (angle*3.14159)/180) ); turtle.origin = tmp; //move/line to that point if(pen_down) { [turtlePoo lineToPoint:turtle.origin]; [pen_states addObject:[NSNumber numberWithInt:1]]; } else { [turtlePoo moveToPoint:turtle.origin]; [pen_states addObject:[NSNumber numberWithInt:0]]; } //add this step to the arrays storing each step [legnths addObject:[NSNumber numberWithInt:legnth]]; [turns addObject:[NSNumber numberWithInt:angle]]; ++step; [self setNeedsDisplay:YES]; } - (void)set_width:(id)sender { [turtlePoo setLineWidth:[sender floatValue]]; [self setNeedsDisplay:YES]; } - (void)set_legnth:(id)sender { legnth = [sender floatValue]; } - (void)set_angle:(id)sender { int tmp = [sender floatValue]; angle -= tmp ; } - (void)flip_pen:(id)sender { pen_down = !pen_down; } //this is to display/not_display the background - (void)flipBackground:(id)sender { noBackground = !noBackground; [self setNeedsDisplay:YES]; } //same for the turtle - (void)flipTurtle:(id)sender { noTurtle = !noTurtle; [self setNeedsDisplay:YES]; } - (void)change_back_color:(id)sender { [background autorelease]; background = [[sender color] retain]; [self setNeedsDisplay:YES]; colorBeenSet = TRUE; } - (void)change_line_color:(id)sender { [line_color autorelease]; line_color = [[sender color] retain]; [self setNeedsDisplay:YES]; colorBeenSet = TRUE; } - (void)dealloc { [line_color release]; [background release]; [super dealloc]; } -(BOOL)checkCommand:(NSString *)command { NSString * tmpCommand = command; BOOL validCommand = TRUE; NSCharacterSet *validChars = [NSCharacterSet characterSetWithCharactersInString:@"0123456789[]FfDdUuLlRr"]; int i = 0; while(i<[tmpCommand length]) { if(![validChars characterIsMember:[tmpCommand characterAtIndex:i]]) { validCommand = FALSE; } ++i; } return validCommand; } //internals //this one is for the undo function it takes the arrays populated w/data and rebuilds the path //i also use it to execute the processed command strings -(NSString *)reconstruct { NSString * err = @"all good"; //debgging string int k; NSPoint pt; pt.x = 125.0; pt.y = 100.0; turtle.origin = pt; int tangle = 90; int t1=0; [turtlePoo removeAllPoints]; //clear [turtlePoo moveToPoint:turtle.origin]; //start again for(k=0;k 0) //so dont we dont try to remove/undo steps/arrayIndicies that arent there (negative valuess) { --step; [legnths removeObjectAtIndex:k]; [turns removeObjectAtIndex:k]; [pen_states removeObjectAtIndex:k]; } else { err = @"no steps to undo"; } [self setNeedsDisplay:YES]; return err; } //this parses the command strings and then fills the arrays w/data, then calls reconstruct to draw the path -(NSString *)executeCommand:(NSString *)command { NSString * tmp = [[command stringByAppendingString:@"*"] uppercaseString]; //temp takes the command string NSString *val; //character sets, i'm cheating here the *letters charSet should be @"RLFDU" NSCharacterSet *nums = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet *letters = [NSCharacterSet letterCharacterSet]; //now i have to parse the string and translate it into my commands //theres probablly a better way to do this with a tokenizer or somthin but i'll use this old method. int i; for(i=0;i<[tmp length];++i) { if(i>0){--i;} unichar token = [tmp characterAtIndex:i]; if( [letters characterIsMember:token] ) //if there is a command { //val = @"found command character"; ++i; int k=0; unichar partials[4]; //this is to convert the values from commands to strings, since 9999 would go off the screen i figured it would be highenough while( [nums characterIsMember:[tmp characterAtIndex:i]] ) //while there is a value to snarf { partials[k] = [tmp characterAtIndex:i]; ++i; ++k; } val = [NSString stringWithCharacters:partials length:k]; //val now holds the commands value int tr=1;//ture int fls=0;//false these are he from when i was debugging you just use 1 and 0 down below switch (token) { //i think these are self-explanority case 'F': [legnths addObject:[NSNumber numberWithInt:[val intValue]]]; [turns addObject:[NSNumber numberWithInt:angle]]; if(pen_down) { [pen_states addObject:[NSNumber numberWithInt:tr]]; } else { [pen_states addObject:[NSNumber numberWithInt:fls]]; } ++step; break; case 'R': angle -= [val intValue]; break; case 'L': angle += [val intValue]; break; case 'U': pen_down = FALSE; break; case 'D': pen_down = TRUE; } } else { if(token == '[') { //increase the level of recursion ++level; unsigned int temp = level; //val = @"repeat found"; //theres gotta be a better way of doing this but i can't seem to get NSString to work with unichars, only unichar arrays, arg! unichar repeat[500]; ++i; int k=0; while( (level !=0) ) { repeat[k] = [tmp characterAtIndex:i]; ++i; ++k; //this is so and inside ']' dont end the current repeating command if ([tmp characterAtIndex:i] == '[') ++level; if ([tmp characterAtIndex:i] == ']') --level; temp=level; } ++i; NSString *exe = [NSString stringWithCharacters:repeat length:k]; k=0; unichar partials[4]; //this is to convert the values from commands to strings, since 9999 would go off the screen i figured it would be highenough while( [nums characterIsMember:[tmp characterAtIndex:i]] ) //while there is a value to snarf { partials[k] = [tmp characterAtIndex:i]; ++i; ++k; } NSString *times = [NSString stringWithCharacters:partials length:k]; //val now holds number of repeats //val = [NSString stringWithString:times]; //now execute the command val times; recursion :) for(k=0;k<[times intValue];++k) { [self executeCommand:exe]; } } else { val = [tmp stringByAppendingString:@"invalid command string"]; //duh } } } ++step; //add a bogus step for recrunstruct to undo [legnths addObject:[NSNumber numberWithInt:0]]; [turns addObject:[NSNumber numberWithInt:0]]; [pen_states addObject:[NSNumber numberWithInt:1]]; return val; } @end