Vuo  2.0.0
VuoWindow.m
Go to the documentation of this file.
1 
10 #import "VuoWindow.h"
12 #import "VuoGraphicsWindow.h"
13 #include "VuoEventLoop.h"
14 #include "VuoCompositionState.h"
15 #include "VuoApp.h"
16 #import "VuoAppSplashWindow.h"
17 
18 #include "module.h"
19 
20 #ifdef VUO_COMPILER
22  "title" : "VuoWindow",
23  "dependencies" : [
24  "AppKit.framework",
25  "VuoGraphicsWindow",
26  "VuoWindowTextInternal"
27  ]
28  });
29 #endif
30 
32 
41 {
42  void *compositionState = vuoCopyCompositionStateFromThreadLocalStorage();
43 
44  __block VuoWindowTextInternal *window = NULL;
45  VUOLOG_PROFILE_BEGIN(mainQueue);
46  dispatch_sync(dispatch_get_main_queue(), ^{
47  VUOLOG_PROFILE_END(mainQueue);
49 
50  VuoApp_init(true);
51  window = [[VuoWindowTextInternal alloc] init];
52 
53  window.alphaValue = 0;
55  [window orderWindow:NSWindowBelow relativeTo:VuoApp_splashWindow.windowNumber];
56  else
57  [window orderFront:NSApp];
58  [window makeKeyWindow];
59 
60  [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
61  context.duration = VuoApp_windowFadeSeconds;
62  window.animator.alphaValue = 1;
63  } completionHandler:^{}];
64 
66  free(compositionState);
67  });
69  return (VuoWindowText *)window;
70 }
71 
78 (
79  VuoWindowText w,
80  VuoOutputTrigger(typedLine, VuoText),
81  VuoOutputTrigger(typedWord, VuoText),
82  VuoOutputTrigger(typedCharacter, VuoText)
83 )
84 {
86  VUOLOG_PROFILE_BEGIN(mainQueue);
87  dispatch_sync(dispatch_get_main_queue(), ^{
88  VUOLOG_PROFILE_END(mainQueue);
89  [window enableTriggersWithTypedLine:typedLine typedWord:typedWord typedCharacter:typedCharacter];
90  });
91 }
92 
99 {
101  VUOLOG_PROFILE_BEGIN(mainQueue);
102  dispatch_sync(dispatch_get_main_queue(), ^{
103  VUOLOG_PROFILE_END(mainQueue);
104  [window disableTriggers];
105  });
106 }
107 
113 void VuoWindowText_appendLine(VuoWindowText vw, const char *text)
114 {
116  char *textCopy = text ? strdup(text) : strdup(""); // ... in case the caller frees text before the asynchronous block uses it.
117  VUOLOG_PROFILE_BEGIN(mainQueue);
118  dispatch_async(dispatch_get_main_queue(), ^{
119  VUOLOG_PROFILE_END(mainQueue);
120  [window appendLine:textCopy];
121  free(textCopy);
122  });
123 }
124 
131 {
133  VuoRetain(window);
134  VUOLOG_PROFILE_BEGIN(mainQueue);
135  dispatch_sync(dispatch_get_main_queue(), ^{
136  VUOLOG_PROFILE_END(mainQueue);
137 
138  void (^completionHandler)(void) = ^{
139  [window close];
140  VuoRelease(window);
141  };
142 
143  // When fullscreen, macOS performs its own close animation, so only apply our fade-out animation when windowed.
144  if (window.styleMask & NSFullScreenWindowMask)
145  completionHandler();
146  else
147  [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
148  context.duration = VuoApp_windowFadeSeconds;
149  window.animator.alphaValue = 0;
150  } completionHandler:completionHandler];
151  });
152 }
153 
160 {
163  [window release];
164  });
165 }
166 
167 
169 
178 (
179  void (*initCallback)(void *, float backingScaleFactor),
180  void (*updateBackingCallback)(void *, float backingScaleFactor),
181  void (*resizeCallback)(void *, unsigned int, unsigned int),
182  VuoIoSurface (*drawCallback)(void *),
183  void *context
184 )
185 {
186  __block VuoGraphicsWindow *window = NULL;
187  void *compositionState = vuoCopyCompositionStateFromThreadLocalStorage();
188 
189  VUOLOG_PROFILE_BEGIN(mainQueue);
190  dispatch_sync(dispatch_get_main_queue(), ^{
191  VUOLOG_PROFILE_END(mainQueue);
193 
194  VuoApp_init(true);
195  window = [[VuoGraphicsWindow alloc] initWithInitCallback:initCallback
196  updateBackingCallback:updateBackingCallback
197  resizeCallback:resizeCallback
198  drawCallback:drawCallback
199  userData:context];
200  window.compositionUid = vuoGetCompositionUniqueIdentifier(compositionState);
201 
202  window.alphaValue = 0;
204  [window orderWindow:NSWindowBelow relativeTo:VuoApp_splashWindow.windowNumber];
205  else
206  [window orderFront:NSApp];
207  [window makeKeyWindow];
208 
209  [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
210  context.duration = VuoApp_windowFadeSeconds;
211  window.animator.alphaValue = 1;
212  } completionHandler:^{}];
213 
215  free(compositionState);
216  });
218  return (VuoWindowOpenGl *)window;
219 }
220 
228 (
229  VuoWindowOpenGl w,
230  VuoOutputTrigger(updatedWindow, VuoRenderedLayers)
231 )
232 {
233  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
234  [window enableUpdatedWindowTrigger:updatedWindow];
235 }
236 
244 (
245  VuoWindowOpenGl w,
246  VuoOutputTrigger(showedWindow, VuoWindowReference),
247  VuoOutputTrigger(requestedFrame, VuoReal)
248 )
249 {
250  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
251  [window enableShowedWindowTrigger:showedWindow requestedFrameTrigger:requestedFrame];
252 }
253 
260 {
261  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
262  [window disableTriggers];
263 }
264 
272 {
273  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
274  [window draw];
275 }
276 
283 {
284  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
285  VUOLOG_PROFILE_BEGIN(mainQueue);
286  dispatch_sync(dispatch_get_main_queue(), ^{
287  VUOLOG_PROFILE_END(mainQueue);
288  [window setProperties:properties];
289  });
290 }
291 
298 void VuoWindowOpenGl_setAspectRatio(VuoWindowOpenGl w, unsigned int pixelsWide, unsigned int pixelsHigh)
299 {
300  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
301  VUOLOG_PROFILE_BEGIN(mainQueue);
302  dispatch_async(dispatch_get_main_queue(), ^{
303  VUOLOG_PROFILE_END(mainQueue);
304  [window setAspectRatioToWidth:pixelsWide height:pixelsHigh];
305  });
306 }
307 
314 {
315  VuoGraphicsWindow *window = (VuoGraphicsWindow *)w;
316  VUOLOG_PROFILE_BEGIN(mainQueue);
317  dispatch_async(dispatch_get_main_queue(), ^{
318  VUOLOG_PROFILE_END(mainQueue);
319  [window unlockAspectRatio];
320  });
321 }
322 
329 void VuoWindowOpenGl_close(VuoWindowOpenGl vw, void (^closedHandler)(void))
330 {
331  VuoGraphicsWindow *window = (VuoGraphicsWindow *)vw;
332  VuoRetain(window);
333  VUOLOG_PROFILE_BEGIN(mainQueue);
334  dispatch_sync(dispatch_get_main_queue(), ^{
335  VUOLOG_PROFILE_END(mainQueue);
336 
337  void (^completionHandler)(void) = ^{
338  [window close];
339  VuoRelease(window);
340  closedHandler();
341  };
342 
343  // When fullscreen, macOS performs its own close animation, so only apply our fade-out animation when windowed.
344  if (window.isFullScreen)
345  completionHandler();
346  else
347  [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
348  context.duration = VuoApp_windowFadeSeconds;
349  window.animator.alphaValue = 0;
350  } completionHandler:completionHandler];
351  });
352 }
353 
360 {
361  VuoGraphicsWindow *window = (VuoGraphicsWindow *)vw;
363  [window release];
364  });
365 }