openshot-audio  0.1.6
juce_mac_CarbonViewWrapperComponent.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2015 - ROLI Ltd.
6 
7  Permission is granted to use this software under the terms of either:
8  a) the GPL v2 (or any later version)
9  b) the Affero GPL v3
10 
11  Details of these licenses can be found at: www.gnu.org/licenses
12 
13  JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17  ------------------------------------------------------------------------------
18 
19  To release a closed-source product which uses JUCE, commercial licenses are
20  available: visit www.juce.com for more information.
21 
22  ==============================================================================
23 */
24 
25 #ifndef JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_H_INCLUDED
26 #define JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_H_INCLUDED
27 
28 
29 //==============================================================================
38  public Timer
39 {
40 public:
42  : ComponentMovementWatcher (this),
44  wrapperWindow (0),
45  carbonWindow (0),
46  embeddedView (0),
49  {
50  }
51 
53  {
54  jassert (embeddedView == 0); // must call deleteWindow() in the subclass's destructor!
55  }
56 
57  virtual HIViewRef attachView (WindowRef windowRef, HIViewRef rootView) = 0;
58  virtual void removeView (HIViewRef embeddedView) = 0;
59  virtual void handleMouseDown (int, int) {}
60  virtual void handlePaint() {}
61 
62  virtual bool getEmbeddedViewSize (int& w, int& h)
63  {
64  if (embeddedView == 0)
65  return false;
66 
67  HIRect bounds;
68  HIViewGetBounds (embeddedView, &bounds);
69  w = jmax (1, roundToInt (bounds.size.width));
70  h = jmax (1, roundToInt (bounds.size.height));
71  return true;
72  }
73 
74  void createWindow()
75  {
76  if (wrapperWindow == 0)
77  {
78  Rect r;
79  r.left = (short) getScreenX();
80  r.top = (short) getScreenY();
81  r.right = (short) (r.left + getWidth());
82  r.bottom = (short) (r.top + getHeight());
83 
84  CreateNewWindow (kDocumentWindowClass,
85  (WindowAttributes) (kWindowStandardHandlerAttribute | kWindowCompositingAttribute
86  | kWindowNoShadowAttribute | kWindowNoTitleBarAttribute),
87  &r, &wrapperWindow);
88 
89  jassert (wrapperWindow != 0);
90  if (wrapperWindow == 0)
91  return;
92 
93  carbonWindow = [[NSWindow alloc] initWithWindowRef: wrapperWindow];
94 
95  [getOwnerWindow() addChildWindow: carbonWindow
96  ordered: NSWindowAbove];
97 
98  embeddedView = attachView (wrapperWindow, HIViewGetRoot (wrapperWindow));
99 
100  // Check for the plugin creating its own floating window, and if there is one,
101  // we need to reparent it to make it visible..
102  if (NSWindow* floatingChildWindow = [[carbonWindow childWindows] objectAtIndex: 0])
103  [getOwnerWindow() addChildWindow: floatingChildWindow
104  ordered: NSWindowAbove];
105 
106  EventTypeSpec windowEventTypes[] =
107  {
108  { kEventClassWindow, kEventWindowGetClickActivation },
109  { kEventClassWindow, kEventWindowHandleDeactivate },
110  { kEventClassWindow, kEventWindowBoundsChanging },
111  { kEventClassMouse, kEventMouseDown },
112  { kEventClassMouse, kEventMouseMoved },
113  { kEventClassMouse, kEventMouseDragged },
114  { kEventClassMouse, kEventMouseUp },
115  { kEventClassWindow, kEventWindowDrawContent },
116  { kEventClassWindow, kEventWindowShown },
117  { kEventClassWindow, kEventWindowHidden }
118  };
119 
120  EventHandlerUPP upp = NewEventHandlerUPP (carbonEventCallback);
121  InstallWindowEventHandler (wrapperWindow, upp,
122  sizeof (windowEventTypes) / sizeof (EventTypeSpec),
123  windowEventTypes, this, &eventHandlerRef);
124 
127 
129  }
130  }
131 
133  {
134  removeView (embeddedView);
135  embeddedView = 0;
136 
137  if (wrapperWindow != 0)
138  {
139  NSWindow* ownerWindow = getOwnerWindow();
140 
141  if ([[ownerWindow childWindows] count] > 0)
142  {
143  [ownerWindow removeChildWindow: carbonWindow];
144  [carbonWindow close];
145  }
146 
147  RemoveEventHandler (eventHandlerRef);
148  DisposeWindow (wrapperWindow);
149  wrapperWindow = 0;
150  }
151  }
152 
153  //==============================================================================
155  {
156  int w, h;
157  if (getEmbeddedViewSize (w, h))
158  {
159  if (w != getWidth() || h != getHeight())
160  {
161  startTimer (50);
162  setSize (w, h);
163 
164  if (Component* p = getParentComponent())
165  p->setSize (w, h);
166  }
167  else
168  {
169  startTimer (jlimit (50, 500, getTimerInterval() + 20));
170  }
171  }
172  else
173  {
174  stopTimer();
175  }
176  }
177 
179  {
180  if (! recursiveResize)
181  {
182  recursiveResize = true;
183 
184  if (embeddedView != 0)
185  {
186  HIRect r;
187  r.origin.x = 0;
188  r.origin.y = 0;
189  r.size.width = (float) getWidth();
190  r.size.height = (float) getHeight();
191  HIViewSetFrame (embeddedView, &r);
192  }
193 
194  if (wrapperWindow != 0)
195  {
197  Rectangle<int> screenBounds (getScreenBounds() * Desktop::getInstance().getGlobalScaleFactor());
198 
199  Rect wr;
200  wr.left = (short) screenBounds.getX();
201  wr.top = (short) screenBounds.getY();
202  wr.right = (short) screenBounds.getRight();
203  wr.bottom = (short) screenBounds.getBottom();
204 
205  SetWindowBounds (wrapperWindow, kWindowContentRgn, &wr);
206 
207  // This group stuff is mainly a workaround for Mackie plugins like FinalMix..
208  WindowGroupRef group = GetWindowGroup (wrapperWindow);
209  WindowRef attachedWindow;
210 
211  if (GetIndexedWindow (group, 2, kWindowGroupContentsReturnWindows, &attachedWindow) == noErr)
212  {
213  SelectWindow (attachedWindow);
214  ActivateWindow (attachedWindow, TRUE);
215  HideWindow (wrapperWindow);
216  }
217 
218  ShowWindow (wrapperWindow);
219  }
220 
221  recursiveResize = false;
222  }
223  }
224 
225  void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override
226  {
228  }
229 
230  // (overridden to intercept movements of the top-level window)
231  void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized) override
232  {
233  ComponentMovementWatcher::componentMovedOrResized (component, wasMoved, wasResized);
234 
235  if (&component == getTopLevelComponent())
237  }
238 
239  void componentPeerChanged() override
240  {
241  deleteWindow();
242  createWindow();
243  }
244 
246  {
247  if (isShowing())
248  createWindow();
249  else if (! keepPluginWindowWhenHidden)
250  deleteWindow();
251 
253  }
254 
255  static void recursiveHIViewRepaint (HIViewRef view)
256  {
257  HIViewSetNeedsDisplay (view, true);
258  HIViewRef child = HIViewGetFirstSubview (view);
259 
260  while (child != 0)
261  {
262  recursiveHIViewRepaint (child);
263  child = HIViewGetNextView (child);
264  }
265  }
266 
267  void timerCallback() override
268  {
269  if (isShowing())
270  {
272 
273  // To avoid strange overpainting problems when the UI is first opened, we'll
274  // repaint it a few times during the first second that it's on-screen..
275  if (repaintChildOnCreation && (Time::getCurrentTime() - creationTime).inMilliseconds() < 1000)
276  recursiveHIViewRepaint (HIViewGetRoot (wrapperWindow));
277  }
278  }
279 
281  {
283  }
284 
285  OSStatus carbonEventHandler (EventHandlerCallRef /*nextHandlerRef*/, EventRef event)
286  {
287  switch (GetEventKind (event))
288  {
289  case kEventWindowHandleDeactivate:
290  ActivateWindow (wrapperWindow, TRUE);
291  return noErr;
292 
293  case kEventWindowGetClickActivation:
294  {
295  getTopLevelComponent()->toFront (false);
296  [carbonWindow makeKeyAndOrderFront: nil];
297 
298  ClickActivationResult howToHandleClick = kActivateAndHandleClick;
299 
300  SetEventParameter (event, kEventParamClickActivation, typeClickActivationResult,
301  sizeof (ClickActivationResult), &howToHandleClick);
302 
303  if (embeddedView != 0)
304  HIViewSetNeedsDisplay (embeddedView, true);
305 
306  return noErr;
307  }
308  }
309 
310  return eventNotHandledErr;
311  }
312 
313  static pascal OSStatus carbonEventCallback (EventHandlerCallRef nextHandlerRef, EventRef event, void* userData)
314  {
315  return ((CarbonViewWrapperComponent*) userData)->carbonEventHandler (nextHandlerRef, event);
316  }
317 
319 
320 protected:
321  WindowRef wrapperWindow;
322  NSWindow* carbonWindow;
323  HIViewRef embeddedView;
326 
327  EventHandlerRef eventHandlerRef;
328 
329  NSWindow* getOwnerWindow() const { return [((NSView*) getWindowHandle()) window]; }
330 };
331 
332 #endif // JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_H_INCLUDED
virtual void removeView(HIViewRef embeddedView)=0
void setSize(int newWidth, int newHeight)
Definition: juce_Component.cpp:1206
ValueType getRight() const noexcept
Definition: juce_Rectangle.h:119
bool keepPluginWindowWhenHidden
Definition: juce_mac_CarbonViewWrapperComponent.h:318
#define true
Definition: ordinals.h:82
#define noexcept
Definition: juce_CompilerSupport.h:141
virtual void componentMovedOrResized(bool wasMoved, bool wasResized)=0
bool repaintChildOnCreation
Definition: juce_mac_CarbonViewWrapperComponent.h:324
NSWindow * carbonWindow
Definition: juce_mac_CarbonViewWrapperComponent.h:322
ValueType getX() const noexcept
Definition: juce_Rectangle.h:107
void * getWindowHandle() const
Definition: juce_Component.cpp:585
Definition: juce_Time.h:41
void componentPeerChanged() override
Definition: juce_mac_CarbonViewWrapperComponent.h:239
int getWidth() const noexcept
Definition: juce_Component.h:268
int getScreenX() const
Definition: juce_Component.cpp:1040
int roundToInt(const FloatType value) noexcept
Definition: juce_core.h:418
void timerCallback() override
Definition: juce_mac_CarbonViewWrapperComponent.h:267
int getTimerInterval() const noexcept
Definition: juce_Timer.h:115
NSWindow * getOwnerWindow() const
Definition: juce_mac_CarbonViewWrapperComponent.h:329
bool recursiveResize
Definition: juce_mac_CarbonViewWrapperComponent.h:324
Definition: juce_ComponentMovementWatcher.h:44
#define false
Definition: ordinals.h:83
Component * getParentComponent() const noexcept
Definition: juce_Component.h:762
long b
Definition: jpegint.h:371
int getHeight() const noexcept
Definition: juce_Component.h:271
EventHandlerRef eventHandlerRef
Definition: juce_mac_CarbonViewWrapperComponent.h:327
WindowRef wrapperWindow
Definition: juce_mac_CarbonViewWrapperComponent.h:321
void componentMovedOrResized(bool, bool) override
Definition: juce_mac_CarbonViewWrapperComponent.h:225
ValueType getBottom() const noexcept
Definition: juce_Rectangle.h:122
OSStatus carbonEventHandler(EventHandlerCallRef, EventRef event)
Definition: juce_mac_CarbonViewWrapperComponent.h:285
void startTimer(int intervalInMilliseconds) noexcept
Definition: juce_Timer.cpp:319
void componentMovedOrResized(Component &component, bool wasMoved, bool wasResized) override
Definition: juce_mac_CarbonViewWrapperComponent.h:231
Definition: juce_Rectangle.h:36
void setRepaintsChildHIViewWhenCreated(bool b) noexcept
Definition: juce_mac_CarbonViewWrapperComponent.h:280
CarbonViewWrapperComponent()
Definition: juce_mac_CarbonViewWrapperComponent.h:41
virtual bool getEmbeddedViewSize(int &w, int &h)
Definition: juce_mac_CarbonViewWrapperComponent.h:62
virtual void handleMouseDown(int, int)
Definition: juce_mac_CarbonViewWrapperComponent.h:59
void setOurSizeToEmbeddedViewSize()
Definition: juce_mac_CarbonViewWrapperComponent.h:154
Definition: juce_Component.h:33
Type jmax(const Type a, const Type b)
Definition: juce_core.h:101
#define TRUE
Definition: jmorecfg.h:233
Time creationTime
Definition: juce_mac_CarbonViewWrapperComponent.h:325
~CarbonViewWrapperComponent()
Definition: juce_mac_CarbonViewWrapperComponent.h:52
void toFront(bool shouldAlsoGainFocus)
Definition: juce_Component.cpp:870
void stopTimer() noexcept
Definition: juce_Timer.cpp:343
Rectangle< int > getScreenBounds() const
Definition: juce_Component.cpp:1044
Type jlimit(const Type lowerLimit, const Type upperLimit, const Type valueToConstrain) noexcept
Definition: juce_MathsFunctions.h:220
#define jassert(a)
Definition: juce_PlatformDefs.h:146
Component * getTopLevelComponent() const noexcept
Definition: juce_Component.cpp:1622
virtual HIViewRef attachView(WindowRef windowRef, HIViewRef rootView)=0
ValueType getY() const noexcept
Definition: juce_Rectangle.h:110
static Desktop &JUCE_CALLTYPE getInstance()
Definition: juce_Desktop.cpp:48
virtual float getDesktopScaleFactor() const
Definition: juce_Component.cpp:742
void setEmbeddedWindowToOurSize()
Definition: juce_mac_CarbonViewWrapperComponent.h:178
virtual void handlePaint()
Definition: juce_mac_CarbonViewWrapperComponent.h:60
void deleteWindow()
Definition: juce_mac_CarbonViewWrapperComponent.h:132
int getScreenY() const
Definition: juce_Component.cpp:1041
bool isShowing() const
Definition: juce_Component.cpp:570
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Definition: juce_Time.cpp:213
Definition: juce_Timer.h:52
static void recursiveHIViewRepaint(HIViewRef view)
Definition: juce_mac_CarbonViewWrapperComponent.h:255
static pascal OSStatus carbonEventCallback(EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
Definition: juce_mac_CarbonViewWrapperComponent.h:313
Definition: juce_mac_CarbonViewWrapperComponent.h:36
void createWindow()
Definition: juce_mac_CarbonViewWrapperComponent.h:74
HIViewRef embeddedView
Definition: juce_mac_CarbonViewWrapperComponent.h:323
void componentVisibilityChanged() override
Definition: juce_mac_CarbonViewWrapperComponent.h:245