Search
lxdream.org :: lxdream/src/cocoaui/cocoa_win.m
lxdream 0.9.1
released Jun 29
Download Now
filename src/cocoaui/cocoa_win.m
changeset 1098:4f2750753a6c
prev1028:f99eeaf084c2
next1298:d0eb2307b847
author nkeynes
date Sat Mar 03 15:52:59 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Swap between run + pause icons when pressed
file annotate diff log raw
nkeynes@964
     1
/**
nkeynes@964
     2
 * $Id$
nkeynes@964
     3
 *
nkeynes@964
     4
 * Construct and maintain the main window under cocoa.
nkeynes@964
     5
 *
nkeynes@964
     6
 * Copyright (c) 2008 Nathan Keynes.
nkeynes@964
     7
 *
nkeynes@964
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@964
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@964
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@964
    11
 * (at your option) any later version.
nkeynes@964
    12
 *
nkeynes@964
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@964
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@964
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@964
    16
 * GNU General Public License for more details.
nkeynes@964
    17
 */
nkeynes@964
    18
nkeynes@964
    19
#include "cocoaui/cocoaui.h"
nkeynes@964
    20
#include "lxdream.h"
nkeynes@964
    21
#include "dreamcast.h"
nkeynes@964
    22
#include "gdrom/gdrom.h"
nkeynes@964
    23
#include <ApplicationServices/ApplicationServices.h>
nkeynes@1028
    24
#include <Carbon/Carbon.h>
nkeynes@964
    25
nkeynes@964
    26
@interface NSWindow (OSX10_5_and_later)
nkeynes@964
    27
#ifndef CGFLOAT_DEFINED
nkeynes@964
    28
# ifdef __LP64__
nkeynes@964
    29
    typedef double CGFloat;
nkeynes@964
    30
# else
nkeynes@964
    31
    typedef float CGFloat;
nkeynes@964
    32
# endif
nkeynes@964
    33
#endif
nkeynes@964
    34
- (void)setAutorecalculatesContentBorderThickness:(BOOL)b forEdge:(NSRectEdge)e;
nkeynes@964
    35
- (void)setContentBorderThickness:(CGFloat)b forEdge:(NSRectEdge)e;
nkeynes@964
    36
@end
nkeynes@964
    37
nkeynes@964
    38
nkeynes@964
    39
#if NSAppKitVersionNumber > NSAppKitVersionNumber10_4 
nkeynes@964
    40
nkeynes@964
    41
#endif
nkeynes@964
    42
nkeynes@964
    43
#define STATUSBAR_HEIGHT 25
nkeynes@964
    44
#define STATUS_TEXT_HEIGHT 22
nkeynes@964
    45
nkeynes@964
    46
@interface LxdreamToolbarDelegate : NSObject {
nkeynes@964
    47
    NSArray *identifiers;
nkeynes@964
    48
    NSArray *defaults;
nkeynes@964
    49
    NSDictionary *items;
nkeynes@964
    50
}
nkeynes@964
    51
- (NSToolbarItem *) createToolbarItem: (NSString *)id label: (NSString *) label 
nkeynes@964
    52
                              tooltip: (NSString *)tooltip 
nkeynes@964
    53
                                 icon: (NSString *)icon action: (SEL) action; 
nkeynes@964
    54
@end
nkeynes@964
    55
nkeynes@964
    56
@implementation LxdreamToolbarDelegate
nkeynes@964
    57
- (id) init
nkeynes@964
    58
{
nkeynes@964
    59
    NSToolbarItem *mount = [self createToolbarItem: @"GdromMount" label: @"Open Image" 
nkeynes@964
    60
                            tooltip: @"Mount a cdrom disc" icon: @"tb-cdrom" 
nkeynes@964
    61
                            action: @selector(mount_action:)];
nkeynes@964
    62
    NSToolbarItem *reset = [self createToolbarItem: @"Reset" label: @"Reset"
nkeynes@964
    63
                            tooltip: @"Reset dreamcast" icon: @"tb-reset"
nkeynes@964
    64
                            action: @selector(reset_action:)];
nkeynes@964
    65
    NSToolbarItem *pause = [self createToolbarItem: @"Pause" label: @"Pause"
nkeynes@964
    66
                            tooltip: @"Pause dreamcast" icon: @"tb-pause"
nkeynes@964
    67
                            action: @selector(pause_action:)];
nkeynes@964
    68
    NSToolbarItem *run = [self createToolbarItem: @"Run" label: @"Resume"
nkeynes@964
    69
                          tooltip: @"Resume" icon: @"tb-run"
nkeynes@964
    70
                          action: @selector(run_action:)];
nkeynes@964
    71
    NSToolbarItem *load = [self createToolbarItem: @"LoadState" label: @"Load State..."
nkeynes@964
    72
                           tooltip: @"Load an lxdream save state" icon: @"tb-load"
nkeynes@964
    73
                           action: @selector(load_action:)];
nkeynes@964
    74
    NSToolbarItem *save = [self createToolbarItem: @"SaveState" label: @"Save State..."
nkeynes@964
    75
                           tooltip: @"Create an lxdream save state" icon: @"tb-save"
nkeynes@964
    76
                           action: @selector(save_action:)];
nkeynes@964
    77
    NSToolbarItem *prefs = [self createToolbarItem: @"Preferences" label: @"Preferences..."
nkeynes@964
    78
                           tooltip: @"Edit preferences" icon: @"tb-preferences"
nkeynes@964
    79
                           action: @selector(preferences_action:)];
nkeynes@964
    80
    [pause setEnabled: NO];
nkeynes@964
    81
    identifiers = 
nkeynes@964
    82
        [NSArray arrayWithObjects: @"GdromMount", @"Reset", @"Pause", @"Run", @"LoadState", @"SaveState", @"Preferences", nil ];
nkeynes@964
    83
    defaults = 
nkeynes@964
    84
        [NSArray arrayWithObjects: @"GdromMount", @"Reset", @"Pause", @"Run", 
nkeynes@964
    85
         NSToolbarSeparatorItemIdentifier, @"LoadState", @"SaveState", 
nkeynes@964
    86
         NSToolbarFlexibleSpaceItemIdentifier, @"Preferences", nil ];
nkeynes@964
    87
    NSArray *values = [NSArray arrayWithObjects: mount, reset, pause, run, load, save, prefs, nil ];
nkeynes@964
    88
    items = [NSDictionary dictionaryWithObjects: values forKeys: identifiers];
nkeynes@964
    89
    return self;
nkeynes@964
    90
}
nkeynes@964
    91
nkeynes@964
    92
- (NSToolbarItem *) createToolbarItem: (NSString *)id label: (NSString *) label 
nkeynes@964
    93
tooltip: (NSString *)tooltip icon: (NSString *)icon action: (SEL) action 
nkeynes@964
    94
{
nkeynes@964
    95
    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier: id];
nkeynes@964
    96
    [item setLabel: label];
nkeynes@964
    97
    [item setToolTip: tooltip];
nkeynes@964
    98
    [item setTarget: [NSApp delegate]];
nkeynes@964
    99
    NSString *iconFile = [[NSBundle mainBundle] pathForResource:icon ofType:@"png"];
nkeynes@964
   100
    NSImage *image = [[NSImage alloc] initWithContentsOfFile: iconFile];
nkeynes@964
   101
    [item setImage: image];
nkeynes@964
   102
    [item setAction: action];
nkeynes@964
   103
    return item;
nkeynes@964
   104
}
nkeynes@964
   105
nkeynes@964
   106
- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar 
nkeynes@964
   107
{
nkeynes@964
   108
    return identifiers;
nkeynes@964
   109
}
nkeynes@964
   110
nkeynes@964
   111
- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar
nkeynes@964
   112
{
nkeynes@964
   113
    return defaults;
nkeynes@964
   114
}
nkeynes@964
   115
nkeynes@964
   116
- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
nkeynes@964
   117
{
nkeynes@964
   118
    return [NSArray arrayWithObjects: @"Pause", @"Run", nil];
nkeynes@964
   119
}
nkeynes@964
   120
nkeynes@964
   121
- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier
nkeynes@964
   122
willBeInsertedIntoToolbar:(BOOL)flag 
nkeynes@964
   123
{
nkeynes@964
   124
    return [items objectForKey: itemIdentifier];
nkeynes@964
   125
}
nkeynes@964
   126
@end
nkeynes@964
   127
nkeynes@964
   128
@implementation LxdreamMainWindow
nkeynes@964
   129
- (id)initWithContentRect:(NSRect)videoRect 
nkeynes@964
   130
{
nkeynes@964
   131
    NSRect contentRect = NSMakeRect(videoRect.origin.x,videoRect.origin.y,
nkeynes@964
   132
            videoRect.size.width,videoRect.size.height+STATUSBAR_HEIGHT);
nkeynes@964
   133
    if( [super initWithContentRect: contentRect
nkeynes@964
   134
         styleMask: ( NSTitledWindowMask | NSClosableWindowMask | 
nkeynes@964
   135
                 NSMiniaturizableWindowMask | NSResizableWindowMask |
nkeynes@964
   136
                 NSUnifiedTitleAndToolbarWindowMask )
nkeynes@964
   137
                 backing: NSBackingStoreBuffered defer: NO ] == nil ) {
nkeynes@964
   138
        return nil;
nkeynes@964
   139
    } else {
nkeynes@964
   140
        useGrab = NO;
nkeynes@964
   141
        isGrabbed = NO;
nkeynes@964
   142
        video = (LxdreamVideoView *)video_osx_create_drawable();
nkeynes@964
   143
        [video setFrameOrigin: NSMakePoint(0.0,STATUSBAR_HEIGHT)];
nkeynes@964
   144
        [video setDelegate: self];
nkeynes@964
   145
nkeynes@964
   146
        status = 
nkeynes@964
   147
            [[NSTextField alloc] initWithFrame: NSMakeRect(0.0,0.0,videoRect.size.width,STATUS_TEXT_HEIGHT)];
nkeynes@964
   148
        [status setStringValue: @"Idle"];
nkeynes@964
   149
        [status setEditable: NO];
nkeynes@964
   150
        [status setDrawsBackground: NO];
nkeynes@964
   151
        [status setBordered: NO];
nkeynes@964
   152
        [[self contentView] addSubview: video];
nkeynes@964
   153
        [[self contentView] addSubview: status];
nkeynes@964
   154
        [self makeFirstResponder: video];
nkeynes@964
   155
nkeynes@964
   156
        if( [self respondsToSelector:@selector(setAutorecalculatesContentBorderThickness:forEdge:)] )
nkeynes@964
   157
            [self setAutorecalculatesContentBorderThickness: NO forEdge: NSMinYEdge ];
nkeynes@964
   158
        if( [self respondsToSelector:@selector(setContentBorderThickness:forEdge:)] ) 
nkeynes@964
   159
            [self setContentBorderThickness: STATUSBAR_HEIGHT forEdge: NSMinYEdge];
nkeynes@964
   160
nkeynes@964
   161
        // Share the app delegate for the purposes of keeping it in one place
nkeynes@964
   162
        [self setDelegate: [NSApp delegate]];
nkeynes@964
   163
        [self setContentMinSize: contentRect.size];
nkeynes@964
   164
        [self setAcceptsMouseMovedEvents: YES];
nkeynes@964
   165
        [self updateTitle];
nkeynes@964
   166
nkeynes@964
   167
        NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier: @"LxdreamToolbar"];
nkeynes@964
   168
        [toolbar setDelegate: [[LxdreamToolbarDelegate alloc] init]];
nkeynes@964
   169
        [toolbar setDisplayMode: NSToolbarDisplayModeIconOnly];
nkeynes@964
   170
        [toolbar setSizeMode: NSToolbarSizeModeSmall];
nkeynes@964
   171
        [toolbar setSelectedItemIdentifier: @"Pause"];
nkeynes@964
   172
        [self setToolbar: toolbar];
nkeynes@964
   173
        return self;
nkeynes@964
   174
    }
nkeynes@964
   175
}
nkeynes@964
   176
nkeynes@964
   177
- (void)updateTitle
nkeynes@964
   178
{
nkeynes@964
   179
    NSString *title;
nkeynes@964
   180
    const char *disc_title = gdrom_get_current_disc_title();
nkeynes@964
   181
    if( disc_title == NULL ) {
nkeynes@1098
   182
        title = [NSString stringWithFormat: @"%s - <no disc>", lxdream_package_name];
nkeynes@964
   183
    } else {
nkeynes@964
   184
        title = [NSString stringWithFormat: @"%s - %s", lxdream_package_name, disc_title];
nkeynes@964
   185
    }
nkeynes@964
   186
    [self setTitle: title];
nkeynes@964
   187
}    
nkeynes@964
   188
nkeynes@964
   189
- (void)setStatusText: (const gchar *)text
nkeynes@964
   190
{
nkeynes@964
   191
    if( isGrabbed ) {
nkeynes@964
   192
        gchar buf[128];
nkeynes@964
   193
        snprintf( buf, sizeof(buf), "%s %s", text, _("(Press <ctrl><alt> to release grab)") );
nkeynes@964
   194
        NSString *s = [NSString stringWithUTF8String: buf]; 
nkeynes@964
   195
        [status setStringValue: s];
nkeynes@964
   196
    } else {
nkeynes@964
   197
        NSString *s = [NSString stringWithUTF8String: text];
nkeynes@964
   198
        [status setStringValue: s];
nkeynes@964
   199
    }   
nkeynes@964
   200
}
nkeynes@964
   201
- (void)setRunning:(BOOL)isRunning
nkeynes@964
   202
{
nkeynes@964
   203
    if( isRunning ) {
nkeynes@964
   204
        [[self toolbar] setSelectedItemIdentifier: @"Run"];
nkeynes@964
   205
        [self setStatusText: _("Running")];
nkeynes@964
   206
    } else {
nkeynes@964
   207
        [[self toolbar] setSelectedItemIdentifier: @"Pause"];
nkeynes@964
   208
        [self setStatusText: _("Stopped")];
nkeynes@964
   209
    }            
nkeynes@964
   210
}
nkeynes@1028
   211
- (BOOL)isFullscreen
nkeynes@1028
   212
{
nkeynes@1028
   213
    return isFullscreen;
nkeynes@1028
   214
}
nkeynes@1028
   215
- (void)setFullscreen:(BOOL)full
nkeynes@1028
   216
{
nkeynes@1028
   217
    if( full != isFullscreen ) {
nkeynes@1028
   218
        isFullscreen = full;
nkeynes@1028
   219
    
nkeynes@1028
   220
        if( full ) {
nkeynes@1028
   221
            savedFrame = [self frame];
nkeynes@1028
   222
            SetSystemUIMode( kUIModeAllHidden, 0 );
nkeynes@1028
   223
            NSRect screenRect = [[NSScreen mainScreen] frame];
nkeynes@1028
   224
            screenRect.size.height += STATUSBAR_HEIGHT;
nkeynes@1028
   225
            screenRect.origin.y -= STATUSBAR_HEIGHT;
nkeynes@1028
   226
            NSRect targetRect = [self frameRectForContentRect: screenRect];
nkeynes@1028
   227
            [self setFrame: targetRect display: YES];
nkeynes@1028
   228
        } else {
nkeynes@1028
   229
            SetSystemUIMode( kUIModeNormal, 0 );
nkeynes@1028
   230
            [self setFrame: savedFrame display: YES];
nkeynes@1028
   231
        }
nkeynes@1028
   232
    }
nkeynes@1028
   233
}
nkeynes@964
   234
- (BOOL)isGrabbed
nkeynes@964
   235
{
nkeynes@964
   236
    return isGrabbed;
nkeynes@964
   237
}
nkeynes@964
   238
- (void)setIsGrabbed:(BOOL)grab
nkeynes@964
   239
{
nkeynes@964
   240
    if( grab != isGrabbed ) {
nkeynes@964
   241
        isGrabbed = grab;
nkeynes@964
   242
        [self setRunning: dreamcast_is_running() ? YES : NO];
nkeynes@964
   243
        
nkeynes@964
   244
        if( isGrabbed ) {
nkeynes@964
   245
            [NSCursor hide];
nkeynes@964
   246
            CGAssociateMouseAndMouseCursorPosition(NO);
nkeynes@964
   247
        } else {
nkeynes@964
   248
            [NSCursor unhide];
nkeynes@964
   249
            CGAssociateMouseAndMouseCursorPosition(YES);
nkeynes@964
   250
        }
nkeynes@964
   251
        [video setIsGrabbed: isGrabbed];
nkeynes@964
   252
    }
nkeynes@964
   253
}
nkeynes@964
   254
- (void)setUseGrab:(BOOL)grab
nkeynes@964
   255
{
nkeynes@964
   256
    if( grab != useGrab ) {
nkeynes@964
   257
        if( !grab && isGrabbed ) {
nkeynes@964
   258
            [self setIsGrabbed: NO];
nkeynes@964
   259
        }
nkeynes@964
   260
        useGrab = grab;
nkeynes@964
   261
    }
nkeynes@964
   262
}
nkeynes@964
   263
nkeynes@964
   264
- (id)viewRequestedGrab: (id)sender
nkeynes@964
   265
{
nkeynes@964
   266
    if( useGrab ) {
nkeynes@964
   267
        [self setIsGrabbed: YES];
nkeynes@964
   268
    }
nkeynes@964
   269
    return useGrab ? self : nil;
nkeynes@964
   270
}
nkeynes@964
   271
- (id)viewRequestedUngrab: (id)sender
nkeynes@964
   272
{
nkeynes@964
   273
    [self setIsGrabbed: NO];
nkeynes@964
   274
    return useGrab ? self : nil;
nkeynes@964
   275
}
nkeynes@1028
   276
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)aScreen
nkeynes@1028
   277
{
nkeynes@1028
   278
    return frameRect;
nkeynes@1028
   279
}
nkeynes@964
   280
@end
nkeynes@964
   281
nkeynes@964
   282
LxdreamMainWindow *cocoa_gui_create_main_window()
nkeynes@964
   283
{
nkeynes@964
   284
    NSRect contentRect = {{0,0},{640,480}};
nkeynes@964
   285
    return [[LxdreamMainWindow alloc] initWithContentRect: contentRect]; 
nkeynes@964
   286
}
.