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