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.

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