The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1520 lines
45KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-7 by Raw Material Software ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the
  7. GNU General Public License, as published by the Free Software Foundation;
  8. either version 2 of the License, or (at your option) any later version.
  9. JUCE is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with JUCE; if not, visit www.gnu.org/licenses or write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. Boston, MA 02111-1307 USA
  17. ------------------------------------------------------------------------------
  18. If you'd like to release a closed-source product which uses JUCE, commercial
  19. licenses are also available: visit www.rawmaterialsoftware.com/juce for
  20. more information.
  21. ==============================================================================
  22. */
  23. // (This file gets included by juce_mac_NativeCode.mm, rather than being
  24. // compiled on its own).
  25. #ifdef JUCE_INCLUDED_FILE
  26. class NSViewComponentPeer;
  27. //==============================================================================
  28. END_JUCE_NAMESPACE
  29. #define JuceNSView MakeObjCClassName(JuceNSView)
  30. @interface JuceNSView : NSView
  31. {
  32. @public
  33. NSViewComponentPeer* owner;
  34. NSNotificationCenter* notificationCenter;
  35. }
  36. - (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner withFrame: (NSRect) frame;
  37. - (void) dealloc;
  38. - (BOOL) isOpaque;
  39. - (void) drawRect: (NSRect) r;
  40. - (void) mouseDown: (NSEvent*) ev;
  41. - (void) mouseUp: (NSEvent*) ev;
  42. - (void) mouseDragged: (NSEvent*) ev;
  43. - (void) mouseMoved: (NSEvent*) ev;
  44. - (void) mouseEntered: (NSEvent*) ev;
  45. - (void) mouseExited: (NSEvent*) ev;
  46. - (void) rightMouseDown: (NSEvent*) ev;
  47. - (void) rightMouseDragged: (NSEvent*) ev;
  48. - (void) rightMouseUp: (NSEvent*) ev;
  49. - (void) scrollWheel: (NSEvent*) ev;
  50. - (BOOL) acceptsFirstMouse: (NSEvent*) ev;
  51. - (void) frameChanged: (NSNotification*) n;
  52. - (void) keyDown: (NSEvent*) ev;
  53. - (void) keyUp: (NSEvent*) ev;
  54. - (void) flagsChanged: (NSEvent*) ev;
  55. #if MACOS_10_4_OR_EARLIER
  56. - (BOOL) performKeyEquivalent: (NSEvent*) ev;
  57. #endif
  58. - (BOOL) becomeFirstResponder;
  59. - (BOOL) resignFirstResponder;
  60. - (NSArray*) getSupportedDragTypes;
  61. - (BOOL) sendDragCallback: (int) type sender: (id <NSDraggingInfo>) sender;
  62. - (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender;
  63. - (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender;
  64. - (void) draggingEnded: (id <NSDraggingInfo>) sender;
  65. - (void) draggingExited: (id <NSDraggingInfo>) sender;
  66. - (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender;
  67. - (BOOL) performDragOperation: (id <NSDraggingInfo>) sender;
  68. - (void) concludeDragOperation: (id <NSDraggingInfo>) sender;
  69. @end
  70. //==============================================================================
  71. #define JuceNSWindow MakeObjCClassName(JuceNSWindow)
  72. @interface JuceNSWindow : NSWindow
  73. {
  74. @private
  75. NSViewComponentPeer* owner;
  76. bool isZooming;
  77. }
  78. - (void) setOwner: (NSViewComponentPeer*) owner;
  79. - (BOOL) canBecomeKeyWindow;
  80. - (void) becomeKeyWindow;
  81. - (BOOL) windowShouldClose: (id) window;
  82. - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen;
  83. - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize;
  84. - (void) zoom: (id) sender;
  85. @end
  86. BEGIN_JUCE_NAMESPACE
  87. //==============================================================================
  88. class NSViewComponentPeer : public ComponentPeer
  89. {
  90. public:
  91. NSViewComponentPeer (Component* const component,
  92. const int windowStyleFlags,
  93. NSView* viewToAttachTo);
  94. ~NSViewComponentPeer();
  95. //==============================================================================
  96. void* getNativeHandle() const;
  97. void setVisible (bool shouldBeVisible);
  98. void setTitle (const String& title);
  99. void setPosition (int x, int y);
  100. void setSize (int w, int h);
  101. void setBounds (int x, int y, int w, int h, const bool isNowFullScreen);
  102. void getBounds (int& x, int& y, int& w, int& h, const bool global) const;
  103. void getBounds (int& x, int& y, int& w, int& h) const;
  104. int getScreenX() const;
  105. int getScreenY() const;
  106. void relativePositionToGlobal (int& x, int& y);
  107. void globalPositionToRelative (int& x, int& y);
  108. void setMinimised (bool shouldBeMinimised);
  109. bool isMinimised() const;
  110. void setFullScreen (bool shouldBeFullScreen);
  111. bool isFullScreen() const;
  112. bool contains (int x, int y, bool trueIfInAChildWindow) const;
  113. const BorderSize getFrameSize() const;
  114. bool setAlwaysOnTop (bool alwaysOnTop);
  115. void toFront (bool makeActiveWindow);
  116. void toBehind (ComponentPeer* other);
  117. void setIcon (const Image& newIcon);
  118. /* When you use multiple DLLs which share similarly-named obj-c classes - like
  119. for example having more than one juce plugin loaded into a host, then when a
  120. method is called, the actual code that runs might actually be in a different module
  121. than the one you expect... So any calls to library functions or statics that are
  122. made inside obj-c methods will probably end up getting executed in a different DLL's
  123. memory space. Not a great thing to happen - this obviously leads to bizarre crashes.
  124. To work around this insanity, I'm only allowing obj-c methods to make calls to
  125. virtual methods of an object that's known to live inside the right module's space.
  126. */
  127. virtual void redirectMouseDown (NSEvent* ev);
  128. virtual void redirectMouseUp (NSEvent* ev);
  129. virtual void redirectMouseDrag (NSEvent* ev);
  130. virtual void redirectMouseMove (NSEvent* ev);
  131. virtual void redirectMouseEnter (NSEvent* ev);
  132. virtual void redirectMouseExit (NSEvent* ev);
  133. virtual void redirectMouseWheel (NSEvent* ev);
  134. bool handleKeyEvent (NSEvent* ev, bool isKeyDown);
  135. virtual bool redirectKeyDown (NSEvent* ev);
  136. virtual bool redirectKeyUp (NSEvent* ev);
  137. virtual void redirectModKeyChange (NSEvent* ev);
  138. #if MACOS_10_4_OR_EARLIER
  139. virtual bool redirectPerformKeyEquivalent (NSEvent* ev);
  140. #endif
  141. virtual BOOL sendDragCallback (int type, id <NSDraggingInfo> sender);
  142. virtual bool isOpaque();
  143. virtual void drawRect (NSRect r);
  144. virtual bool canBecomeKeyWindow();
  145. virtual bool windowShouldClose();
  146. virtual void redirectMovedOrResized();
  147. virtual NSRect constrainRect (NSRect r);
  148. static void showArrowCursorIfNeeded();
  149. //==============================================================================
  150. virtual void viewFocusGain();
  151. virtual void viewFocusLoss();
  152. bool isFocused() const;
  153. void grabFocus();
  154. void textInputRequired (int x, int y);
  155. //==============================================================================
  156. void repaint (int x, int y, int w, int h);
  157. void performAnyPendingRepaintsNow();
  158. //==============================================================================
  159. juce_UseDebuggingNewOperator
  160. NSWindow* window;
  161. JuceNSView* view;
  162. bool isSharedWindow, fullScreen;
  163. };
  164. //==============================================================================
  165. END_JUCE_NAMESPACE
  166. @implementation JuceNSView
  167. - (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner_
  168. withFrame: (NSRect) frame
  169. {
  170. [super initWithFrame: frame];
  171. owner = owner_;
  172. notificationCenter = [NSNotificationCenter defaultCenter];
  173. [notificationCenter addObserver: self
  174. selector: @selector (frameChanged:)
  175. name: NSViewFrameDidChangeNotification
  176. object: self];
  177. if (! owner_->isSharedWindow)
  178. {
  179. [notificationCenter addObserver: self
  180. selector: @selector (frameChanged:)
  181. name: NSWindowDidMoveNotification
  182. object: owner_->window];
  183. }
  184. [self registerForDraggedTypes: [self getSupportedDragTypes]];
  185. return self;
  186. }
  187. - (void) dealloc
  188. {
  189. [notificationCenter removeObserver: self];
  190. [super dealloc];
  191. }
  192. //==============================================================================
  193. - (void) drawRect: (NSRect) r
  194. {
  195. if (owner != 0)
  196. owner->drawRect (r);
  197. }
  198. - (BOOL) isOpaque
  199. {
  200. return owner == 0 || owner->isOpaque();
  201. }
  202. //==============================================================================
  203. - (void) mouseDown: (NSEvent*) ev
  204. {
  205. if (owner != 0)
  206. owner->redirectMouseDown (ev);
  207. }
  208. - (void) mouseUp: (NSEvent*) ev
  209. {
  210. if (owner != 0)
  211. owner->redirectMouseUp (ev);
  212. }
  213. - (void) mouseDragged: (NSEvent*) ev
  214. {
  215. if (owner != 0)
  216. owner->redirectMouseDrag (ev);
  217. }
  218. - (void) mouseMoved: (NSEvent*) ev
  219. {
  220. if (owner != 0)
  221. owner->redirectMouseMove (ev);
  222. }
  223. - (void) mouseEntered: (NSEvent*) ev
  224. {
  225. if (owner != 0)
  226. owner->redirectMouseEnter (ev);
  227. }
  228. - (void) mouseExited: (NSEvent*) ev
  229. {
  230. if (owner != 0)
  231. owner->redirectMouseExit (ev);
  232. }
  233. - (void) rightMouseDown: (NSEvent*) ev
  234. {
  235. [self mouseDown: ev];
  236. }
  237. - (void) rightMouseDragged: (NSEvent*) ev
  238. {
  239. [self mouseDragged: ev];
  240. }
  241. - (void) rightMouseUp: (NSEvent*) ev
  242. {
  243. [self mouseUp: ev];
  244. }
  245. - (void) scrollWheel: (NSEvent*) ev
  246. {
  247. if (owner != 0)
  248. owner->redirectMouseWheel (ev);
  249. }
  250. - (BOOL) acceptsFirstMouse: (NSEvent*) ev
  251. {
  252. return YES;
  253. }
  254. - (void) frameChanged: (NSNotification*) n
  255. {
  256. if (owner != 0)
  257. owner->redirectMovedOrResized();
  258. }
  259. //==============================================================================
  260. - (void) keyDown: (NSEvent*) ev
  261. {
  262. if (owner == 0 || ! owner->redirectKeyDown (ev))
  263. [super keyDown: ev];
  264. }
  265. - (void) keyUp: (NSEvent*) ev
  266. {
  267. if (owner == 0 || ! owner->redirectKeyUp (ev))
  268. [super keyUp: ev];
  269. }
  270. - (void) flagsChanged: (NSEvent*) ev
  271. {
  272. if (owner != 0)
  273. owner->redirectModKeyChange (ev);
  274. }
  275. #if MACOS_10_4_OR_EARLIER
  276. - (BOOL) performKeyEquivalent: (NSEvent*) ev
  277. {
  278. if (owner != 0 && owner->redirectPerformKeyEquivalent (ev))
  279. return true;
  280. return [super performKeyEquivalent: ev];
  281. }
  282. #endif
  283. - (BOOL) becomeFirstResponder
  284. {
  285. if (owner != 0)
  286. owner->viewFocusGain();
  287. return true;
  288. }
  289. - (BOOL) resignFirstResponder
  290. {
  291. if (owner != 0)
  292. owner->viewFocusLoss();
  293. return true;
  294. }
  295. //==============================================================================
  296. - (NSArray*) getSupportedDragTypes
  297. {
  298. return [NSArray arrayWithObjects: NSFilenamesPboardType, /*NSFilesPromisePboardType, NSStringPboardType,*/ nil];
  299. }
  300. - (BOOL) sendDragCallback: (int) type sender: (id <NSDraggingInfo>) sender
  301. {
  302. return owner != 0 && owner->sendDragCallback (type, sender);
  303. }
  304. - (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender
  305. {
  306. if ([self sendDragCallback: 0 sender: sender])
  307. return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric;
  308. else
  309. return NSDragOperationNone;
  310. }
  311. - (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender
  312. {
  313. if ([self sendDragCallback: 0 sender: sender])
  314. return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric;
  315. else
  316. return NSDragOperationNone;
  317. }
  318. - (void) draggingEnded: (id <NSDraggingInfo>) sender
  319. {
  320. [self sendDragCallback: 1 sender: sender];
  321. }
  322. - (void) draggingExited: (id <NSDraggingInfo>) sender
  323. {
  324. [self sendDragCallback: 1 sender: sender];
  325. }
  326. - (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender
  327. {
  328. return YES;
  329. }
  330. - (BOOL) performDragOperation: (id <NSDraggingInfo>) sender
  331. {
  332. return [self sendDragCallback: 2 sender: sender];
  333. }
  334. - (void) concludeDragOperation: (id <NSDraggingInfo>) sender
  335. {
  336. }
  337. @end
  338. //==============================================================================
  339. @implementation JuceNSWindow
  340. - (void) setOwner: (NSViewComponentPeer*) owner_
  341. {
  342. owner = owner_;
  343. isZooming = false;
  344. }
  345. - (BOOL) canBecomeKeyWindow
  346. {
  347. return owner != 0 && owner->canBecomeKeyWindow();
  348. }
  349. - (void) becomeKeyWindow
  350. {
  351. [super becomeKeyWindow];
  352. if (owner != 0)
  353. owner->grabFocus();
  354. }
  355. - (BOOL) windowShouldClose: (id) window
  356. {
  357. return owner == 0 || owner->windowShouldClose();
  358. }
  359. - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen
  360. {
  361. if (owner != 0)
  362. frameRect = owner->constrainRect (frameRect);
  363. return frameRect;
  364. }
  365. - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize
  366. {
  367. if (isZooming)
  368. return proposedFrameSize;
  369. NSRect frameRect = [self frame];
  370. frameRect.origin.y -= proposedFrameSize.height - frameRect.size.height;
  371. frameRect.size = proposedFrameSize;
  372. if (owner != 0)
  373. frameRect = owner->constrainRect (frameRect);
  374. return frameRect.size;
  375. }
  376. - (void) zoom: (id) sender
  377. {
  378. isZooming = true;
  379. [super zoom: sender];
  380. isZooming = false;
  381. }
  382. - (void) windowWillMove: (NSNotification*) notification
  383. {
  384. if (juce::Component::getCurrentlyModalComponent() != 0
  385. && owner->getComponent()->isCurrentlyBlockedByAnotherModalComponent()
  386. && (owner->getStyleFlags() & juce::ComponentPeer::windowHasTitleBar) != 0)
  387. juce::Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
  388. }
  389. @end
  390. //==============================================================================
  391. //==============================================================================
  392. BEGIN_JUCE_NAMESPACE
  393. //==============================================================================
  394. class JuceNSImage
  395. {
  396. public:
  397. JuceNSImage (const int width, const int height, const bool hasAlpha)
  398. : juceImage (hasAlpha ? Image::ARGB : Image::RGB,
  399. width, height, hasAlpha)
  400. {
  401. lineStride = 0;
  402. pixelStride = 0;
  403. imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height,
  404. lineStride, pixelStride);
  405. imageRep = [[NSBitmapImageRep alloc]
  406. initWithBitmapDataPlanes: &imageData
  407. pixelsWide: width
  408. pixelsHigh: height
  409. bitsPerSample: 8
  410. samplesPerPixel: pixelStride
  411. hasAlpha: hasAlpha
  412. isPlanar: NO
  413. colorSpaceName: NSCalibratedRGBColorSpace
  414. bitmapFormat: /*NSAlphaFirstBitmapFormat*/ (NSBitmapFormat) 0
  415. bytesPerRow: lineStride
  416. bitsPerPixel: 8 * pixelStride ];
  417. juceImage.releasePixelDataReadWrite (imageData);
  418. }
  419. ~JuceNSImage()
  420. {
  421. [imageRep release];
  422. }
  423. Image& getJuceImage() throw() { return juceImage; }
  424. void draw (const float x, const float y,
  425. const RectangleList& clip,
  426. const int originX, const int originY) const
  427. {
  428. // Our data is BGRA and the damned image rep only takes RGBA, so
  429. // we need to byte-swap the active areas if there's an alpha channel...
  430. if (juceImage.hasAlphaChannel())
  431. {
  432. RectangleList::Iterator iter (clip);
  433. while (iter.next())
  434. {
  435. const Rectangle* const r = iter.getRectangle();
  436. swapRGBOrder (r->getX() + originX,
  437. r->getY() + originY,
  438. r->getWidth(),
  439. r->getHeight());
  440. }
  441. }
  442. NSPoint p;
  443. p.x = x;
  444. p.y = y;
  445. [imageRep drawAtPoint: p];
  446. }
  447. void drawNSImage (NSImage* imageToDraw)
  448. {
  449. const ScopedAutoReleasePool pool;
  450. [NSGraphicsContext setCurrentContext:
  451. [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]];
  452. [imageToDraw drawAtPoint: NSZeroPoint
  453. fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height)
  454. operation: NSCompositeSourceOver
  455. fraction: 1.0f];
  456. [[NSGraphicsContext currentContext] flushGraphics];
  457. if (juceImage.hasAlphaChannel())
  458. swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());
  459. }
  460. private:
  461. Image juceImage;
  462. NSBitmapImageRep* imageRep;
  463. uint8* imageData;
  464. int pixelStride, lineStride;
  465. void swapRGBOrder (const int x, const int y, const int w, int h) const
  466. {
  467. #if JUCE_BIG_ENDIAN
  468. jassert (pixelStride == 4);
  469. #endif
  470. jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight())
  471. .contains (Rectangle (x, y, w, h)));
  472. uint8* start = imageData + x * pixelStride + y * lineStride;
  473. while (--h >= 0)
  474. {
  475. uint8* p = start;
  476. start += lineStride;
  477. for (int i = w; --i >= 0;)
  478. {
  479. #if JUCE_BIG_ENDIAN
  480. const uint8 oldp3 = p[3];
  481. const uint8 oldp1 = p[1];
  482. p[3] = p[0];
  483. p[0] = oldp1;
  484. p[1] = p[2];
  485. p[2] = oldp3;
  486. #else
  487. const uint8 oldp0 = p[0];
  488. p[0] = p[2];
  489. p[2] = oldp0;
  490. #endif
  491. p += pixelStride;
  492. }
  493. }
  494. }
  495. };
  496. //==============================================================================
  497. static ComponentPeer* currentlyFocusedPeer = 0;
  498. static VoidArray keysCurrentlyDown;
  499. bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw()
  500. {
  501. if (keysCurrentlyDown.contains ((void*) keyCode))
  502. return true;
  503. if (keyCode >= 'A' && keyCode <= 'Z'
  504. && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode)))
  505. return true;
  506. if (keyCode >= 'a' && keyCode <= 'z'
  507. && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode)))
  508. return true;
  509. return false;
  510. }
  511. static int getKeyCodeFromEvent (NSEvent* ev)
  512. {
  513. const String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
  514. int keyCode = unmodified[0];
  515. if (keyCode == 0x19) // (backwards-tab)
  516. keyCode = 9;
  517. return keyCode;
  518. }
  519. static int currentModifiers = 0;
  520. static void updateModifiers (NSEvent* e)
  521. {
  522. int m = currentModifiers & ~(ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier
  523. | ModifierKeys::altModifier | ModifierKeys::commandModifier);
  524. if (([e modifierFlags] & NSShiftKeyMask) != 0)
  525. m |= ModifierKeys::shiftModifier;
  526. if (([e modifierFlags] & NSControlKeyMask) != 0)
  527. m |= ModifierKeys::ctrlModifier;
  528. if (([e modifierFlags] & NSAlternateKeyMask) != 0)
  529. m |= ModifierKeys::altModifier;
  530. if (([e modifierFlags] & NSCommandKeyMask) != 0)
  531. m |= ModifierKeys::commandModifier;
  532. currentModifiers = m;
  533. }
  534. static void updateKeysDown (NSEvent* ev, bool isKeyDown)
  535. {
  536. updateModifiers (ev);
  537. int keyCode = getKeyCodeFromEvent (ev);
  538. if (keyCode != 0)
  539. {
  540. if (isKeyDown)
  541. keysCurrentlyDown.addIfNotAlreadyThere ((void*) keyCode);
  542. else
  543. keysCurrentlyDown.removeValue ((void*) keyCode);
  544. }
  545. }
  546. const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
  547. {
  548. return ModifierKeys (currentModifiers);
  549. }
  550. void ModifierKeys::updateCurrentModifiers() throw()
  551. {
  552. currentModifierFlags = currentModifiers;
  553. }
  554. static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; }
  555. static void getMousePos (NSEvent* e, NSView* view, int& x, int& y)
  556. {
  557. NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil];
  558. x = roundFloatToInt (p.x);
  559. y = roundFloatToInt ([view frame].size.height - p.y);
  560. }
  561. static int getModifierForButtonNumber (const int num) throw()
  562. {
  563. return num == 0 ? ModifierKeys::leftButtonModifier
  564. : (num == 1 ? ModifierKeys::rightButtonModifier
  565. : (num == 2 ? ModifierKeys::middleButtonModifier : 0));
  566. }
  567. //==============================================================================
  568. NSViewComponentPeer::NSViewComponentPeer (Component* const component,
  569. const int windowStyleFlags,
  570. NSView* viewToAttachTo)
  571. : ComponentPeer (component, windowStyleFlags),
  572. window (0),
  573. view (0)
  574. {
  575. NSRect r;
  576. r.origin.x = 0;
  577. r.origin.y = 0;
  578. r.size.width = (float) component->getWidth();
  579. r.size.height = (float) component->getHeight();
  580. view = [[JuceNSView alloc] initWithOwner: this withFrame: r];
  581. [view setPostsFrameChangedNotifications: YES];
  582. if (viewToAttachTo != 0)
  583. {
  584. window = [viewToAttachTo window];
  585. [viewToAttachTo addSubview: view];
  586. isSharedWindow = true;
  587. setVisible (component->isVisible());
  588. }
  589. else
  590. {
  591. isSharedWindow = false;
  592. r.origin.x = (float) component->getX();
  593. r.origin.y = (float) component->getY();
  594. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
  595. unsigned int style = 0;
  596. if ((windowStyleFlags & windowHasTitleBar) == 0)
  597. style = NSBorderlessWindowMask;
  598. else
  599. style = NSTitledWindowMask;
  600. if ((windowStyleFlags & windowHasMinimiseButton) != 0)
  601. style |= NSMiniaturizableWindowMask;
  602. if ((windowStyleFlags & windowHasCloseButton) != 0)
  603. style |= NSClosableWindowMask;
  604. if ((windowStyleFlags & windowIsResizable) != 0)
  605. style |= NSResizableWindowMask;
  606. window = [[JuceNSWindow alloc] initWithContentRect: r
  607. styleMask: style
  608. backing: NSBackingStoreBuffered
  609. defer: YES ];
  610. [((JuceNSWindow*) window) setOwner: this];
  611. [window orderOut: nil];
  612. [window setDelegate: window];
  613. [window setOpaque: component->isOpaque()];
  614. [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)];
  615. if (component->isAlwaysOnTop())
  616. [window setLevel: NSFloatingWindowLevel];
  617. [window setContentView: view];
  618. [window setAutodisplay: YES];
  619. [window setAcceptsMouseMovedEvents: YES];
  620. [window setReleasedWhenClosed: YES];
  621. [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0];
  622. [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0];
  623. }
  624. setTitle (component->getName());
  625. }
  626. NSViewComponentPeer::~NSViewComponentPeer()
  627. {
  628. view->owner = 0;
  629. [view removeFromSuperview];
  630. [view release];
  631. if (! isSharedWindow)
  632. {
  633. [((JuceNSWindow*) window) setOwner: 0];
  634. [window close];
  635. }
  636. }
  637. //==============================================================================
  638. void* NSViewComponentPeer::getNativeHandle() const
  639. {
  640. return view;
  641. }
  642. void NSViewComponentPeer::setVisible (bool shouldBeVisible)
  643. {
  644. if (isSharedWindow)
  645. {
  646. [view setHidden: ! shouldBeVisible];
  647. }
  648. else
  649. {
  650. if (shouldBeVisible)
  651. [window orderFront: nil];
  652. else
  653. [window orderOut: nil];
  654. }
  655. }
  656. void NSViewComponentPeer::setTitle (const String& title)
  657. {
  658. const ScopedAutoReleasePool pool;
  659. if (! isSharedWindow)
  660. [window setTitle: juceStringToNS (title)];
  661. }
  662. void NSViewComponentPeer::setPosition (int x, int y)
  663. {
  664. setBounds (x, y, component->getWidth(), component->getHeight(), false);
  665. }
  666. void NSViewComponentPeer::setSize (int w, int h)
  667. {
  668. setBounds (component->getX(), component->getY(), w, h, false);
  669. }
  670. void NSViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
  671. {
  672. fullScreen = isNowFullScreen;
  673. w = jmax (0, w);
  674. h = jmax (0, h);
  675. NSRect r;
  676. r.origin.x = (float) x;
  677. r.origin.y = (float) y;
  678. r.size.width = (float) w;
  679. r.size.height = (float) h;
  680. if (isSharedWindow)
  681. {
  682. r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height);
  683. if ([view frame].size.width != r.size.width
  684. || [view frame].size.height != r.size.height)
  685. [view setNeedsDisplay: true];
  686. [view setFrame: r];
  687. }
  688. else
  689. {
  690. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
  691. [window setFrame: [window frameRectForContentRect: r]
  692. display: true];
  693. }
  694. }
  695. void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const
  696. {
  697. NSRect r = [view frame];
  698. if (global && [view window] != 0)
  699. {
  700. r = [view convertRect: r toView: nil];
  701. NSRect wr = [[view window] frame];
  702. r.origin.x += wr.origin.x;
  703. r.origin.y += wr.origin.y;
  704. y = (int) ([[[NSScreen screens] objectAtIndex:0] frame].size.height - r.origin.y - r.size.height);
  705. }
  706. else
  707. {
  708. y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height);
  709. }
  710. x = (int) r.origin.x;
  711. w = (int) r.size.width;
  712. h = (int) r.size.height;
  713. }
  714. void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const
  715. {
  716. getBounds (x, y, w, h, ! isSharedWindow);
  717. }
  718. int NSViewComponentPeer::getScreenX() const
  719. {
  720. int x, y, w, h;
  721. getBounds (x, y, w, h, true);
  722. return x;
  723. }
  724. int NSViewComponentPeer::getScreenY() const
  725. {
  726. int x, y, w, h;
  727. getBounds (x, y, w, h, true);
  728. return y;
  729. }
  730. void NSViewComponentPeer::relativePositionToGlobal (int& x, int& y)
  731. {
  732. int wx, wy, ww, wh;
  733. getBounds (wx, wy, ww, wh, true);
  734. x += wx;
  735. y += wy;
  736. }
  737. void NSViewComponentPeer::globalPositionToRelative (int& x, int& y)
  738. {
  739. int wx, wy, ww, wh;
  740. getBounds (wx, wy, ww, wh, true);
  741. x -= wx;
  742. y -= wy;
  743. }
  744. NSRect NSViewComponentPeer::constrainRect (NSRect r)
  745. {
  746. if (constrainer != 0)
  747. {
  748. NSRect current = [window frame];
  749. current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height;
  750. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;
  751. int x = (int) r.origin.x;
  752. int y = (int) r.origin.y;
  753. int w = (int) r.size.width;
  754. int h = (int) r.size.height;
  755. Rectangle original ((int) current.origin.x, (int) current.origin.y,
  756. (int) current.size.width, (int) current.size.height);
  757. constrainer->checkBounds (x, y, w, h,
  758. original,
  759. Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
  760. y != original.getY() && y + h == original.getBottom(),
  761. x != original.getX() && x + w == original.getRight(),
  762. y == original.getY() && y + h != original.getBottom(),
  763. x == original.getX() && x + w != original.getRight());
  764. r.origin.x = x;
  765. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - y;
  766. r.size.width = w;
  767. r.size.height = h;
  768. }
  769. return r;
  770. }
  771. void NSViewComponentPeer::setMinimised (bool shouldBeMinimised)
  772. {
  773. if (! isSharedWindow)
  774. {
  775. if (shouldBeMinimised)
  776. [window miniaturize: nil];
  777. else
  778. [window deminiaturize: nil];
  779. }
  780. }
  781. bool NSViewComponentPeer::isMinimised() const
  782. {
  783. return window != 0 && [window isMiniaturized];
  784. }
  785. void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen)
  786. {
  787. if (! isSharedWindow)
  788. {
  789. Rectangle r (lastNonFullscreenBounds);
  790. setMinimised (false);
  791. if (fullScreen != shouldBeFullScreen)
  792. {
  793. if (shouldBeFullScreen)
  794. r = Desktop::getInstance().getMainMonitorArea();
  795. // (can't call the component's setBounds method because that'll reset our fullscreen flag)
  796. if (r != getComponent()->getBounds() && ! r.isEmpty())
  797. setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
  798. }
  799. }
  800. }
  801. bool NSViewComponentPeer::isFullScreen() const
  802. {
  803. return fullScreen;
  804. }
  805. bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const
  806. {
  807. if (((unsigned int) x) >= (unsigned int) component->getWidth()
  808. || ((unsigned int) y) >= (unsigned int) component->getHeight())
  809. return false;
  810. NSPoint p;
  811. p.x = (float) x;
  812. p.y = (float) y;
  813. NSView* v = [view hitTest: p];
  814. if (trueIfInAChildWindow)
  815. return v != nil;
  816. return v == view;
  817. }
  818. const BorderSize NSViewComponentPeer::getFrameSize() const
  819. {
  820. BorderSize b;
  821. if (! isSharedWindow)
  822. {
  823. NSRect v = [view convertRect: [view frame] toView: nil];
  824. NSRect w = [window frame];
  825. b.setTop ((int) (w.size.height - (v.origin.y + v.size.height)));
  826. b.setBottom ((int) v.origin.y);
  827. b.setLeft ((int) v.origin.x);
  828. b.setRight ((int) (w.size.width - (v.origin.x + v.size.width)));
  829. }
  830. return b;
  831. }
  832. bool NSViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop)
  833. {
  834. if (! isSharedWindow)
  835. {
  836. [window setLevel: alwaysOnTop ? NSFloatingWindowLevel
  837. : NSNormalWindowLevel];
  838. }
  839. return true;
  840. }
  841. void NSViewComponentPeer::toFront (bool makeActiveWindow)
  842. {
  843. if (isSharedWindow)
  844. {
  845. [[view superview] addSubview: view
  846. positioned: NSWindowAbove
  847. relativeTo: nil];
  848. }
  849. if (window != 0 && component->isVisible())
  850. {
  851. if (makeActiveWindow)
  852. [window makeKeyAndOrderFront: nil];
  853. else
  854. [window orderFront: nil];
  855. }
  856. }
  857. void NSViewComponentPeer::toBehind (ComponentPeer* other)
  858. {
  859. NSViewComponentPeer* o = (NSViewComponentPeer*) other;
  860. if (isSharedWindow)
  861. {
  862. [[view superview] addSubview: view
  863. positioned: NSWindowBelow
  864. relativeTo: o->view];
  865. }
  866. else
  867. {
  868. [window orderWindow: NSWindowBelow
  869. relativeTo: o->window != 0 ? [o->window windowNumber]
  870. : nil ];
  871. }
  872. }
  873. void NSViewComponentPeer::setIcon (const Image& /*newIcon*/)
  874. {
  875. // to do..
  876. }
  877. //==============================================================================
  878. void NSViewComponentPeer::viewFocusGain()
  879. {
  880. if (currentlyFocusedPeer != this)
  881. {
  882. if (ComponentPeer::isValidPeer (currentlyFocusedPeer))
  883. currentlyFocusedPeer->handleFocusLoss();
  884. currentlyFocusedPeer = this;
  885. handleFocusGain();
  886. }
  887. }
  888. void NSViewComponentPeer::viewFocusLoss()
  889. {
  890. if (currentlyFocusedPeer == this)
  891. {
  892. currentlyFocusedPeer = 0;
  893. handleFocusLoss();
  894. }
  895. }
  896. void juce_HandleProcessFocusChange()
  897. {
  898. keysCurrentlyDown.clear();
  899. if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer))
  900. {
  901. if (Process::isForegroundProcess())
  902. {
  903. currentlyFocusedPeer->handleFocusGain();
  904. }
  905. else
  906. {
  907. currentlyFocusedPeer->handleFocusLoss();
  908. // turn kiosk mode off if we lose focus..
  909. Desktop::getInstance().setKioskModeComponent (0);
  910. }
  911. }
  912. }
  913. bool NSViewComponentPeer::isFocused() const
  914. {
  915. return window != 0 && [window isKeyWindow];
  916. }
  917. void NSViewComponentPeer::grabFocus()
  918. {
  919. if (window != 0)
  920. {
  921. [window makeKeyWindow];
  922. [window makeFirstResponder: view];
  923. viewFocusGain();
  924. }
  925. }
  926. void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/)
  927. {
  928. }
  929. bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
  930. {
  931. String unicode (nsStringToJuce ([ev characters]));
  932. String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
  933. int keyCode = getKeyCodeFromEvent (ev);
  934. //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0]));
  935. //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0]));
  936. if (unicode.isNotEmpty() || keyCode != 0)
  937. {
  938. if (isKeyDown)
  939. {
  940. bool used = false;
  941. while (unicode.length() > 0)
  942. {
  943. juce_wchar textCharacter = unicode[0];
  944. unicode = unicode.substring (1);
  945. if (([ev modifierFlags] & NSCommandKeyMask) != 0)
  946. textCharacter = 0;
  947. used = handleKeyUpOrDown() || used;
  948. used = handleKeyPress (keyCode, textCharacter) || used;
  949. }
  950. return used;
  951. }
  952. else
  953. {
  954. if (handleKeyUpOrDown())
  955. return true;
  956. }
  957. }
  958. return false;
  959. }
  960. bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)
  961. {
  962. updateKeysDown (ev, true);
  963. bool used = handleKeyEvent (ev, true);
  964. if (([ev modifierFlags] & NSCommandKeyMask) != 0)
  965. {
  966. // for command keys, the key-up event is thrown away, so simulate one..
  967. updateKeysDown (ev, false);
  968. used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used;
  969. }
  970. return used;
  971. }
  972. bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev)
  973. {
  974. updateKeysDown (ev, false);
  975. return handleKeyEvent (ev, false);
  976. }
  977. void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
  978. {
  979. updateModifiers (ev);
  980. handleModifierKeysChange();
  981. }
  982. #if MACOS_10_4_OR_EARLIER
  983. bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)
  984. {
  985. if ([ev type] == NSKeyDown)
  986. return redirectKeyDown (ev);
  987. else if ([ev type] == NSKeyUp)
  988. return redirectKeyUp (ev);
  989. return false;
  990. }
  991. #endif
  992. //==============================================================================
  993. void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)
  994. {
  995. updateModifiers (ev);
  996. currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
  997. int x, y;
  998. getMousePos (ev, view, x, y);
  999. handleMouseDown (x, y, getMouseTime (ev));
  1000. }
  1001. void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)
  1002. {
  1003. const int oldMods = currentModifiers;
  1004. updateModifiers (ev);
  1005. currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]);
  1006. int x, y;
  1007. getMousePos (ev, view, x, y);
  1008. handleMouseUp (oldMods, x, y, getMouseTime (ev));
  1009. showArrowCursorIfNeeded();
  1010. }
  1011. void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)
  1012. {
  1013. updateModifiers (ev);
  1014. currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
  1015. int x, y;
  1016. getMousePos (ev, view, x, y);
  1017. handleMouseDrag (x, y, getMouseTime (ev));
  1018. }
  1019. void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)
  1020. {
  1021. updateModifiers (ev);
  1022. int x, y;
  1023. getMousePos (ev, view, x, y);
  1024. handleMouseMove (x, y, getMouseTime (ev));
  1025. showArrowCursorIfNeeded();
  1026. }
  1027. void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)
  1028. {
  1029. updateModifiers (ev);
  1030. int x, y;
  1031. getMousePos (ev, view, x, y);
  1032. handleMouseEnter (x, y, getMouseTime (ev));
  1033. }
  1034. void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)
  1035. {
  1036. updateModifiers (ev);
  1037. int x, y;
  1038. getMousePos (ev, view, x, y);
  1039. handleMouseExit (x, y, getMouseTime (ev));
  1040. }
  1041. void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)
  1042. {
  1043. updateModifiers (ev);
  1044. handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f),
  1045. roundFloatToInt ([ev deltaY] * 10.0f),
  1046. getMouseTime (ev));
  1047. }
  1048. void NSViewComponentPeer::showArrowCursorIfNeeded()
  1049. {
  1050. if (Component::getComponentUnderMouse() == 0)
  1051. {
  1052. int mx, my;
  1053. Desktop::getInstance().getMousePosition (mx, my);
  1054. if (Desktop::getInstance().findComponentAt (mx, my) == 0)
  1055. [[NSCursor arrowCursor] set];
  1056. }
  1057. }
  1058. //==============================================================================
  1059. BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender)
  1060. {
  1061. NSString* bestType
  1062. = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]];
  1063. if (bestType == nil)
  1064. return false;
  1065. NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil];
  1066. int x = (int) p.x;
  1067. int y = (int) ([view frame].size.height - p.y);
  1068. StringArray files;
  1069. id list = [[sender draggingPasteboard] propertyListForType: bestType];
  1070. if (list == nil)
  1071. return false;
  1072. if ([list isKindOfClass: [NSArray class]])
  1073. {
  1074. NSArray* items = (NSArray*) list;
  1075. for (unsigned int i = 0; i < [items count]; ++i)
  1076. files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i]));
  1077. }
  1078. if (files.size() == 0)
  1079. return false;
  1080. if (type == 0)
  1081. handleFileDragMove (files, x, y);
  1082. else if (type == 1)
  1083. handleFileDragExit (files);
  1084. else if (type == 2)
  1085. handleFileDragDrop (files, x, y);
  1086. return true;
  1087. }
  1088. bool NSViewComponentPeer::isOpaque()
  1089. {
  1090. if (! getComponent()->isValidComponent())
  1091. return true;
  1092. return getComponent()->isOpaque();
  1093. }
  1094. void NSViewComponentPeer::drawRect (NSRect r)
  1095. {
  1096. if (r.size.width < 1.0f || r.size.height < 1.0f)
  1097. return;
  1098. const float y = [view frame].size.height - (r.origin.y + r.size.height);
  1099. JuceNSImage temp ((int) (r.size.width + 0.5f),
  1100. (int) (r.size.height + 0.5f),
  1101. ! getComponent()->isOpaque());
  1102. LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
  1103. const int originX = -roundFloatToInt (r.origin.x);
  1104. const int originY = -roundFloatToInt (y);
  1105. context.setOrigin (originX, originY);
  1106. const NSRect* rects = 0;
  1107. NSInteger numRects = 0;
  1108. [view getRectsBeingDrawn: &rects count: &numRects];
  1109. RectangleList clip;
  1110. for (int i = 0; i < numRects; ++i)
  1111. {
  1112. clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
  1113. roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
  1114. roundFloatToInt (rects[i].size.width),
  1115. roundFloatToInt (rects[i].size.height)));
  1116. }
  1117. if (context.reduceClipRegion (clip))
  1118. {
  1119. handlePaint (context);
  1120. temp.draw (r.origin.x, r.origin.y, clip, originX, originY);
  1121. }
  1122. }
  1123. bool NSViewComponentPeer::canBecomeKeyWindow()
  1124. {
  1125. // If running as a plugin, let the component decide whether it's going to allow the window to get focused.
  1126. return JUCEApplication::getInstance() != 0
  1127. || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus());
  1128. }
  1129. bool NSViewComponentPeer::windowShouldClose()
  1130. {
  1131. if (! isValidPeer (this))
  1132. return YES;
  1133. handleUserClosingWindow();
  1134. return NO;
  1135. }
  1136. void NSViewComponentPeer::redirectMovedOrResized()
  1137. {
  1138. handleMovedOrResized();
  1139. }
  1140. //==============================================================================
  1141. void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars)
  1142. {
  1143. // Very annoyingly, this function has to use the old SetSystemUIMode function,
  1144. // which is in Carbon.framework. But, because there's no Cocoa equivalent, it
  1145. // is apparently still available in 64-bit apps..
  1146. if (enableOrDisable)
  1147. {
  1148. SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0);
  1149. kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false));
  1150. }
  1151. else
  1152. {
  1153. SetSystemUIMode (kUIModeNormal, 0);
  1154. }
  1155. }
  1156. //==============================================================================
  1157. void NSViewComponentPeer::repaint (int x, int y, int w, int h)
  1158. {
  1159. [view setNeedsDisplayInRect:
  1160. NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)),
  1161. (float) w, (float) h)];
  1162. }
  1163. void NSViewComponentPeer::performAnyPendingRepaintsNow()
  1164. {
  1165. [view displayIfNeeded];
  1166. }
  1167. ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
  1168. {
  1169. return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo);
  1170. }
  1171. //==============================================================================
  1172. static Image* NSImageToJuceImage (NSImage* image)
  1173. {
  1174. JuceNSImage juceIm ((int) [image size].width,
  1175. (int) [image size].height,
  1176. true);
  1177. juceIm.drawNSImage (image);
  1178. return juceIm.getJuceImage().createCopy();
  1179. }
  1180. Image* juce_createIconForFile (const File& file)
  1181. {
  1182. const ScopedAutoReleasePool pool;
  1183. NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
  1184. return NSImageToJuceImage (im);
  1185. }
  1186. //==============================================================================
  1187. const int KeyPress::spaceKey = ' ';
  1188. const int KeyPress::returnKey = 0x0d;
  1189. const int KeyPress::escapeKey = 0x1b;
  1190. const int KeyPress::backspaceKey = 0x7f;
  1191. const int KeyPress::leftKey = NSLeftArrowFunctionKey;
  1192. const int KeyPress::rightKey = NSRightArrowFunctionKey;
  1193. const int KeyPress::upKey = NSUpArrowFunctionKey;
  1194. const int KeyPress::downKey = NSDownArrowFunctionKey;
  1195. const int KeyPress::pageUpKey = NSPageUpFunctionKey;
  1196. const int KeyPress::pageDownKey = NSPageDownFunctionKey;
  1197. const int KeyPress::endKey = NSEndFunctionKey;
  1198. const int KeyPress::homeKey = NSHomeFunctionKey;
  1199. const int KeyPress::deleteKey = NSDeleteFunctionKey;
  1200. const int KeyPress::insertKey = -1;
  1201. const int KeyPress::tabKey = 9;
  1202. const int KeyPress::F1Key = NSF1FunctionKey;
  1203. const int KeyPress::F2Key = NSF2FunctionKey;
  1204. const int KeyPress::F3Key = NSF3FunctionKey;
  1205. const int KeyPress::F4Key = NSF4FunctionKey;
  1206. const int KeyPress::F5Key = NSF5FunctionKey;
  1207. const int KeyPress::F6Key = NSF6FunctionKey;
  1208. const int KeyPress::F7Key = NSF7FunctionKey;
  1209. const int KeyPress::F8Key = NSF8FunctionKey;
  1210. const int KeyPress::F9Key = NSF9FunctionKey;
  1211. const int KeyPress::F10Key = NSF10FunctionKey;
  1212. const int KeyPress::F11Key = NSF1FunctionKey;
  1213. const int KeyPress::F12Key = NSF12FunctionKey;
  1214. const int KeyPress::F13Key = NSF13FunctionKey;
  1215. const int KeyPress::F14Key = NSF14FunctionKey;
  1216. const int KeyPress::F15Key = NSF15FunctionKey;
  1217. const int KeyPress::F16Key = NSF16FunctionKey;
  1218. const int KeyPress::numberPad0 = 0x30020;
  1219. const int KeyPress::numberPad1 = 0x30021;
  1220. const int KeyPress::numberPad2 = 0x30022;
  1221. const int KeyPress::numberPad3 = 0x30023;
  1222. const int KeyPress::numberPad4 = 0x30024;
  1223. const int KeyPress::numberPad5 = 0x30025;
  1224. const int KeyPress::numberPad6 = 0x30026;
  1225. const int KeyPress::numberPad7 = 0x30027;
  1226. const int KeyPress::numberPad8 = 0x30028;
  1227. const int KeyPress::numberPad9 = 0x30029;
  1228. const int KeyPress::numberPadAdd = 0x3002a;
  1229. const int KeyPress::numberPadSubtract = 0x3002b;
  1230. const int KeyPress::numberPadMultiply = 0x3002c;
  1231. const int KeyPress::numberPadDivide = 0x3002d;
  1232. const int KeyPress::numberPadSeparator = 0x3002e;
  1233. const int KeyPress::numberPadDecimalPoint = 0x3002f;
  1234. const int KeyPress::numberPadEquals = 0x30030;
  1235. const int KeyPress::numberPadDelete = 0x30031;
  1236. const int KeyPress::playKey = 0x30000;
  1237. const int KeyPress::stopKey = 0x30001;
  1238. const int KeyPress::fastForwardKey = 0x30002;
  1239. const int KeyPress::rewindKey = 0x30003;
  1240. #endif