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.

1587 lines
47KB

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