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.

1529 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. //==============================================================================
  149. virtual void viewFocusGain();
  150. virtual void viewFocusLoss();
  151. bool isFocused() const;
  152. void grabFocus();
  153. void textInputRequired (int x, int y);
  154. //==============================================================================
  155. void repaint (int x, int y, int w, int h);
  156. void performAnyPendingRepaintsNow();
  157. //==============================================================================
  158. juce_UseDebuggingNewOperator
  159. NSWindow* window;
  160. JuceNSView* view;
  161. bool isSharedWindow, fullScreen;
  162. };
  163. //==============================================================================
  164. END_JUCE_NAMESPACE
  165. @implementation JuceNSView
  166. - (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner_
  167. withFrame: (NSRect) frame
  168. {
  169. [super initWithFrame: frame];
  170. owner = owner_;
  171. notificationCenter = [NSNotificationCenter defaultCenter];
  172. [notificationCenter addObserver: self
  173. selector: @selector (frameChanged:)
  174. name: NSViewFrameDidChangeNotification
  175. object: self];
  176. if (! owner_->isSharedWindow)
  177. {
  178. [notificationCenter addObserver: self
  179. selector: @selector (frameChanged:)
  180. name: NSWindowDidMoveNotification
  181. object: owner_->window];
  182. }
  183. [self registerForDraggedTypes: [self getSupportedDragTypes]];
  184. return self;
  185. }
  186. - (void) dealloc
  187. {
  188. [notificationCenter removeObserver: self];
  189. [super dealloc];
  190. }
  191. //==============================================================================
  192. - (void) drawRect: (NSRect) r
  193. {
  194. if (owner != 0)
  195. owner->drawRect (r);
  196. }
  197. - (BOOL) isOpaque
  198. {
  199. return owner == 0 || owner->isOpaque();
  200. }
  201. //==============================================================================
  202. - (void) mouseDown: (NSEvent*) ev
  203. {
  204. if (owner != 0)
  205. owner->redirectMouseDown (ev);
  206. }
  207. - (void) mouseUp: (NSEvent*) ev
  208. {
  209. if (owner != 0)
  210. owner->redirectMouseUp (ev);
  211. }
  212. - (void) mouseDragged: (NSEvent*) ev
  213. {
  214. if (owner != 0)
  215. owner->redirectMouseDrag (ev);
  216. }
  217. - (void) mouseMoved: (NSEvent*) ev
  218. {
  219. if (owner != 0)
  220. owner->redirectMouseMove (ev);
  221. }
  222. - (void) mouseEntered: (NSEvent*) ev
  223. {
  224. if (owner != 0)
  225. owner->redirectMouseEnter (ev);
  226. }
  227. - (void) mouseExited: (NSEvent*) ev
  228. {
  229. if (owner != 0)
  230. owner->redirectMouseExit (ev);
  231. }
  232. - (void) rightMouseDown: (NSEvent*) ev
  233. {
  234. [self mouseDown: ev];
  235. }
  236. - (void) rightMouseDragged: (NSEvent*) ev
  237. {
  238. [self mouseDragged: ev];
  239. }
  240. - (void) rightMouseUp: (NSEvent*) ev
  241. {
  242. [self mouseUp: ev];
  243. }
  244. - (void) scrollWheel: (NSEvent*) ev
  245. {
  246. if (owner != 0)
  247. owner->redirectMouseWheel (ev);
  248. }
  249. - (BOOL) acceptsFirstMouse: (NSEvent*) ev
  250. {
  251. return YES;
  252. }
  253. - (void) frameChanged: (NSNotification*) n
  254. {
  255. if (owner != 0)
  256. owner->redirectMovedOrResized();
  257. }
  258. //==============================================================================
  259. - (void) keyDown: (NSEvent*) ev
  260. {
  261. if (owner == 0 || ! owner->redirectKeyDown (ev))
  262. [super keyDown: ev];
  263. }
  264. - (void) keyUp: (NSEvent*) ev
  265. {
  266. if (owner == 0 || ! owner->redirectKeyUp (ev))
  267. [super keyUp: ev];
  268. }
  269. - (void) flagsChanged: (NSEvent*) ev
  270. {
  271. if (owner != 0)
  272. owner->redirectModKeyChange (ev);
  273. }
  274. #if MACOS_10_4_OR_EARLIER
  275. - (BOOL) performKeyEquivalent: (NSEvent*) ev
  276. {
  277. if (owner != 0 && owner->redirectPerformKeyEquivalent (ev))
  278. return true;
  279. return [super performKeyEquivalent: ev];
  280. }
  281. #endif
  282. - (BOOL) becomeFirstResponder
  283. {
  284. if (owner != 0)
  285. owner->viewFocusGain();
  286. return true;
  287. }
  288. - (BOOL) resignFirstResponder
  289. {
  290. if (owner != 0)
  291. owner->viewFocusLoss();
  292. return true;
  293. }
  294. //==============================================================================
  295. - (NSArray*) getSupportedDragTypes
  296. {
  297. return [NSArray arrayWithObjects: NSFilenamesPboardType, /*NSFilesPromisePboardType, NSStringPboardType,*/ nil];
  298. }
  299. - (BOOL) sendDragCallback: (int) type sender: (id <NSDraggingInfo>) sender
  300. {
  301. return owner != 0 && owner->sendDragCallback (type, sender);
  302. }
  303. - (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender
  304. {
  305. if ([self sendDragCallback: 0 sender: sender])
  306. return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric;
  307. else
  308. return NSDragOperationNone;
  309. }
  310. - (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender
  311. {
  312. if ([self sendDragCallback: 0 sender: sender])
  313. return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric;
  314. else
  315. return NSDragOperationNone;
  316. }
  317. - (void) draggingEnded: (id <NSDraggingInfo>) sender
  318. {
  319. [self sendDragCallback: 1 sender: sender];
  320. }
  321. - (void) draggingExited: (id <NSDraggingInfo>) sender
  322. {
  323. [self sendDragCallback: 1 sender: sender];
  324. }
  325. - (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender
  326. {
  327. return YES;
  328. }
  329. - (BOOL) performDragOperation: (id <NSDraggingInfo>) sender
  330. {
  331. return [self sendDragCallback: 2 sender: sender];
  332. }
  333. - (void) concludeDragOperation: (id <NSDraggingInfo>) sender
  334. {
  335. }
  336. @end
  337. //==============================================================================
  338. @implementation JuceNSWindow
  339. - (void) setOwner: (NSViewComponentPeer*) owner_
  340. {
  341. owner = owner_;
  342. isZooming = false;
  343. }
  344. - (BOOL) canBecomeKeyWindow
  345. {
  346. return owner != 0 && owner->canBecomeKeyWindow();
  347. }
  348. - (void) becomeKeyWindow
  349. {
  350. [super becomeKeyWindow];
  351. if (owner != 0)
  352. owner->grabFocus();
  353. }
  354. - (BOOL) windowShouldClose: (id) window
  355. {
  356. return owner == 0 || owner->windowShouldClose();
  357. }
  358. - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen
  359. {
  360. if (owner != 0)
  361. frameRect = owner->constrainRect (frameRect);
  362. return frameRect;
  363. }
  364. - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize
  365. {
  366. if (isZooming)
  367. return proposedFrameSize;
  368. NSRect frameRect = [self frame];
  369. frameRect.size = proposedFrameSize;
  370. if (owner != 0)
  371. frameRect = owner->constrainRect (frameRect);
  372. return frameRect.size;
  373. }
  374. - (void) zoom: (id) sender
  375. {
  376. isZooming = true;
  377. [super zoom: sender];
  378. isZooming = false;
  379. }
  380. - (void) windowWillMove: (NSNotification*) notification
  381. {
  382. if (juce::Component::getCurrentlyModalComponent() != 0
  383. && owner->getComponent()->isCurrentlyBlockedByAnotherModalComponent()
  384. && (owner->getStyleFlags() & juce::ComponentPeer::windowHasTitleBar) != 0)
  385. juce::Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
  386. }
  387. @end
  388. //==============================================================================
  389. //==============================================================================
  390. BEGIN_JUCE_NAMESPACE
  391. //==============================================================================
  392. class JuceNSImage
  393. {
  394. public:
  395. JuceNSImage (const int width, const int height, const bool hasAlpha)
  396. : juceImage (hasAlpha ? Image::ARGB : Image::RGB,
  397. width, height, hasAlpha)
  398. {
  399. lineStride = 0;
  400. pixelStride = 0;
  401. imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height,
  402. lineStride, pixelStride);
  403. imageRep = [[NSBitmapImageRep alloc]
  404. initWithBitmapDataPlanes: &imageData
  405. pixelsWide: width
  406. pixelsHigh: height
  407. bitsPerSample: 8
  408. samplesPerPixel: pixelStride
  409. hasAlpha: hasAlpha
  410. isPlanar: NO
  411. colorSpaceName: NSCalibratedRGBColorSpace
  412. bitmapFormat: /*NSAlphaFirstBitmapFormat*/ (NSBitmapFormat) 0
  413. bytesPerRow: lineStride
  414. bitsPerPixel: 8 * pixelStride ];
  415. juceImage.releasePixelDataReadWrite (imageData);
  416. }
  417. ~JuceNSImage()
  418. {
  419. [imageRep release];
  420. }
  421. Image& getJuceImage() throw() { return juceImage; }
  422. void draw (const float x, const float y,
  423. const RectangleList& clip,
  424. const int originX, const int originY) const
  425. {
  426. // Our data is BGRA and the damned image rep only takes RGBA, so
  427. // we need to byte-swap the active areas if there's an alpha channel...
  428. if (juceImage.hasAlphaChannel())
  429. {
  430. RectangleList::Iterator iter (clip);
  431. while (iter.next())
  432. {
  433. const Rectangle* const r = iter.getRectangle();
  434. swapRGBOrder (r->getX() + originX,
  435. r->getY() + originY,
  436. r->getWidth(),
  437. r->getHeight());
  438. }
  439. }
  440. NSPoint p;
  441. p.x = x;
  442. p.y = y;
  443. [imageRep drawAtPoint: p];
  444. }
  445. void drawNSImage (NSImage* imageToDraw)
  446. {
  447. const ScopedAutoReleasePool pool;
  448. [NSGraphicsContext setCurrentContext:
  449. [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]];
  450. [imageToDraw drawAtPoint: NSZeroPoint
  451. fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height)
  452. operation: NSCompositeSourceOver
  453. fraction: 1.0f];
  454. [[NSGraphicsContext currentContext] flushGraphics];
  455. if (juceImage.hasAlphaChannel())
  456. swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());
  457. }
  458. private:
  459. Image juceImage;
  460. NSBitmapImageRep* imageRep;
  461. uint8* imageData;
  462. int pixelStride, lineStride;
  463. void swapRGBOrder (const int x, const int y, const int w, int h) const
  464. {
  465. #if JUCE_BIG_ENDIAN
  466. jassert (pixelStride == 4);
  467. #endif
  468. jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight())
  469. .contains (Rectangle (x, y, w, h)));
  470. uint8* start = imageData + x * pixelStride + y * lineStride;
  471. while (--h >= 0)
  472. {
  473. uint8* p = start;
  474. start += lineStride;
  475. for (int i = w; --i >= 0;)
  476. {
  477. #if JUCE_BIG_ENDIAN
  478. const uint8 oldp3 = p[3];
  479. const uint8 oldp1 = p[1];
  480. p[3] = p[0];
  481. p[0] = oldp1;
  482. p[1] = p[2];
  483. p[2] = oldp3;
  484. #else
  485. const uint8 oldp0 = p[0];
  486. p[0] = p[2];
  487. p[2] = oldp0;
  488. #endif
  489. p += pixelStride;
  490. }
  491. }
  492. }
  493. };
  494. //==============================================================================
  495. static ComponentPeer* currentlyFocusedPeer = 0;
  496. static VoidArray keysCurrentlyDown;
  497. bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw()
  498. {
  499. if (keysCurrentlyDown.contains ((void*) keyCode))
  500. return true;
  501. if (keyCode >= 'A' && keyCode <= 'Z'
  502. && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode)))
  503. return true;
  504. if (keyCode >= 'a' && keyCode <= 'z'
  505. && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode)))
  506. return true;
  507. return false;
  508. }
  509. static int getKeyCodeFromEvent (NSEvent* ev)
  510. {
  511. String unicode (nsStringToJuce ([ev characters]));
  512. String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
  513. int keyCode = unmodified[0];
  514. if (keyCode == 0x19) // (backwards-tab)
  515. keyCode = 9;
  516. return keyCode;
  517. }
  518. static int currentModifiers = 0;
  519. static void updateModifiers (NSEvent* e)
  520. {
  521. int m = currentModifiers & ~(ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier
  522. | ModifierKeys::altModifier | ModifierKeys::commandModifier);
  523. if (([e modifierFlags] & NSShiftKeyMask) != 0)
  524. m |= ModifierKeys::shiftModifier;
  525. if (([e modifierFlags] & NSControlKeyMask) != 0)
  526. m |= ModifierKeys::ctrlModifier;
  527. if (([e modifierFlags] & NSAlternateKeyMask) != 0)
  528. m |= ModifierKeys::altModifier;
  529. if (([e modifierFlags] & NSCommandKeyMask) != 0)
  530. m |= ModifierKeys::commandModifier;
  531. currentModifiers = m;
  532. }
  533. static void updateKeysDown (NSEvent* ev, bool isKeyDown)
  534. {
  535. updateModifiers (ev);
  536. int keyCode = getKeyCodeFromEvent (ev);
  537. if (keyCode != 0)
  538. {
  539. if (isKeyDown)
  540. keysCurrentlyDown.addIfNotAlreadyThere ((void*) keyCode);
  541. else
  542. keysCurrentlyDown.removeValue ((void*) keyCode);
  543. }
  544. }
  545. const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
  546. {
  547. return ModifierKeys (currentModifiers);
  548. }
  549. void ModifierKeys::updateCurrentModifiers() throw()
  550. {
  551. currentModifierFlags = currentModifiers;
  552. }
  553. static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; }
  554. static void getMousePos (NSEvent* e, NSView* view, int& x, int& y)
  555. {
  556. NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil];
  557. x = roundFloatToInt (p.x);
  558. y = roundFloatToInt ([view frame].size.height - p.y);
  559. }
  560. static int getModifierForButtonNumber (const int num) throw()
  561. {
  562. return num == 0 ? ModifierKeys::leftButtonModifier
  563. : (num == 1 ? ModifierKeys::rightButtonModifier
  564. : (num == 2 ? ModifierKeys::middleButtonModifier : 0));
  565. }
  566. //==============================================================================
  567. NSViewComponentPeer::NSViewComponentPeer (Component* const component,
  568. const int windowStyleFlags,
  569. NSView* viewToAttachTo)
  570. : ComponentPeer (component, windowStyleFlags),
  571. window (0),
  572. view (0)
  573. {
  574. NSRect r;
  575. r.origin.x = 0;
  576. r.origin.y = 0;
  577. r.size.width = (float) component->getWidth();
  578. r.size.height = (float) component->getHeight();
  579. view = [[JuceNSView alloc] initWithOwner: this withFrame: r];
  580. [view setPostsFrameChangedNotifications: YES];
  581. if (viewToAttachTo != 0)
  582. {
  583. window = [viewToAttachTo window];
  584. [viewToAttachTo addSubview: view];
  585. isSharedWindow = true;
  586. setVisible (component->isVisible());
  587. }
  588. else
  589. {
  590. isSharedWindow = false;
  591. r.origin.x = (float) component->getX();
  592. r.origin.y = (float) component->getY();
  593. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
  594. unsigned int style = 0;
  595. if ((windowStyleFlags & windowHasTitleBar) == 0)
  596. style = NSBorderlessWindowMask;
  597. else
  598. style = NSTitledWindowMask;
  599. if ((windowStyleFlags & windowHasMinimiseButton) != 0)
  600. style |= NSMiniaturizableWindowMask;
  601. if ((windowStyleFlags & windowHasCloseButton) != 0)
  602. style |= NSClosableWindowMask;
  603. if ((windowStyleFlags & windowIsResizable) != 0)
  604. style |= NSResizableWindowMask;
  605. window = [[JuceNSWindow alloc] initWithContentRect: r
  606. styleMask: style
  607. backing: NSBackingStoreBuffered
  608. defer: YES ];
  609. [((JuceNSWindow*) window) setOwner: this];
  610. [window orderOut: nil];
  611. [window setDelegate: window];
  612. [window setOpaque: component->isOpaque()];
  613. [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)];
  614. if (component->isAlwaysOnTop())
  615. [window setLevel: NSFloatingWindowLevel];
  616. [window setContentView: view];
  617. [window setAutodisplay: YES];
  618. [window setAcceptsMouseMovedEvents: YES];
  619. [window setReleasedWhenClosed: YES];
  620. [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0];
  621. [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0];
  622. }
  623. setTitle (component->getName());
  624. }
  625. NSViewComponentPeer::~NSViewComponentPeer()
  626. {
  627. view->owner = 0;
  628. [view removeFromSuperview];
  629. [view release];
  630. if (! isSharedWindow)
  631. {
  632. [((JuceNSWindow*) window) setOwner: 0];
  633. [window close];
  634. }
  635. }
  636. //==============================================================================
  637. void* NSViewComponentPeer::getNativeHandle() const
  638. {
  639. return view;
  640. }
  641. void NSViewComponentPeer::setVisible (bool shouldBeVisible)
  642. {
  643. if (isSharedWindow)
  644. {
  645. [view setHidden: ! shouldBeVisible];
  646. }
  647. else
  648. {
  649. if (shouldBeVisible)
  650. [window orderFront: nil];
  651. else
  652. [window orderOut: nil];
  653. }
  654. }
  655. void NSViewComponentPeer::setTitle (const String& title)
  656. {
  657. const ScopedAutoReleasePool pool;
  658. if (! isSharedWindow)
  659. [window setTitle: juceStringToNS (title)];
  660. }
  661. void NSViewComponentPeer::setPosition (int x, int y)
  662. {
  663. setBounds (x, y, component->getWidth(), component->getHeight(), false);
  664. }
  665. void NSViewComponentPeer::setSize (int w, int h)
  666. {
  667. setBounds (component->getX(), component->getY(), w, h, false);
  668. }
  669. void NSViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
  670. {
  671. fullScreen = isNowFullScreen;
  672. w = jmax (0, w);
  673. h = jmax (0, h);
  674. NSRect r;
  675. r.origin.x = (float) x;
  676. r.origin.y = (float) y;
  677. r.size.width = (float) w;
  678. r.size.height = (float) h;
  679. if (isSharedWindow)
  680. {
  681. r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height);
  682. if ([view frame].size.width != r.size.width
  683. || [view frame].size.height != r.size.height)
  684. [view setNeedsDisplay: true];
  685. [view setFrame: r];
  686. }
  687. else
  688. {
  689. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
  690. [window setFrame: [window frameRectForContentRect: r]
  691. display: true];
  692. }
  693. }
  694. void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const
  695. {
  696. NSRect r = [view frame];
  697. if (global && [view window] != 0)
  698. {
  699. r = [view convertRect: r toView: nil];
  700. NSRect wr = [[view window] frame];
  701. r.origin.x += wr.origin.x;
  702. r.origin.y += wr.origin.y;
  703. y = (int) ([[[NSScreen screens] objectAtIndex:0] frame].size.height - r.origin.y - r.size.height);
  704. }
  705. else
  706. {
  707. y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height);
  708. }
  709. x = (int) r.origin.x;
  710. w = (int) r.size.width;
  711. h = (int) r.size.height;
  712. }
  713. void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const
  714. {
  715. getBounds (x, y, w, h, ! isSharedWindow);
  716. }
  717. int NSViewComponentPeer::getScreenX() const
  718. {
  719. int x, y, w, h;
  720. getBounds (x, y, w, h, true);
  721. return x;
  722. }
  723. int NSViewComponentPeer::getScreenY() const
  724. {
  725. int x, y, w, h;
  726. getBounds (x, y, w, h, true);
  727. return y;
  728. }
  729. void NSViewComponentPeer::relativePositionToGlobal (int& x, int& y)
  730. {
  731. int wx, wy, ww, wh;
  732. getBounds (wx, wy, ww, wh, true);
  733. x += wx;
  734. y += wy;
  735. }
  736. void NSViewComponentPeer::globalPositionToRelative (int& x, int& y)
  737. {
  738. int wx, wy, ww, wh;
  739. getBounds (wx, wy, ww, wh, true);
  740. x -= wx;
  741. y -= wy;
  742. }
  743. NSRect NSViewComponentPeer::constrainRect (NSRect r)
  744. {
  745. if (constrainer != 0)
  746. {
  747. const MessageManagerLock mml;
  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. const MessageManagerLock messLock;
  881. if (currentlyFocusedPeer != this)
  882. {
  883. if (ComponentPeer::isValidPeer (currentlyFocusedPeer))
  884. currentlyFocusedPeer->handleFocusLoss();
  885. currentlyFocusedPeer = this;
  886. handleFocusGain();
  887. }
  888. }
  889. void NSViewComponentPeer::viewFocusLoss()
  890. {
  891. if (currentlyFocusedPeer == this)
  892. {
  893. currentlyFocusedPeer = 0;
  894. handleFocusLoss();
  895. }
  896. }
  897. void juce_HandleProcessFocusChange()
  898. {
  899. keysCurrentlyDown.clear();
  900. if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer))
  901. {
  902. if (Process::isForegroundProcess())
  903. {
  904. currentlyFocusedPeer->handleFocusGain();
  905. }
  906. else
  907. {
  908. currentlyFocusedPeer->handleFocusLoss();
  909. // turn kiosk mode off if we lose focus..
  910. Desktop::getInstance().setKioskModeComponent (0);
  911. }
  912. }
  913. }
  914. bool NSViewComponentPeer::isFocused() const
  915. {
  916. return window != 0 && [window isKeyWindow];
  917. }
  918. void NSViewComponentPeer::grabFocus()
  919. {
  920. if (window != 0)
  921. {
  922. [window makeKeyWindow];
  923. [window makeFirstResponder: view];
  924. viewFocusGain();
  925. }
  926. }
  927. void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/)
  928. {
  929. }
  930. bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
  931. {
  932. const MessageManagerLock mml;
  933. String unicode (nsStringToJuce ([ev characters]));
  934. String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
  935. int keyCode = getKeyCodeFromEvent (ev);
  936. //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0]));
  937. //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0]));
  938. if (unicode.isNotEmpty() || keyCode != 0)
  939. {
  940. if (isKeyDown)
  941. {
  942. bool used = false;
  943. while (unicode.length() > 0)
  944. {
  945. juce_wchar textCharacter = unicode[0];
  946. unicode = unicode.substring (1);
  947. if (([ev modifierFlags] & NSCommandKeyMask) != 0)
  948. textCharacter = 0;
  949. used = handleKeyUpOrDown() || used;
  950. used = handleKeyPress (keyCode, textCharacter) || used;
  951. }
  952. return used;
  953. }
  954. else
  955. {
  956. if (handleKeyUpOrDown())
  957. return true;
  958. }
  959. }
  960. return false;
  961. }
  962. bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)
  963. {
  964. const MessageManagerLock mml;
  965. updateKeysDown (ev, true);
  966. bool used = handleKeyEvent (ev, true);
  967. if (([ev modifierFlags] & NSCommandKeyMask) != 0)
  968. {
  969. // for command keys, the key-up event is thrown away, so simulate one..
  970. updateKeysDown (ev, false);
  971. used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used;
  972. }
  973. return used;
  974. }
  975. bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev)
  976. {
  977. const MessageManagerLock mml;
  978. updateKeysDown (ev, false);
  979. return handleKeyEvent (ev, false);
  980. }
  981. void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
  982. {
  983. const MessageManagerLock mml;
  984. updateModifiers (ev);
  985. handleModifierKeysChange();
  986. }
  987. #if MACOS_10_4_OR_EARLIER
  988. bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)
  989. {
  990. const MessageManagerLock mml;
  991. if ([ev type] == NSKeyDown)
  992. return redirectKeyDown (ev);
  993. else if ([ev type] == NSKeyUp)
  994. return redirectKeyUp (ev);
  995. return false;
  996. }
  997. #endif
  998. //==============================================================================
  999. void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)
  1000. {
  1001. const MessageManagerLock mml;
  1002. updateModifiers (ev);
  1003. currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
  1004. int x, y;
  1005. getMousePos (ev, view, x, y);
  1006. handleMouseDown (x, y, getMouseTime (ev));
  1007. }
  1008. void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)
  1009. {
  1010. const MessageManagerLock mml;
  1011. const int oldMods = currentModifiers;
  1012. updateModifiers (ev);
  1013. currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]);
  1014. int x, y;
  1015. getMousePos (ev, view, x, y);
  1016. handleMouseUp (oldMods, x, y, getMouseTime (ev));
  1017. }
  1018. void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)
  1019. {
  1020. const MessageManagerLock mml;
  1021. updateModifiers (ev);
  1022. currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
  1023. int x, y;
  1024. getMousePos (ev, view, x, y);
  1025. handleMouseDrag (x, y, getMouseTime (ev));
  1026. }
  1027. void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)
  1028. {
  1029. const MessageManagerLock mml;
  1030. updateModifiers (ev);
  1031. int x, y;
  1032. getMousePos (ev, view, x, y);
  1033. handleMouseMove (x, y, getMouseTime (ev));
  1034. }
  1035. void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)
  1036. {
  1037. const MessageManagerLock mml;
  1038. updateModifiers (ev);
  1039. int x, y;
  1040. getMousePos (ev, view, x, y);
  1041. handleMouseEnter (x, y, getMouseTime (ev));
  1042. }
  1043. void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)
  1044. {
  1045. const MessageManagerLock mml;
  1046. updateModifiers (ev);
  1047. int x, y;
  1048. getMousePos (ev, view, x, y);
  1049. handleMouseExit (x, y, getMouseTime (ev));
  1050. }
  1051. void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)
  1052. {
  1053. const MessageManagerLock mml;
  1054. updateModifiers (ev);
  1055. handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f),
  1056. roundFloatToInt ([ev deltaY] * 10.0f),
  1057. getMouseTime (ev));
  1058. }
  1059. //==============================================================================
  1060. BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender)
  1061. {
  1062. const MessageManagerLock mml;
  1063. NSString* bestType
  1064. = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]];
  1065. if (bestType == nil)
  1066. return false;
  1067. NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil];
  1068. int x = (int) p.x;
  1069. int y = (int) ([view frame].size.height - p.y);
  1070. StringArray files;
  1071. id list = [[sender draggingPasteboard] propertyListForType: bestType];
  1072. if (list == nil)
  1073. return false;
  1074. if ([list isKindOfClass: [NSArray class]])
  1075. {
  1076. NSArray* items = (NSArray*) list;
  1077. for (unsigned int i = 0; i < [items count]; ++i)
  1078. files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i]));
  1079. }
  1080. if (files.size() == 0)
  1081. return false;
  1082. if (type == 0)
  1083. handleFileDragMove (files, x, y);
  1084. else if (type == 1)
  1085. handleFileDragExit (files);
  1086. else if (type == 2)
  1087. handleFileDragDrop (files, x, y);
  1088. return true;
  1089. }
  1090. bool NSViewComponentPeer::isOpaque()
  1091. {
  1092. if (! getComponent()->isValidComponent())
  1093. return true;
  1094. return getComponent()->isOpaque();
  1095. }
  1096. void NSViewComponentPeer::drawRect (NSRect r)
  1097. {
  1098. if (r.size.width < 1.0f || r.size.height < 1.0f)
  1099. return;
  1100. const MessageManagerLock mml;
  1101. const float y = [view frame].size.height - (r.origin.y + r.size.height);
  1102. JuceNSImage temp ((int) (r.size.width + 0.5f),
  1103. (int) (r.size.height + 0.5f),
  1104. ! getComponent()->isOpaque());
  1105. LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
  1106. const int originX = -roundFloatToInt (r.origin.x);
  1107. const int originY = -roundFloatToInt (y);
  1108. context.setOrigin (originX, originY);
  1109. const NSRect* rects = 0;
  1110. NSInteger numRects = 0;
  1111. [view getRectsBeingDrawn: &rects count: &numRects];
  1112. RectangleList clip;
  1113. for (int i = 0; i < numRects; ++i)
  1114. {
  1115. clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
  1116. roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
  1117. roundFloatToInt (rects[i].size.width),
  1118. roundFloatToInt (rects[i].size.height)));
  1119. }
  1120. if (context.reduceClipRegion (clip))
  1121. {
  1122. handlePaint (context);
  1123. temp.draw (r.origin.x, r.origin.y, clip, originX, originY);
  1124. }
  1125. }
  1126. bool NSViewComponentPeer::canBecomeKeyWindow()
  1127. {
  1128. const MessageManagerLock mml;
  1129. // If running as a plugin, let the component decide whether it's going to allow the window to get focused.
  1130. return JUCEApplication::getInstance() != 0
  1131. || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus());
  1132. }
  1133. bool NSViewComponentPeer::windowShouldClose()
  1134. {
  1135. const MessageManagerLock mml;
  1136. if (! isValidPeer (this))
  1137. return YES;
  1138. handleUserClosingWindow();
  1139. return NO;
  1140. }
  1141. void NSViewComponentPeer::redirectMovedOrResized()
  1142. {
  1143. const MessageManagerLock mml;
  1144. handleMovedOrResized();
  1145. }
  1146. //==============================================================================
  1147. void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars)
  1148. {
  1149. // Very annoyingly, this function has to use the old SetSystemUIMode function,
  1150. // which is in Carbon.framework. But, because there's no Cocoa equivalent, it
  1151. // is apparently still available in 64-bit apps..
  1152. if (enableOrDisable)
  1153. {
  1154. SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0);
  1155. kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false));
  1156. }
  1157. else
  1158. {
  1159. SetSystemUIMode (kUIModeNormal, 0);
  1160. }
  1161. }
  1162. //==============================================================================
  1163. void NSViewComponentPeer::repaint (int x, int y, int w, int h)
  1164. {
  1165. [view setNeedsDisplayInRect:
  1166. NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)),
  1167. (float) w, (float) h)];
  1168. }
  1169. void NSViewComponentPeer::performAnyPendingRepaintsNow()
  1170. {
  1171. [view displayIfNeeded];
  1172. }
  1173. ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
  1174. {
  1175. return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo);
  1176. }
  1177. //==============================================================================
  1178. static Image* NSImageToJuceImage (NSImage* image)
  1179. {
  1180. JuceNSImage juceIm ((int) [image size].width,
  1181. (int) [image size].height,
  1182. true);
  1183. juceIm.drawNSImage (image);
  1184. return juceIm.getJuceImage().createCopy();
  1185. }
  1186. Image* juce_createIconForFile (const File& file)
  1187. {
  1188. const ScopedAutoReleasePool pool;
  1189. NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
  1190. return NSImageToJuceImage (im);
  1191. }
  1192. //==============================================================================
  1193. const int KeyPress::spaceKey = ' ';
  1194. const int KeyPress::returnKey = 0x0d;
  1195. const int KeyPress::escapeKey = 0x1b;
  1196. const int KeyPress::backspaceKey = 0x7f;
  1197. const int KeyPress::leftKey = NSLeftArrowFunctionKey;
  1198. const int KeyPress::rightKey = NSRightArrowFunctionKey;
  1199. const int KeyPress::upKey = NSUpArrowFunctionKey;
  1200. const int KeyPress::downKey = NSDownArrowFunctionKey;
  1201. const int KeyPress::pageUpKey = NSPageUpFunctionKey;
  1202. const int KeyPress::pageDownKey = NSPageDownFunctionKey;
  1203. const int KeyPress::endKey = NSEndFunctionKey;
  1204. const int KeyPress::homeKey = NSHomeFunctionKey;
  1205. const int KeyPress::deleteKey = NSDeleteFunctionKey;
  1206. const int KeyPress::insertKey = -1;
  1207. const int KeyPress::tabKey = 9;
  1208. const int KeyPress::F1Key = NSF1FunctionKey;
  1209. const int KeyPress::F2Key = NSF2FunctionKey;
  1210. const int KeyPress::F3Key = NSF3FunctionKey;
  1211. const int KeyPress::F4Key = NSF4FunctionKey;
  1212. const int KeyPress::F5Key = NSF5FunctionKey;
  1213. const int KeyPress::F6Key = NSF6FunctionKey;
  1214. const int KeyPress::F7Key = NSF7FunctionKey;
  1215. const int KeyPress::F8Key = NSF8FunctionKey;
  1216. const int KeyPress::F9Key = NSF9FunctionKey;
  1217. const int KeyPress::F10Key = NSF10FunctionKey;
  1218. const int KeyPress::F11Key = NSF1FunctionKey;
  1219. const int KeyPress::F12Key = NSF12FunctionKey;
  1220. const int KeyPress::F13Key = NSF13FunctionKey;
  1221. const int KeyPress::F14Key = NSF14FunctionKey;
  1222. const int KeyPress::F15Key = NSF15FunctionKey;
  1223. const int KeyPress::F16Key = NSF16FunctionKey;
  1224. const int KeyPress::numberPad0 = 0x30020;
  1225. const int KeyPress::numberPad1 = 0x30021;
  1226. const int KeyPress::numberPad2 = 0x30022;
  1227. const int KeyPress::numberPad3 = 0x30023;
  1228. const int KeyPress::numberPad4 = 0x30024;
  1229. const int KeyPress::numberPad5 = 0x30025;
  1230. const int KeyPress::numberPad6 = 0x30026;
  1231. const int KeyPress::numberPad7 = 0x30027;
  1232. const int KeyPress::numberPad8 = 0x30028;
  1233. const int KeyPress::numberPad9 = 0x30029;
  1234. const int KeyPress::numberPadAdd = 0x3002a;
  1235. const int KeyPress::numberPadSubtract = 0x3002b;
  1236. const int KeyPress::numberPadMultiply = 0x3002c;
  1237. const int KeyPress::numberPadDivide = 0x3002d;
  1238. const int KeyPress::numberPadSeparator = 0x3002e;
  1239. const int KeyPress::numberPadDecimalPoint = 0x3002f;
  1240. const int KeyPress::numberPadEquals = 0x30030;
  1241. const int KeyPress::numberPadDelete = 0x30031;
  1242. const int KeyPress::playKey = 0x30000;
  1243. const int KeyPress::stopKey = 0x30001;
  1244. const int KeyPress::fastForwardKey = 0x30002;
  1245. const int KeyPress::rewindKey = 0x30003;
  1246. #endif