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.

1503 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. - (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. const String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
  512. int keyCode = unmodified[0];
  513. if (keyCode == 0x19) // (backwards-tab)
  514. keyCode = 9;
  515. return keyCode;
  516. }
  517. static int currentModifiers = 0;
  518. static void updateModifiers (NSEvent* e)
  519. {
  520. int m = currentModifiers & ~(ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier
  521. | ModifierKeys::altModifier | ModifierKeys::commandModifier);
  522. if (([e modifierFlags] & NSShiftKeyMask) != 0)
  523. m |= ModifierKeys::shiftModifier;
  524. if (([e modifierFlags] & NSControlKeyMask) != 0)
  525. m |= ModifierKeys::ctrlModifier;
  526. if (([e modifierFlags] & NSAlternateKeyMask) != 0)
  527. m |= ModifierKeys::altModifier;
  528. if (([e modifierFlags] & NSCommandKeyMask) != 0)
  529. m |= ModifierKeys::commandModifier;
  530. currentModifiers = m;
  531. }
  532. static void updateKeysDown (NSEvent* ev, bool isKeyDown)
  533. {
  534. updateModifiers (ev);
  535. int keyCode = getKeyCodeFromEvent (ev);
  536. if (keyCode != 0)
  537. {
  538. if (isKeyDown)
  539. keysCurrentlyDown.addIfNotAlreadyThere ((void*) keyCode);
  540. else
  541. keysCurrentlyDown.removeValue ((void*) keyCode);
  542. }
  543. }
  544. const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
  545. {
  546. return ModifierKeys (currentModifiers);
  547. }
  548. void ModifierKeys::updateCurrentModifiers() throw()
  549. {
  550. currentModifierFlags = currentModifiers;
  551. }
  552. static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; }
  553. static void getMousePos (NSEvent* e, NSView* view, int& x, int& y)
  554. {
  555. NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil];
  556. x = roundFloatToInt (p.x);
  557. y = roundFloatToInt ([view frame].size.height - p.y);
  558. }
  559. static int getModifierForButtonNumber (const int num) throw()
  560. {
  561. return num == 0 ? ModifierKeys::leftButtonModifier
  562. : (num == 1 ? ModifierKeys::rightButtonModifier
  563. : (num == 2 ? ModifierKeys::middleButtonModifier : 0));
  564. }
  565. //==============================================================================
  566. NSViewComponentPeer::NSViewComponentPeer (Component* const component,
  567. const int windowStyleFlags,
  568. NSView* viewToAttachTo)
  569. : ComponentPeer (component, windowStyleFlags),
  570. window (0),
  571. view (0)
  572. {
  573. NSRect r;
  574. r.origin.x = 0;
  575. r.origin.y = 0;
  576. r.size.width = (float) component->getWidth();
  577. r.size.height = (float) component->getHeight();
  578. view = [[JuceNSView alloc] initWithOwner: this withFrame: r];
  579. [view setPostsFrameChangedNotifications: YES];
  580. if (viewToAttachTo != 0)
  581. {
  582. window = [viewToAttachTo window];
  583. [viewToAttachTo addSubview: view];
  584. isSharedWindow = true;
  585. setVisible (component->isVisible());
  586. }
  587. else
  588. {
  589. isSharedWindow = false;
  590. r.origin.x = (float) component->getX();
  591. r.origin.y = (float) component->getY();
  592. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
  593. unsigned int style = 0;
  594. if ((windowStyleFlags & windowHasTitleBar) == 0)
  595. style = NSBorderlessWindowMask;
  596. else
  597. style = NSTitledWindowMask;
  598. if ((windowStyleFlags & windowHasMinimiseButton) != 0)
  599. style |= NSMiniaturizableWindowMask;
  600. if ((windowStyleFlags & windowHasCloseButton) != 0)
  601. style |= NSClosableWindowMask;
  602. if ((windowStyleFlags & windowIsResizable) != 0)
  603. style |= NSResizableWindowMask;
  604. window = [[JuceNSWindow alloc] initWithContentRect: r
  605. styleMask: style
  606. backing: NSBackingStoreBuffered
  607. defer: YES ];
  608. [((JuceNSWindow*) window) setOwner: this];
  609. [window orderOut: nil];
  610. [window setDelegate: window];
  611. [window setOpaque: component->isOpaque()];
  612. [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)];
  613. if (component->isAlwaysOnTop())
  614. [window setLevel: NSFloatingWindowLevel];
  615. [window setContentView: view];
  616. [window setAutodisplay: YES];
  617. [window setAcceptsMouseMovedEvents: YES];
  618. [window setReleasedWhenClosed: YES];
  619. [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0];
  620. [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0];
  621. }
  622. setTitle (component->getName());
  623. }
  624. NSViewComponentPeer::~NSViewComponentPeer()
  625. {
  626. view->owner = 0;
  627. [view removeFromSuperview];
  628. [view release];
  629. if (! isSharedWindow)
  630. {
  631. [((JuceNSWindow*) window) setOwner: 0];
  632. [window close];
  633. }
  634. }
  635. //==============================================================================
  636. void* NSViewComponentPeer::getNativeHandle() const
  637. {
  638. return view;
  639. }
  640. void NSViewComponentPeer::setVisible (bool shouldBeVisible)
  641. {
  642. if (isSharedWindow)
  643. {
  644. [view setHidden: ! shouldBeVisible];
  645. }
  646. else
  647. {
  648. if (shouldBeVisible)
  649. [window orderFront: nil];
  650. else
  651. [window orderOut: nil];
  652. }
  653. }
  654. void NSViewComponentPeer::setTitle (const String& title)
  655. {
  656. const ScopedAutoReleasePool pool;
  657. if (! isSharedWindow)
  658. [window setTitle: juceStringToNS (title)];
  659. }
  660. void NSViewComponentPeer::setPosition (int x, int y)
  661. {
  662. setBounds (x, y, component->getWidth(), component->getHeight(), false);
  663. }
  664. void NSViewComponentPeer::setSize (int w, int h)
  665. {
  666. setBounds (component->getX(), component->getY(), w, h, false);
  667. }
  668. void NSViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
  669. {
  670. fullScreen = isNowFullScreen;
  671. w = jmax (0, w);
  672. h = jmax (0, h);
  673. NSRect r;
  674. r.origin.x = (float) x;
  675. r.origin.y = (float) y;
  676. r.size.width = (float) w;
  677. r.size.height = (float) h;
  678. if (isSharedWindow)
  679. {
  680. r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height);
  681. if ([view frame].size.width != r.size.width
  682. || [view frame].size.height != r.size.height)
  683. [view setNeedsDisplay: true];
  684. [view setFrame: r];
  685. }
  686. else
  687. {
  688. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
  689. [window setFrame: [window frameRectForContentRect: r]
  690. display: true];
  691. }
  692. }
  693. void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const
  694. {
  695. NSRect r = [view frame];
  696. if (global && [view window] != 0)
  697. {
  698. r = [view convertRect: r toView: nil];
  699. NSRect wr = [[view window] frame];
  700. r.origin.x += wr.origin.x;
  701. r.origin.y += wr.origin.y;
  702. y = (int) ([[[NSScreen screens] objectAtIndex:0] frame].size.height - r.origin.y - r.size.height);
  703. }
  704. else
  705. {
  706. y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height);
  707. }
  708. x = (int) r.origin.x;
  709. w = (int) r.size.width;
  710. h = (int) r.size.height;
  711. }
  712. void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const
  713. {
  714. getBounds (x, y, w, h, ! isSharedWindow);
  715. }
  716. int NSViewComponentPeer::getScreenX() const
  717. {
  718. int x, y, w, h;
  719. getBounds (x, y, w, h, true);
  720. return x;
  721. }
  722. int NSViewComponentPeer::getScreenY() const
  723. {
  724. int x, y, w, h;
  725. getBounds (x, y, w, h, true);
  726. return y;
  727. }
  728. void NSViewComponentPeer::relativePositionToGlobal (int& x, int& y)
  729. {
  730. int wx, wy, ww, wh;
  731. getBounds (wx, wy, ww, wh, true);
  732. x += wx;
  733. y += wy;
  734. }
  735. void NSViewComponentPeer::globalPositionToRelative (int& x, int& y)
  736. {
  737. int wx, wy, ww, wh;
  738. getBounds (wx, wy, ww, wh, true);
  739. x -= wx;
  740. y -= wy;
  741. }
  742. NSRect NSViewComponentPeer::constrainRect (NSRect r)
  743. {
  744. if (constrainer != 0)
  745. {
  746. NSRect current = [window frame];
  747. current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height;
  748. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;
  749. int x = (int) r.origin.x;
  750. int y = (int) r.origin.y;
  751. int w = (int) r.size.width;
  752. int h = (int) r.size.height;
  753. Rectangle original ((int) current.origin.x, (int) current.origin.y,
  754. (int) current.size.width, (int) current.size.height);
  755. constrainer->checkBounds (x, y, w, h,
  756. original,
  757. Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
  758. y != original.getY() && y + h == original.getBottom(),
  759. x != original.getX() && x + w == original.getRight(),
  760. y == original.getY() && y + h != original.getBottom(),
  761. x == original.getX() && x + w != original.getRight());
  762. r.origin.x = x;
  763. r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - y;
  764. r.size.width = w;
  765. r.size.height = h;
  766. }
  767. return r;
  768. }
  769. void NSViewComponentPeer::setMinimised (bool shouldBeMinimised)
  770. {
  771. if (! isSharedWindow)
  772. {
  773. if (shouldBeMinimised)
  774. [window miniaturize: nil];
  775. else
  776. [window deminiaturize: nil];
  777. }
  778. }
  779. bool NSViewComponentPeer::isMinimised() const
  780. {
  781. return window != 0 && [window isMiniaturized];
  782. }
  783. void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen)
  784. {
  785. if (! isSharedWindow)
  786. {
  787. Rectangle r (lastNonFullscreenBounds);
  788. setMinimised (false);
  789. if (fullScreen != shouldBeFullScreen)
  790. {
  791. if (shouldBeFullScreen)
  792. r = Desktop::getInstance().getMainMonitorArea();
  793. // (can't call the component's setBounds method because that'll reset our fullscreen flag)
  794. if (r != getComponent()->getBounds() && ! r.isEmpty())
  795. setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
  796. }
  797. }
  798. }
  799. bool NSViewComponentPeer::isFullScreen() const
  800. {
  801. return fullScreen;
  802. }
  803. bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const
  804. {
  805. if (((unsigned int) x) >= (unsigned int) component->getWidth()
  806. || ((unsigned int) y) >= (unsigned int) component->getHeight())
  807. return false;
  808. NSPoint p;
  809. p.x = (float) x;
  810. p.y = (float) y;
  811. NSView* v = [view hitTest: p];
  812. if (trueIfInAChildWindow)
  813. return v != nil;
  814. return v == view;
  815. }
  816. const BorderSize NSViewComponentPeer::getFrameSize() const
  817. {
  818. BorderSize b;
  819. if (! isSharedWindow)
  820. {
  821. NSRect v = [view convertRect: [view frame] toView: nil];
  822. NSRect w = [window frame];
  823. b.setTop ((int) (w.size.height - (v.origin.y + v.size.height)));
  824. b.setBottom ((int) v.origin.y);
  825. b.setLeft ((int) v.origin.x);
  826. b.setRight ((int) (w.size.width - (v.origin.x + v.size.width)));
  827. }
  828. return b;
  829. }
  830. bool NSViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop)
  831. {
  832. if (! isSharedWindow)
  833. {
  834. [window setLevel: alwaysOnTop ? NSFloatingWindowLevel
  835. : NSNormalWindowLevel];
  836. }
  837. return true;
  838. }
  839. void NSViewComponentPeer::toFront (bool makeActiveWindow)
  840. {
  841. if (isSharedWindow)
  842. {
  843. [[view superview] addSubview: view
  844. positioned: NSWindowAbove
  845. relativeTo: nil];
  846. }
  847. if (window != 0 && component->isVisible())
  848. {
  849. if (makeActiveWindow)
  850. [window makeKeyAndOrderFront: nil];
  851. else
  852. [window orderFront: nil];
  853. }
  854. }
  855. void NSViewComponentPeer::toBehind (ComponentPeer* other)
  856. {
  857. NSViewComponentPeer* o = (NSViewComponentPeer*) other;
  858. if (isSharedWindow)
  859. {
  860. [[view superview] addSubview: view
  861. positioned: NSWindowBelow
  862. relativeTo: o->view];
  863. }
  864. else
  865. {
  866. [window orderWindow: NSWindowBelow
  867. relativeTo: o->window != 0 ? [o->window windowNumber]
  868. : nil ];
  869. }
  870. }
  871. void NSViewComponentPeer::setIcon (const Image& /*newIcon*/)
  872. {
  873. // to do..
  874. }
  875. //==============================================================================
  876. void NSViewComponentPeer::viewFocusGain()
  877. {
  878. if (currentlyFocusedPeer != this)
  879. {
  880. if (ComponentPeer::isValidPeer (currentlyFocusedPeer))
  881. currentlyFocusedPeer->handleFocusLoss();
  882. currentlyFocusedPeer = this;
  883. handleFocusGain();
  884. }
  885. }
  886. void NSViewComponentPeer::viewFocusLoss()
  887. {
  888. if (currentlyFocusedPeer == this)
  889. {
  890. currentlyFocusedPeer = 0;
  891. handleFocusLoss();
  892. }
  893. }
  894. void juce_HandleProcessFocusChange()
  895. {
  896. keysCurrentlyDown.clear();
  897. if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer))
  898. {
  899. if (Process::isForegroundProcess())
  900. {
  901. currentlyFocusedPeer->handleFocusGain();
  902. }
  903. else
  904. {
  905. currentlyFocusedPeer->handleFocusLoss();
  906. // turn kiosk mode off if we lose focus..
  907. Desktop::getInstance().setKioskModeComponent (0);
  908. }
  909. }
  910. }
  911. bool NSViewComponentPeer::isFocused() const
  912. {
  913. return window != 0 && [window isKeyWindow];
  914. }
  915. void NSViewComponentPeer::grabFocus()
  916. {
  917. if (window != 0)
  918. {
  919. [window makeKeyWindow];
  920. [window makeFirstResponder: view];
  921. viewFocusGain();
  922. }
  923. }
  924. void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/)
  925. {
  926. }
  927. bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
  928. {
  929. String unicode (nsStringToJuce ([ev characters]));
  930. String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers]));
  931. int keyCode = getKeyCodeFromEvent (ev);
  932. //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0]));
  933. //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0]));
  934. if (unicode.isNotEmpty() || keyCode != 0)
  935. {
  936. if (isKeyDown)
  937. {
  938. bool used = false;
  939. while (unicode.length() > 0)
  940. {
  941. juce_wchar textCharacter = unicode[0];
  942. unicode = unicode.substring (1);
  943. if (([ev modifierFlags] & NSCommandKeyMask) != 0)
  944. textCharacter = 0;
  945. used = handleKeyUpOrDown() || used;
  946. used = handleKeyPress (keyCode, textCharacter) || used;
  947. }
  948. return used;
  949. }
  950. else
  951. {
  952. if (handleKeyUpOrDown())
  953. return true;
  954. }
  955. }
  956. return false;
  957. }
  958. bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev)
  959. {
  960. updateKeysDown (ev, true);
  961. bool used = handleKeyEvent (ev, true);
  962. if (([ev modifierFlags] & NSCommandKeyMask) != 0)
  963. {
  964. // for command keys, the key-up event is thrown away, so simulate one..
  965. updateKeysDown (ev, false);
  966. used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used;
  967. }
  968. return used;
  969. }
  970. bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev)
  971. {
  972. updateKeysDown (ev, false);
  973. return handleKeyEvent (ev, false);
  974. }
  975. void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
  976. {
  977. updateModifiers (ev);
  978. handleModifierKeysChange();
  979. }
  980. #if MACOS_10_4_OR_EARLIER
  981. bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev)
  982. {
  983. if ([ev type] == NSKeyDown)
  984. return redirectKeyDown (ev);
  985. else if ([ev type] == NSKeyUp)
  986. return redirectKeyUp (ev);
  987. return false;
  988. }
  989. #endif
  990. //==============================================================================
  991. void NSViewComponentPeer::redirectMouseDown (NSEvent* ev)
  992. {
  993. updateModifiers (ev);
  994. currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
  995. int x, y;
  996. getMousePos (ev, view, x, y);
  997. handleMouseDown (x, y, getMouseTime (ev));
  998. }
  999. void NSViewComponentPeer::redirectMouseUp (NSEvent* ev)
  1000. {
  1001. const int oldMods = currentModifiers;
  1002. updateModifiers (ev);
  1003. currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]);
  1004. int x, y;
  1005. getMousePos (ev, view, x, y);
  1006. handleMouseUp (oldMods, x, y, getMouseTime (ev));
  1007. }
  1008. void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev)
  1009. {
  1010. updateModifiers (ev);
  1011. currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]);
  1012. int x, y;
  1013. getMousePos (ev, view, x, y);
  1014. handleMouseDrag (x, y, getMouseTime (ev));
  1015. }
  1016. void NSViewComponentPeer::redirectMouseMove (NSEvent* ev)
  1017. {
  1018. updateModifiers (ev);
  1019. int x, y;
  1020. getMousePos (ev, view, x, y);
  1021. handleMouseMove (x, y, getMouseTime (ev));
  1022. }
  1023. void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev)
  1024. {
  1025. updateModifiers (ev);
  1026. int x, y;
  1027. getMousePos (ev, view, x, y);
  1028. handleMouseEnter (x, y, getMouseTime (ev));
  1029. }
  1030. void NSViewComponentPeer::redirectMouseExit (NSEvent* ev)
  1031. {
  1032. updateModifiers (ev);
  1033. int x, y;
  1034. getMousePos (ev, view, x, y);
  1035. handleMouseExit (x, y, getMouseTime (ev));
  1036. }
  1037. void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev)
  1038. {
  1039. updateModifiers (ev);
  1040. handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f),
  1041. roundFloatToInt ([ev deltaY] * 10.0f),
  1042. getMouseTime (ev));
  1043. }
  1044. //==============================================================================
  1045. BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender)
  1046. {
  1047. NSString* bestType
  1048. = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]];
  1049. if (bestType == nil)
  1050. return false;
  1051. NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil];
  1052. int x = (int) p.x;
  1053. int y = (int) ([view frame].size.height - p.y);
  1054. StringArray files;
  1055. id list = [[sender draggingPasteboard] propertyListForType: bestType];
  1056. if (list == nil)
  1057. return false;
  1058. if ([list isKindOfClass: [NSArray class]])
  1059. {
  1060. NSArray* items = (NSArray*) list;
  1061. for (unsigned int i = 0; i < [items count]; ++i)
  1062. files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i]));
  1063. }
  1064. if (files.size() == 0)
  1065. return false;
  1066. if (type == 0)
  1067. handleFileDragMove (files, x, y);
  1068. else if (type == 1)
  1069. handleFileDragExit (files);
  1070. else if (type == 2)
  1071. handleFileDragDrop (files, x, y);
  1072. return true;
  1073. }
  1074. bool NSViewComponentPeer::isOpaque()
  1075. {
  1076. if (! getComponent()->isValidComponent())
  1077. return true;
  1078. return getComponent()->isOpaque();
  1079. }
  1080. void NSViewComponentPeer::drawRect (NSRect r)
  1081. {
  1082. if (r.size.width < 1.0f || r.size.height < 1.0f)
  1083. return;
  1084. const float y = [view frame].size.height - (r.origin.y + r.size.height);
  1085. JuceNSImage temp ((int) (r.size.width + 0.5f),
  1086. (int) (r.size.height + 0.5f),
  1087. ! getComponent()->isOpaque());
  1088. LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
  1089. const int originX = -roundFloatToInt (r.origin.x);
  1090. const int originY = -roundFloatToInt (y);
  1091. context.setOrigin (originX, originY);
  1092. const NSRect* rects = 0;
  1093. NSInteger numRects = 0;
  1094. [view getRectsBeingDrawn: &rects count: &numRects];
  1095. RectangleList clip;
  1096. for (int i = 0; i < numRects; ++i)
  1097. {
  1098. clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x),
  1099. roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)),
  1100. roundFloatToInt (rects[i].size.width),
  1101. roundFloatToInt (rects[i].size.height)));
  1102. }
  1103. if (context.reduceClipRegion (clip))
  1104. {
  1105. handlePaint (context);
  1106. temp.draw (r.origin.x, r.origin.y, clip, originX, originY);
  1107. }
  1108. }
  1109. bool NSViewComponentPeer::canBecomeKeyWindow()
  1110. {
  1111. // If running as a plugin, let the component decide whether it's going to allow the window to get focused.
  1112. return JUCEApplication::getInstance() != 0
  1113. || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus());
  1114. }
  1115. bool NSViewComponentPeer::windowShouldClose()
  1116. {
  1117. if (! isValidPeer (this))
  1118. return YES;
  1119. handleUserClosingWindow();
  1120. return NO;
  1121. }
  1122. void NSViewComponentPeer::redirectMovedOrResized()
  1123. {
  1124. handleMovedOrResized();
  1125. }
  1126. //==============================================================================
  1127. void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars)
  1128. {
  1129. // Very annoyingly, this function has to use the old SetSystemUIMode function,
  1130. // which is in Carbon.framework. But, because there's no Cocoa equivalent, it
  1131. // is apparently still available in 64-bit apps..
  1132. if (enableOrDisable)
  1133. {
  1134. SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0);
  1135. kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false));
  1136. }
  1137. else
  1138. {
  1139. SetSystemUIMode (kUIModeNormal, 0);
  1140. }
  1141. }
  1142. //==============================================================================
  1143. void NSViewComponentPeer::repaint (int x, int y, int w, int h)
  1144. {
  1145. [view setNeedsDisplayInRect:
  1146. NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)),
  1147. (float) w, (float) h)];
  1148. }
  1149. void NSViewComponentPeer::performAnyPendingRepaintsNow()
  1150. {
  1151. [view displayIfNeeded];
  1152. }
  1153. ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
  1154. {
  1155. return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo);
  1156. }
  1157. //==============================================================================
  1158. static Image* NSImageToJuceImage (NSImage* image)
  1159. {
  1160. JuceNSImage juceIm ((int) [image size].width,
  1161. (int) [image size].height,
  1162. true);
  1163. juceIm.drawNSImage (image);
  1164. return juceIm.getJuceImage().createCopy();
  1165. }
  1166. Image* juce_createIconForFile (const File& file)
  1167. {
  1168. const ScopedAutoReleasePool pool;
  1169. NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
  1170. return NSImageToJuceImage (im);
  1171. }
  1172. //==============================================================================
  1173. const int KeyPress::spaceKey = ' ';
  1174. const int KeyPress::returnKey = 0x0d;
  1175. const int KeyPress::escapeKey = 0x1b;
  1176. const int KeyPress::backspaceKey = 0x7f;
  1177. const int KeyPress::leftKey = NSLeftArrowFunctionKey;
  1178. const int KeyPress::rightKey = NSRightArrowFunctionKey;
  1179. const int KeyPress::upKey = NSUpArrowFunctionKey;
  1180. const int KeyPress::downKey = NSDownArrowFunctionKey;
  1181. const int KeyPress::pageUpKey = NSPageUpFunctionKey;
  1182. const int KeyPress::pageDownKey = NSPageDownFunctionKey;
  1183. const int KeyPress::endKey = NSEndFunctionKey;
  1184. const int KeyPress::homeKey = NSHomeFunctionKey;
  1185. const int KeyPress::deleteKey = NSDeleteFunctionKey;
  1186. const int KeyPress::insertKey = -1;
  1187. const int KeyPress::tabKey = 9;
  1188. const int KeyPress::F1Key = NSF1FunctionKey;
  1189. const int KeyPress::F2Key = NSF2FunctionKey;
  1190. const int KeyPress::F3Key = NSF3FunctionKey;
  1191. const int KeyPress::F4Key = NSF4FunctionKey;
  1192. const int KeyPress::F5Key = NSF5FunctionKey;
  1193. const int KeyPress::F6Key = NSF6FunctionKey;
  1194. const int KeyPress::F7Key = NSF7FunctionKey;
  1195. const int KeyPress::F8Key = NSF8FunctionKey;
  1196. const int KeyPress::F9Key = NSF9FunctionKey;
  1197. const int KeyPress::F10Key = NSF10FunctionKey;
  1198. const int KeyPress::F11Key = NSF1FunctionKey;
  1199. const int KeyPress::F12Key = NSF12FunctionKey;
  1200. const int KeyPress::F13Key = NSF13FunctionKey;
  1201. const int KeyPress::F14Key = NSF14FunctionKey;
  1202. const int KeyPress::F15Key = NSF15FunctionKey;
  1203. const int KeyPress::F16Key = NSF16FunctionKey;
  1204. const int KeyPress::numberPad0 = 0x30020;
  1205. const int KeyPress::numberPad1 = 0x30021;
  1206. const int KeyPress::numberPad2 = 0x30022;
  1207. const int KeyPress::numberPad3 = 0x30023;
  1208. const int KeyPress::numberPad4 = 0x30024;
  1209. const int KeyPress::numberPad5 = 0x30025;
  1210. const int KeyPress::numberPad6 = 0x30026;
  1211. const int KeyPress::numberPad7 = 0x30027;
  1212. const int KeyPress::numberPad8 = 0x30028;
  1213. const int KeyPress::numberPad9 = 0x30029;
  1214. const int KeyPress::numberPadAdd = 0x3002a;
  1215. const int KeyPress::numberPadSubtract = 0x3002b;
  1216. const int KeyPress::numberPadMultiply = 0x3002c;
  1217. const int KeyPress::numberPadDivide = 0x3002d;
  1218. const int KeyPress::numberPadSeparator = 0x3002e;
  1219. const int KeyPress::numberPadDecimalPoint = 0x3002f;
  1220. const int KeyPress::numberPadEquals = 0x30030;
  1221. const int KeyPress::numberPadDelete = 0x30031;
  1222. const int KeyPress::playKey = 0x30000;
  1223. const int KeyPress::stopKey = 0x30001;
  1224. const int KeyPress::fastForwardKey = 0x30002;
  1225. const int KeyPress::rewindKey = 0x30003;
  1226. #endif