]> git.sesse.net Git - vlc/commitdiff
macosx: add new common window class in order to deduplicate code
authorDavid Fuhrmann <david.fuhrmann@googlemail.com>
Thu, 13 Sep 2012 13:23:23 +0000 (15:23 +0200)
committerDavid Fuhrmann <david.fuhrmann@googlemail.com>
Thu, 13 Sep 2012 13:29:05 +0000 (15:29 +0200)
moved custom zoom/minimize/close implementation, added new file for window related stuff
fixed minimize / close support for !video-deco window

extras/package/macosx/vlc.xcodeproj/project.pbxproj
modules/gui/macosx/MainWindow.h
modules/gui/macosx/MainWindow.m
modules/gui/macosx/Modules.am
modules/gui/macosx/Windows.h [new file with mode: 0644]
modules/gui/macosx/Windows.m [new file with mode: 0644]
modules/gui/macosx/misc.h
modules/gui/macosx/misc.m

index 69b7c780e86ae9a868afd9f3451db8710b61f721..3bcd59cb1bbf0102c2a194d5486232edadf9f38d 100644 (file)
                DC769AB8085DF0DB001A838D /* wizard.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = wizard.h; path = ../../../modules/gui/macosx/wizard.h; sourceTree = SOURCE_ROOT; };
                DCE7BD0608A5724D007B10AE /* bookmarks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = bookmarks.m; path = ../../../modules/gui/macosx/bookmarks.m; sourceTree = SOURCE_ROOT; };
                DCE7BD0708A5724D007B10AE /* bookmarks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bookmarks.h; path = ../../../modules/gui/macosx/bookmarks.h; sourceTree = SOURCE_ROOT; };
+               E06CF7F416020F6200C698B7 /* Windows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Windows.h; path = ../../../modules/gui/macosx/Windows.h; sourceTree = SOURCE_ROOT; };
+               E06CF7F516020F6200C698B7 /* Windows.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Windows.m; path = ../../../modules/gui/macosx/Windows.m; sourceTree = SOURCE_ROOT; };
                F69B0CA702E24F6401A80112 /* English */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.plist.strings; name = English; path = Resources/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
                CC017A0E14A4C8B600C09A4F /* custom UI code */ = {
                        isa = PBXGroup;
                        children = (
+                               E06CF7F416020F6200C698B7 /* Windows.h */,
+                               E06CF7F516020F6200C698B7 /* Windows.m */,
                                8ED6C27F03E2EB1C0059A3A7 /* misc.h */,
                                8ED6C28003E2EB1C0059A3A7 /* misc.m */,
                                CC017A0B14A4C8AF00C09A4F /* MainWindowTitle.h */,
index 38b06642ab5a681aaf2093e61e548d6877e6726b..f34dc5916701c3fbce74a9c160c50885c2f81568 100644 (file)
 #import "PXSourceList.h"
 #import "PXSourceListDataSource.h"
 #import <vlc_input.h>
+#import "Windows.h"
 #import "misc.h"
 #import "fspanel.h"
 #import "MainWindowTitle.h"
 
-@interface VLCMainWindow : NSWindow <PXSourceListDataSource, PXSourceListDelegate, NSWindowDelegate, NSAnimationDelegate, NSSplitViewDelegate> {
+@interface VLCMainWindow : VLCVideoWindowCommon <PXSourceListDataSource, PXSourceListDelegate, NSWindowDelegate, NSAnimationDelegate, NSSplitViewDelegate> {
     IBOutlet id o_play_btn;
     IBOutlet id o_bwd_btn;
     IBOutlet id o_fwd_btn;
     IBOutlet id o_podcast_unsubscribe_ok_btn;
     IBOutlet id o_podcast_unsubscribe_cancel_btn;
 
-    BOOL b_dark_interface;
     BOOL b_nativeFullscreenMode;
     BOOL b_video_playback_enabled;
     BOOL b_dropzone_active;
 
     VLCColorView * o_color_backdrop;
     NSInteger i_originalLevel;
-    NSRect previousSavedFrame;
 
     VLCWindow *o_extra_video_window;
     id o_current_video_window;
 - (IBAction)removePodcastWindowAction:(id)sender;
 
 - (void)setTitle:(NSString *)title;
-- (void)customZoom:(id)sender;
 - (void)windowResizedOrMoved:(NSNotification *)notification;
 
 - (void)showDropZone;
 - (id)detachedTitlebarView;
 @end
 
-@interface VLCDetachedVideoWindow : NSWindow
-{
-    BOOL b_dark_interface;
-    NSRect previousSavedFrame;
-}
-
-- (void)customZoom:(id)sender;
+@interface VLCDetachedVideoWindow : VLCVideoWindowCommon
 
 @end
\ No newline at end of file
index f015f25594b7109cebec4586c97123c3458d87b2..a92877f15d02409ff4e7bbf3d236dab68d0e14df 100644 (file)
@@ -56,7 +56,6 @@
 - (void)makeSplitViewVisible;
 - (void)makeSplitViewHidden;
 
-- (NSRect)customConstrainFrameRect: (NSRect)frameRect toScreen: (NSScreen*)screen;
 @end
 
 @implementation VLCMainWindow
@@ -86,29 +85,12 @@ static VLCMainWindow *_o_sharedInstance = nil;
 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
                   backing:(NSBackingStoreType)backingType defer:(BOOL)flag
 {
-    b_dark_interface = config_GetInt(VLCIntf, "macosx-interfacestyle");
-
-    if (b_dark_interface) {
-        styleMask = NSBorderlessWindowMask;
-#ifdef MAC_OS_X_VERSION_10_7
-        if (!OSX_SNOW_LEOPARD)
-            styleMask |= NSResizableWindowMask;
-#endif
-    }
-
     self = [super initWithContentRect:contentRect styleMask:styleMask
                               backing:backingType defer:flag];
     _o_sharedInstance = self;
 
     [[VLCMain sharedInstance] updateTogglePlaylistState];
 
-    /* we want to be moveable regardless of our style */
-    [self setMovableByWindowBackground: YES];
-
-    /* we don't want this window to be restored on relaunch */
-    if (!OSX_SNOW_LEOPARD)
-        [self setRestorable:NO];
-
     return self;
 }
 
@@ -1274,16 +1256,6 @@ static VLCMainWindow *_o_sharedInstance = nil;
     return YES;
 }
 
-- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
-{
-    SEL s_menuAction = [menuItem action];
-
-    if ((s_menuAction == @selector(performClose:)) || (s_menuAction == @selector(performMiniaturize:)) || (s_menuAction == @selector(performZoom:)))
-            return YES;
-
-    return [super validateMenuItem:menuItem];
-}
-
 - (void)setTitle:(NSString *)title
 {
     if (b_dark_interface) {
@@ -1295,136 +1267,6 @@ static VLCMainWindow *_o_sharedInstance = nil;
     [super setTitle: title];
 }
 
-- (void)performClose:(id)sender
-{
-    NSWindow *o_key_window = [NSApp keyWindow];
-
-    if (b_dark_interface) {
-        [o_key_window orderOut: sender];
-        if ([[VLCMain sharedInstance] activeVideoPlayback] && (!b_nonembedded || o_key_window != self))
-            [[VLCCoreInteraction sharedInstance] stop];
-    } else {
-        if (b_nonembedded && o_key_window != self)
-            [o_detached_video_window performClose: sender];
-        else
-            [super performClose: sender];
-    }
-}
-
-- (void)performMiniaturize:(id)sender
-{
-    if (b_dark_interface)
-        [self miniaturize: sender];
-    else
-        [super performMiniaturize: sender];
-}
-
-- (void)performZoom:(id)sender
-{
-    if (b_dark_interface)
-        [self customZoom: sender];
-    else
-        [super performZoom: sender];
-}
-
-- (void)zoom:(id)sender
-{
-    if (b_dark_interface)
-        [self customZoom: sender];
-    else
-        [super zoom: sender];
-}
-
-/**
- * Given a proposed frame rectangle, return a modified version
- * which will fit inside the screen.
- *
- * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+.
- *    Authors:  Scott Christley <scottc@net-community.com>, Venkat Ajjanagadde <venkat@ocbi.com>,
- *              Felipe A. Rodriguez <far@ix.netcom.com>, Richard Frith-Macdonald <richard@brainstorm.co.uk>
- *    Copyright (C) 1996 Free Software Foundation, Inc.
- */
-- (NSRect) customConstrainFrameRect: (NSRect)frameRect toScreen: (NSScreen*)screen
-{
-    NSRect screenRect = [screen visibleFrame];
-    float difference;
-
-    /* Move top edge of the window inside the screen */
-    difference = NSMaxY (frameRect) - NSMaxY (screenRect);
-    if (difference > 0)
-        frameRect.origin.y -= difference;
-
-    /* If the window is resizable, resize it (if needed) so that the
-     bottom edge is on the screen or can be on the screen when the user moves
-     the window */
-    difference = NSMaxY (screenRect) - NSMaxY (frameRect);
-    if (_styleMask & NSResizableWindowMask) {
-        float difference2;
-
-        difference2 = screenRect.origin.y - frameRect.origin.y;
-        difference2 -= difference;
-        // Take in account the space between the top of window and the top of the
-        // screen which can be used to move the bottom of the window on the screen
-        if (difference2 > 0) {
-            frameRect.size.height -= difference2;
-            frameRect.origin.y += difference2;
-        }
-
-        /* Ensure that resizing doesn't makewindow smaller than minimum */
-        difference2 = [self minSize].height - frameRect.size.height;
-        if (difference2 > 0) {
-            frameRect.size.height += difference2;
-            frameRect.origin.y -= difference2;
-        }
-    }
-
-    return frameRect;
-}
-
-#define DIST 3
-
-/**
- Zooms the receiver.   This method calls the delegate method
- windowShouldZoom:toFrame: to determine if the window should
- be allowed to zoom to full screen.
- *
- * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+.
- *    Authors:  Scott Christley <scottc@net-community.com>, Venkat Ajjanagadde <venkat@ocbi.com>,
- *              Felipe A. Rodriguez <far@ix.netcom.com>, Richard Frith-Macdonald <richard@brainstorm.co.uk>
- *    Copyright (C) 1996 Free Software Foundation, Inc.
- */
-- (void)customZoom:(id)sender
-{
-    NSRect maxRect = [[self screen] visibleFrame];
-    NSRect currentFrame = [self frame];
-
-    if ([[self delegate] respondsToSelector: @selector(windowWillUseStandardFrame:defaultFrame:)]) {
-        maxRect = [[self delegate] windowWillUseStandardFrame: self defaultFrame: maxRect];
-    }
-
-    maxRect = [self customConstrainFrameRect: maxRect toScreen: [self screen]];
-
-    // Compare the new frame with the current one
-    if ((abs(NSMaxX(maxRect) - NSMaxX(currentFrame)) < DIST)
-        && (abs(NSMaxY(maxRect) - NSMaxY(currentFrame)) < DIST)
-        && (abs(NSMinX(maxRect) - NSMinX(currentFrame)) < DIST)
-        && (abs(NSMinY(maxRect) - NSMinY(currentFrame)) < DIST)) {
-        // Already in zoomed mode, reset user frame, if stored
-        if ([self frameAutosaveName] != nil) {
-            [self setFrame: previousSavedFrame display: YES animate: YES];
-            [self saveFrameUsingName: [self frameAutosaveName]];
-        }
-        return;
-    }
-
-    if ([self frameAutosaveName] != nil) {
-        [self saveFrameUsingName: [self frameAutosaveName]];
-        previousSavedFrame = [self frame];
-    }
-
-    [self setFrame: maxRect display: YES animate: YES];
-}
-
 - (void)windowResizedOrMoved:(NSNotification *)notification
 {
     [self saveFrameUsingName: [self frameAutosaveName]];
@@ -1435,9 +1277,11 @@ static VLCMainWindow *_o_sharedInstance = nil;
     [self saveFrameUsingName: [self frameAutosaveName]];
 }
 
+
 - (void)someWindowWillClose:(NSNotification *)notification
 {
-    if ([notification object] == o_detached_video_window || ([notification object] == self && !b_nonembedded)) {
+    id obj = [notification object];
+    if (obj == o_detached_video_window || obj == o_extra_video_window || (obj == self && !b_nonembedded)) {
         if ([[VLCMain sharedInstance] activeVideoPlayback])
             [[VLCCoreInteraction sharedInstance] stop];
     }
@@ -1446,7 +1290,8 @@ static VLCMainWindow *_o_sharedInstance = nil;
 - (void)someWindowWillMiniaturize:(NSNotification *)notification
 {
     if (config_GetInt(VLCIntf, "macosx-pause-minimized")) {
-        if ([notification object] == o_detached_video_window || ([notification object] == self && !b_nonembedded)) {
+        id obj = [notification object];
+        if (obj == o_detached_video_window || obj == o_extra_video_window || (obj == self && !b_nonembedded)) {
             if ([[VLCMain sharedInstance] activeVideoPlayback])
                 [[VLCCoreInteraction sharedInstance] pause];
         }
@@ -1802,7 +1647,7 @@ static VLCMainWindow *_o_sharedInstance = nil;
             mask |= NSResizableWindowMask;
 
         BOOL b_no_video_deco_only = !b_video_wallpaper;
-        o_extra_video_window = [[VLCWindow alloc] initWithContentRect:window_rect styleMask:mask backing:NSBackingStoreBuffered defer:YES];
+        o_extra_video_window = [[VLCVideoWindowCommon alloc] initWithContentRect:window_rect styleMask:mask backing:NSBackingStoreBuffered defer:YES];
         [o_extra_video_window setDelegate:self];
 
         if (b_video_wallpaper)
@@ -2935,32 +2780,6 @@ static VLCMainWindow *_o_sharedInstance = nil;
 
 @implementation VLCDetachedVideoWindow
 
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
-                  backing:(NSBackingStoreType)backingType defer:(BOOL)flag
-{
-    b_dark_interface = config_GetInt(VLCIntf, "macosx-interfacestyle");
-
-    if (b_dark_interface) {
-        styleMask = NSBorderlessWindowMask;
-#ifdef MAC_OS_X_VERSION_10_7
-        if (!OSX_SNOW_LEOPARD)
-            styleMask |= NSResizableWindowMask;
-#endif
-    }
-
-    self = [super initWithContentRect:contentRect styleMask:styleMask
-                                  backing:backingType defer:flag];
-
-    /* we want to be moveable regardless of our style */
-    [self setMovableByWindowBackground: YES];
-
-    /* we don't want this window to be restored on relaunch */
-    if (!OSX_SNOW_LEOPARD)
-        [self setRestorable:NO];
-
-    return self;
-}
-
 - (void)awakeFromNib
 {
     [self setAcceptsMouseMovedEvents: YES];
@@ -2979,144 +2798,11 @@ static VLCMainWindow *_o_sharedInstance = nil;
     [[VLCCoreInteraction sharedInstance] toggleFullscreen];
 }
 
-- (void)performClose:(id)sender
-{
-    if (b_dark_interface)
-        [[VLCMainWindow sharedInstance] performClose: sender];
-    else
-        [super performClose: sender];
-}
-
-- (void)performMiniaturize:(id)sender
-{
-    if (b_dark_interface)
-        [self miniaturize: sender];
-    else
-        [super performMiniaturize: sender];
-}
-
-- (void)performZoom:(id)sender
-{
-    if (b_dark_interface)
-        [self customZoom: sender];
-    else
-        [super performZoom: sender];
-}
-
-- (void)zoom:(id)sender
-{
-    if (b_dark_interface)
-        [self customZoom: sender];
-    else
-        [super zoom: sender];
-}
-
 - (BOOL)canBecomeKeyWindow
 {
     return YES;
 }
 
-- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
-{
-    SEL s_menuAction = [menuItem action];
-
-    if ((s_menuAction == @selector(performClose:)) || (s_menuAction == @selector(performMiniaturize:)) || (s_menuAction == @selector(performZoom:)))
-        return YES;
-
-    return [super validateMenuItem:menuItem];
-}
-
-/**
- * Given a proposed frame rectangle, return a modified version
- * which will fit inside the screen.
- *
- * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+.
- *    Authors:  Scott Christley <scottc@net-community.com>, Venkat Ajjanagadde <venkat@ocbi.com>,
- *              Felipe A. Rodriguez <far@ix.netcom.com>, Richard Frith-Macdonald <richard@brainstorm.co.uk>
- *    Copyright (C) 1996 Free Software Foundation, Inc.
- */
-- (NSRect) customConstrainFrameRect: (NSRect)frameRect toScreen: (NSScreen*)screen
-{
-    NSRect screenRect = [screen visibleFrame];
-    float difference;
-
-    /* Move top edge of the window inside the screen */
-    difference = NSMaxY (frameRect) - NSMaxY (screenRect);
-    if (difference > 0) {
-        frameRect.origin.y -= difference;
-    }
-
-    /* If the window is resizable, resize it (if needed) so that the
-     bottom edge is on the screen or can be on the screen when the user moves
-     the window */
-    difference = NSMaxY (screenRect) - NSMaxY (frameRect);
-    if (_styleMask & NSResizableWindowMask) {
-        float difference2;
-
-        difference2 = screenRect.origin.y - frameRect.origin.y;
-        difference2 -= difference;
-        // Take in account the space between the top of window and the top of the
-        // screen which can be used to move the bottom of the window on the screen
-        if (difference2 > 0) {
-            frameRect.size.height -= difference2;
-            frameRect.origin.y += difference2;
-        }
-
-        /* Ensure that resizing doesn't makewindow smaller than minimum */
-        difference2 = [self minSize].height - frameRect.size.height;
-        if (difference2 > 0) {
-            frameRect.size.height += difference2;
-            frameRect.origin.y -= difference2;
-        }
-    }
-
-    return frameRect;
-}
-
-#define DIST 3
-
-/**
- Zooms the receiver.   This method calls the delegate method
- windowShouldZoom:toFrame: to determine if the window should
- be allowed to zoom to full screen.
- *
- * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+.
- *    Authors:  Scott Christley <scottc@net-community.com>, Venkat Ajjanagadde <venkat@ocbi.com>,
- *              Felipe A. Rodriguez <far@ix.netcom.com>, Richard Frith-Macdonald <richard@brainstorm.co.uk>
- *    Copyright (C) 1996 Free Software Foundation, Inc.
- */
-- (void) customZoom: (id)sender
-{
-    NSRect maxRect = [[self screen] visibleFrame];
-    NSRect currentFrame = [self frame];
-
-    if ([[self delegate] respondsToSelector: @selector(windowWillUseStandardFrame:defaultFrame:)]) {
-        maxRect = [[self delegate] windowWillUseStandardFrame: self defaultFrame: maxRect];
-    }
-
-    maxRect = [self customConstrainFrameRect: maxRect toScreen: [self screen]];
-
-    // Compare the new frame with the current one
-    if ((abs(NSMaxX(maxRect) - NSMaxX(currentFrame)) < DIST)
-        && (abs(NSMaxY(maxRect) - NSMaxY(currentFrame)) < DIST)
-        && (abs(NSMinX(maxRect) - NSMinX(currentFrame)) < DIST)
-        && (abs(NSMinY(maxRect) - NSMinY(currentFrame)) < DIST)) {
-        // Already in zoomed mode, reset user frame, if stored
-        if ([self frameAutosaveName] != nil) {
-            [self setFrame: previousSavedFrame display: YES animate: YES];
-            [self saveFrameUsingName: [self frameAutosaveName]];
-        }
-        return;
-    }
-
-    if ([self frameAutosaveName] != nil) {
-        [self saveFrameUsingName: [self frameAutosaveName]];
-        previousSavedFrame = [self frame];
-    }
-
-    [self setFrame: maxRect display: YES animate: YES];
-}
-
 - (NSArray *)accessibilityAttributeNames
 {
     if (!b_dark_interface)
index 6ecd39d4b756e6208d3364592952f5497ecbf53c..d5abfd60476009cb960570dd31e1b3f18155ed94 100644 (file)
@@ -80,4 +80,6 @@ SOURCES_macosx = \
        ConvertAndSave.m \
        SharedDialogs.h \
        SharedDialogs.m \
+       Windows.h \
+       Windows.m \
        $(NULL)
diff --git a/modules/gui/macosx/Windows.h b/modules/gui/macosx/Windows.h
new file mode 100644 (file)
index 0000000..d0c4e77
--- /dev/null
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Windows.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
+ *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+#import "CompatibilityFixes.h"
+
+/*****************************************************************************
+ * VLCWindow
+ *
+ *  Missing extension to NSWindow
+ *****************************************************************************/
+
+@interface VLCWindow : NSWindow <NSWindowDelegate>
+{
+    BOOL b_canBecomeKeyWindow;
+    BOOL b_isset_canBecomeKeyWindow;
+    BOOL b_canBecomeMainWindow;
+    BOOL b_isset_canBecomeMainWindow;
+    NSViewAnimation *animation;
+}
+@property (readwrite) BOOL canBecomeKeyWindow;
+@property (readwrite) BOOL canBecomeMainWindow;
+
+/* animate mode is only supported in >=10.4 */
+- (void)orderFront: (id)sender animate: (BOOL)animate;
+
+/* animate mode is only supported in >=10.4 */
+- (void)orderOut: (id)sender animate: (BOOL)animate;
+
+/* animate mode is only supported in >=10.4 */
+- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback;
+
+/* animate mode is only supported in >=10.4 */
+- (void)closeAndAnimate: (BOOL)animate;
+
+@end
+
+
+/*****************************************************************************
+ * VLCVideoWindowCommon
+ *
+ *  Common code for main window, detached window and extra video window
+ *****************************************************************************/
+
+@interface VLCVideoWindowCommon : VLCWindow
+{
+    NSRect previousSavedFrame;
+    BOOL b_dark_interface;
+}
+
+@end
\ No newline at end of file
diff --git a/modules/gui/macosx/Windows.m b/modules/gui/macosx/Windows.m
new file mode 100644 (file)
index 0000000..8cb1350
--- /dev/null
@@ -0,0 +1,394 @@
+/*****************************************************************************
+ * Windows.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
+ *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "Windows.h"
+#import "intf.h"
+#import "CoreInteraction.h"
+
+/*****************************************************************************
+ * VLCWindow
+ *
+ *  Missing extension to NSWindow
+ *****************************************************************************/
+
+@implementation VLCWindow
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
+                  backing:(NSBackingStoreType)backingType defer:(BOOL)flag
+{
+    self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
+    if (self) {
+        b_isset_canBecomeKeyWindow = NO;
+        /* we don't want this window to be restored on relaunch */
+        if (!OSX_SNOW_LEOPARD)
+            [self setRestorable:NO];
+    }
+    return self;
+}
+
+- (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
+{
+    b_isset_canBecomeKeyWindow = YES;
+    b_canBecomeKeyWindow = canBecomeKey;
+}
+
+- (BOOL)canBecomeKeyWindow
+{
+    if (b_isset_canBecomeKeyWindow)
+        return b_canBecomeKeyWindow;
+
+    return [super canBecomeKeyWindow];
+}
+
+- (void)setCanBecomeMainWindow: (BOOL)canBecomeMain
+{
+    b_isset_canBecomeMainWindow = YES;
+    b_canBecomeMainWindow = canBecomeMain;
+}
+
+- (BOOL)canBecomeMainWindow
+{
+    if (b_isset_canBecomeMainWindow)
+        return b_canBecomeMainWindow;
+
+    return [super canBecomeMainWindow];
+}
+
+- (void)closeAndAnimate: (BOOL)animate
+{
+    NSInvocation *invoc;
+
+    if (!animate) {
+        [super close];
+        return;
+    }
+
+    invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
+    [invoc setTarget: self];
+
+    if (![self isVisible] || [self alphaValue] == 0.0) {
+        [super close];
+        return;
+    }
+
+    [self orderOut: self animate: YES callback: invoc];
+}
+
+- (void)orderOut: (id)sender animate: (BOOL)animate
+{
+    NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
+    [invoc setTarget: self];
+    [invoc setArgument: sender atIndex: 0];
+    [self orderOut: sender animate: animate callback: invoc];
+}
+
+- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
+{
+    NSViewAnimation *anim;
+    NSViewAnimation *current_anim;
+    NSMutableDictionary *dict;
+
+    if (!animate) {
+        [self orderOut: sender];
+        return;
+    }
+
+    dict = [[NSMutableDictionary alloc] initWithCapacity:2];
+
+    [dict setObject:self forKey:NSViewAnimationTargetKey];
+
+    [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
+    anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
+    [dict release];
+
+    [anim setAnimationBlockingMode:NSAnimationNonblocking];
+    [anim setDuration:0.9];
+    [anim setFrameRate:30];
+    [anim setUserInfo: callback];
+
+    @synchronized(self) {
+        current_anim = self->animation;
+
+        if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating]) {
+            [anim release];
+        } else {
+            if (current_anim) {
+                [current_anim stopAnimation];
+                [anim setCurrentProgress:1.0-[current_anim currentProgress]];
+                [current_anim release];
+            }
+            else
+                [anim setCurrentProgress:1.0 - [self alphaValue]];
+            self->animation = anim;
+            [self setDelegate: self];
+            [anim startAnimation];
+        }
+    }
+}
+
+- (void)orderFront: (id)sender animate: (BOOL)animate
+{
+    NSViewAnimation *anim;
+    NSViewAnimation *current_anim;
+    NSMutableDictionary *dict;
+
+    if (!animate) {
+        [super orderFront: sender];
+        [self setAlphaValue: 1.0];
+        return;
+    }
+
+    if (![self isVisible]) {
+        [self setAlphaValue: 0.0];
+        [super orderFront: sender];
+    }
+    else if ([self alphaValue] == 1.0) {
+        [super orderFront: self];
+        return;
+    }
+
+    dict = [[NSMutableDictionary alloc] initWithCapacity:2];
+
+    [dict setObject:self forKey:NSViewAnimationTargetKey];
+
+    [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
+    anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
+    [dict release];
+
+    [anim setAnimationBlockingMode:NSAnimationNonblocking];
+    [anim setDuration:0.5];
+    [anim setFrameRate:30];
+
+    @synchronized(self) {
+        current_anim = self->animation;
+
+        if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating]) {
+            [anim release];
+        } else {
+            if (current_anim) {
+                [current_anim stopAnimation];
+                [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
+                [current_anim release];
+            }
+            else
+                [anim setCurrentProgress:[self alphaValue]];
+            self->animation = anim;
+            [self setDelegate: self];
+            [self orderFront: sender];
+            [anim startAnimation];
+        }
+    }
+}
+
+- (void)animationDidEnd:(NSAnimation*)anim
+{
+    if ([self alphaValue] <= 0.0) {
+        NSInvocation * invoc;
+        [super orderOut: nil];
+        [self setAlphaValue: 1.0];
+        if ((invoc = [anim userInfo]))
+            [invoc invoke];
+    }
+}
+
+- (IBAction)fullscreen:(id)sender
+{
+    [[VLCCoreInteraction sharedInstance] toggleFullscreen];
+}
+
+@end
+
+
+/*****************************************************************************
+ * VLCVideoWindowCommon
+ *
+ *  Common code for main window, detached window and extra video window
+ *****************************************************************************/
+
+@implementation VLCVideoWindowCommon
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
+                  backing:(NSBackingStoreType)backingType defer:(BOOL)flag
+{
+    b_dark_interface = config_GetInt(VLCIntf, "macosx-interfacestyle");
+
+    if (b_dark_interface) {
+        styleMask = NSBorderlessWindowMask;
+#ifdef MAC_OS_X_VERSION_10_7
+        if (!OSX_SNOW_LEOPARD)
+            styleMask |= NSResizableWindowMask;
+#endif
+    }
+
+    self = [super initWithContentRect:contentRect styleMask:styleMask
+                              backing:backingType defer:flag];
+
+    /* we want to be moveable regardless of our style */
+    [self setMovableByWindowBackground: YES];
+
+    return self;
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+    SEL s_menuAction = [menuItem action];
+
+    if ((s_menuAction == @selector(performClose:)) || (s_menuAction == @selector(performMiniaturize:)) || (s_menuAction == @selector(performZoom:)))
+        return YES;
+
+    return [super validateMenuItem:menuItem];
+}
+
+- (BOOL)windowShouldClose:(id)sender
+{
+    return YES;
+}
+
+- (void)performClose:(id)sender
+{
+    if (!([self styleMask] & NSTitledWindowMask)) {
+        [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowWillCloseNotification object:self];
+
+        [self orderOut: sender];
+    } else
+        [super performClose: sender];
+}
+
+- (void)performMiniaturize:(id)sender
+{
+    if (!([self styleMask] & NSTitledWindowMask))
+        [self miniaturize: sender];
+    else
+        [super performMiniaturize: sender];
+}
+
+- (void)performZoom:(id)sender
+{
+    if (!([self styleMask] & NSTitledWindowMask))
+        [self customZoom: sender];
+    else
+        [super performZoom: sender];
+}
+
+- (void)zoom:(id)sender
+{
+    if (!([self styleMask] & NSTitledWindowMask))
+        [self customZoom: sender];
+    else
+        [super zoom: sender];
+}
+
+/**
+ * Given a proposed frame rectangle, return a modified version
+ * which will fit inside the screen.
+ *
+ * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+.
+ *    Authors:  Scott Christley <scottc@net-community.com>, Venkat Ajjanagadde <venkat@ocbi.com>,
+ *              Felipe A. Rodriguez <far@ix.netcom.com>, Richard Frith-Macdonald <richard@brainstorm.co.uk>
+ *    Copyright (C) 1996 Free Software Foundation, Inc.
+ */
+- (NSRect) customConstrainFrameRect: (NSRect)frameRect toScreen: (NSScreen*)screen
+{
+    NSRect screenRect = [screen visibleFrame];
+    float difference;
+
+    /* Move top edge of the window inside the screen */
+    difference = NSMaxY (frameRect) - NSMaxY (screenRect);
+    if (difference > 0) {
+        frameRect.origin.y -= difference;
+    }
+
+    /* If the window is resizable, resize it (if needed) so that the
+     bottom edge is on the screen or can be on the screen when the user moves
+     the window */
+    difference = NSMaxY (screenRect) - NSMaxY (frameRect);
+    if (_styleMask & NSResizableWindowMask) {
+        float difference2;
+
+        difference2 = screenRect.origin.y - frameRect.origin.y;
+        difference2 -= difference;
+        // Take in account the space between the top of window and the top of the
+        // screen which can be used to move the bottom of the window on the screen
+        if (difference2 > 0) {
+            frameRect.size.height -= difference2;
+            frameRect.origin.y += difference2;
+        }
+
+        /* Ensure that resizing doesn't makewindow smaller than minimum */
+        difference2 = [self minSize].height - frameRect.size.height;
+        if (difference2 > 0) {
+            frameRect.size.height += difference2;
+            frameRect.origin.y -= difference2;
+        }
+    }
+
+    return frameRect;
+}
+
+#define DIST 3
+
+/**
+ Zooms the receiver.   This method calls the delegate method
+ windowShouldZoom:toFrame: to determine if the window should
+ be allowed to zoom to full screen.
+ *
+ * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+.
+ *    Authors:  Scott Christley <scottc@net-community.com>, Venkat Ajjanagadde <venkat@ocbi.com>,
+ *              Felipe A. Rodriguez <far@ix.netcom.com>, Richard Frith-Macdonald <richard@brainstorm.co.uk>
+ *    Copyright (C) 1996 Free Software Foundation, Inc.
+ */
+- (void) customZoom: (id)sender
+{
+    NSRect maxRect = [[self screen] visibleFrame];
+    NSRect currentFrame = [self frame];
+
+    if ([[self delegate] respondsToSelector: @selector(windowWillUseStandardFrame:defaultFrame:)]) {
+        maxRect = [[self delegate] windowWillUseStandardFrame: self defaultFrame: maxRect];
+    }
+
+    maxRect = [self customConstrainFrameRect: maxRect toScreen: [self screen]];
+
+    // Compare the new frame with the current one
+    if ((abs(NSMaxX(maxRect) - NSMaxX(currentFrame)) < DIST)
+        && (abs(NSMaxY(maxRect) - NSMaxY(currentFrame)) < DIST)
+        && (abs(NSMinX(maxRect) - NSMinX(currentFrame)) < DIST)
+        && (abs(NSMinY(maxRect) - NSMinY(currentFrame)) < DIST)) {
+        // Already in zoomed mode, reset user frame, if stored
+        if ([self frameAutosaveName] != nil) {
+            [self setFrame: previousSavedFrame display: YES animate: YES];
+            [self saveFrameUsingName: [self frameAutosaveName]];
+        }
+        return;
+    }
+
+    if ([self frameAutosaveName] != nil) {
+        [self saveFrameUsingName: [self frameAutosaveName]];
+        previousSavedFrame = [self frame];
+    }
+
+    [self setFrame: maxRect display: YES animate: YES];
+}
+
+
+
+@end
index 7c76bb0fdc550ec8c6023f86f57d9cfc7bcc8689..3520d3cde93dc2d7067e2948ba3f4dbec868bce9 100644 (file)
 + (void)unblackoutScreens;
 @end
 
-/*****************************************************************************
- * VLCWindow
- *
- *  Missing extension to NSWindow
- *****************************************************************************/
-
-@interface VLCWindow : NSWindow <NSWindowDelegate>
-{
-    BOOL b_canBecomeKeyWindow;
-    BOOL b_isset_canBecomeKeyWindow;
-    BOOL b_canBecomeMainWindow;
-    BOOL b_isset_canBecomeMainWindow;
-    NSViewAnimation *animation;
-}
-@property (readwrite) BOOL canBecomeKeyWindow;
-@property (readwrite) BOOL canBecomeMainWindow;
-
-/* animate mode is only supported in >=10.4 */
-- (void)orderFront: (id)sender animate: (BOOL)animate;
-
-/* animate mode is only supported in >=10.4 */
-- (void)orderOut: (id)sender animate: (BOOL)animate;
-
-/* animate mode is only supported in >=10.4 */
-- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback;
-
-/* animate mode is only supported in >=10.4 */
-- (void)closeAndAnimate: (BOOL)animate;
-
-@end
-
 
 /*****************************************************************************
  * VLBrushedMetalImageView
index 3cb382b883d85eb5c1964e2ccbac492514c7181e..1d540d95599f516a7109178fb0e62c35d1a3ea73 100644 (file)
@@ -249,198 +249,6 @@ static NSMutableArray *blackoutWindows = NULL;
 
 @end
 
-/*****************************************************************************
- * VLCWindow
- *
- *  Missing extension to NSWindow
- *****************************************************************************/
-
-@implementation VLCWindow
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
-    backing:(NSBackingStoreType)backingType defer:(BOOL)flag
-{
-    self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
-    if ( self ) {
-        b_isset_canBecomeKeyWindow = NO;
-        /* we don't want this window to be restored on relaunch */
-        if (!OSX_SNOW_LEOPARD)
-            [self setRestorable:NO];
-    }
-    return self;
-}
-
-- (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
-{
-    b_isset_canBecomeKeyWindow = YES;
-    b_canBecomeKeyWindow = canBecomeKey;
-}
-
-- (BOOL)canBecomeKeyWindow
-{
-    if (b_isset_canBecomeKeyWindow)
-        return b_canBecomeKeyWindow;
-
-    return [super canBecomeKeyWindow];
-}
-
-- (void)setCanBecomeMainWindow: (BOOL)canBecomeMain
-{
-    b_isset_canBecomeMainWindow = YES;
-    b_canBecomeMainWindow = canBecomeMain;
-}
-
-- (BOOL)canBecomeMainWindow
-{
-    if (b_isset_canBecomeMainWindow)
-        return b_canBecomeMainWindow;
-
-    return [super canBecomeMainWindow];
-}
-
-- (void)closeAndAnimate: (BOOL)animate
-{
-    NSInvocation *invoc;
-
-    if (!animate) {
-        [super close];
-        return;
-    }
-
-    invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
-    [invoc setTarget: self];
-
-    if (![self isVisible] || [self alphaValue] == 0.0) {
-        [super close];
-        return;
-    }
-
-    [self orderOut: self animate: YES callback: invoc];
-}
-
-- (void)orderOut: (id)sender animate: (BOOL)animate
-{
-    NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
-    [invoc setTarget: self];
-    [invoc setArgument: sender atIndex: 0];
-    [self orderOut: sender animate: animate callback: invoc];
-}
-
-- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
-{
-    NSViewAnimation *anim;
-    NSViewAnimation *current_anim;
-    NSMutableDictionary *dict;
-
-    if (!animate) {
-        [self orderOut: sender];
-        return;
-    }
-
-    dict = [[NSMutableDictionary alloc] initWithCapacity:2];
-
-    [dict setObject:self forKey:NSViewAnimationTargetKey];
-
-    [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
-    anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
-    [dict release];
-
-    [anim setAnimationBlockingMode:NSAnimationNonblocking];
-    [anim setDuration:0.9];
-    [anim setFrameRate:30];
-    [anim setUserInfo: callback];
-
-    @synchronized(self) {
-        current_anim = self->animation;
-
-        if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating]) {
-            [anim release];
-        } else {
-            if (current_anim) {
-                [current_anim stopAnimation];
-                [anim setCurrentProgress:1.0-[current_anim currentProgress]];
-                [current_anim release];
-            }
-            else
-                [anim setCurrentProgress:1.0 - [self alphaValue]];
-            self->animation = anim;
-            [self setDelegate: self];
-            [anim startAnimation];
-        }
-    }
-}
-
-- (void)orderFront: (id)sender animate: (BOOL)animate
-{
-    NSViewAnimation *anim;
-    NSViewAnimation *current_anim;
-    NSMutableDictionary *dict;
-
-    if (!animate) {
-        [super orderFront: sender];
-        [self setAlphaValue: 1.0];
-        return;
-    }
-
-    if (![self isVisible]) {
-        [self setAlphaValue: 0.0];
-        [super orderFront: sender];
-    }
-    else if ([self alphaValue] == 1.0) {
-        [super orderFront: self];
-        return;
-    }
-
-    dict = [[NSMutableDictionary alloc] initWithCapacity:2];
-
-    [dict setObject:self forKey:NSViewAnimationTargetKey];
-
-    [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
-    anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
-    [dict release];
-
-    [anim setAnimationBlockingMode:NSAnimationNonblocking];
-    [anim setDuration:0.5];
-    [anim setFrameRate:30];
-
-    @synchronized(self) {
-        current_anim = self->animation;
-
-        if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating]) {
-            [anim release];
-        } else {
-            if (current_anim) {
-                [current_anim stopAnimation];
-                [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
-                [current_anim release];
-            }
-            else
-                [anim setCurrentProgress:[self alphaValue]];
-            self->animation = anim;
-            [self setDelegate: self];
-            [self orderFront: sender];
-            [anim startAnimation];
-        }
-    }
-}
-
-- (void)animationDidEnd:(NSAnimation*)anim
-{
-    if ([self alphaValue] <= 0.0) {
-        NSInvocation * invoc;
-        [super orderOut: nil];
-        [self setAlphaValue: 1.0];
-        if ((invoc = [anim userInfo]))
-            [invoc invoke];
-    }
-}
-
-- (IBAction)fullscreen:(id)sender
-{
-    [[VLCCoreInteraction sharedInstance] toggleFullscreen];
-}
-
-@end
-
 /*****************************************************************************
  * VLBrushedMetalImageView
  *****************************************************************************/