OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4WindowController.mm
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #include <GL/glew.h>
17 
18 #include "C4Include.h"
19 #include "game/C4Application.h"
20 #include "game/C4Viewport.h"
22 #include "game/C4FullScreen.h"
23 #include "landscape/C4Landscape.h"
24 
26 #import "graphics/C4DrawGLMac.h"
29 #import "AppKit/NSOpenGL.h"
30 
31 static SInt32 osVersion()
32 {
33  SInt32 ver;
34  Gestalt(gestaltSystemVersion, &ver);
35  return ver;
36 }
37 
38 bool lionAndBeyond() {return osVersion() >= 0x1070;}
39 
40 #ifdef USE_COCOA
41 
42 // Turns out, it is necessary to derive a NSWindow class after all - or else the screen-filling window won't be able to become the key window
43 
44 @interface ClonkScreenfillingWindow: NSWindow
45 {}
46 - (BOOL) canBecomeKeyWindow;
47 @end
48 
49 @implementation ClonkScreenfillingWindow
50 - (BOOL) canBecomeKeyWindow;
51 {
52  return YES; // a resounding one
53 }
54 @end
55 
56 @implementation C4WindowController
57 
58 @synthesize stdWindow, openGLView, scrollView;
59 
60 - (void) awakeFromNib
61 {
62  [super awakeFromNib];
63  if (!Application.isEditor)
64  C4AppDelegate.instance.gameWindowController = self;
65 }
66 
67 - (void) fadeOut:(CGDisplayFadeReservationToken*)token
68 {
69  if (CGAcquireDisplayFadeReservation(15, token) == 0)
70  CGDisplayFade(*token, 0.2, 0.0, 1.0, 0, 0, 0, YES);
71 }
72 
73 - (void) fadeIn:(CGDisplayFadeReservationToken)token
74 {
75  CGDisplayFade(token, 0.2, 1.0, 0.0, 0, 0, 0, YES);
76  CGReleaseDisplayFadeReservation(token);
77 }
78 
79 - (BOOL) isFullScreen {
80  return fullscreenWindow != nil;
81 }
82 
84 {
85  return
86  [self isFullScreen] ||
87  (lionAndBeyond() && (self.window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask);
88 }
89 
90 - (void) setFullscreen:(BOOL)fullscreen
91 {
92  if (fullscreen != [self isFullScreen])
93  {
94  // fade out
95 #ifndef _DEBUG
96  CGDisplayFadeReservationToken token;
97  [self fadeOut:&token];
98 #endif
99  if (![self isFullScreen])
100  {
101  NSRect fullscreenRect = NSScreen.mainScreen.frame;
102  fullscreenWindow = [[ClonkScreenfillingWindow alloc] initWithContentRect:fullscreenRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
103  [fullscreenWindow setLevel:NSMainMenuWindowLevel+1];
104  [fullscreenWindow setOpaque:YES];
105  [fullscreenWindow setHidesOnDeactivate:YES];
106  [fullscreenWindow setContentView:openGLView];
107  [fullscreenWindow setReleasedWhenClosed:YES];
108  [fullscreenWindow setDelegate:self];
109  [self.window orderOut:self];
110  [fullscreenWindow setInitialFirstResponder:openGLView];
111  [fullscreenWindow makeKeyAndOrderFront:self];
112  //[openGLView setContextSurfaceBackingSizeToOwnDimensions];
113  [openGLView enableEvents];
114  // hide cursor completely
115  [NSCursor hide];
116  }
117  else
118  {
119  // unhide and rely on cursor rects again
120  [NSCursor unhide];
121 
122  [fullscreenWindow close];
123  fullscreenWindow = nil;
124  [self.window setContentView:openGLView];
125  [self.window orderFront:self];
126  [openGLView setFrame:[self.window.contentView frame]];
127  [openGLView enableEvents];
128  [self.window makeKeyAndOrderFront:self];
129  }
130  [openGLView display];
131 #ifndef _DEBUG
132  // fade in again
133  [self fadeIn:token];
134 #endif
135  }
136 }
137 
138 - (BOOL) windowShouldClose:(id)sender
139 {
140  if (sender == self.window && self.stdWindow)
141  {
142  [self.openGLView showCursor];
143  self.stdWindow->Close();
144  }
145  return YES;
146 }
147 
148 - (C4Viewport*) viewport
149 {
150  for (C4Viewport* v = ::Viewports.GetFirstViewport(); v; v = v->GetNext())
151  if (v->GetWindow() == stdWindow || (!v->GetWindow() && stdWindow == &FullScreen))
152  return v;
153  return NULL;
154 }
155 
156 - (IBAction) scroll:(id)sender
157 {
158  C4Viewport* viewport = self.viewport;
159  if (viewport)
160  {
161  viewport->ViewPositionByScrollBars();
162  viewport->Execute();
163  }
164 }
165 
166 - (void) windowDidResize:(NSNotification *)notification
167 {
168  if (Application.isEditor)
169  {
170  C4Viewport* viewport = self.viewport;
171  if (viewport && Application.isEditor)
172  {
173  viewport->ScrollBarsByViewPosition();
174  }
175  }
176 }
177 
178 - (BOOL) isLiveResizing
179 {
180  return self.window.inLiveResize;
181 }
182 
183 - (NSRect) windowWillUseStandardFrame:(NSWindow*) window defaultFrame:(NSRect) newFrame
184 {
185  return NSMakeRect(newFrame.origin.x, newFrame.origin.y, preferredContentSize.width, preferredContentSize.height);
186 }
187 
188 - (NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
189 {
190  if (stdWindow == &::FullScreen)
191  return NSMakeSize(
192  CGDisplayPixelsWide(C4OpenGLView.displayID),
193  CGDisplayPixelsHigh(C4OpenGLView.displayID)
194  );
195  else
196  return proposedSize;
197 }
198 
199 - (void) windowWillExitFullScreen:(NSNotification *)notification
200 {
201  if (!Application.isEditor)
202  {
203  CGAssociateMouseAndMouseCursorPosition(TRUE);
204  }
205 }
206 
207 - (void) setContentSize:(NSSize)size
208 {
209  [self.window setContentSize:size];
210  preferredContentSize = size;
211 }
212 
213 @end
214 
215 @interface NSScroller (ClonkZoom)
216 - (void) setToLandscapeCoordinate:(float)lc
217  size:(int) s
218  viewportSize:(int) vs
219  zoom: (float) z;
220 - (float) landscapeCoordinateForSize:(int) s
221  viewportSize:(int) vs
222  zoom:(float) z;
223 @end
224 @implementation NSScroller (ClonkZoom)
225 - (void) setToLandscapeCoordinate:(float)lc
226  size:(int) s
227  viewportSize:(int) vs
228  zoom: (float) z
229 {
230  self.doubleValue = (double)lc/((double)s - (double)vs/z);
231  self.knobProportion = (CGFloat)std::min(1.0, (double)vs/(s*z));
232 }
233 
234 - (float) landscapeCoordinateForSize:(int) s
235  viewportSize:(int) vs
236  zoom:(float) z
237 {
238  return self.doubleValue * ((double)s - (double)vs/z);
239 }
240 @end
241 
242 // C4ViewportWindow
243 
244 #if !defined(WITH_QT_EDITOR)
246 {
247  if (PlayerLock) return false;
248  NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
249  [scrollView.horizontalScroller setToLandscapeCoordinate:GetViewX() size:Landscape.GetWidth() viewportSize:ViewWdt zoom:GetZoom()];
250  [scrollView.verticalScroller setToLandscapeCoordinate:GetViewY() size:Landscape.GetHeight() viewportSize:ViewHgt zoom:GetZoom()];
251  return true;
252 }
253 
255 {
256  NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
257  if (PlayerLock)
258  {
259  PlayerLock = false;
260  if (scrollView)
261  {
262  [scrollView.verticalScroller setEnabled:YES];
263  [scrollView.horizontalScroller setEnabled:YES];
264  [scrollView setAutohidesScrollers:NO];
265  }
266  ScrollBarsByViewPosition();
267  }
268  else
269  {
270  PlayerLock = true;
271  if (scrollView)
272  {
273  [scrollView.verticalScroller setEnabled:NO];
274  [scrollView.horizontalScroller setEnabled:NO];
275  [scrollView setAutohidesScrollers:YES];
276  }
277  }
278  return true;
279 }
280 #endif
281 
283 {
284  NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
285  SetViewX([scrollView.horizontalScroller landscapeCoordinateForSize:Landscape.GetWidth() viewportSize:ViewWdt zoom:GetZoom()]);
286  SetViewY([scrollView.verticalScroller landscapeCoordinateForSize:Landscape.GetHeight() viewportSize:ViewHgt zoom:GetZoom()]);
287  return true;
288 }
289 
290 #endif
C4Viewport * GetFirstViewport()
Definition: C4Viewport.h:156
C4OpenGLView * openGLView
#define z
NSScrollView * scrollView
C4FullScreen FullScreen
Definition: C4Globals.cpp:46
C4Viewport * GetNext()
Definition: C4Viewport.h:66
BOOL isFullScreenConsideringLionFullScreen()
float GetZoom()
Definition: C4Gui.h:2828
C4Viewport * viewport()
C4Landscape Landscape
bool TogglePlayerLock()
Definition: C4Console.cpp:715
int32_t GetHeight() const
C4ViewportList Viewports
Definition: C4Viewport.cpp:841
bool ScrollBarsByViewPosition()
Definition: C4Console.cpp:714
C4AppDelegate * instance()
void Execute()
Definition: C4Viewport.cpp:380
bool lionAndBeyond()
C4Application Application
Definition: C4Globals.cpp:44
int32_t GetWidth() const
bool ViewPositionByScrollBars()