nkeynes@681 | 1 | /**
|
nkeynes@681 | 2 | * $Id$
|
nkeynes@681 | 3 | *
|
nkeynes@681 | 4 | * Construct and maintain the main window under cocoa.
|
nkeynes@681 | 5 | *
|
nkeynes@681 | 6 | * Copyright (c) 2008 Nathan Keynes.
|
nkeynes@681 | 7 | *
|
nkeynes@681 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@681 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@681 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@681 | 11 | * (at your option) any later version.
|
nkeynes@681 | 12 | *
|
nkeynes@681 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@681 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@681 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@681 | 16 | * GNU General Public License for more details.
|
nkeynes@681 | 17 | */
|
nkeynes@681 | 18 |
|
nkeynes@681 | 19 | #include "cocoaui/cocoaui.h"
|
nkeynes@681 | 20 | #include "lxdream.h"
|
nkeynes@681 | 21 | #include <ApplicationServices/ApplicationServices.h>
|
nkeynes@681 | 22 |
|
nkeynes@757 | 23 | @interface NSWindow (OSX10_5_and_later)
|
nkeynes@757 | 24 | #ifndef CGFLOAT_DEFINED
|
nkeynes@757 | 25 | # ifdef __LP64__
|
nkeynes@757 | 26 | typedef double CGFloat;
|
nkeynes@757 | 27 | # else
|
nkeynes@757 | 28 | typedef float CGFloat;
|
nkeynes@757 | 29 | # endif
|
nkeynes@757 | 30 | #endif
|
nkeynes@757 | 31 | - (void)setAutorecalculatesContentBorderThickness:(BOOL)b forEdge:(NSRectEdge)e;
|
nkeynes@757 | 32 | - (void)setContentBorderThickness:(CGFloat)b forEdge:(NSRectEdge)e;
|
nkeynes@757 | 33 | @end
|
nkeynes@757 | 34 |
|
nkeynes@757 | 35 |
|
nkeynes@757 | 36 | #if NSAppKitVersionNumber > NSAppKitVersionNumber10_4
|
nkeynes@757 | 37 |
|
nkeynes@757 | 38 | #endif
|
nkeynes@757 | 39 |
|
nkeynes@705 | 40 | #define STATUSBAR_HEIGHT 25
|
nkeynes@705 | 41 | #define STATUS_TEXT_HEIGHT 22
|
nkeynes@681 | 42 |
|
nkeynes@681 | 43 | @interface LxdreamToolbarDelegate : NSObject {
|
nkeynes@681 | 44 | NSArray *identifiers;
|
nkeynes@681 | 45 | NSArray *defaults;
|
nkeynes@681 | 46 | NSDictionary *items;
|
nkeynes@681 | 47 | }
|
nkeynes@681 | 48 | - (NSToolbarItem *) createToolbarItem: (NSString *)id label: (NSString *) label
|
nkeynes@736 | 49 | tooltip: (NSString *)tooltip
|
nkeynes@736 | 50 | icon: (NSString *)icon action: (SEL) action;
|
nkeynes@681 | 51 | @end
|
nkeynes@681 | 52 |
|
nkeynes@681 | 53 | @implementation LxdreamToolbarDelegate
|
nkeynes@681 | 54 | - (id) init
|
nkeynes@681 | 55 | {
|
nkeynes@681 | 56 | NSToolbarItem *mount = [self createToolbarItem: @"GdromMount" label: @"Open Image"
|
nkeynes@681 | 57 | tooltip: @"Mount a cdrom disc" icon: @"tb-cdrom"
|
nkeynes@681 | 58 | action: @selector(mount_action:)];
|
nkeynes@681 | 59 | NSToolbarItem *reset = [self createToolbarItem: @"Reset" label: @"Reset"
|
nkeynes@681 | 60 | tooltip: @"Reset dreamcast" icon: @"tb-reset"
|
nkeynes@681 | 61 | action: @selector(reset_action:)];
|
nkeynes@681 | 62 | NSToolbarItem *pause = [self createToolbarItem: @"Pause" label: @"Pause"
|
nkeynes@681 | 63 | tooltip: @"Pause dreamcast" icon: @"tb-pause"
|
nkeynes@681 | 64 | action: @selector(pause_action:)];
|
nkeynes@681 | 65 | NSToolbarItem *run = [self createToolbarItem: @"Run" label: @"Resume"
|
nkeynes@736 | 66 | tooltip: @"Resume" icon: @"tb-run"
|
nkeynes@736 | 67 | action: @selector(run_action:)];
|
nkeynes@681 | 68 | NSToolbarItem *load = [self createToolbarItem: @"LoadState" label: @"Load State..."
|
nkeynes@736 | 69 | tooltip: @"Load an lxdream save state" icon: @"tb-load"
|
nkeynes@736 | 70 | action: @selector(load_action:)];
|
nkeynes@681 | 71 | NSToolbarItem *save = [self createToolbarItem: @"SaveState" label: @"Save State..."
|
nkeynes@736 | 72 | tooltip: @"Create an lxdream save state" icon: @"tb-save"
|
nkeynes@736 | 73 | action: @selector(save_action:)];
|
nkeynes@681 | 74 | [pause setEnabled: NO];
|
nkeynes@681 | 75 | identifiers =
|
nkeynes@681 | 76 | [NSArray arrayWithObjects: @"GdromMount", @"Reset", @"Pause", @"Run", @"LoadState", @"SaveState", nil ];
|
nkeynes@681 | 77 | defaults =
|
nkeynes@681 | 78 | [NSArray arrayWithObjects: @"GdromMount", @"Reset", @"Pause", @"Run",
|
nkeynes@736 | 79 | NSToolbarSeparatorItemIdentifier, @"LoadState", @"SaveState", nil ];
|
nkeynes@681 | 80 | NSArray *values = [NSArray arrayWithObjects: mount, reset, pause, run, load, save, nil ];
|
nkeynes@681 | 81 | items = [NSDictionary dictionaryWithObjects: values forKeys: identifiers];
|
nkeynes@681 | 82 | return self;
|
nkeynes@681 | 83 | }
|
nkeynes@681 | 84 |
|
nkeynes@681 | 85 | - (NSToolbarItem *) createToolbarItem: (NSString *)id label: (NSString *) label
|
nkeynes@736 | 86 | tooltip: (NSString *)tooltip icon: (NSString *)icon action: (SEL) action
|
nkeynes@681 | 87 | {
|
nkeynes@681 | 88 | NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier: id];
|
nkeynes@681 | 89 | [item setLabel: label];
|
nkeynes@681 | 90 | [item setToolTip: tooltip];
|
nkeynes@681 | 91 | [item setTarget: [NSApp delegate]];
|
nkeynes@681 | 92 | NSString *iconFile = [[NSBundle mainBundle] pathForResource:icon ofType:@"png"];
|
nkeynes@681 | 93 | NSImage *image = [[NSImage alloc] initWithContentsOfFile: iconFile];
|
nkeynes@681 | 94 | [item setImage: image];
|
nkeynes@681 | 95 | [item setAction: action];
|
nkeynes@681 | 96 | return item;
|
nkeynes@681 | 97 | }
|
nkeynes@681 | 98 |
|
nkeynes@681 | 99 | - (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
|
nkeynes@681 | 100 | {
|
nkeynes@681 | 101 | return identifiers;
|
nkeynes@681 | 102 | }
|
nkeynes@681 | 103 |
|
nkeynes@681 | 104 | - (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar
|
nkeynes@681 | 105 | {
|
nkeynes@681 | 106 | return defaults;
|
nkeynes@681 | 107 | }
|
nkeynes@681 | 108 |
|
nkeynes@681 | 109 | - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
|
nkeynes@681 | 110 | {
|
nkeynes@681 | 111 | return [NSArray arrayWithObjects: @"Pause", @"Run", nil];
|
nkeynes@681 | 112 | }
|
nkeynes@681 | 113 |
|
nkeynes@681 | 114 | - (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier
|
nkeynes@736 | 115 | willBeInsertedIntoToolbar:(BOOL)flag
|
nkeynes@681 | 116 | {
|
nkeynes@736 | 117 | return [items objectForKey: itemIdentifier];
|
nkeynes@681 | 118 | }
|
nkeynes@681 | 119 | @end
|
nkeynes@681 | 120 |
|
nkeynes@681 | 121 | @implementation LxdreamMainWindow
|
nkeynes@681 | 122 | - (id)initWithContentRect:(NSRect)videoRect
|
nkeynes@681 | 123 | {
|
nkeynes@681 | 124 | NSRect contentRect = NSMakeRect(videoRect.origin.x,videoRect.origin.y,
|
nkeynes@681 | 125 | videoRect.size.width,videoRect.size.height+STATUSBAR_HEIGHT);
|
nkeynes@681 | 126 | if( [super initWithContentRect: contentRect
|
nkeynes@736 | 127 | styleMask: ( NSTitledWindowMask | NSClosableWindowMask |
|
nkeynes@736 | 128 | NSMiniaturizableWindowMask | NSResizableWindowMask |
|
nkeynes@736 | 129 | NSUnifiedTitleAndToolbarWindowMask )
|
nkeynes@736 | 130 | backing: NSBackingStoreBuffered defer: NO ] == nil ) {
|
nkeynes@681 | 131 | return nil;
|
nkeynes@681 | 132 | } else {
|
nkeynes@681 | 133 | isGrabbed = NO;
|
nkeynes@681 | 134 | video = video_osx_create_drawable();
|
nkeynes@681 | 135 | [video setFrameOrigin: NSMakePoint(0.0,STATUSBAR_HEIGHT)];
|
nkeynes@736 | 136 |
|
nkeynes@681 | 137 | status =
|
nkeynes@705 | 138 | [[NSTextField alloc] initWithFrame: NSMakeRect(0.0,0.0,videoRect.size.width,STATUS_TEXT_HEIGHT)];
|
nkeynes@681 | 139 | [status setStringValue: @"Idle"];
|
nkeynes@681 | 140 | [status setEditable: NO];
|
nkeynes@681 | 141 | [status setDrawsBackground: NO];
|
nkeynes@681 | 142 | [status setBordered: NO];
|
nkeynes@681 | 143 | [[self contentView] addSubview: video];
|
nkeynes@681 | 144 | [[self contentView] addSubview: status];
|
nkeynes@681 | 145 | [self makeFirstResponder: video];
|
nkeynes@681 | 146 |
|
nkeynes@757 | 147 | if( [self respondsToSelector:@selector(setAutorecalculatesContentBorderThickness:forEdge:)] )
|
nkeynes@757 | 148 | [self setAutorecalculatesContentBorderThickness: NO forEdge: NSMinYEdge ];
|
nkeynes@757 | 149 | if( [self respondsToSelector:@selector(setContentBorderThickness:forEdge:)] )
|
nkeynes@757 | 150 | [self setContentBorderThickness: STATUSBAR_HEIGHT forEdge: NSMinYEdge];
|
nkeynes@681 | 151 |
|
nkeynes@681 | 152 | // Share the app delegate for the purposes of keeping it in one place
|
nkeynes@681 | 153 | [self setDelegate: [NSApp delegate]];
|
nkeynes@681 | 154 | [self setContentMinSize: contentRect.size];
|
nkeynes@681 | 155 | [self setAcceptsMouseMovedEvents: YES];
|
nkeynes@681 | 156 |
|
nkeynes@738 | 157 | NSString *title = [[NSString alloc] initWithCString: lxdream_package_name encoding: NSASCIIStringEncoding];
|
nkeynes@681 | 158 | [self setTitle: title];
|
nkeynes@681 | 159 |
|
nkeynes@681 | 160 | NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier: @"LxdreamToolbar"];
|
nkeynes@681 | 161 | [toolbar setDelegate: [[LxdreamToolbarDelegate alloc] init]];
|
nkeynes@681 | 162 | [toolbar setDisplayMode: NSToolbarDisplayModeIconOnly];
|
nkeynes@681 | 163 | [toolbar setSizeMode: NSToolbarSizeModeSmall];
|
nkeynes@681 | 164 | [toolbar setSelectedItemIdentifier: @"Pause"];
|
nkeynes@681 | 165 | [self setToolbar: toolbar];
|
nkeynes@681 | 166 | return self;
|
nkeynes@681 | 167 | }
|
nkeynes@681 | 168 | }
|
nkeynes@681 | 169 |
|
nkeynes@681 | 170 | - (void)setStatusText: (const gchar *)text
|
nkeynes@681 | 171 | {
|
nkeynes@681 | 172 | if( isGrabbed ) {
|
nkeynes@681 | 173 | gchar buf[128];
|
nkeynes@681 | 174 | snprintf( buf, sizeof(buf), "%s %s", text, _("(Press <ctrl><alt> to release grab)") );
|
nkeynes@681 | 175 | NSString *s = [NSString stringWithUTF8String: buf];
|
nkeynes@681 | 176 | [status setStringValue: s];
|
nkeynes@681 | 177 | } else {
|
nkeynes@681 | 178 | NSString *s = [NSString stringWithUTF8String: text];
|
nkeynes@681 | 179 | [status setStringValue: s];
|
nkeynes@681 | 180 | }
|
nkeynes@681 | 181 | }
|
nkeynes@681 | 182 | - (void)setRunning:(BOOL)isRunning
|
nkeynes@681 | 183 | {
|
nkeynes@681 | 184 | if( isRunning ) {
|
nkeynes@681 | 185 | [[self toolbar] setSelectedItemIdentifier: @"Run"];
|
nkeynes@681 | 186 | [self setStatusText: _("Running")];
|
nkeynes@681 | 187 | } else {
|
nkeynes@681 | 188 | [[self toolbar] setSelectedItemIdentifier: @"Pause"];
|
nkeynes@681 | 189 | [self setStatusText: _("Stopped")];
|
nkeynes@681 | 190 | }
|
nkeynes@681 | 191 | }
|
nkeynes@681 | 192 | - (BOOL)isGrabbed
|
nkeynes@681 | 193 | {
|
nkeynes@681 | 194 | return isGrabbed;
|
nkeynes@681 | 195 | }
|
nkeynes@681 | 196 | - (void)setIsGrabbed:(BOOL)grab
|
nkeynes@681 | 197 | {
|
nkeynes@681 | 198 | if( grab != isGrabbed ) {
|
nkeynes@681 | 199 | isGrabbed = grab;
|
nkeynes@681 | 200 | [self setRunning: dreamcast_is_running() ? YES : NO];
|
nkeynes@681 | 201 | }
|
nkeynes@681 | 202 | }
|
nkeynes@681 | 203 |
|
nkeynes@681 | 204 | @end
|
nkeynes@681 | 205 |
|
nkeynes@681 | 206 | NSWindow *cocoa_gui_create_main_window()
|
nkeynes@681 | 207 | {
|
nkeynes@736 | 208 | NSRect contentRect = {{0,0},{640,480}};
|
nkeynes@736 | 209 | NSWindow *main_win = [[LxdreamMainWindow alloc] initWithContentRect: contentRect];
|
nkeynes@736 | 210 | return main_win;
|
nkeynes@681 | 211 | }
|