| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #import "SkNSView.h" | 9 #import "SkNSView.h" |
| 10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
| 11 #include "SkCGUtils.h" | 11 #include "SkCGUtils.h" |
| 12 #include "SkEvent.h" | 12 #include "SkEvent.h" |
| 13 SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build); | 13 SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build); |
| 14 | 14 |
| 15 //#define FORCE_REDRAW | 15 //#define FORCE_REDRAW |
| 16 // Can be dropped when we no longer support 10.6. |
| 17 #define RETINA_API_AVAILABLE (defined(MAC_OS_X_VERSION_10_7) && \ |
| 18 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_1
0_7) |
| 16 @implementation SkNSView | 19 @implementation SkNSView |
| 17 @synthesize fWind, fTitle, fOptionsDelegate, fGLContext; | 20 @synthesize fWind, fTitle, fOptionsDelegate, fGLContext; |
| 18 | 21 |
| 19 - (id)initWithCoder:(NSCoder*)coder { | 22 - (id)initWithCoder:(NSCoder*)coder { |
| 20 if ((self = [super initWithCoder:coder])) { | 23 if ((self = [super initWithCoder:coder])) { |
| 21 self = [self initWithDefaults]; | 24 self = [self initWithDefaults]; |
| 22 [self setUpWindow]; | 25 [self setUpWindow]; |
| 23 } | 26 } |
| 24 return self; | 27 return self; |
| 25 } | 28 } |
| 26 | 29 |
| 27 - (id)initWithFrame:(NSRect)frameRect { | 30 - (id)initWithFrame:(NSRect)frameRect { |
| 28 if ((self = [super initWithFrame:frameRect])) { | 31 if ((self = [super initWithFrame:frameRect])) { |
| 29 self = [self initWithDefaults]; | 32 self = [self initWithDefaults]; |
| 30 [self setUpWindow]; | 33 [self setUpWindow]; |
| 31 } | 34 } |
| 32 return self; | 35 return self; |
| 33 } | 36 } |
| 34 | 37 |
| 35 - (id)initWithDefaults { | 38 - (id)initWithDefaults { |
| 39 #if RETINA_API_AVAILABLE |
| 40 [self setWantsBestResolutionOpenGLSurface:YES]; |
| 41 #endif |
| 36 fRedrawRequestPending = false; | 42 fRedrawRequestPending = false; |
| 37 fWind = NULL; | 43 fWind = NULL; |
| 38 return self; | 44 return self; |
| 39 } | 45 } |
| 40 | 46 |
| 41 - (void)setUpWindow { | 47 - (void)setUpWindow { |
| 48 [[NSNotificationCenter defaultCenter] addObserver:self |
| 49 selector:@selector(backingPropertiesCh
anged:) |
| 50 name:@"NSWindowDidChangeBackingPropert
iesNotification" |
| 51 object:[self window]]; |
| 42 if (NULL != fWind) { | 52 if (NULL != fWind) { |
| 43 fWind->setVisibleP(true); | 53 fWind->setVisibleP(true); |
| 44 fWind->resize((int) self.frame.size.width, (int) self.frame.size.height,
| 54 NSSize size = self.frame.size; |
| 55 #if RETINA_API_AVAILABLE |
| 56 size = [self convertSizeToBacking:self.frame.size]; |
| 57 #endif |
| 58 fWind->resize((int) size.width, (int) size.height, |
| 45 SkBitmap::kARGB_8888_Config); | 59 SkBitmap::kARGB_8888_Config); |
| 46 } | 60 } |
| 47 } | 61 } |
| 48 | 62 |
| 49 -(BOOL) isFlipped { | 63 -(BOOL) isFlipped { |
| 50 return YES; | 64 return YES; |
| 51 } | 65 } |
| 52 | 66 |
| 53 - (BOOL)acceptsFirstResponder { | 67 - (BOOL)acceptsFirstResponder { |
| 54 return YES; | 68 return YES; |
| 55 } | 69 } |
| 56 | 70 |
| 71 - (float)scaleFactor { |
| 72 NSWindow *window = [self window]; |
| 73 #if RETINA_API_AVAILABLE |
| 74 if (window) { |
| 75 return [window backingScaleFactor]; |
| 76 } |
| 77 return [[NSScreen mainScreen] backingScaleFactor]; |
| 78 #else |
| 79 if (window) { |
| 80 return [window userSpaceScaleFactor]; |
| 81 } |
| 82 return [[NSScreen mainScreen] userSpaceScaleFactor]; |
| 83 #endif |
| 84 } |
| 85 |
| 86 - (void)backingPropertiesChanged:(NSNotification *)notification { |
| 87 CGFloat oldBackingScaleFactor = [ |
| 88 [notification.userInfo objectForKey:@"NSBackingPropertyOldScaleFactorKey
"] doubleValue |
| 89 ]; |
| 90 CGFloat newBackingScaleFactor = [self scaleFactor]; |
| 91 if (oldBackingScaleFactor == newBackingScaleFactor) { |
| 92 return; |
| 93 } |
| 94 |
| 95 // TODO: need a better way to force a refresh (that works). |
| 96 // [fGLContext update] does not appear to update if the point size has not c
hanged, |
| 97 // even if the backing size has changed. |
| 98 [self setFrameSize:NSMakeSize(self.frame.size.width + 1, self.frame.size.hei
ght + 1)]; |
| 99 } |
| 100 |
| 57 - (void)resizeSkView:(NSSize)newSize { | 101 - (void)resizeSkView:(NSSize)newSize { |
| 58 if (NULL != fWind && (fWind->width() != newSize.width || fWind->height() !=
newSize.height)) { | 102 #if RETINA_API_AVAILABLE |
| 103 newSize = [self convertSizeToBacking:newSize]; |
| 104 #endif |
| 105 if (NULL != fWind && |
| 106 (fWind->width() != newSize.width || |
| 107 fWind->height() != newSize.height)) |
| 108 { |
| 59 fWind->resize((int) newSize.width, (int) newSize.height); | 109 fWind->resize((int) newSize.width, (int) newSize.height); |
| 60 if (NULL != fGLContext) { | 110 if (NULL != fGLContext) { |
| 61 glClear(GL_STENCIL_BUFFER_BIT); | 111 glClear(GL_STENCIL_BUFFER_BIT); |
| 112 [fGLContext update]; |
| 62 } | 113 } |
| 63 [fGLContext update]; | |
| 64 } | 114 } |
| 65 } | 115 } |
| 66 | 116 |
| 67 - (void) setFrameSize:(NSSize)newSize { | 117 - (void) setFrameSize:(NSSize)newSize { |
| 68 [super setFrameSize:newSize]; | 118 [super setFrameSize:newSize]; |
| 69 [self resizeSkView:newSize]; | 119 [self resizeSkView:newSize]; |
| 70 } | 120 } |
| 71 | 121 |
| 72 - (void)dealloc { | 122 - (void)dealloc { |
| 73 delete fWind; | 123 delete fWind; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 } | 262 } |
| 213 return skModi; | 263 return skModi; |
| 214 } | 264 } |
| 215 | 265 |
| 216 - (void)mouseDown:(NSEvent *)event { | 266 - (void)mouseDown:(NSEvent *)event { |
| 217 NSPoint p = [event locationInWindow]; | 267 NSPoint p = [event locationInWindow]; |
| 218 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 268 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
| 219 | 269 |
| 220 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 270 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
| 221 NSPoint loc = [self convertPoint:p fromView:nil]; | 271 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 272 #if RETINA_API_AVAILABLE |
| 273 loc = [self convertPointToBacking:loc]; //y-up |
| 274 loc.y = -loc.y; |
| 275 #endif |
| 222 fWind->handleClick((int) loc.x, (int) loc.y, | 276 fWind->handleClick((int) loc.x, (int) loc.y, |
| 223 SkView::Click::kDown_State, self, modi); | 277 SkView::Click::kDown_State, self, modi); |
| 224 } | 278 } |
| 225 } | 279 } |
| 226 | 280 |
| 227 - (void)mouseDragged:(NSEvent *)event { | 281 - (void)mouseDragged:(NSEvent *)event { |
| 228 NSPoint p = [event locationInWindow]; | 282 NSPoint p = [event locationInWindow]; |
| 229 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 283 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
| 230 | 284 |
| 231 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 285 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
| 232 NSPoint loc = [self convertPoint:p fromView:nil]; | 286 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 287 #if RETINA_API_AVAILABLE |
| 288 loc = [self convertPointToBacking:loc]; //y-up |
| 289 loc.y = -loc.y; |
| 290 #endif |
| 233 fWind->handleClick((int) loc.x, (int) loc.y, | 291 fWind->handleClick((int) loc.x, (int) loc.y, |
| 234 SkView::Click::kMoved_State, self, modi); | 292 SkView::Click::kMoved_State, self, modi); |
| 235 } | 293 } |
| 236 } | 294 } |
| 237 | 295 |
| 238 - (void)mouseMoved:(NSEvent *)event { | 296 - (void)mouseMoved:(NSEvent *)event { |
| 239 NSPoint p = [event locationInWindow]; | 297 NSPoint p = [event locationInWindow]; |
| 240 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 298 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
| 241 | 299 |
| 242 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 300 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
| 243 NSPoint loc = [self convertPoint:p fromView:nil]; | 301 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 302 #if RETINA_API_AVAILABLE |
| 303 loc = [self convertPointToBacking:loc]; //y-up |
| 304 loc.y = -loc.y; |
| 305 #endif |
| 244 fWind->handleClick((int) loc.x, (int) loc.y, | 306 fWind->handleClick((int) loc.x, (int) loc.y, |
| 245 SkView::Click::kMoved_State, self, modi); | 307 SkView::Click::kMoved_State, self, modi); |
| 246 } | 308 } |
| 247 } | 309 } |
| 248 | 310 |
| 249 - (void)mouseUp:(NSEvent *)event { | 311 - (void)mouseUp:(NSEvent *)event { |
| 250 NSPoint p = [event locationInWindow]; | 312 NSPoint p = [event locationInWindow]; |
| 251 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 313 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
| 252 | 314 |
| 253 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 315 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
| 254 NSPoint loc = [self convertPoint:p fromView:nil]; | 316 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 317 #if RETINA_API_AVAILABLE |
| 318 loc = [self convertPointToBacking:loc]; //y-up |
| 319 loc.y = -loc.y; |
| 320 #endif |
| 255 fWind->handleClick((int) loc.x, (int) loc.y, | 321 fWind->handleClick((int) loc.x, (int) loc.y, |
| 256 SkView::Click::kUp_State, self, modi); | 322 SkView::Click::kUp_State, self, modi); |
| 257 } | 323 } |
| 258 } | 324 } |
| 259 | 325 |
| 260 /////////////////////////////////////////////////////////////////////////////// | 326 /////////////////////////////////////////////////////////////////////////////// |
| 261 #include <OpenGL/OpenGL.h> | 327 #include <OpenGL/OpenGL.h> |
| 262 | 328 |
| 263 namespace { | 329 namespace { |
| 264 CGLContextObj createGLContext(int msaaSampleCount) { | 330 CGLContextObj createGLContext(int msaaSampleCount) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 if (NULL == fGLContext) { | 388 if (NULL == fGLContext) { |
| 323 return false; | 389 return false; |
| 324 } | 390 } |
| 325 [fGLContext setView:self]; | 391 [fGLContext setView:self]; |
| 326 } | 392 } |
| 327 | 393 |
| 328 [fGLContext makeCurrentContext]; | 394 [fGLContext makeCurrentContext]; |
| 329 CGLPixelFormatObj format = CGLGetPixelFormat((CGLContextObj)[fGLContext CGLC
ontextObj]); | 395 CGLPixelFormatObj format = CGLGetPixelFormat((CGLContextObj)[fGLContext CGLC
ontextObj]); |
| 330 CGLDescribePixelFormat(format, 0, kCGLPFASamples, &info->fSampleCount); | 396 CGLDescribePixelFormat(format, 0, kCGLPFASamples, &info->fSampleCount); |
| 331 CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &info->fStencilBits); | 397 CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &info->fStencilBits); |
| 332 glViewport(0, 0, (int) self.bounds.size.width, (int) self.bounds.size.width)
; | 398 NSSize size = self.bounds.size; |
| 399 #if RETINA_API_AVAILABLE |
| 400 size = [self convertSizeToBacking:size]; |
| 401 #endif |
| 402 glViewport(0, 0, (int) size.width, (int) size.height); |
| 333 glClearColor(0, 0, 0, 0); | 403 glClearColor(0, 0, 0, 0); |
| 334 glClearStencil(0); | 404 glClearStencil(0); |
| 335 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 405 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| 336 return true; | 406 return true; |
| 337 } | 407 } |
| 338 | 408 |
| 339 - (void)detach { | 409 - (void)detach { |
| 340 [fGLContext release]; | 410 [fGLContext release]; |
| 341 fGLContext = nil; | 411 fGLContext = nil; |
| 342 } | 412 } |
| 343 | 413 |
| 344 - (void)present { | 414 - (void)present { |
| 345 if (nil != fGLContext) { | 415 if (nil != fGLContext) { |
| 346 [fGLContext flushBuffer]; | 416 [fGLContext flushBuffer]; |
| 347 } | 417 } |
| 348 } | 418 } |
| 349 @end | 419 @end |
| OLD | NEW |