}
/* ----------------------------------------------------------------------
+ * About box.
+ */
+
+@class AboutBox;
+
+@interface AboutBox : NSWindow
+{
+}
+- (id)init;
+@end
+
+@implementation AboutBox
+- (id)init
+{
+ NSRect totalrect;
+ NSView *views[16];
+ int nviews = 0;
+ NSImageView *iv;
+ NSTextField *tf;
+ NSFont *font1 = [NSFont systemFontOfSize:0];
+ NSFont *font2 = [NSFont boldSystemFontOfSize:[font1 pointSize] * 1.1];
+ const int border = 24;
+ int i;
+ double y;
+
+ /*
+ * Construct the controls that go in the About box.
+ */
+
+ iv = [[NSImageView alloc] initWithFrame:NSMakeRect(0,0,64,64)];
+ [iv setImage:[NSImage imageNamed:@"NSApplicationIcon"]];
+ views[nviews++] = iv;
+
+ tf = [[NSTextField alloc]
+ initWithFrame:NSMakeRect(0,0,400,1)];
+ [tf setEditable:NO];
+ [tf setSelectable:NO];
+ [tf setBordered:NO];
+ [tf setDrawsBackground:NO];
+ [tf setFont:font2];
+ [tf setStringValue:@"Simon Tatham's Portable Puzzle Collection"];
+ [tf sizeToFit];
+ views[nviews++] = tf;
+
+ tf = [[NSTextField alloc]
+ initWithFrame:NSMakeRect(0,0,400,1)];
+ [tf setEditable:NO];
+ [tf setSelectable:NO];
+ [tf setBordered:NO];
+ [tf setDrawsBackground:NO];
+ [tf setFont:font1];
+ [tf setStringValue:[NSString stringWithCString:ver]];
+ [tf sizeToFit];
+ views[nviews++] = tf;
+
+ /*
+ * Lay the controls out.
+ */
+ totalrect = NSMakeRect(0,0,0,0);
+ for (i = 0; i < nviews; i++) {
+ NSRect r = [views[i] frame];
+ if (totalrect.size.width < r.size.width)
+ totalrect.size.width = r.size.width;
+ totalrect.size.height += border + r.size.height;
+ }
+ totalrect.size.width += 2 * border;
+ totalrect.size.height += border;
+ y = totalrect.size.height;
+ for (i = 0; i < nviews; i++) {
+ NSRect r = [views[i] frame];
+ r.origin.x = (totalrect.size.width - r.size.width) / 2;
+ y -= border + r.size.height;
+ r.origin.y = y;
+ [views[i] setFrame:r];
+ }
+
+ self = [super initWithContentRect:totalrect
+ styleMask:(NSTitledWindowMask | NSMiniaturizableWindowMask |
+ NSClosableWindowMask)
+ backing:NSBackingStoreBuffered
+ defer:YES];
+
+ for (i = 0; i < nviews; i++)
+ [[self contentView] addSubview:views[i]];
+
+ [self center]; /* :-) */
+
+ return self;
+}
+@end
+
+/* ----------------------------------------------------------------------
* The front end presented to midend.c.
*
* This is mostly a subclass of NSWindow. The actual `frontend'
- (void)keyDown:(NSEvent *)ev;
- (void)activateTimer;
- (void)deactivateTimer;
-- (void)setStatusLine:(NSString *)text;
+- (void)setStatusLine:(char *)text;
@end
@implementation MyImageView
frame.origin.y = 0;
frame.origin.x = 0;
- midend_size(me, &w, &h);
+ w = h = INT_MAX;
+ midend_size(me, &w, &h, FALSE);
frame.size.width = w;
frame.size.height = h;
* initWithGame: simply call that one and pass it NULL.
*/
midend_new_game(me);
- midend_size(me, &w, &h);
+ w = h = INT_MAX;
+ midend_size(me, &w, &h, FALSE);
rect.size.width = w;
rect.size.height = h;
* function key codes.
*/
if (c >= 0x80) {
+ int mods = FALSE;
switch (c) {
case NSUpArrowFunctionKey:
c = CURSOR_UP;
+ mods = TRUE;
break;
case NSDownArrowFunctionKey:
c = CURSOR_DOWN;
+ mods = TRUE;
break;
case NSLeftArrowFunctionKey:
c = CURSOR_LEFT;
+ mods = TRUE;
break;
case NSRightArrowFunctionKey:
c = CURSOR_RIGHT;
+ mods = TRUE;
break;
default:
continue;
}
+
+ if (mods) {
+ if ([ev modifierFlags] & NSShiftKeyMask)
+ c |= MOD_SHFT;
+ if ([ev modifierFlags] & NSControlKeyMask)
+ c |= MOD_CTRL;
+ }
}
+ if (c >= '0' && c <= '9' && ([ev modifierFlags] & NSNumericPadKeyMask))
+ c |= MOD_NUM_KEYPAD;
+
[self processButton:c x:-1 y:-1];
}
}
}
- (void)restartGame:(id)sender
{
- [self processButton:'r' x:-1 y:-1];
+ midend_restart_game(me);
}
- (void)undoMove:(id)sender
{
NSBeep();
}
+- (void)solveGame:(id)sender
+{
+ char *msg;
+ NSAlert *alert;
+
+ msg = midend_solve(me);
+
+ if (msg) {
+ alert = [[[NSAlert alloc] init] autorelease];
+ [alert addButtonWithTitle:@"Bah"];
+ [alert setInformativeText:[NSString stringWithCString:msg]];
+ [alert beginSheetModalForWindow:self modalDelegate:nil
+ didEndSelector:nil contextInfo:nil];
+ }
+}
+
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
if ([item action] == @selector(copy:))
return (ourgame->can_format_as_text ? YES : NO);
+ else if ([item action] == @selector(solveGame:))
+ return (ourgame->can_solve ? YES : NO);
else
return [super validateMenuItem:item];
}
NSSize size = {0,0};
int w, h;
- midend_size(me, &w, &h);
+ w = h = INT_MAX;
+ midend_size(me, &w, &h, FALSE);
size.width = w;
size.height = h;
- (void)specificGame:(id)sender
{
+ [self startConfigureSheet:CFG_DESC];
+}
+
+- (void)specificRandomGame:(id)sender
+{
[self startConfigureSheet:CFG_SEED];
}
[self sheetEndWithStatus:NO];
}
-- (void)setStatusLine:(NSString *)text
+- (void)setStatusLine:(char *)text
{
- [[status cell] setTitle:text];
+ char *rewritten = midend_rewrite_statusbar(me, text);
+ [[status cell] setTitle:[NSString stringWithCString:rewritten]];
+ sfree(rewritten);
}
@end
else
[path stroke];
}
+void draw_circle(frontend *fe, int cx, int cy, int radius,
+ int fill, int colour)
+{
+ NSBezierPath *path = [NSBezierPath bezierPath];
+
+ [[NSGraphicsContext currentContext] setShouldAntialias:YES];
+
+ assert(colour >= 0 && colour < fe->ncolours);
+ [fe->colours[colour] set];
+
+ [path appendBezierPathWithArcWithCenter:NSMakePoint(cx + 0.5, cy + 0.5)
+ radius:radius startAngle:0.0 endAngle:360.0];
+
+ [path closePath];
+
+ if (fill)
+ [path fill];
+ else
+ [path stroke];
+}
void draw_line(frontend *fe, int x1, int y1, int x2, int y2, int colour)
{
NSBezierPath *path = [NSBezierPath bezierPath];
[string drawAtPoint:point withAttributes:attr];
}
+struct blitter {
+ int w, h;
+ int x, y;
+ NSImage *img;
+};
+blitter *blitter_new(int w, int h)
+{
+ blitter *bl = snew(blitter);
+ bl->x = bl->y = -1;
+ bl->w = w;
+ bl->h = h;
+ bl->img = [[NSImage alloc] initWithSize:NSMakeSize(w, h)];
+ [bl->img setFlipped:YES];
+ return bl;
+}
+void blitter_free(blitter *bl)
+{
+ [bl->img release];
+ sfree(bl);
+}
+void blitter_save(frontend *fe, blitter *bl, int x, int y)
+{
+ [fe->image unlockFocus];
+ [bl->img lockFocus];
+ [fe->image drawInRect:NSMakeRect(0, 0, bl->w, bl->h)
+ fromRect:NSMakeRect(x, y, bl->w, bl->h)
+ operation:NSCompositeCopy fraction:1.0];
+ [bl->img unlockFocus];
+ [fe->image lockFocus];
+ bl->x = x;
+ bl->y = y;
+}
+void blitter_load(frontend *fe, blitter *bl, int x, int y)
+{
+ if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) {
+ x = bl->x;
+ y = bl->y;
+ }
+ [bl->img drawInRect:NSMakeRect(x, y, bl->w, bl->h)
+ fromRect:NSMakeRect(0, 0, bl->w, bl->h)
+ operation:NSCompositeCopy fraction:1.0];
+}
void draw_update(frontend *fe, int x, int y, int w, int h)
{
[fe->view setNeedsDisplayInRect:NSMakeRect(x,y,w,h)];
void status_bar(frontend *fe, char *text)
{
- [fe->window setStatusLine:[NSString stringWithCString:text]];
+ [fe->window setStatusLine:text];
}
/* ----------------------------------------------------------------------
{
}
- (void)newGameWindow:(id)sender;
+- (void)about:(id)sender;
@end
@implementation AppController
[win makeKeyAndOrderFront:self];
}
+- (void)about:(id)sender
+{
+ id win;
+
+ win = [[AboutBox alloc] init];
+ [win makeKeyAndOrderFront:self];
+}
+
- (NSMenu *)applicationDockMenu:(NSApplication *)sender
{
NSMenu *menu = newmenu("Dock Menu");
[NSApp setMainMenu: newmenu("Main Menu")];
menu = newsubmenu([NSApp mainMenu], "Apple Menu");
+ item = newitem(menu, "About Puzzles", "", NULL, @selector(about:));
+ [menu addItem:[NSMenuItem separatorItem]];
[NSApp setServicesMenu:newsubmenu(menu, "Services")];
[menu addItem:[NSMenuItem separatorItem]];
item = newitem(menu, "Hide Puzzles", "h", NSApp, @selector(hide:));
item = newitem(menu, "New Game", "n", NULL, @selector(newGame:));
item = newitem(menu, "Restart Game", "r", NULL, @selector(restartGame:));
item = newitem(menu, "Specific Game", "", NULL, @selector(specificGame:));
+ item = newitem(menu, "Specific Random Seed", "", NULL,
+ @selector(specificRandomGame:));
[menu addItem:[NSMenuItem separatorItem]];
{
NSMenu *submenu = newsubmenu(menu, "New Window");
item = newitem(menu, "Cut", "x", NULL, @selector(cut:));
item = newitem(menu, "Copy", "c", NULL, @selector(copy:));
item = newitem(menu, "Paste", "v", NULL, @selector(paste:));
+ [menu addItem:[NSMenuItem separatorItem]];
+ item = newitem(menu, "Solve", "S-s", NULL, @selector(solveGame:));
menu = newsubmenu([NSApp mainMenu], "Type");
typemenu = menu;