summaryrefslogtreecommitdiffstats
path: root/NativeApp/Apple/Source/Classes/OSX/WindowController.mm
blob: 5904f6c0a12f3ae77e9a1244eb2f0a0a45678b1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 Copyright (C) 2015 Apple Inc. All Rights Reserved.
 See LICENSE.txt for this sample’s licensing information
 
 Abstract:
 Window controller subclass.
 */

#import "WindowController.h"
#import "FullscreenWindow.h"
#import "ViewBase.h"

@interface WindowController ()

// Fullscreen window
@property(strong) FullscreenWindow *fullscreenWindow;

// Non-Fullscreen window (also the initial window)
@property(strong) NSWindow* standardWindow;

@end

@implementation WindowController
{
    bool CommandKeyPressed;
}

- (instancetype)initWithWindow:(NSWindow *)window
{
    self = [super initWithWindow:window];

	if (self)
	{
		// Initialize to nil since it indicates app is not fullscreen
        _fullscreenWindow = nil;
    }

    CommandKeyPressed = false;

	return self;
}

- (void) goFullscreen
{
	// If app is already fullscreen...
    if([self fullscreenWindow])
	{
		//...don't do anything
		return;
	}

    ViewBase* view = (ViewBase*)self.window.contentView;

    // We must stop the display link while
    // switching the windows to make sure
    // that render commands are not issued
    // from another thread
    [view stopDisplayLink];

	// Allocate a new fullscreen window
    [self setFullscreenWindow: [[FullscreenWindow alloc] init]];

    [[self fullscreenWindow] setAcceptsMouseMovedEvents:YES];

	// Resize the view to screensize
	NSRect viewRect = [[self fullscreenWindow] frame];

	// Set the view to the size of the fullscreen window
	[self.window.contentView setFrameSize: viewRect.size];

	// Set the view in the fullscreen window
	[[self fullscreenWindow] setContentView:self.window.contentView];

    [self setStandardWindow:[self window]];

	// Hide non-fullscreen window so it doesn't show up when switching out
	// of this app (i.e. with CMD-TAB)
	[[self standardWindow] orderOut:self];

	// Set controller to the fullscreen window so that all input will go to
	// this controller (self)
	[self setWindow:[self fullscreenWindow]];

	// Show the window and make it the key window for input
	[[self fullscreenWindow] makeKeyAndOrderFront:self];

    // Restore display link
    [view startDisplayLink];
}

- (void) goWindow
{
	// If controller doesn't have a full screen window...
	if([self fullscreenWindow] == nil)
	{
		//...app is already windowed so don't do anything
		return;
	}

    ViewBase* view = (ViewBase*)self.window.contentView;

    // We must stop the display link while
    // switching the windows to make sure
    // that render commands are not issued
    // from another thread
    [view stopDisplayLink];

	// Get the rectangle of the original window
	NSRect viewRect = [[self standardWindow] frame];
	
	// Set the view rect to the new size
	[self.window.contentView setFrame:viewRect];

    // Hide fullscreen window
    [[self fullscreenWindow] orderOut:self];

	// Set controller to the standard window so that all input will go to
	// this controller (self)
	[self setWindow:[self standardWindow]];

	// Set the content of the original window to the view
	[[self window] setContentView: [self fullscreenWindow].contentView];

	// Show the window and make it the key window for input
	[[self window] makeKeyAndOrderFront:self];

	// Ensure we set fullscreen Window to nil so our checks for 
	// windowed vs. fullscreen mode elsewhere are correct
    [self setFullscreenWindow: nil];

    // Restore display link
    [view startDisplayLink];
}


- (void) keyDown:(NSEvent *)event
{
	unichar c = [[event charactersIgnoringModifiers] characterAtIndex:0];

	switch (c)
	{
		// Handle [ESC] key
		case 27:
            if([self fullscreenWindow] != nil)
			{
				[self goWindow];
			}
			return;

		// Have Command+f or Command+Enter toggle fullscreen
        case 13:
		case 'f':
            if (CommandKeyPressed)
            {
                if([self fullscreenWindow] == nil)
                {
                    [self goFullscreen];
                }
                else
                {
                    [self goWindow];
                }
            }
			return;
	}

	// Allow other character to be handled (or not and beep)
	//[super keyDown:event];
}

// Informs the receiver that the user has pressed or released a
// modifier key (Shift, Control, and so on)
- (void)flagsChanged:(NSEvent *)event
{
    auto modifierFlags = [event modifierFlags];
    CommandKeyPressed = modifierFlags & NSEventModifierFlagCommand;

    [super flagsChanged:event];
}

@end