1 /*****************************************************************************
2 * MainWindowTitle.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2011-2012 Felix Paul Kühne
7 * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #import <vlc_common.h>
26 #import "MainWindowTitle.h"
27 #import "CoreInteraction.h"
28 #import "CompatibilityFixes.h"
30 /*****************************************************************************
31 * VLCMainWindowTitleView
33 * this is our title bar, which can do anything a title should do
34 * it relies on the VLCWindowButtonCell to display the correct traffic light
35 * states, since we can't capture the mouse-moved events here correctly
36 *****************************************************************************/
38 @implementation VLCMainWindowTitleView
41 [[NSNotificationCenter defaultCenter] removeObserver: self];
44 [o_red_over_img release];
45 [o_red_on_img release];
46 [o_yellow_img release];
47 [o_yellow_over_img release];
48 [o_yellow_on_img release];
49 [o_green_img release];
50 [o_green_over_img release];
51 [o_green_on_img release];
58 [self setAutoresizesSubviews: YES];
59 [self setImagesLeft:[NSImage imageNamed:@"topbar-dark-left"] middle: [NSImage imageNamed:@"topbar-dark-center-fill"] right:[NSImage imageNamed:@"topbar-dark-right"]];
61 [self loadButtonIcons];
62 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(controlTintChanged:) name: NSControlTintDidChangeNotification object: nil];
64 [o_red_btn setImage: o_red_img];
65 [o_red_btn setAlternateImage: o_red_on_img];
66 [[o_red_btn cell] setShowsBorderOnlyWhileMouseInside: YES];
67 [[o_red_btn cell] setTag: 0];
68 [o_yellow_btn setImage: o_yellow_img];
69 [o_yellow_btn setAlternateImage: o_yellow_on_img];
70 [[o_yellow_btn cell] setShowsBorderOnlyWhileMouseInside: YES];
71 [[o_yellow_btn cell] setTag: 1];
72 [o_green_btn setImage: o_green_img];
73 [o_green_btn setAlternateImage: o_green_on_img];
74 [[o_green_btn cell] setShowsBorderOnlyWhileMouseInside: YES];
75 [[o_green_btn cell] setTag: 2];
76 [o_fullscreen_btn setImage: [NSImage imageNamed:@"window-fullscreen"]];
77 [o_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"window-fullscreen-on"]];
78 [[o_fullscreen_btn cell] setShowsBorderOnlyWhileMouseInside: YES];
79 [[o_fullscreen_btn cell] setTag: 3];
82 - (void)controlTintChanged:(NSNotification *)notification
85 [o_red_over_img release];
86 [o_red_on_img release];
87 [o_yellow_img release];
88 [o_yellow_over_img release];
89 [o_yellow_on_img release];
90 [o_green_img release];
91 [o_green_over_img release];
92 [o_green_on_img release];
94 [self loadButtonIcons];
96 [o_red_btn setNeedsDisplay];
97 [o_yellow_btn setNeedsDisplay];
98 [o_green_btn setNeedsDisplay];
101 - (void)loadButtonIcons
105 if( [NSColor currentControlTint] == NSBlueControlTint )
107 o_red_img = [[NSImage imageNamed:@"lion-window-close"] retain];
108 o_red_over_img = [[NSImage imageNamed:@"lion-window-close-over"] retain];
109 o_red_on_img = [[NSImage imageNamed:@"lion-window-close-on"] retain];
110 o_yellow_img = [[NSImage imageNamed:@"lion-window-minimize"] retain];
111 o_yellow_over_img = [[NSImage imageNamed:@"lion-window-minimize-over"] retain];
112 o_yellow_on_img = [[NSImage imageNamed:@"lion-window-minimize-on"] retain];
113 o_green_img = [[NSImage imageNamed:@"lion-window-zoom"] retain];
114 o_green_over_img = [[NSImage imageNamed:@"lion-window-zoom-over"] retain];
115 o_green_on_img = [[NSImage imageNamed:@"lion-window-zoom-on"] retain];
117 o_red_img = [[NSImage imageNamed:@"lion-window-close-graphite"] retain];
118 o_red_over_img = [[NSImage imageNamed:@"lion-window-close-over-graphite"] retain];
119 o_red_on_img = [[NSImage imageNamed:@"lion-window-close-on-graphite"] retain];
120 o_yellow_img = [[NSImage imageNamed:@"lion-window-minimize-graphite"] retain];
121 o_yellow_over_img = [[NSImage imageNamed:@"lion-window-minimize-over-graphite"] retain];
122 o_yellow_on_img = [[NSImage imageNamed:@"lion-window-minimize-on-graphite"] retain];
123 o_green_img = [[NSImage imageNamed:@"lion-window-zoom-graphite"] retain];
124 o_green_over_img = [[NSImage imageNamed:@"lion-window-zoom-over-graphite"] retain];
125 o_green_on_img = [[NSImage imageNamed:@"lion-window-zoom-on-graphite"] retain];
128 if( [NSColor currentControlTint] == NSBlueControlTint )
130 o_red_img = [[NSImage imageNamed:@"snowleo-window-close"] retain];
131 o_red_over_img = [[NSImage imageNamed:@"snowleo-window-close-over"] retain];
132 o_red_on_img = [[NSImage imageNamed:@"snowleo-window-close-on"] retain];
133 o_yellow_img = [[NSImage imageNamed:@"snowleo-window-minimize"] retain];
134 o_yellow_over_img = [[NSImage imageNamed:@"snowleo-window-minimize-over"] retain];
135 o_yellow_on_img = [[NSImage imageNamed:@"snowleo-window-minimize-on"] retain];
136 o_green_img = [[NSImage imageNamed:@"snowleo-window-zoom"] retain];
137 o_green_over_img = [[NSImage imageNamed:@"snowleo-window-zoom-over"] retain];
138 o_green_on_img = [[NSImage imageNamed:@"snowleo-window-zoom-on"] retain];
140 o_red_img = [[NSImage imageNamed:@"snowleo-window-close-graphite"] retain];
141 o_red_over_img = [[NSImage imageNamed:@"snowleo-window-close-over-graphite"] retain];
142 o_red_on_img = [[NSImage imageNamed:@"snowleo-window-close-on-graphite"] retain];
143 o_yellow_img = [[NSImage imageNamed:@"snowleo-window-minimize-graphite"] retain];
144 o_yellow_over_img = [[NSImage imageNamed:@"snowleo-window-minimize-over-graphite"] retain];
145 o_yellow_on_img = [[NSImage imageNamed:@"snowleo-window-minimize-on-graphite"] retain];
146 o_green_img = [[NSImage imageNamed:@"snowleo-window-zoom-graphite"] retain];
147 o_green_over_img = [[NSImage imageNamed:@"snowleo-window-zoom-over-graphite"] retain];
148 o_green_on_img = [[NSImage imageNamed:@"snowleo-window-zoom-on-graphite"] retain];
153 - (BOOL)mouseDownCanMoveWindow
158 - (IBAction)buttonAction:(id)sender
160 if (sender == o_red_btn)
161 [[self window] performClose: sender];
162 else if (sender == o_yellow_btn)
163 [[self window] miniaturize: sender];
164 else if (sender == o_green_btn)
165 [[self window] performZoom: sender];
166 else if (sender == o_fullscreen_btn)
167 [[VLCCoreInteraction sharedInstance] toggleFullscreen];
169 msg_Err( VLCIntf, "unknown button action sender" );
171 [self setWindowButtonOver: NO];
172 [self setWindowFullscreenButtonOver: NO];
175 - (void)setWindowTitle:(NSString *)title
177 [o_title_lbl setStringValue: title];
180 - (void)setFullscreenButtonHidden:(BOOL)b_value
182 [o_fullscreen_btn setHidden: b_value];
185 - (void)setWindowButtonOver:(BOOL)b_value
189 [o_red_btn setImage: o_red_over_img];
190 [o_yellow_btn setImage: o_yellow_over_img];
191 [o_green_btn setImage: o_green_over_img];
195 [o_red_btn setImage: o_red_img];
196 [o_yellow_btn setImage: o_yellow_img];
197 [o_green_btn setImage: o_green_img];
201 - (void)setWindowFullscreenButtonOver:(BOOL)b_value
204 [o_fullscreen_btn setImage: [NSImage imageNamed:@"window-fullscreen-over"]];
206 [o_fullscreen_btn setImage: [NSImage imageNamed:@"window-fullscreen"]];
210 /*****************************************************************************
211 * VLCWindowButtonCell
213 * since the title bar cannot fetch these mouse events (the more top-level
214 * NSButton is unable fetch them as well), we are using a subclass of the
215 * button cell to do so. It's set in the nib for the respective objects.
216 *****************************************************************************/
218 @implementation VLCWindowButtonCell
220 - (void)mouseEntered:(NSEvent *)theEvent
223 [(VLCMainWindowTitleView *)[[self controlView] superview] setWindowFullscreenButtonOver: YES];
225 [(VLCMainWindowTitleView *)[[self controlView] superview] setWindowButtonOver: YES];
228 - (void)mouseExited:(NSEvent *)theEvent
231 [(VLCMainWindowTitleView *)[[self controlView] superview] setWindowFullscreenButtonOver: NO];
233 [(VLCMainWindowTitleView *)[[self controlView] superview] setWindowButtonOver: NO];
239 /*****************************************************************************
242 * For Leopard and Snow Leopard, we need to emulate the resize control on the
243 * bottom right of the window, since it is gone by using the borderless window
244 * mask. A proper fix would be Lion-only.
245 *****************************************************************************/
247 @implementation VLCResizeControl
249 - (void)mouseDragged:(NSEvent *)theEvent
251 NSRect windowFrame = [[self window] frame];
252 CGFloat deltaX, deltaY, oldOriginY;
253 deltaX = [theEvent deltaX];
254 deltaY = [theEvent deltaY];
255 oldOriginY = windowFrame.origin.y;
257 windowFrame.origin.y = (oldOriginY + windowFrame.size.height) - (windowFrame.size.height + deltaY);
258 windowFrame.size.width += deltaX;
259 windowFrame.size.height += deltaY;
261 NSSize winMinSize = [self window].minSize;
262 if (windowFrame.size.width < winMinSize.width)
263 windowFrame.size.width = winMinSize.width;
265 if (windowFrame.size.height < winMinSize.height)
267 windowFrame.size.height = winMinSize.height;
268 windowFrame.origin.y = oldOriginY;
271 [[self window] setFrame: windowFrame display: YES animate: NO];
276 /*****************************************************************************
279 * since we are using a clear window color when using the black window
280 * style, some filling is needed behind the video and some other elements
281 *****************************************************************************/
283 @implementation VLCColorView
285 - (void)drawRect:(NSRect)rect {
286 [[NSColor blackColor] setFill];