Subversion Repositories gelsvn

Rev

Rev 657 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 657 Rev 659
1
#import "BasicOpenGLView.h"
1
#import "BasicOpenGLView.h"
2
#include <GLGraphics/MeshEditor.h>
2
#include <GLGraphics/MeshEditor.h>
3
 
3
 
4
using namespace CGLA;
4
using namespace CGLA;
5
using namespace GLGraphics;
5
using namespace GLGraphics;
6
 
6
 
7
MeshEditor me;
7
MeshEditor me;
8
 
8
 
9
// ==================================
9
// ==================================
10
#pragma mark ---- Error Reporting ----
10
#pragma mark ---- Error Reporting ----
11
 
11
 
12
// error reporting as both window message and debugger string
12
// error reporting as both window message and debugger string
13
void reportError (char * strError, int where)
13
void reportError (char * strError, int where)
14
{
14
{
15
    NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
15
    NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
16
    [attribs setObject: [NSFont fontWithName: @"Monaco" size: 9.0f] forKey: NSFontAttributeName];
16
    [attribs setObject: [NSFont fontWithName: @"Monaco" size: 9.0f] forKey: NSFontAttributeName];
17
    [attribs setObject: [NSColor whiteColor] forKey: NSForegroundColorAttributeName];
17
    [attribs setObject: [NSColor whiteColor] forKey: NSForegroundColorAttributeName];
18
    
18
    
19
    //	gErrorTime = getElapsedTime ();
19
    //	gErrorTime = getElapsedTime ();
20
	NSString * errString = [NSString stringWithFormat:@"Error: %s @ line %d", strError, where ];
20
	NSString * errString = [NSString stringWithFormat:@"Error: %s @ line %d", strError, where ];
21
	NSLog (@"%@\n", errString);
21
	NSLog (@"%@\n", errString);
22
}
22
}
23
 
23
 
24
// ---------------------------------
24
// ---------------------------------
25
 
25
 
26
// if error dump gl errors to debugger string, return error
26
// if error dump gl errors to debugger string, return error
27
GLenum glReportError (int where = -1)
27
GLenum glReportError (int where = -1)
28
{
28
{
29
	GLenum err = glGetError();
29
	GLenum err = glGetError();
30
	if (GL_NO_ERROR != err)
30
	if (GL_NO_ERROR != err)
31
		reportError ((char *) gluErrorString (err), where);
31
		reportError ((char *) gluErrorString (err), where);
32
	return err;
32
	return err;
33
}
33
}
34
 
34
 
35
#pragma mark ---- OpenGL Utils ----
35
#pragma mark ---- OpenGL Utils ----
36
 
36
 
37
// ---------------------------------
37
// ---------------------------------
38
 
38
 
39
 
39
 
40
// ===================================
40
// ===================================
41
 
41
 
42
@implementation BasicOpenGLView
42
@implementation BasicOpenGLView
43
 
43
 
44
// ---------------------------------
44
// ---------------------------------
45
 
45
 
46
// handles resizing of GL need context update and if the window dimensions change, a
46
// handles resizing of GL need context update and if the window dimensions change, a
47
// a window dimension update, reseting of viewport and an update of the projection matrix
47
// a window dimension update, reseting of viewport and an update of the projection matrix
48
- (void) reshape
48
- (void) reshape
49
{
49
{
50
    NSRect backRect = [self convertRectToBacking:[self bounds]];
50
    NSRect backRect = [self convertRectToBacking:[self bounds]];
51
    glViewport (0, 0, NSWidth(backRect), NSHeight(backRect));
51
    glViewport (0, 0, NSWidth(backRect), NSHeight(backRect));
52
	me.reshape(NSWidth(backRect),NSHeight(backRect));
52
	me.reshape(NSWidth(backRect),NSHeight(backRect));
53
}
53
}
54
 
54
 
55
// ---------------------------------
55
// ---------------------------------
56
// ---------------------------------
56
// ---------------------------------
57
 
57
 
58
// per-window timer function, basic time based animation preformed here
58
// per-window timer function, basic time based animation preformed here
59
- (void)animationTimer:(NSTimer *)timer
59
- (void)animationTimer:(NSTimer *)timer
60
{
60
{
61
    if(me.try_spinning_ball())
61
    if(me.try_spinning_ball())
62
        [self setNeedsDisplay: YES];
62
        [self setNeedsDisplay: YES];
63
}
63
}
64
 
64
 
65
-(IBAction)save_window_to_pasteboard:(id)sender
65
-(IBAction)save_window_to_pasteboard:(id)sender
66
{
66
{
67
    
67
    // Get the pasteboard.
68
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
68
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
69
    
69
    
70
    // Telling the pasteboard what type of data we're going to send in
70
    // Telling the pasteboard what type of data we're going to send in
71
    [pb declareTypes:[NSArray arrayWithObjects:NSPasteboardTypePNG,nil] owner:self];
71
    [pb declareTypes:[NSArray arrayWithObjects:NSPasteboardTypePNG,nil] owner:self];
72
    
72
    
-
 
73
    // Get the size of the image in a retina safe way
73
    NSRect backRect = [self convertRectToBacking: [self bounds]];
74
    NSRect backRect = [self convertRectToBacking: [self bounds]];
74
    NSSize sz;
-
 
75
    sz.width = NSWidth(backRect);
75
    int W = NSWidth(backRect);
76
    sz.height = NSHeight(backRect);
76
    int H = NSHeight(backRect);
77
    
77
 
-
 
78
    // Create image. Note no alpha channel. I don't copy that.
78
    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
79
    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
79
                                                                    pixelsWide: sz.width
80
                                                                    pixelsWide: W
80
                                                                    pixelsHigh: sz.height
81
                                                                    pixelsHigh: H
81
                                                                 bitsPerSample: 8
82
                                                                 bitsPerSample: 8
82
                                                               samplesPerPixel: 3
83
                                                               samplesPerPixel: 3
83
                                                                      hasAlpha: NO
84
                                                                      hasAlpha: NO
84
                                                                      isPlanar: NO
85
                                                                      isPlanar: NO
85
                                                                colorSpaceName: NSCalibratedRGBColorSpace
86
                                                                colorSpaceName: NSCalibratedRGBColorSpace
86
                                                                   bytesPerRow: 0				// indicates no empty bytes at row end
87
                                                                   bytesPerRow: 3*W
87
                                                                  bitsPerPixel: 0];
88
                                                                  bitsPerPixel: 0];
88
    
89
    
-
 
90
    // The following block does the actual reading of the image
-
 
91
    glPushAttrib(GL_PIXEL_MODE_BIT); // Save state about reading buffers
89
    glReadBuffer(GL_FRONT);
92
    glReadBuffer(GL_FRONT);
90
    int bytesPerRow = [rep bytesPerRow];
-
 
91
	glPixelStorei(GL_PACK_ROW_LENGTH, 8*bytesPerRow/[rep bitsPerPixel]);
93
    glPixelStorei(GL_PACK_ALIGNMENT, 1); // Dense packing
92
    glReadPixels(0, 0, NSWidth(backRect), NSHeight(backRect), GL_RGB, GL_UNSIGNED_BYTE,  [rep bitmapData]);
94
    glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, [rep bitmapData]);
-
 
95
    glPopAttrib();
93
    
96
    
-
 
97
    // So we need one more image, since we must flip its orientation.
94
    NSBitmapImageRep* flipped =  [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
98
    NSBitmapImageRep* flipped =  [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
95
                                                                         pixelsWide: sz.width
99
                                                                         pixelsWide: W
96
                                                                         pixelsHigh: sz.height
100
                                                                         pixelsHigh: H
97
                                                                      bitsPerSample: 8
101
                                                                      bitsPerSample: 8
98
                                                                    samplesPerPixel: 3
102
                                                                    samplesPerPixel: 3
99
                                                                           hasAlpha: NO
103
                                                                           hasAlpha: NO
100
                                                                           isPlanar: NO
104
                                                                           isPlanar: NO
101
                                                                     colorSpaceName: NSCalibratedRGBColorSpace
105
                                                                     colorSpaceName: NSCalibratedRGBColorSpace
102
                                                                        bytesPerRow: 0				// indicates no empty bytes at row end
106
                                                                        bytesPerRow: 3*W
103
                                                                       bitsPerPixel: 0];
107
                                                                       bitsPerPixel: 0];
104
    
108
    
-
 
109
    // Primitive double for loop flipping the row order. Should be a better way. Can't find it.
105
    for(int j=1; j< sz.height+1; ++j)
110
    for(int j=1; j< H+1; ++j)
106
        for(int i=0;i<sz.width;++i)
111
        for(int i=0;i<W;++i)
107
        {
112
        {
108
            NSUInteger pixels[4];
113
            NSUInteger pixels[4];
109
            [rep getPixel: pixels atX:i y:j];
114
            [rep getPixel: pixels atX:i y:j];
110
            [flipped setPixel: pixels atX:i y:sz.height-j];
115
            [flipped setPixel: pixels atX:i y:H-j];
111
        }
116
        }
112
    
117
    
113
    // Converting the representation to PNG and sending it to the pasteboard (with type indicated)
118
    // Converting the representation to PNG and sending it to the pasteboard (with type indicated)
114
    [pb setData:[flipped representationUsingType:NSPNGFileType properties:nil] forType:NSPasteboardTypePNG];
119
    [pb setData:[flipped representationUsingType:NSPNGFileType properties:nil] forType:NSPasteboardTypePNG];
115
    
-
 
116
    
-
 
117
    
-
 
118
}
120
}
119
 
121
 
120
 
122
 
121
 
123
 
122
-(void)keyDown:(NSEvent *)theEvent
124
-(void)keyDown:(NSEvent *)theEvent
123
{
125
{
124
    switch ([theEvent keyCode]) {
126
    switch ([theEvent keyCode]) {
125
        case 123:
127
        case 123:
126
            me.key_left();
128
            me.key_left();
127
            break;
129
            break;
128
        case 124:
130
        case 124:
129
            me.key_right();
131
            me.key_right();
130
            break;
132
            break;
131
        case 126:
133
        case 126:
132
            me.key_up();
134
            me.key_up();
133
            break;
135
            break;
134
        case 125:
136
        case 125:
135
            me.key_down();
137
            me.key_down();
136
            break;
138
            break;
137
        case 115:
139
        case 115:
138
            me.key_home();
140
            me.key_home();
139
            break;
141
            break;
140
        case 119:
142
        case 119:
141
            me.key_end();
143
            me.key_end();
142
            break;
144
            break;
143
        default:
145
        default:
144
            NSString *characters = [theEvent characters];
146
            NSString *characters = [theEvent characters];
145
            if ([characters length]) {
147
            if ([characters length]) {
146
                unichar character = [characters characterAtIndex:0];
148
                unichar character = [characters characterAtIndex:0];
147
                me.keyparse(character);
149
                me.keyparse(character);
148
            }
150
            }
149
            break;
151
            break;
150
    }
152
    }
151
    [self setNeedsDisplay: YES];
153
    [self setNeedsDisplay: YES];
152
}
154
}
153
 
155
 
154
 
156
 
155
// ---------------------------------
157
// ---------------------------------
156
 
158
 
157
- (void)mouseDown:(NSEvent *)theEvent // trackball
159
- (void)mouseDown:(NSEvent *)theEvent // trackball
158
{
160
{
159
    if ([theEvent modifierFlags] & NSAlternateKeyMask) // send to pan
161
    if ([theEvent modifierFlags] & NSAlternateKeyMask) // send to pan
160
		[self rightMouseDown:theEvent];
162
		[self rightMouseDown:theEvent];
161
	else {
163
	else {
162
        
164
        
163
        NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
165
        NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
164
        [[self openGLContext] makeCurrentContext];
166
        [[self openGLContext] makeCurrentContext];
165
        Vec2i pos(location.x,location.y);
167
        Vec2i pos(location.x,location.y);
166
        pos *= int([[self window]backingScaleFactor]);
168
        pos *= int([[self window]backingScaleFactor]);
167
        if([theEvent modifierFlags] & NSShiftKeyMask)
169
        if([theEvent modifierFlags] & NSShiftKeyMask)
168
            me.grab_mesh(pos);
170
            me.grab_mesh(pos);
169
        else if([theEvent modifierFlags] & NSControlKeyMask) {
171
        else if([theEvent modifierFlags] & NSControlKeyMask) {
170
            if(me.select_vertex(pos))
172
            if(me.select_vertex(pos))
171
                [self setNeedsDisplay: YES];
173
                [self setNeedsDisplay: YES];
172
        }
174
        }
173
        else
175
        else
174
            me.grab_ball(ROTATE_ACTION,pos);
176
            me.grab_ball(ROTATE_ACTION,pos);
175
	}
177
	}
176
}
178
}
177
 
179
 
178
 
180
 
179
 
181
 
180
// ---------------------------------
182
// ---------------------------------
181
 
183
 
182
- (void)rightMouseDown:(NSEvent *)theEvent // pan
184
- (void)rightMouseDown:(NSEvent *)theEvent // pan
183
{
185
{
184
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
186
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
185
    Vec2i pos(location.x,location.y);
187
    Vec2i pos(location.x,location.y);
186
    pos *= int([[self window]backingScaleFactor]);
188
    pos *= int([[self window]backingScaleFactor]);
187
    me.grab_ball(PAN_ACTION,pos);
189
    me.grab_ball(PAN_ACTION,pos);
188
}
190
}
189
 
191
 
190
// ---------------------------------
192
// ---------------------------------
191
 
193
 
192
- (void)otherMouseDown:(NSEvent *)theEvent //dolly
194
- (void)otherMouseDown:(NSEvent *)theEvent //dolly
193
{
195
{
194
}
196
}
195
 
197
 
196
// ---------------------------------
198
// ---------------------------------
197
 
199
 
198
- (void)mouseUp:(NSEvent *)theEvent
200
- (void)mouseUp:(NSEvent *)theEvent
199
{
201
{
200
    me.release_mesh();
202
    me.release_mesh();
201
    me.release_ball();
203
    me.release_ball();
202
}
204
}
203
 
205
 
204
// ---------------------------------
206
// ---------------------------------
205
 
207
 
206
- (void)rightMouseUp:(NSEvent *)theEvent
208
- (void)rightMouseUp:(NSEvent *)theEvent
207
{
209
{
208
	[self mouseUp:theEvent];
210
	[self mouseUp:theEvent];
209
}
211
}
210
 
212
 
211
// ---------------------------------
213
// ---------------------------------
212
 
214
 
213
- (void)otherMouseUp:(NSEvent *)theEvent
215
- (void)otherMouseUp:(NSEvent *)theEvent
214
{
216
{
215
	[self mouseUp:theEvent];
217
	[self mouseUp:theEvent];
216
}
218
}
217
 
219
 
218
// ---------------------------------
220
// ---------------------------------
219
 
221
 
220
- (void)mouseDragged:(NSEvent *)theEvent
222
- (void)mouseDragged:(NSEvent *)theEvent
221
{
223
{
222
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
224
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
223
    Vec2i pos(location.x,location.y);
225
    Vec2i pos(location.x,location.y);
224
    pos *= int([[self window]backingScaleFactor]);
226
    pos *= int([[self window]backingScaleFactor]);
225
//    NSLog(@"Pos <%d %d> ", pos[0], pos[1]);
227
//    NSLog(@"Pos <%d %d> ", pos[0], pos[1]);
226
    [[self openGLContext] makeCurrentContext];
228
    [[self openGLContext] makeCurrentContext];
227
    if(!me.drag_mesh(pos))
229
    if(!me.drag_mesh(pos))
228
        me.roll_ball(pos);
230
        me.roll_ball(pos);
229
    [self setNeedsDisplay: YES];
231
    [self setNeedsDisplay: YES];
230
    
232
    
231
}
233
}
232
 
234
 
233
// ---------------------------------
235
// ---------------------------------
234
 
236
 
235
- (void)scrollWheel:(NSEvent *)theEvent
237
- (void)scrollWheel:(NSEvent *)theEvent
236
{
238
{
237
    Vec2i pos(0,300);
239
    Vec2i pos(0,300);
238
    me.grab_ball(ZOOM_ACTION,pos);
240
    me.grab_ball(ZOOM_ACTION,pos);
239
    pos[1] -= 3*[theEvent deltaY];
241
    pos[1] -= 3*[theEvent deltaY];
240
    me.roll_ball(pos);
242
    me.roll_ball(pos);
241
    me.release_ball();
243
    me.release_ball();
242
    [self setNeedsDisplay: YES];
244
    [self setNeedsDisplay: YES];
243
}
245
}
244
 
246
 
245
// ---------------------------------
247
// ---------------------------------
246
 
248
 
247
- (void)rightMouseDragged:(NSEvent *)theEvent
249
- (void)rightMouseDragged:(NSEvent *)theEvent
248
{
250
{
249
	[self mouseDragged: theEvent];
251
	[self mouseDragged: theEvent];
250
}
252
}
251
 
253
 
252
// ---------------------------------
254
// ---------------------------------
253
 
255
 
254
- (void)otherMouseDragged:(NSEvent *)theEvent
256
- (void)otherMouseDragged:(NSEvent *)theEvent
255
{
257
{
256
	[self mouseDragged: theEvent];
258
	[self mouseDragged: theEvent];
257
}
259
}
258
 
260
 
259
// ---------------------------------
261
// ---------------------------------
260
 
262
 
261
- (void) drawRect:(NSRect)rect
263
- (void) drawRect:(NSRect)rect
262
{
264
{
263
    NSOpenGLContext* ctxt = [self openGLContext];
265
    NSOpenGLContext* ctxt = [self openGLContext];
264
    if(ctxt != nil) {
266
    if(ctxt != nil) {
265
        [ctxt makeCurrentContext];
267
        [ctxt makeCurrentContext];
266
        me.display(int([[self window]backingScaleFactor]));
268
        me.display(int([[self window]backingScaleFactor]));
267
        [ctxt flushBuffer];
269
        [ctxt flushBuffer];
268
    }
270
    }
269
}
271
}
270
 
272
 
271
// ---------------------------------
273
// ---------------------------------
272
 
274
 
273
// set initial OpenGL state (current context is set)
275
// set initial OpenGL state (current context is set)
274
// called after context is created
276
// called after context is created
275
- (void) prepareOpenGL
277
- (void) prepareOpenGL
276
{
278
{
277
    [[self openGLContext] makeCurrentContext];
279
    [[self openGLContext] makeCurrentContext];
278
    GLint swapInt = 1;
280
    GLint swapInt = 1;
279
    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
281
    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
280
    me.init();
282
    me.init();
281
    NSLog(@"OpenGL Initialized");
283
    NSLog(@"OpenGL Initialized");
282
}
284
}
283
// ---------------------------------
285
// ---------------------------------
284
 
286
 
285
// this can be a troublesome call to do anything heavyweight, as it is called on window moves, resizes, and display config changes.  So be
287
// this can be a troublesome call to do anything heavyweight, as it is called on window moves, resizes, and display config changes.  So be
286
// careful of doing too much here.
288
// careful of doing too much here.
287
- (void) update // window resizes, moves and display changes (resize, depth and display config change)
289
- (void) update // window resizes, moves and display changes (resize, depth and display config change)
288
{
290
{
289
	[super update];
291
	[super update];
290
	if (![self inLiveResize])  {// if not doing live resize
292
	if (![self inLiveResize])  {// if not doing live resize
291
	}
293
	}
292
    
294
    
293
}
295
}
294
 
296
 
295
// ---------------------------------
297
// ---------------------------------
296
 
298
 
297
-(id) initWithFrame: (NSRect) frameRect
299
-(id) initWithFrame: (NSRect) frameRect
298
{
300
{
299
	self = [super initWithFrame: frameRect ];
301
	self = [super initWithFrame: frameRect ];
300
    return self;
302
    return self;
301
}
303
}
302
 
304
 
303
// ---------------------------------
305
// ---------------------------------
304
 
306
 
305
- (BOOL)acceptsFirstResponder
307
- (BOOL)acceptsFirstResponder
306
{
308
{
307
    return YES;
309
    return YES;
308
}
310
}
309
 
311
 
310
// ---------------------------------
312
// ---------------------------------
311
 
313
 
312
- (BOOL)becomeFirstResponder
314
- (BOOL)becomeFirstResponder
313
{
315
{
314
    return  YES;
316
    return  YES;
315
}
317
}
316
 
318
 
317
// ---------------------------------
319
// ---------------------------------
318
 
320
 
319
- (BOOL)resignFirstResponder
321
- (BOOL)resignFirstResponder
320
{
322
{
321
    return YES;
323
    return YES;
322
}
324
}
323
 
325
 
324
// ---------------------------------
326
// ---------------------------------
325
 
327
 
326
- (void) awakeFromNib
328
- (void) awakeFromNib
327
{
329
{
328
	timer = [NSTimer timerWithTimeInterval:(1.0f/60.0f) target:self selector:@selector(animationTimer:) userInfo:nil repeats:YES];
330
	timer = [NSTimer timerWithTimeInterval:(1.0f/60.0f) target:self selector:@selector(animationTimer:) userInfo:nil repeats:YES];
329
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
331
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
330
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; // ensure timer fires during resize
332
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; // ensure timer fires during resize
331
    [[NSApplication sharedApplication] setDelegate: self];
333
    [[NSApplication sharedApplication] setDelegate: self];
332
    [self registerForDraggedTypes: [NSArray arrayWithObjects: (id) kUTTypeData,nil]];
334
    [self registerForDraggedTypes: [NSArray arrayWithObjects: (id) kUTTypeData,nil]];
333
}
335
}
334
 
336
 
335
-(IBAction)open_file_dialog:(id)sender
337
-(IBAction)open_file_dialog:(id)sender
336
{
338
{
337
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];
339
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];
338
    [openDlg setCanChooseFiles:YES];
340
    [openDlg setCanChooseFiles:YES];
339
    [openDlg setCanChooseDirectories:NO];
341
    [openDlg setCanChooseDirectories:NO];
340
    [openDlg setAllowsMultipleSelection:YES];
342
    [openDlg setAllowsMultipleSelection:YES];
341
    if ( [openDlg runModal] == NSOKButton )
343
    if ( [openDlg runModal] == NSOKButton )
342
        for(NSURL *fileURL in [openDlg URLs]) {
344
        for(NSURL *fileURL in [openDlg URLs]) {
343
            me.add_file([ [fileURL path] UTF8String]);
345
            me.add_file([ [fileURL path] UTF8String]);
344
            [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
346
            [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
345
        }
347
        }
346
    [self setNeedsDisplay: YES];
348
    [self setNeedsDisplay: YES];
347
}
349
}
348
 
350
 
349
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
351
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
350
{
352
{
351
    if(me.add_file([ filename UTF8String])) {
353
    if(me.add_file([ filename UTF8String])) {
352
        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
354
        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
353
        [self setNeedsDisplay: YES];
355
        [self setNeedsDisplay: YES];
354
        return YES;
356
        return YES;
355
    }
357
    }
356
    return NO;
358
    return NO;
357
}
359
}
358
 
360
 
359
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
361
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
360
{
362
{
361
    NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
363
    NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
362
    me.add_file([[fileURL path] UTF8String]);
364
    me.add_file([[fileURL path] UTF8String]);
363
    [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
365
    [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
364
    [self setNeedsDisplay: YES];
366
    [self setNeedsDisplay: YES];
365
    return YES;
367
    return YES;
366
}
368
}
367
 
369
 
368
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
370
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
369
{
371
{
370
    return YES;
372
    return YES;
371
}
373
}
372
 
374
 
373
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
375
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
374
{
376
{
375
    return NSDragOperationCopy;
377
    return NSDragOperationCopy;
376
}
378
}
377
 
379
 
378
 
380
 
379
@end
381
@end
380
 
382