Search
lxdream.org :: lxdream/src/cocoaui/cocoa_cfg.m
lxdream 0.9.1
released Jun 29
Download Now
filename src/cocoaui/cocoa_cfg.m
changeset 1298:d0eb2307b847
prev1072:d82e04e6d497
author nkeynes
date Wed Feb 04 08:38:23 2015 +1000 (5 years ago)
permissions -rw-r--r--
last change Fix assorted compile warnings reported by Clang
file annotate diff log raw
nkeynes@1072
     1
/**
nkeynes@1072
     2
 * $Id$
nkeynes@1072
     3
 *
nkeynes@1072
     4
 * Construct and manage a configuration pane based on an underlying
nkeynes@1072
     5
 * configuration group.
nkeynes@1072
     6
 *
nkeynes@1072
     7
 * Copyright (c) 2009 Nathan Keynes.
nkeynes@1072
     8
 *
nkeynes@1072
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@1072
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@1072
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@1072
    12
 * (at your option) any later version.
nkeynes@1072
    13
 *
nkeynes@1072
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@1072
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@1072
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@1072
    17
 * GNU General Public License for more details.
nkeynes@1072
    18
 */
nkeynes@1072
    19
nkeynes@1072
    20
#include "cocoaui.h"
nkeynes@1072
    21
#include "display.h"
nkeynes@1072
    22
#include "lxpaths.h"
nkeynes@1072
    23
#include "maple/maple.h"
nkeynes@1072
    24
nkeynes@1072
    25
static void cocoa_config_keysym_hook(void *data, const gchar *keysym);
nkeynes@1072
    26
nkeynes@1072
    27
@interface KeyBindingEditor (Private)
nkeynes@1072
    28
- (void)updateKeysym: (const gchar *)sym;
nkeynes@1072
    29
@end
nkeynes@1072
    30
nkeynes@1072
    31
@implementation KeyBindingEditor
nkeynes@1072
    32
- (id)init
nkeynes@1072
    33
{
nkeynes@1072
    34
    self = [super init];
nkeynes@1072
    35
    isPrimed = NO;
nkeynes@1072
    36
    lastValue = nil;
nkeynes@1072
    37
    [self setFieldEditor: YES];
nkeynes@1072
    38
    [self setEditable: FALSE];
nkeynes@1072
    39
    return self;
nkeynes@1072
    40
}
nkeynes@1072
    41
- (void)dealloc
nkeynes@1072
    42
{
nkeynes@1072
    43
    if( lastValue != nil ) {
nkeynes@1072
    44
        [lastValue release];
nkeynes@1072
    45
        lastValue = nil;
nkeynes@1072
    46
    }
nkeynes@1072
    47
    [super dealloc];
nkeynes@1072
    48
}
nkeynes@1072
    49
- (void)setPrimed: (BOOL)primed
nkeynes@1072
    50
{
nkeynes@1072
    51
    if( primed != isPrimed ) {
nkeynes@1072
    52
        isPrimed = primed;
nkeynes@1072
    53
        if( primed ) {
nkeynes@1072
    54
            lastValue = [[NSString stringWithString: [self string]] retain];
nkeynes@1072
    55
            [self setString: @"<press key>"];
nkeynes@1072
    56
            input_set_keysym_hook(cocoa_config_keysym_hook, self);
nkeynes@1072
    57
        } else {
nkeynes@1072
    58
            [lastValue release];
nkeynes@1072
    59
            lastValue = nil;
nkeynes@1072
    60
            input_set_keysym_hook(NULL,NULL);
nkeynes@1072
    61
        }
nkeynes@1072
    62
    }
nkeynes@1072
    63
}
nkeynes@1072
    64
- (BOOL)resignFirstResponder
nkeynes@1072
    65
{
nkeynes@1072
    66
    if( isPrimed ) {
nkeynes@1072
    67
        [self setString: lastValue];
nkeynes@1072
    68
        [self setPrimed: NO];
nkeynes@1072
    69
    }
nkeynes@1072
    70
    return [super resignFirstResponder];
nkeynes@1072
    71
}
nkeynes@1072
    72
- (void)fireBindingChanged
nkeynes@1072
    73
{
nkeynes@1072
    74
    id delegate = [self delegate];
nkeynes@1072
    75
    if( delegate != nil && [delegate respondsToSelector:@selector(textDidChange:)] ) {
nkeynes@1072
    76
        [delegate textDidChange: [NSNotification notificationWithName: NSTextDidChangeNotification object: self]];
nkeynes@1072
    77
    }
nkeynes@1072
    78
}
nkeynes@1072
    79
nkeynes@1072
    80
- (void)updateKeysym: (const gchar *)sym
nkeynes@1072
    81
{
nkeynes@1072
    82
    if( sym != NULL ) {
nkeynes@1072
    83
        [self setString: [NSString stringWithCString: sym]];
nkeynes@1072
    84
        [self setPrimed: NO];
nkeynes@1072
    85
        [self fireBindingChanged];
nkeynes@1072
    86
    }
nkeynes@1072
    87
}
nkeynes@1072
    88
- (void)updateMousesym: (int)button
nkeynes@1072
    89
{
nkeynes@1072
    90
    gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, (button+1) );
nkeynes@1072
    91
    if( keysym != NULL ) {
nkeynes@1072
    92
        [self updateKeysym: keysym ];
nkeynes@1072
    93
        g_free(keysym);
nkeynes@1072
    94
    }
nkeynes@1072
    95
}
nkeynes@1072
    96
- (void)keyPressed: (int)keycode
nkeynes@1072
    97
{
nkeynes@1072
    98
    gchar *keysym = input_keycode_to_keysym(NULL, keycode);
nkeynes@1072
    99
    if( keysym != NULL ) {
nkeynes@1072
   100
        [self updateKeysym: keysym];
nkeynes@1072
   101
        g_free(keysym);
nkeynes@1072
   102
    }
nkeynes@1072
   103
}
nkeynes@1072
   104
- (void)insertText:(id)string
nkeynes@1072
   105
{
nkeynes@1072
   106
    // Do nothing
nkeynes@1072
   107
}
nkeynes@1072
   108
- (void)mouseDown: (NSEvent *)event
nkeynes@1072
   109
{
nkeynes@1072
   110
    if( isPrimed ) {
nkeynes@1072
   111
        [self updateMousesym: 0];
nkeynes@1072
   112
    } else {
nkeynes@1072
   113
        [self setPrimed: YES];
nkeynes@1072
   114
        [super mouseDown: event];
nkeynes@1072
   115
    }
nkeynes@1072
   116
}
nkeynes@1072
   117
- (void)rightMouseDown: (NSEvent *)event
nkeynes@1072
   118
{
nkeynes@1072
   119
    if( isPrimed ) {
nkeynes@1072
   120
        [self updateMousesym: 1];
nkeynes@1072
   121
    }
nkeynes@1072
   122
}
nkeynes@1072
   123
- (void)otherMouseDown: (NSEvent *)event
nkeynes@1072
   124
{
nkeynes@1072
   125
    if( isPrimed ) {
nkeynes@1072
   126
        [self updateMousesym: [event buttonNumber]];
nkeynes@1072
   127
    }
nkeynes@1072
   128
}
nkeynes@1072
   129
- (void)keyDown: (NSEvent *) event
nkeynes@1072
   130
{
nkeynes@1072
   131
    NSString *chars = [event characters];
nkeynes@1072
   132
    if( isPrimed ) {
nkeynes@1072
   133
        if( chars != NULL && [chars length] == 1 && [chars characterAtIndex: 0] == 27 ) {
nkeynes@1072
   134
            // Escape char = abort change
nkeynes@1072
   135
            [self setString: lastValue];
nkeynes@1072
   136
            [self setPrimed: NO];
nkeynes@1072
   137
        } else {
nkeynes@1072
   138
            [self keyPressed: ([event keyCode]+1)];
nkeynes@1072
   139
        }
nkeynes@1072
   140
    } else {
nkeynes@1072
   141
        if( chars != NULL && [chars length] == 1 ) {
nkeynes@1072
   142
            int ch = [chars characterAtIndex: 0];
nkeynes@1072
   143
            switch( ch ) {
nkeynes@1072
   144
            case 0x7F:
nkeynes@1072
   145
                [self setString: @""];
nkeynes@1072
   146
                [self fireBindingChanged];
nkeynes@1072
   147
                break;
nkeynes@1072
   148
            case '\r':
nkeynes@1072
   149
                [self setPrimed: YES];
nkeynes@1072
   150
                break;
nkeynes@1072
   151
            default:
nkeynes@1072
   152
                [super keyDown: event];
nkeynes@1072
   153
                break;
nkeynes@1072
   154
            }
nkeynes@1072
   155
        } else {
nkeynes@1072
   156
            [super keyDown: event];
nkeynes@1072
   157
        }
nkeynes@1072
   158
    }
nkeynes@1072
   159
}
nkeynes@1072
   160
- (void)flagsChanged: (NSEvent *) event
nkeynes@1072
   161
{
nkeynes@1072
   162
    if( isPrimed ) {
nkeynes@1072
   163
        [self keyPressed: ([event keyCode]+1)];
nkeynes@1072
   164
    }
nkeynes@1072
   165
    [super flagsChanged: event];
nkeynes@1072
   166
}
nkeynes@1072
   167
@end
nkeynes@1072
   168
nkeynes@1072
   169
static void cocoa_config_keysym_hook(void *data, const gchar *keysym)
nkeynes@1072
   170
{
nkeynes@1072
   171
    KeyBindingEditor *editor = (KeyBindingEditor *)data;
nkeynes@1072
   172
    [editor updateKeysym: keysym];
nkeynes@1072
   173
}
nkeynes@1072
   174
nkeynes@1072
   175
@implementation KeyBindingField
nkeynes@1072
   176
@end
nkeynes@1072
   177
nkeynes@1072
   178
/*************************** Configuration sub-view ***********************/
nkeynes@1072
   179
nkeynes@1072
   180
#define KEYBINDING_SIZE 110
nkeynes@1072
   181
#define DEFAULT_LABEL_WIDTH 150
nkeynes@1072
   182
#define RIGHT_MARGIN 40
nkeynes@1072
   183
nkeynes@1072
   184
@implementation ConfigurationView
nkeynes@1072
   185
- (id)initWithFrame: (NSRect)frameRect
nkeynes@1072
   186
{
nkeynes@1072
   187
    return [self initWithFrame: frameRect configGroup: NULL];
nkeynes@1072
   188
}
nkeynes@1072
   189
- (id)initWithFrame: (NSRect)frameRect configGroup: (lxdream_config_group_t)config
nkeynes@1072
   190
{
nkeynes@1072
   191
    if( [super initWithFrame: frameRect] == nil ) {
nkeynes@1072
   192
        return nil;
nkeynes@1072
   193
    } else {
nkeynes@1072
   194
        group = NULL;
nkeynes@1072
   195
        labelWidth = DEFAULT_LABEL_WIDTH;
nkeynes@1072
   196
        [self setConfigGroup: config];
nkeynes@1072
   197
        return self;
nkeynes@1072
   198
    }
nkeynes@1072
   199
}
nkeynes@1072
   200
- (BOOL)isFlipped
nkeynes@1072
   201
{
nkeynes@1072
   202
    return YES;
nkeynes@1072
   203
}
nkeynes@1072
   204
- (void)setLabelWidth: (int)width
nkeynes@1072
   205
{
nkeynes@1072
   206
    labelWidth = width;
nkeynes@1072
   207
}
nkeynes@1072
   208
- (void)removeSubviews
nkeynes@1072
   209
{
nkeynes@1072
   210
    [[self subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
nkeynes@1072
   211
}
nkeynes@1072
   212
- (void)updateField: (int)binding
nkeynes@1072
   213
{
nkeynes@1072
   214
    const gchar *p = NULL;
nkeynes@1072
   215
    NSString *val1 = [fields[binding][0] stringValue];
nkeynes@1072
   216
     if( fields[binding][1] == NULL ) {
nkeynes@1072
   217
         p = [val1 UTF8String];
nkeynes@1072
   218
         lxdream_set_config_value( group, binding, p );
nkeynes@1072
   219
     } else {
nkeynes@1072
   220
         NSString *val2 = [fields[binding][1] stringValue];
nkeynes@1072
   221
         char buf[ [val1 length] + [val2 length] + 2 ];
nkeynes@1072
   222
nkeynes@1072
   223
         if( [val1 length] == 0 ) {
nkeynes@1072
   224
             if( [val2 length] != 0 ) {
nkeynes@1072
   225
                 p = [val2 UTF8String];
nkeynes@1072
   226
             }
nkeynes@1072
   227
         } else if( [val2 length] == 0 ) {
nkeynes@1072
   228
             p = [val1 UTF8String];
nkeynes@1072
   229
         } else {
nkeynes@1072
   230
             sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );
nkeynes@1072
   231
             p = buf;
nkeynes@1072
   232
         }
nkeynes@1072
   233
         lxdream_set_config_value( group, binding, p );
nkeynes@1072
   234
     }
nkeynes@1072
   235
     lxdream_save_config();
nkeynes@1072
   236
}
nkeynes@1072
   237
nkeynes@1072
   238
- (void)controlTextDidChange: (NSNotification *)notify
nkeynes@1072
   239
{
nkeynes@1072
   240
    if( [[notify object] isKindOfClass: [KeyBindingField class]] ) {
nkeynes@1072
   241
        [self updateField: [[notify object] tag]];
nkeynes@1072
   242
    }
nkeynes@1072
   243
}
nkeynes@1072
   244
- (void)controlTextDidEndEditing: (NSNotification *)notify
nkeynes@1072
   245
{
nkeynes@1072
   246
    [self updateField: [[notify object] tag]];
nkeynes@1072
   247
}
nkeynes@1072
   248
nkeynes@1072
   249
- (void)openFileDialog: (id)sender
nkeynes@1072
   250
{
nkeynes@1072
   251
    int tag = [sender tag];
nkeynes@1298
   252
    /* NSString *text = [fields[tag][0] stringValue]; */
nkeynes@1072
   253
    NSOpenPanel *panel = [NSOpenPanel openPanel];
nkeynes@1072
   254
    int result = [panel runModalForDirectory: nil file: nil types: nil];
nkeynes@1072
   255
    if( result == NSOKButton && [[panel filenames] count] > 0 ) {
nkeynes@1072
   256
        NSString *filename = [[panel filenames] objectAtIndex: 0];
nkeynes@1072
   257
        gchar *str = get_escaped_path( [filename UTF8String] );
nkeynes@1072
   258
        [fields[tag][0] setStringValue: [NSString stringWithUTF8String: str]];
nkeynes@1072
   259
        lxdream_set_global_config_value(tag,str);
nkeynes@1072
   260
        lxdream_save_config();
nkeynes@1072
   261
    }
nkeynes@1072
   262
}
nkeynes@1072
   263
- (void)openDirDialog: (id)sender
nkeynes@1072
   264
{
nkeynes@1072
   265
    int tag = [sender tag];
nkeynes@1298
   266
    /* NSString *text = [fields[tag][0] stringValue]; */
nkeynes@1072
   267
    NSOpenPanel *panel = [NSOpenPanel openPanel];
nkeynes@1072
   268
    [panel setCanChooseDirectories: YES];
nkeynes@1072
   269
    [panel setCanCreateDirectories: YES];
nkeynes@1072
   270
    int result = [panel runModalForDirectory: nil file: nil types: nil];
nkeynes@1072
   271
    if( result == NSOKButton && [[panel filenames] count] > 0 ) {
nkeynes@1072
   272
        NSString *filename = [[panel filenames] objectAtIndex: 0];
nkeynes@1072
   273
        gchar *str = get_escaped_path( [filename UTF8String] );
nkeynes@1072
   274
        [fields[tag][0] setStringValue: [NSString stringWithUTF8String: str]];
nkeynes@1072
   275
        lxdream_set_global_config_value(tag,str);
nkeynes@1072
   276
        lxdream_save_config();
nkeynes@1072
   277
    }
nkeynes@1072
   278
}
nkeynes@1072
   279
nkeynes@1072
   280
- (void)setConfigGroup: (lxdream_config_group_t) config
nkeynes@1072
   281
{
nkeynes@1072
   282
    if( group == config ) {
nkeynes@1072
   283
        return;
nkeynes@1072
   284
    }
nkeynes@1072
   285
    int width = [self frame].size.width;
nkeynes@1072
   286
    int fieldWidth;
nkeynes@1072
   287
nkeynes@1072
   288
    group = config;
nkeynes@1072
   289
    [self removeSubviews];
nkeynes@1072
   290
    if( config != NULL && config->params[0].key != NULL ) {
nkeynes@1072
   291
        int count, i, y, x;
nkeynes@1072
   292
nkeynes@1072
   293
        for( count=0; config->params[count].label != NULL; count++ );
nkeynes@1072
   294
        int minWidth = labelWidth+KEYBINDING_SIZE*2+TEXT_GAP*4;
nkeynes@1072
   295
        if( minWidth > width ) {
nkeynes@1072
   296
            width = minWidth;
nkeynes@1072
   297
        }
nkeynes@1072
   298
        NSSize size = NSMakeSize( width, count*(TEXT_HEIGHT+TEXT_GAP)+TEXT_GAP);
nkeynes@1072
   299
        [self setFrameSize: size];
nkeynes@1072
   300
        [self scrollRectToVisible: NSMakeRect(0,0,1,1)];
nkeynes@1072
   301
nkeynes@1072
   302
        x = TEXT_GAP;
nkeynes@1072
   303
        y = TEXT_GAP;
nkeynes@1072
   304
        for( i=0; config->params[i].label != NULL; i++ ) {
nkeynes@1072
   305
            /* Add label */
nkeynes@1072
   306
            NSRect frame = NSMakeRect(x, y + 2, labelWidth, LABEL_HEIGHT);
nkeynes@1072
   307
            NSTextField *label = cocoa_gui_add_label(self, NS_(config->params[i].label), frame);
nkeynes@1072
   308
            [label setAlignment: NSRightTextAlignment];
nkeynes@1072
   309
nkeynes@1072
   310
            switch(config->params[i].type) {
nkeynes@1072
   311
            case CONFIG_TYPE_KEY:
nkeynes@1072
   312
                frame = NSMakeRect( x + labelWidth + TEXT_GAP, y, KEYBINDING_SIZE, TEXT_HEIGHT);
nkeynes@1072
   313
                fields[i][0] = [[KeyBindingField alloc] initWithFrame: frame];
nkeynes@1072
   314
                [fields[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
nkeynes@1072
   315
                [fields[i][0] setTag: i];
nkeynes@1298
   316
                [fields[i][0] setDelegate: (id)self];
nkeynes@1072
   317
                [self addSubview: fields[i][0]];
nkeynes@1072
   318
nkeynes@1072
   319
                frame = NSMakeRect( x + labelWidth + KEYBINDING_SIZE + (TEXT_GAP*2), y, KEYBINDING_SIZE, TEXT_HEIGHT);
nkeynes@1072
   320
                fields[i][1] = [[KeyBindingField alloc] initWithFrame: frame];
nkeynes@1072
   321
                [fields[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
nkeynes@1072
   322
                [fields[i][1] setTag: i];
nkeynes@1298
   323
                [fields[i][1] setDelegate: (id)self];
nkeynes@1072
   324
                [self addSubview: fields[i][1]];
nkeynes@1072
   325
nkeynes@1072
   326
                if( config->params[i].value != NULL ) {
nkeynes@1072
   327
                    gchar **parts = g_strsplit(config->params[i].value,",",3);
nkeynes@1072
   328
                    if( parts[0] != NULL ) {
nkeynes@1072
   329
                        [fields[i][0] setStringValue: [NSString stringWithCString: parts[0]]];
nkeynes@1072
   330
                        if( parts[1] != NULL ) {
nkeynes@1072
   331
                            [fields[i][1] setStringValue: [NSString stringWithCString: parts[1]]];
nkeynes@1072
   332
                        }
nkeynes@1072
   333
                    }
nkeynes@1072
   334
                    g_strfreev(parts);
nkeynes@1072
   335
                }
nkeynes@1072
   336
                break;
nkeynes@1072
   337
            case CONFIG_TYPE_FILE:
nkeynes@1072
   338
            case CONFIG_TYPE_PATH:
nkeynes@1072
   339
                fieldWidth = width - labelWidth - x - TEXT_HEIGHT - RIGHT_MARGIN - (TEXT_GAP*2);
nkeynes@1072
   340
                frame = NSMakeRect( x + labelWidth + TEXT_GAP, y, fieldWidth, TEXT_HEIGHT );
nkeynes@1072
   341
                NSTextField *field = [[NSTextField alloc] initWithFrame: frame];
nkeynes@1072
   342
                [field setTag: i];
nkeynes@1072
   343
                [field setStringValue: [NSString stringWithCString: config->params[i].value]];
nkeynes@1298
   344
                [field setDelegate: (id)self];
nkeynes@1072
   345
                [field setAutoresizingMask: (NSViewMinYMargin|NSViewWidthSizable)];
nkeynes@1072
   346
nkeynes@1072
   347
                frame = NSMakeRect( x+ labelWidth + fieldWidth + (TEXT_GAP*2), y,  TEXT_HEIGHT, TEXT_HEIGHT );
nkeynes@1072
   348
                NSButton *button = [[NSButton alloc] initWithFrame: frame];
nkeynes@1072
   349
                [button setTag: i];
nkeynes@1072
   350
                [button setTitle: @""];
nkeynes@1072
   351
                [button setButtonType: NSMomentaryPushInButton];
nkeynes@1072
   352
                [button setBezelStyle: NSRoundedDisclosureBezelStyle];
nkeynes@1072
   353
                [button setAutoresizingMask: (NSViewMinYMargin|NSViewMinXMargin)];
nkeynes@1072
   354
                [button setTarget: self];
nkeynes@1072
   355
                if( config->params[i].type == CONFIG_TYPE_FILE ) {
nkeynes@1072
   356
                    [button setAction: @selector(openFileDialog:)];
nkeynes@1072
   357
                } else {
nkeynes@1072
   358
                    [button setAction: @selector(openDirDialog:)];
nkeynes@1072
   359
                }
nkeynes@1072
   360
nkeynes@1072
   361
                [self addSubview: label];
nkeynes@1072
   362
                [self addSubview: field];
nkeynes@1072
   363
                [self addSubview: button];
nkeynes@1072
   364
                fields[i][0] = field;
nkeynes@1072
   365
                fields[i][1] = NULL;
nkeynes@1072
   366
            }
nkeynes@1072
   367
            y += (TEXT_HEIGHT + TEXT_GAP);
nkeynes@1072
   368
        }
nkeynes@1072
   369
    } else {
nkeynes@1072
   370
        [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];
nkeynes@1072
   371
    }
nkeynes@1072
   372
}
nkeynes@1072
   373
nkeynes@1072
   374
- (void)setDevice: (maple_device_t)newDevice
nkeynes@1072
   375
{
nkeynes@1072
   376
    if( newDevice != NULL && !MAPLE_IS_VMU(newDevice) ) {
nkeynes@1072
   377
        [self setConfigGroup: maple_get_device_config(newDevice)];
nkeynes@1072
   378
    } else {
nkeynes@1072
   379
        [self setConfigGroup: NULL];
nkeynes@1072
   380
    }
nkeynes@1072
   381
}
nkeynes@1072
   382
@end
nkeynes@1072
   383
.