1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
3 * VIM - Vi IMproved by Bram Moolenaar
4 * MacVim GUI port by Bjorn Winckler
6 * Do ":help uganda" in Vim to read copying and usage conditions.
7 * Do ":help credits" in Vim to see a list of people who contributed.
8 * See README.txt for an overview of the Vim source code.
13 * Support for full-screen editing.
18 #import "MMFullscreenWindow.h"
19 #import <PSMTabBarControl.h>
21 #import "MMTextView.h"
22 #import "MMWindowController.h"
23 #import <Carbon/Carbon.h>
27 @implementation MMFullscreenWindow
29 - (MMFullscreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
31 NSScreen* screen = [t screen];
33 // XXX: what if screen == nil?
35 // you can't change the style of an existing window in cocoa. create a new
36 // window and move the MMTextView into it.
37 // (another way would be to make the existing window large enough that the
38 // title bar is off screen. but that doesn't work with multiple screens).
39 self = [super initWithContentRect:[screen frame]
40 styleMask:NSBorderlessWindowMask
41 backing:NSBackingStoreBuffered
48 [self setHasShadow:NO];
49 [self setShowsResizeIndicator:NO];
50 [self setBackgroundColor:[NSColor blackColor]];
51 [self setReleasedWhenClosed:NO];
53 target = t; [target retain];
54 view = v; [view retain];
69 NSRect outer = [self frame], inner = [view frame];
70 //NSLog(@"%s %@%@", _cmd, NSStringFromRect(outer), NSStringFromRect(inner));
72 NSPoint origin = NSMakePoint((outer.size.width - inner.size.width)/2,
73 (outer.size.height - inner.size.height)/2);
74 [view setFrameOrigin:origin];
77 - (void)enterFullscreen
79 // hide menu and dock, both appear on demand
80 SetSystemUIMode(kUIModeAllSuppressed, 0); //requires 10.3
83 Boolean didBlend = NO;
84 CGDisplayFadeReservationToken token;
85 if (CGAcquireDisplayFadeReservation(.5, &token) == kCGErrorSuccess) {
86 CGDisplayFade(token, .25, kCGDisplayBlendNormal,
87 kCGDisplayBlendSolidColor, .0, .0, .0, true);
92 id delegate = [target delegate];
93 [target setDelegate:nil];
95 // make target's window controller believe that it's now controlling us
96 [target retain]; // NSWindowController will release target once in the
98 [[target windowController] setWindow:self];
101 oldTabBarStyle = [[view tabBarControl] styleName];
102 [[view tabBarControl] setStyleNamed:@"Unified"];
105 oldPosition = [view frame].origin;
107 [[self contentView] addSubview:view];
108 [self setInitialFirstResponder:[view textView]];
110 [self setTitle:[target title]];
111 [self setOpaque:[target isOpaque]];
113 // don't set this sooner, so we don't get an additional
114 // focus gained message
115 [self setDelegate:delegate];
117 // update bottom right corner scrollbar (no resize handle in fu mode)
120 // move vim view to the window's center
123 // make us visible and target invisible
124 [target orderOut:self];
125 [self makeKeyAndOrderFront:self];
129 CGDisplayFade(token, .25, kCGDisplayBlendSolidColor,
130 kCGDisplayBlendNormal, .0, .0, .0, false);
131 CGReleaseDisplayFadeReservation(token);
135 - (void)leaveFullscreen
138 Boolean didBlend = NO;
139 CGDisplayFadeReservationToken token;
140 if (CGAcquireDisplayFadeReservation(.5, &token) == kCGErrorSuccess) {
141 CGDisplayFade(token, .25, kCGDisplayBlendNormal,
142 kCGDisplayBlendSolidColor, .0, .0, .0, true);
146 // fix up target controller
147 [self retain]; // NSWindowController releases us once
148 [[self windowController] setWindow:target];
150 [[view tabBarControl] setStyleNamed:oldTabBarStyle];
153 id delegate = [self delegate];
154 [self setDelegate:nil];
156 // move text view back to original window, hide fullscreen window,
157 // show original window
158 // do this _after_ resetting delegate and window controller, so the
159 // window controller doesn't get a focus lost message from the fullscreen
161 [[target contentView] addSubview:view];
162 [view setFrameOrigin:oldPosition];
164 [target makeKeyAndOrderFront:self];
166 // ...but we don't want a focus gained message either, so don't set this
168 [target setDelegate:delegate];
170 // update bottom right corner scrollbar (resize handle reappears)
175 CGDisplayFade(token, .25, kCGDisplayBlendSolidColor,
176 kCGDisplayBlendNormal, .0, .0, .0, false);
177 CGReleaseDisplayFadeReservation(token);
180 // order menu and dock back in
181 SetSystemUIMode(kUIModeNormal, 0);
184 // Title-less windows normally don't receive key presses, override this
185 - (BOOL)canBecomeKeyWindow
190 // Title-less windows normally can't become main which means that another
191 // non-fullscreen window will have the "active" titlebar in expose. Bad, fix it.
192 - (BOOL)canBecomeMainWindow
198 #pragma mark Proxy/Decorator/whatever stuff
200 - (void)scrollWheel:(NSEvent *)theEvent
202 [[view textView] scrollWheel:theEvent];
205 // the window controller will send us messages that are meant for the original,
206 // non-fullscreen window. forward those, and interpret the messages that are
207 // interesting for us
209 - (void)setTitle:(NSString *)title
211 [target setTitle:title];
212 [super setTitle:title];
215 // HACK: if the T flag in guioptions is changed in fu mode, the toolbar needs
216 // to be changed when nofu is set. MMWindowController gets the toolbar object,
217 // so we need to return a toolbar from this method, even if none is visible for
218 // the fullscreen window. Seems to work, though.
219 - (NSToolbar *)toolbar
221 return [target toolbar];
224 - (void)setFrame:(NSRect)frame display:(BOOL)display
226 // HACK: if the target window would resize, we have to call our own
227 // windowDidResize method so that placeViews in MMWindowController is called
228 if (!NSEqualRects(frame, [target frame]))
230 [target setFrame:frame display:NO];
232 // XXX: send this directly to MMVimView
233 if ([[self delegate] respondsToSelector:@selector(windowDidResize:)])
234 [[self delegate] windowDidResize:nil];
243 return [target frame]; // really? needed by MMWindowController placeViews.
244 // but mucks up display
247 - (NSRect)contentRectForFrameRect:(NSRect)rect
249 //return [target contentRectForFrameRect:rect];
251 // EVIL HACK: if this is always called with [[self window] frame] as
252 // argument from MMWindowController, we can't let frame return the frame
253 // of target so "fix" this here.
254 if (NSEqualRects([self frame], rect)) {
255 return [target contentRectForFrameRect:[target frame]];
257 return [target contentRectForFrameRect:rect];
261 - (NSRect)frameRectForContentRect:(NSRect)contentRect
263 return [target frameRectForContentRect:contentRect];
266 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen
268 return [target constrainFrameRect:frameRect toScreen:screen];
271 - (void)setContentResizeIncrements:(NSSize)size
273 [target setContentResizeIncrements:size];
276 - (void)setOpaque:(BOOL)isOpaque
278 // XXX: Do we want transparency even in fullscreen mode?
279 [super setOpaque:isOpaque];
280 [target setOpaque:isOpaque];