Search
lxdream.org :: lxdream/src/cocoaui/cocoa_ctrl.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/cocoaui/cocoa_ctrl.c
changeset 849:bbe26d798fc2
prev787:6717c02ff81f
author nkeynes
date Mon Sep 08 05:13:51 2008 +0000 (12 years ago)
permissions -rw-r--r--
last change Refactor mouse event management - button events are now usable for controllers
file annotate diff log raw
nkeynes@765
     1
/**
nkeynes@765
     2
 * $Id$
nkeynes@765
     3
 *
nkeynes@765
     4
 * Construct and manage the controller configuration pane
nkeynes@765
     5
 *
nkeynes@765
     6
 * Copyright (c) 2008 Nathan Keynes.
nkeynes@765
     7
 *
nkeynes@765
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@765
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@765
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@765
    11
 * (at your option) any later version.
nkeynes@765
    12
 *
nkeynes@765
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@765
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@765
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@765
    16
 * GNU General Public License for more details.
nkeynes@765
    17
 */
nkeynes@765
    18
nkeynes@765
    19
#include "cocoaui.h"
nkeynes@765
    20
#include "config.h"
nkeynes@770
    21
#include "display.h"
nkeynes@765
    22
#include "maple/maple.h"
nkeynes@765
    23
nkeynes@770
    24
#include <glib/gstrfuncs.h>
nkeynes@770
    25
nkeynes@765
    26
#define MAX_DEVICES 4
nkeynes@765
    27
nkeynes@849
    28
#define KEYBINDING_SIZE 110
nkeynes@849
    29
nkeynes@770
    30
static void cocoa_config_keysym_hook(void *data, const gchar *keysym);
nkeynes@770
    31
nkeynes@770
    32
@interface KeyBindingEditor (Private)
nkeynes@770
    33
- (void)updateKeysym: (const gchar *)sym;
nkeynes@770
    34
@end
nkeynes@770
    35
nkeynes@770
    36
@implementation KeyBindingEditor
nkeynes@770
    37
- (id)init
nkeynes@770
    38
{
nkeynes@770
    39
    self = [super init];
nkeynes@770
    40
    isPrimed = NO;
nkeynes@770
    41
    lastValue = nil;
nkeynes@770
    42
    [self setFieldEditor: YES];
nkeynes@770
    43
    [self setEditable: FALSE];
nkeynes@770
    44
    return self;
nkeynes@770
    45
}
nkeynes@770
    46
- (void)dealloc
nkeynes@770
    47
{
nkeynes@770
    48
    if( lastValue != nil ) {
nkeynes@770
    49
        [lastValue release];
nkeynes@770
    50
        lastValue = nil;
nkeynes@770
    51
    }
nkeynes@770
    52
    [super dealloc];
nkeynes@770
    53
}
nkeynes@770
    54
- (void)setPrimed: (BOOL)primed
nkeynes@770
    55
{
nkeynes@770
    56
    if( primed != isPrimed ) {
nkeynes@770
    57
        isPrimed = primed;
nkeynes@770
    58
        if( primed ) {
nkeynes@770
    59
            lastValue = [[NSString stringWithString: [self string]] retain];
nkeynes@770
    60
            [self setString: @"<press key>"];
nkeynes@770
    61
            input_set_keysym_hook(cocoa_config_keysym_hook, self);            
nkeynes@770
    62
        } else {
nkeynes@770
    63
            [lastValue release];
nkeynes@770
    64
            lastValue = nil;
nkeynes@770
    65
            input_set_keysym_hook(NULL,NULL);
nkeynes@770
    66
        }
nkeynes@770
    67
    }
nkeynes@770
    68
}
nkeynes@787
    69
- (void)resignFirstResponder
nkeynes@787
    70
{
nkeynes@787
    71
    if( isPrimed ) {
nkeynes@787
    72
        [self setString: lastValue];
nkeynes@787
    73
        [self setPrimed: NO];
nkeynes@787
    74
    }
nkeynes@787
    75
    [super resignFirstResponder];
nkeynes@787
    76
}
nkeynes@770
    77
- (void)fireBindingChanged
nkeynes@770
    78
{
nkeynes@770
    79
    id delegate = [self delegate];
nkeynes@770
    80
    if( delegate != nil && [delegate respondsToSelector:@selector(textDidChange:)] ) {
nkeynes@770
    81
        [delegate textDidChange: [NSNotification notificationWithName: NSTextDidChangeNotification object: self]];
nkeynes@770
    82
    }
nkeynes@770
    83
}
nkeynes@770
    84
        
nkeynes@770
    85
- (void)updateKeysym: (const gchar *)sym
nkeynes@770
    86
{
nkeynes@770
    87
    if( sym != NULL ) {
nkeynes@770
    88
        [self setString: [NSString stringWithCString: sym]];
nkeynes@770
    89
        [self setPrimed: NO];
nkeynes@770
    90
        [self fireBindingChanged];
nkeynes@770
    91
    }
nkeynes@770
    92
}
nkeynes@849
    93
- (void)updateMousesym: (int)button
nkeynes@849
    94
{
nkeynes@849
    95
    gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, (button+1) );
nkeynes@849
    96
    if( keysym != NULL ) {
nkeynes@849
    97
        [self updateKeysym: keysym ];
nkeynes@849
    98
        g_free(keysym);
nkeynes@849
    99
    }
nkeynes@849
   100
}
nkeynes@770
   101
- (void)keyPressed: (int)keycode
nkeynes@770
   102
{
nkeynes@770
   103
    gchar *keysym = input_keycode_to_keysym(NULL, keycode);
nkeynes@770
   104
    if( keysym != NULL ) {
nkeynes@770
   105
        [self updateKeysym: keysym];
nkeynes@770
   106
        g_free(keysym);
nkeynes@770
   107
    }
nkeynes@770
   108
}
nkeynes@770
   109
- (void)insertText:(id)string
nkeynes@770
   110
{
nkeynes@770
   111
    // Do nothing
nkeynes@770
   112
}
nkeynes@770
   113
- (void)mouseDown: (NSEvent *)event
nkeynes@770
   114
{
nkeynes@849
   115
    if( isPrimed ) {
nkeynes@849
   116
        [self updateMousesym: 0];
nkeynes@849
   117
    } else {
nkeynes@849
   118
        [self setPrimed: YES];
nkeynes@849
   119
        [super mouseDown: event];
nkeynes@849
   120
    }
nkeynes@849
   121
}
nkeynes@849
   122
- (void)rightMouseDown: (NSEvent *)event
nkeynes@849
   123
{
nkeynes@849
   124
    if( isPrimed ) {
nkeynes@849
   125
        [self updateMousesym: 1];
nkeynes@849
   126
    }
nkeynes@849
   127
}
nkeynes@849
   128
- (void)otherMouseDown: (NSEvent *)event
nkeynes@849
   129
{
nkeynes@849
   130
    if( isPrimed ) {
nkeynes@849
   131
        [self updateMousesym: [event buttonNumber]];
nkeynes@849
   132
    }
nkeynes@770
   133
}
nkeynes@770
   134
- (void)keyDown: (NSEvent *) event
nkeynes@770
   135
{
nkeynes@770
   136
    NSString *chars = [event characters];
nkeynes@770
   137
    if( isPrimed ) {
nkeynes@770
   138
        if( chars != NULL && [chars length] == 1 && [chars characterAtIndex: 0] == 27 ) {
nkeynes@770
   139
            // Escape char = abort change
nkeynes@770
   140
            [self setString: lastValue];
nkeynes@770
   141
            [self setPrimed: NO];
nkeynes@770
   142
        } else {
nkeynes@770
   143
            [self keyPressed: ([event keyCode]+1)];
nkeynes@770
   144
        }
nkeynes@770
   145
    } else {
nkeynes@770
   146
        if( chars != NULL && [chars length] == 1 ) {
nkeynes@770
   147
            int ch = [chars characterAtIndex: 0];
nkeynes@770
   148
            switch( ch ) {
nkeynes@770
   149
            case 0x7F:
nkeynes@770
   150
                [self setString: @""]; 
nkeynes@770
   151
                [self fireBindingChanged];
nkeynes@770
   152
                break;
nkeynes@770
   153
            case '\r':
nkeynes@770
   154
                [self setPrimed: YES];
nkeynes@770
   155
                break;
nkeynes@770
   156
            default:
nkeynes@770
   157
                [super keyDown: event];
nkeynes@770
   158
                break;
nkeynes@770
   159
            }
nkeynes@770
   160
        } else {
nkeynes@770
   161
            [super keyDown: event];
nkeynes@770
   162
        }
nkeynes@770
   163
    }
nkeynes@770
   164
}
nkeynes@770
   165
- (void)flagsChanged: (NSEvent *) event
nkeynes@770
   166
{
nkeynes@770
   167
    if( isPrimed ) {
nkeynes@770
   168
        [self keyPressed: ([event keyCode]+1)];
nkeynes@770
   169
    }
nkeynes@770
   170
    [super flagsChanged: event];
nkeynes@770
   171
}
nkeynes@770
   172
@end
nkeynes@770
   173
nkeynes@770
   174
static void cocoa_config_keysym_hook(void *data, const gchar *keysym)
nkeynes@770
   175
{
nkeynes@770
   176
    KeyBindingEditor *editor = (KeyBindingEditor *)data;
nkeynes@770
   177
    [editor updateKeysym: keysym];
nkeynes@770
   178
}
nkeynes@770
   179
nkeynes@770
   180
nkeynes@770
   181
@implementation KeyBindingField
nkeynes@770
   182
@end
nkeynes@770
   183
nkeynes@770
   184
/*************************** Key-binding sub-view ***********************/
nkeynes@770
   185
nkeynes@770
   186
#define MAX_KEY_BINDINGS 32
nkeynes@770
   187
nkeynes@770
   188
@interface ControllerKeyBindingView : NSView
nkeynes@770
   189
{
nkeynes@770
   190
    maple_device_t device;
nkeynes@770
   191
    KeyBindingField *field[MAX_KEY_BINDINGS][2];
nkeynes@770
   192
}
nkeynes@770
   193
- (id)initWithFrame: (NSRect)frameRect;
nkeynes@770
   194
- (void)setDevice: (maple_device_t)device;
nkeynes@770
   195
@end
nkeynes@770
   196
nkeynes@770
   197
@implementation ControllerKeyBindingView
nkeynes@770
   198
- (id)initWithFrame: (NSRect)frameRect
nkeynes@770
   199
{
nkeynes@770
   200
    if( [super initWithFrame: frameRect] == nil ) {
nkeynes@770
   201
        return nil;
nkeynes@770
   202
    } else {
nkeynes@770
   203
        device = NULL;
nkeynes@770
   204
        return self;
nkeynes@770
   205
    }
nkeynes@770
   206
}
nkeynes@770
   207
- (BOOL)isFlipped
nkeynes@770
   208
{
nkeynes@770
   209
    return YES;
nkeynes@770
   210
}
nkeynes@770
   211
- (void)removeSubviews
nkeynes@770
   212
{
nkeynes@770
   213
    [[self subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
nkeynes@770
   214
}
nkeynes@770
   215
- (void)controlTextDidChange: (NSNotification *)notify
nkeynes@770
   216
{
nkeynes@770
   217
    int binding = [[notify object] tag];
nkeynes@770
   218
    NSString *val1 = [field[binding][0] stringValue];
nkeynes@770
   219
    NSString *val2 = [field[binding][1] stringValue];
nkeynes@770
   220
    char buf[ [val1 length] + [val2 length] + 2 ];
nkeynes@770
   221
    const gchar *p = NULL;
nkeynes@770
   222
    
nkeynes@770
   223
    if( [val1 length] == 0 ) {
nkeynes@770
   224
        if( [val2 length] != 0 ) {
nkeynes@770
   225
            p = [val2 UTF8String];
nkeynes@770
   226
        }
nkeynes@770
   227
    } else if( [val2 length] == 0 ) {
nkeynes@770
   228
        p = [val1 UTF8String];
nkeynes@770
   229
    } else {
nkeynes@770
   230
        sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );
nkeynes@770
   231
        p = buf;
nkeynes@770
   232
    }
nkeynes@770
   233
    maple_set_device_config_value( device, binding, p ); 
nkeynes@770
   234
    lxdream_save_config();
nkeynes@770
   235
}
nkeynes@770
   236
- (void)setDevice: (maple_device_t)newDevice
nkeynes@770
   237
{
nkeynes@770
   238
    device = newDevice;
nkeynes@770
   239
    [self removeSubviews];
nkeynes@770
   240
    if( device != NULL ) {
nkeynes@770
   241
        lxdream_config_entry_t config = maple_get_device_config(device);
nkeynes@770
   242
        if( config != NULL ) {
nkeynes@770
   243
            int count, i, y, x;
nkeynes@770
   244
nkeynes@770
   245
            for( count=0; config[count].key != NULL; count++ );
nkeynes@770
   246
            x = TEXT_GAP;
nkeynes@849
   247
            NSSize size = NSMakeSize(85+KEYBINDING_SIZE*2+TEXT_GAP*4, count*(TEXT_HEIGHT+TEXT_GAP)+TEXT_GAP);
nkeynes@770
   248
            [self setFrameSize: size];
nkeynes@770
   249
            [self scrollRectToVisible: NSMakeRect(0,0,1,1)]; 
nkeynes@770
   250
            y = TEXT_GAP;
nkeynes@770
   251
            for( i=0; config[i].key != NULL; i++ ) {
nkeynes@770
   252
                NSRect frame = NSMakeRect(x, y + 2, 85, LABEL_HEIGHT);
nkeynes@770
   253
                NSTextField *label = cocoa_gui_add_label(self, NS_(config[i].label), frame);
nkeynes@770
   254
                [label setAlignment: NSRightTextAlignment];
nkeynes@770
   255
nkeynes@849
   256
                frame = NSMakeRect( x + 85 + TEXT_GAP, y, KEYBINDING_SIZE, TEXT_HEIGHT);
nkeynes@770
   257
                field[i][0] = [[KeyBindingField alloc] initWithFrame: frame];
nkeynes@770
   258
                [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
nkeynes@770
   259
                [field[i][0] setTag: i];
nkeynes@770
   260
                [field[i][0] setDelegate: self];
nkeynes@770
   261
                [self addSubview: field[i][0]];
nkeynes@770
   262
                
nkeynes@849
   263
                frame = NSMakeRect( x + 85 + KEYBINDING_SIZE + (TEXT_GAP*2), y, KEYBINDING_SIZE, TEXT_HEIGHT);
nkeynes@770
   264
                field[i][1] = [[KeyBindingField alloc] initWithFrame: frame];
nkeynes@770
   265
                [field[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
nkeynes@770
   266
                [field[i][1] setTag: i];
nkeynes@770
   267
                [field[i][1] setDelegate: self];
nkeynes@770
   268
                [self addSubview: field[i][1]];
nkeynes@770
   269
nkeynes@770
   270
                if( config[i].value != NULL ) {
nkeynes@770
   271
                    gchar **parts = g_strsplit(config[i].value,",",3);
nkeynes@770
   272
                    if( parts[0] != NULL ) {
nkeynes@770
   273
                        [field[i][0] setStringValue: [NSString stringWithCString: parts[0]]];
nkeynes@770
   274
                        if( parts[1] != NULL ) {
nkeynes@770
   275
                            [field[i][1] setStringValue: [NSString stringWithCString: parts[1]]];
nkeynes@770
   276
                        }
nkeynes@770
   277
                    }
nkeynes@770
   278
                    g_strfreev(parts);
nkeynes@770
   279
                }
nkeynes@770
   280
                
nkeynes@770
   281
                y += (TEXT_HEIGHT + TEXT_GAP);
nkeynes@770
   282
            }
nkeynes@770
   283
        } else {
nkeynes@770
   284
            [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];
nkeynes@770
   285
        }
nkeynes@770
   286
    } else {
nkeynes@770
   287
        [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];
nkeynes@770
   288
    }
nkeynes@770
   289
}
nkeynes@770
   290
@end
nkeynes@770
   291
nkeynes@770
   292
/*************************** Top-level controller pane ***********************/
nkeynes@770
   293
nkeynes@770
   294
@interface LxdreamPrefsControllerPane: LxdreamPrefsPane
nkeynes@770
   295
{
nkeynes@770
   296
    struct maple_device *save_controller[4];
nkeynes@770
   297
    NSButton *radio[4];
nkeynes@770
   298
    ControllerKeyBindingView *key_bindings;
nkeynes@770
   299
}
nkeynes@770
   300
+ (LxdreamPrefsControllerPane *)new;
nkeynes@770
   301
@end
nkeynes@770
   302
nkeynes@765
   303
@implementation LxdreamPrefsControllerPane
nkeynes@765
   304
+ (LxdreamPrefsControllerPane *)new
nkeynes@765
   305
{
nkeynes@765
   306
    return [[LxdreamPrefsControllerPane alloc] initWithFrame: NSMakeRect(0,0,600,400)];
nkeynes@765
   307
}
nkeynes@765
   308
- (id)initWithFrame: (NSRect)frameRect
nkeynes@765
   309
{
nkeynes@765
   310
    if( [super initWithFrame: frameRect title: NS_("Controllers")] == nil ) {
nkeynes@765
   311
        return nil;
nkeynes@765
   312
    } else {
nkeynes@765
   313
        const struct maple_device_class **devices = maple_get_device_classes();
nkeynes@765
   314
        char buf[16];
nkeynes@765
   315
        int i,j;
nkeynes@770
   316
        int y = [self contentHeight] - TEXT_HEIGHT - TEXT_GAP;
nkeynes@770
   317
nkeynes@770
   318
        NSBox *rule = [[NSBox alloc] initWithFrame: 
nkeynes@770
   319
                NSMakeRect(210+(TEXT_GAP*3), 1, 1, [self contentHeight] + TEXT_GAP - 2)];
nkeynes@770
   320
        [rule setAutoresizingMask: (NSViewMaxXMargin|NSViewHeightSizable)];
nkeynes@770
   321
        [rule setBoxType: NSBoxSeparator];
nkeynes@770
   322
        [self addSubview: rule];
nkeynes@770
   323
        
nkeynes@770
   324
        NSRect bindingFrame = NSMakeRect(210+(TEXT_GAP*4), 0,
nkeynes@770
   325
                   frameRect.size.width - (210+(TEXT_GAP*4)), [self contentHeight] + TEXT_GAP );
nkeynes@770
   326
        NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: bindingFrame];
nkeynes@770
   327
        key_bindings = [[ControllerKeyBindingView alloc] initWithFrame: bindingFrame ];
nkeynes@770
   328
        [scrollView setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
nkeynes@770
   329
        [scrollView setDocumentView: key_bindings];
nkeynes@770
   330
        [scrollView setDrawsBackground: NO];
nkeynes@770
   331
        [scrollView setHasVerticalScroller: YES];
nkeynes@770
   332
        [scrollView setAutohidesScrollers: YES];
nkeynes@770
   333
 
nkeynes@770
   334
        [self addSubview: scrollView];
nkeynes@770
   335
        [key_bindings setDevice: maple_get_device(0,0)];
nkeynes@770
   336
        
nkeynes@765
   337
        for( i=0; i<MAX_DEVICES; i++ ) {
nkeynes@770
   338
            int x = TEXT_GAP;
nkeynes@765
   339
            save_controller[i] = NULL;
nkeynes@765
   340
            maple_device_t device = maple_get_device(i,0);
nkeynes@770
   341
nkeynes@765
   342
            snprintf( buf, sizeof(buf), _("Slot %d."), i );
nkeynes@770
   343
            radio[i] = [[NSButton alloc] initWithFrame: NSMakeRect( x, y, 60, TEXT_HEIGHT )];
nkeynes@770
   344
            [radio[i] setTitle: [NSString stringWithUTF8String: buf]];
nkeynes@770
   345
            [radio[i] setTag: i];
nkeynes@770
   346
            [radio[i] setButtonType: NSRadioButton];
nkeynes@770
   347
            [radio[i] setAlignment: NSRightTextAlignment];
nkeynes@770
   348
            [radio[i] setTarget: self];
nkeynes@770
   349
            [radio[i] setAction: @selector(radioChanged:)];
nkeynes@770
   350
            [radio[i] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
nkeynes@770
   351
            [self addSubview: radio[i]];
nkeynes@770
   352
            x += 60 + TEXT_GAP;
nkeynes@770
   353
nkeynes@770
   354
            NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame: NSMakeRect(x,y,150,TEXT_HEIGHT) 
nkeynes@770
   355
                                                          pullsDown: NO];
nkeynes@765
   356
            [popup addItemWithTitle: NS_("<empty>")];
nkeynes@765
   357
            [popup setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
nkeynes@765
   358
            [[popup itemAtIndex: 0] setTag: 0];
nkeynes@765
   359
            for( j=0; devices[j] != NULL; j++ ) {
nkeynes@765
   360
                [popup addItemWithTitle: [NSString stringWithUTF8String: devices[j]->name]];
nkeynes@765
   361
                if( device != NULL && device->device_class == devices[j] ) {
nkeynes@765
   362
                    [popup selectItemAtIndex: (j+1)];
nkeynes@765
   363
                }
nkeynes@765
   364
                [[popup itemAtIndex: (j+1)] setTag: (j+1)];
nkeynes@765
   365
            }
nkeynes@765
   366
            [popup setTarget: self];
nkeynes@765
   367
            [popup setAction: @selector(deviceChanged:)];
nkeynes@765
   368
            [popup setTag: i];
nkeynes@765
   369
            [self addSubview: popup];
nkeynes@770
   370
            y -= (TEXT_HEIGHT+TEXT_GAP);
nkeynes@765
   371
        }
nkeynes@770
   372
        
nkeynes@770
   373
        [radio[0] setState: NSOnState];
nkeynes@765
   374
        return self;
nkeynes@765
   375
    }
nkeynes@765
   376
}
nkeynes@770
   377
- (void)radioChanged: (id)sender
nkeynes@770
   378
{
nkeynes@770
   379
    int slot = [sender tag];
nkeynes@770
   380
    int i;
nkeynes@770
   381
    for( i=0; i<MAX_DEVICES; i++ ) {
nkeynes@770
   382
        if( i != slot ) {
nkeynes@770
   383
            [radio[i] setState: NSOffState];
nkeynes@770
   384
        }
nkeynes@770
   385
    }
nkeynes@770
   386
    [key_bindings setDevice: maple_get_device(slot,0)];
nkeynes@770
   387
}
nkeynes@765
   388
- (void)deviceChanged: (id)sender
nkeynes@765
   389
{
nkeynes@765
   390
    int slot = [sender tag];
nkeynes@770
   391
    int new_device_idx = [sender indexOfSelectedItem] - 1, i; 
nkeynes@765
   392
    maple_device_class_t new_device_class = NULL;
nkeynes@765
   393
    
nkeynes@770
   394
    for( i=0; i<MAX_DEVICES; i++ ) {
nkeynes@770
   395
        if( i == slot ) {
nkeynes@770
   396
            [radio[i] setState: NSOnState];
nkeynes@770
   397
        } else {
nkeynes@770
   398
            [radio[i] setState: NSOffState];
nkeynes@770
   399
        }
nkeynes@770
   400
    }
nkeynes@770
   401
    
nkeynes@765
   402
    maple_device_t current = maple_get_device(slot,0);
nkeynes@765
   403
    maple_device_t new_device = NULL;
nkeynes@765
   404
    if( new_device_idx != -1 ) {
nkeynes@765
   405
        new_device_class = maple_get_device_classes()[new_device_idx];
nkeynes@765
   406
    }
nkeynes@765
   407
    if( current == NULL ? new_device_class == NULL : current->device_class == new_device_class ) {
nkeynes@765
   408
        // No change
nkeynes@770
   409
        [key_bindings setDevice: current];
nkeynes@765
   410
        return;
nkeynes@765
   411
    }
nkeynes@765
   412
    if( current != NULL && current->device_class == &controller_class ) {
nkeynes@765
   413
        save_controller[slot] = current->clone(current);
nkeynes@765
   414
    }
nkeynes@765
   415
    if( new_device_class == NULL ) {
nkeynes@765
   416
        maple_detach_device(slot,0);
nkeynes@765
   417
    } else {
nkeynes@765
   418
        if( new_device_class == &controller_class && save_controller[slot] != NULL ) {
nkeynes@765
   419
            new_device = save_controller[slot];
nkeynes@765
   420
            save_controller[slot] = NULL;
nkeynes@765
   421
        } else {
nkeynes@765
   422
            new_device = maple_new_device( new_device_class->name );
nkeynes@765
   423
        }
nkeynes@765
   424
        maple_attach_device(new_device,slot,0);
nkeynes@765
   425
    }
nkeynes@770
   426
    [key_bindings setDevice: maple_get_device(slot,0)];
nkeynes@765
   427
    lxdream_save_config();
nkeynes@765
   428
}
nkeynes@765
   429
@end
nkeynes@770
   430
nkeynes@770
   431
NSView *cocoa_gui_create_prefs_controller_pane()
nkeynes@770
   432
{
nkeynes@770
   433
    return [LxdreamPrefsControllerPane new];
nkeynes@770
   434
}
.