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.

1495 lines
44KB

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