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.

1473 lines
43KB

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