OpenClonk
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 #define GL_SILENCE_DEPRECATION
17 #include <epoxy/gl.h>
18 #import <AppKit/AppKit.h>
19 
20 #include "C4Include.h"
21 #include "game/C4Application.h"
22 #include "game/C4Viewport.h"
24 #include "game/C4FullScreen.h"
25 #include "landscape/C4Landscape.h"
26 
28 #import "graphics/C4DrawGLMac.h"
31 
33 {
34  return NSAppKitVersionNumber >= NSAppKitVersionNumber10_7;
35 }
36 
37 #ifdef USE_COCOA
38 
39 // 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
40 
41 @interface ClonkScreenfillingWindow: NSWindow
42 {}
43 - (BOOL) canBecomeKeyWindow;
44 @end
45 
46 @implementation ClonkScreenfillingWindow
47 - (BOOL) canBecomeKeyWindow
48 {
49  return YES; // a resounding one
50 }
51 @end
52 
53 @implementation C4WindowController
54 
55 @synthesize stdWindow, openGLView, scrollView;
56 
57 - (void) awakeFromNib
58 {
59  [super awakeFromNib];
60  if (!Application.isEditor)
61  C4AppDelegate.instance.gameWindowController = self;
62 }
63 
64 - (void) fadeOut:(CGDisplayFadeReservationToken*)token
65 {
66  if (CGAcquireDisplayFadeReservation(15, token) == 0)
67  CGDisplayFade(*token, 0.2, 0.0, 1.0, 0, 0, 0, YES);
68 }
69 
70 - (void) fadeIn:(CGDisplayFadeReservationToken)token
71 {
72  CGDisplayFade(token, 0.2, 1.0, 0.0, 0, 0, 0, YES);
73  CGReleaseDisplayFadeReservation(token);
74 }
75 
76 - (BOOL) isFullScreen {
77  return fullscreenWindow != nil;
78 }
79 
81 {
82  return
83  [self isFullScreen] ||
84  (lionAndBeyond() && (self.window.styleMask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen);
85 }
86 
87 - (void) setFullscreen:(BOOL)fullscreen
88 {
89  if (fullscreen != [self isFullScreen])
90  {
91  // fade out
92 #ifndef _DEBUG
93  CGDisplayFadeReservationToken token;
94  [self fadeOut:&token];
95 #endif
96  if (![self isFullScreen])
97  {
98  NSRect fullscreenRect = NSScreen.mainScreen.frame;
99  fullscreenWindow = [[ClonkScreenfillingWindow alloc] initWithContentRect:fullscreenRect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES];
100  [fullscreenWindow setLevel:NSMainMenuWindowLevel+1];
101  [fullscreenWindow setOpaque:YES];
102  [fullscreenWindow setHidesOnDeactivate:YES];
103  [fullscreenWindow setContentView:openGLView];
104  [fullscreenWindow setReleasedWhenClosed:YES];
105  [fullscreenWindow setDelegate:self];
106  [self.window orderOut:self];
107  [fullscreenWindow setInitialFirstResponder:openGLView];
108  [fullscreenWindow makeKeyAndOrderFront:self];
109  //[openGLView setContextSurfaceBackingSizeToOwnDimensions];
110  [openGLView enableEvents];
111  // hide cursor completely
112  [NSCursor hide];
113  }
114  else
115  {
116  // unhide and rely on cursor rects again
117  [NSCursor unhide];
118 
119  [fullscreenWindow close];
120  fullscreenWindow = nil;
121  [self.window setContentView:openGLView];
122  [self.window orderFront:self];
123  [openGLView setFrame:[self.window.contentView frame]];
124  [openGLView enableEvents];
125  [self.window makeKeyAndOrderFront:self];
126  }
127  [openGLView display];
128 #ifndef _DEBUG
129  // fade in again
130  [self fadeIn:token];
131 #endif
132  }
133 }
134 
135 - (BOOL) windowShouldClose:(id)sender
136 {
137  if (sender == self.window && self.stdWindow)
138  {
139  [self.openGLView showCursor];
140  self.stdWindow->Close();
141  }
142  return YES;
143 }
144 
145 - (C4Viewport*) viewport
146 {
147  for (C4Viewport* v = ::Viewports.GetFirstViewport(); v; v = v->GetNext())
148  if (v->GetWindow() == stdWindow || (!v->GetWindow() && stdWindow == &FullScreen))
149  return v;
150  return NULL;
151 }
152 
153 - (IBAction) scroll:(id)sender
154 {
155  C4Viewport* viewport = self.viewport;
156  if (viewport)
157  {
159  viewport->Execute();
160  }
161 }
162 
163 - (void) windowDidResize:(NSNotification *)notification
164 {
165  if (Application.isEditor)
166  {
167  C4Viewport* viewport = self.viewport;
169  {
171  }
172  }
173 }
174 
175 - (BOOL) isLiveResizing
176 {
177  return self.window.inLiveResize;
178 }
179 
180 - (NSRect) windowWillUseStandardFrame:(NSWindow*) window defaultFrame:(NSRect) newFrame
181 {
182  return NSMakeRect(newFrame.origin.x, newFrame.origin.y, preferredContentSize.width, preferredContentSize.height);
183 }
184 
185 - (NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
186 {
187  if (stdWindow == &::FullScreen)
188  return NSMakeSize(
189  CGDisplayPixelsWide(C4OpenGLView.displayID),
190  CGDisplayPixelsHigh(C4OpenGLView.displayID)
191  );
192  else
193  return proposedSize;
194 }
195 
196 - (void) windowWillExitFullScreen:(NSNotification *)notification
197 {
198  if (!Application.isEditor)
199  {
200  CGAssociateMouseAndMouseCursorPosition(TRUE);
201  }
202 }
203 
204 - (void) setContentSize:(NSSize)size
205 {
206  [self.window setContentSize:size];
207  preferredContentSize = size;
208 }
209 
210 @end
211 
212 @interface NSScroller (ClonkZoom)
213 - (void) setToLandscapeCoordinate:(float)lc
214  size:(int) s
215  viewportSize:(int) vs
216  zoom: (float) z;
217 - (float) landscapeCoordinateForSize:(int) s
218  viewportSize:(int) vs
219  zoom:(float) z;
220 @end
221 @implementation NSScroller (ClonkZoom)
222 - (void) setToLandscapeCoordinate:(float)lc
223  size:(int) s
224  viewportSize:(int) vs
225  zoom: (float) z
226 {
227  self.doubleValue = (double)lc/((double)s - (double)vs/z);
228  self.knobProportion = (CGFloat)std::min(1.0, (double)vs/(s*z));
229 }
230 
231 - (float) landscapeCoordinateForSize:(int) s
232  viewportSize:(int) vs
233  zoom:(float) z
234 {
235  return self.doubleValue * ((double)s - (double)vs/z);
236 }
237 @end
238 
239 // C4ViewportWindow
240 
241 #if !defined(WITH_QT_EDITOR)
243 {
244  if (PlayerLock) return false;
245  NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
246  [scrollView.horizontalScroller setToLandscapeCoordinate:GetViewX() size:Landscape.GetWidth() viewportSize:ViewWdt zoom:GetZoom()];
247  [scrollView.verticalScroller setToLandscapeCoordinate:GetViewY() size:Landscape.GetHeight() viewportSize:ViewHgt zoom:GetZoom()];
248  return true;
249 }
250 
252 {
253  NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
254  if (PlayerLock)
255  {
256  PlayerLock = false;
257  if (scrollView)
258  {
259  [scrollView.verticalScroller setEnabled:YES];
260  [scrollView.horizontalScroller setEnabled:YES];
261  [scrollView setAutohidesScrollers:NO];
262  }
263  ScrollBarsByViewPosition();
264  }
265  else
266  {
267  PlayerLock = true;
268  if (scrollView)
269  {
270  [scrollView.verticalScroller setEnabled:NO];
271  [scrollView.horizontalScroller setEnabled:NO];
272  [scrollView setAutohidesScrollers:YES];
273  }
274  }
275  return true;
276 }
277 #endif
278 
280 {
281  NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
282  SetViewX([scrollView.horizontalScroller landscapeCoordinateForSize:Landscape.GetWidth() viewportSize:ViewWdt zoom:GetZoom()]);
283  SetViewY([scrollView.verticalScroller landscapeCoordinateForSize:Landscape.GetHeight() viewportSize:ViewHgt zoom:GetZoom()]);
284  return true;
285 }
286 
287 #endif
#define s
C4Application Application
Definition: C4Globals.cpp:44
C4FullScreen FullScreen
Definition: C4Globals.cpp:46
C4Landscape Landscape
#define z
C4ViewportList Viewports
bool lionAndBeyond()
int32_t GetWidth() const
int32_t GetHeight() const
bool ViewPositionByScrollBars()
bool ScrollBarsByViewPosition()
Definition: C4Console.cpp:710
C4Viewport * GetNext()
Definition: C4Viewport.h:69
bool TogglePlayerLock()
Definition: C4Console.cpp:711
void Execute()
Definition: C4Viewport.cpp:443
C4Viewport * GetFirstViewport()
Definition: C4Viewport.h:159
C4AppDelegate * instance()
BOOL isFullScreenConsideringLionFullScreen()
C4Viewport * viewport()
NSScrollView * scrollView
C4OpenGLView * openGLView
float GetZoom()
Definition: C4Gui.h:2831