mpv/video/out/cocoa/window.m

171 lines
4.6 KiB
Objective-C

/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libavutil/common.h>
#include "input/keycodes.h"
#include "osdep/macosx_application.h"
#include "osdep/macosx_events.h"
#include "osdep/macosx_compat.h"
#include "video/out/cocoa/additions.h"
#include "video/out/cocoa_common.h"
#include "window.h"
@implementation MpvVideoWindow {
NSSize _queued_video_size;
bool _fs_resize_scheduled;
bool _recenter_window_during_constraint;
}
@synthesize adapter = _adapter;
- (id)initWithContentRect:(NSRect)content_rect
styleMask:(NSUInteger)style_mask
backing:(NSBackingStoreType)buffering_type
defer:(BOOL)flag
{
if (self = [super initWithContentRect:content_rect
styleMask:style_mask
backing:buffering_type
defer:flag]) {
[self setBackgroundColor:[NSColor blackColor]];
}
return self;
}
- (void)windowDidResize:(NSNotification *) notification
{
[self.adapter setNeedsResize];
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
[self.adapter setNeedsResize];
}
- (BOOL)isInFullScreenMode
{
return (([self styleMask] & NSFullScreenWindowMask) ==
NSFullScreenWindowMask);
}
- (void)setFullScreen:(BOOL)willBeFullscreen
{
if (willBeFullscreen && ![self isInFullScreenMode]) {
[self setContentResizeIncrements:NSMakeSize(1, 1)];
[self toggleFullScreen:nil];
}
if (!willBeFullscreen && [self isInFullScreenMode]) {
[self setContentAspectRatio:self->_queued_video_size];
[self toggleFullScreen:nil];
}
}
- (BOOL)canBecomeMainWindow { return YES; }
- (BOOL)canBecomeKeyWindow { return YES; }
- (BOOL)windowShouldClose:(id)sender
{
cocoa_put_key(MP_KEY_CLOSE_WIN);
// We have to wait for MPlayer to handle this,
// otherwise we are in trouble if the
// MP_KEY_CLOSE_WIN handler is disabled
return NO;
}
- (void)normalSize { [self mulSize:1.0f]; }
- (void)halfSize { [self mulSize:0.5f];}
- (void)doubleSize { [self mulSize:2.0f];}
- (void)mulSize:(float)multiplier
{
char *cmd = ta_asprintf(NULL, "set window-scale %f", multiplier);
[self.adapter putCommand:cmd];
}
- (int)titleHeight
{
NSRect of = [self frame];
NSRect cb = [[self contentView] bounds];
return of.size.height - cb.size.height;
}
- (void)setCenteredContentSize:(NSSize)ns
{
NSRect f = [self frame];
CGFloat dx = (f.size.width - ns.width) / 2;
CGFloat dy = (f.size.height - ns.height - [self titleHeight]) / 2;
NSRect nf = NSRectFromCGRect(CGRectInset(NSRectToCGRect(f), dx, dy));
self->_recenter_window_during_constraint = true;
[self setFrame:nf display:NO animate:NO];
}
- (NSRect)constrainFrameRect:(NSRect)nf toScreen:(NSScreen *)screen
{
NSRect s = [[self screen] visibleFrame];
if (nf.origin.y + nf.size.height > s.origin.y + s.size.height) {
if (self->_recenter_window_during_constraint)
nf.size.height = s.size.height;
nf.origin.y = s.origin.y + s.size.height - nf.size.height;
}
return nf;
}
- (void)setFrame:(NSRect)frame display:(BOOL)display animate:(BOOL)animate
{
[super setFrame:frame display:display animate:animate];
self->_recenter_window_during_constraint = false;
}
- (void)queueNewVideoSize:(NSSize)new_size
{
NSSize prev_size = self->_queued_video_size;
self->_queued_video_size = new_size;
if (!CGSizeEqualToSize(prev_size, new_size))
[self dispatchNewVideoSize];
}
- (void)dispatchNewVideoSize
{
if ([self.adapter isInFullScreenMode]) {
self->_fs_resize_scheduled = true;
} else {
[self applyNewVideoSize];
}
}
- (void)applyNewVideoSize
{
[self setCenteredContentSize:self->_queued_video_size];
[self setContentAspectRatio:self->_queued_video_size];
}
- (void)didChangeFullScreenState
{
if (![self.adapter isInFullScreenMode] && self->_fs_resize_scheduled) {
self->_fs_resize_scheduled = false;
[self applyNewVideoSize];
}
}
@end