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.

1581 lines
47KB

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