VideoView.m 9.47 KB
Newer Older
1
/*****************************************************************************
2
 * VideoView.m: MacOS X video output module
3
 *****************************************************************************
4
 * Copyright (C) 2002-2012 VLC authors and VideoLAN
bigben's avatar
...  
bigben committed
5
 * $Id$
6
 *
7
 * Authors: Derk-Jan Hartman <hartman at videolan dot org>
8
 *          Eric Petit <titer@m0k.org>
9
 *          Benjamin Pracht <bigben at videolan dot org>
10
 *          Pierre d'Herbemont <pdherbemont # videolan org>
11
 *          Felix Paul Kühne <fkuehne at videolan dot org>
12 13 14 15 16
 *
 * 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.
17
 *
18 19 20 21 22 23 24
 * 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
dionoea's avatar
dionoea committed
25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 27 28 29 30
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
31 32 33 34
#import <stdlib.h>                                                 /* free() */
#import <string.h>

#import "intf.h"
35
#import "VideoView.h"
36 37
#import "CoreInteraction.h"
#import "MainMenu.h"
38
#import "MainWindow.h"
39 40 41

#import <vlc_common.h>
#import <vlc_keys.h>
42

43

44 45 46 47
/*****************************************************************************
 * VLCVoutView implementation
 *****************************************************************************/
@implementation VLCVoutView
48 49 50 51 52 53 54 55 56 57

#pragma mark -
#pragma mark drag & drop support

- (void)dealloc
{
    [self unregisterDraggedTypes];
    [super dealloc];
}

58
-(id)initWithFrame:(NSRect)frameRect
59
{
60 61 62
    if (self = [super initWithFrame:frameRect]) {
        [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
    }
63

64
    i_lastScrollWheelDirection = 0;
65
    f_cumulated_magnification = 0.0;
66 67

    return self;
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
}

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
    if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
        return NSDragOperationGeneric;
    return NSDragOperationNone;
}

- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
    return YES;
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
    BOOL b_returned;
    b_returned = [[VLCCoreInteraction sharedInstance] performDragOperation: sender];

    [self setNeedsDisplay:YES];
    return b_returned;
}

- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
    [self setNeedsDisplay:YES];
}

#pragma mark -
#pragma mark vout actions

99 100 101
- (void)keyDown:(NSEvent *)o_event
{
    unichar key = 0;
102
    vlc_value_t val;
103
    unsigned int i_pressed_modifiers = 0;
104
    val.i_int = 0;
105

106
    i_pressed_modifiers = [o_event modifierFlags];
107

108
    if (i_pressed_modifiers & NSShiftKeyMask)
109
        val.i_int |= KEY_MODIFIER_SHIFT;
110
    if (i_pressed_modifiers & NSControlKeyMask)
111
        val.i_int |= KEY_MODIFIER_CTRL;
112
    if (i_pressed_modifiers & NSAlternateKeyMask)
113
        val.i_int |= KEY_MODIFIER_ALT;
114
    if (i_pressed_modifiers & NSCommandKeyMask)
115
        val.i_int |= KEY_MODIFIER_COMMAND;
116

117
    NSString * characters = [o_event charactersIgnoringModifiers];
118
    if ([characters length] > 0) {
119 120
        key = [[characters lowercaseString] characterAtIndex: 0];

121
        if (key) {
122 123
            vout_thread_t * p_vout = getVout();
            /* Escape should always get you out of fullscreen */
124 125 126
            if (key == (unichar) 0x1b) {
                playlist_t * p_playlist = pl_Get(VLCIntf);
                 if (var_GetBool(p_playlist, "fullscreen"))
127
                     [[VLCCoreInteraction sharedInstance] toggleFullscreen];
128
            }
129
            /* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
130
            else if (key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask)
131
                [[VLCCoreInteraction sharedInstance] toggleFullscreen];
132 133
            else if (p_vout) {
                if (key == ' ')
134
                    [[VLCCoreInteraction sharedInstance] play];
135 136 137
                else {
                    val.i_int |= (int)CocoaKeyToVLC(key);
                    var_Set(p_vout->p_libvlc, "key-pressed", val);
138
                }
139
            }
140
            else
141
                msg_Dbg(VLCIntf, "could not send keyevent to VLC core");
142

143
            if (p_vout)
144
                vlc_object_release(p_vout);
145 146 147

            return;
        }
148
    }
149
    [super keyDown: o_event];
150 151
}

152 153 154 155 156
- (BOOL)performKeyEquivalent:(NSEvent *)o_event
{
    return [[VLCMainWindow sharedInstance] performKeyEquivalent: o_event];
}

157
- (void)mouseDown:(NSEvent *)o_event
158
{
159 160
    if (([o_event type] == NSLeftMouseDown) && (! ([o_event modifierFlags] &  NSControlKeyMask))) {
        if ([o_event clickCount] > 1)
161
            [[VLCCoreInteraction sharedInstance] toggleFullscreen];
162 163 164
    } else if (([o_event type] == NSRightMouseDown) ||
               (([o_event type] == NSLeftMouseDown) &&
               ([o_event modifierFlags] &  NSControlKeyMask)))
165
        [NSMenu popUpContextMenu: [[VLCMainMenu sharedInstance] voutMenu] withEvent: o_event forView: self];
166 167

    [super mouseDown: o_event];
168 169 170 171
}

- (void)rightMouseDown:(NSEvent *)o_event
{
172
    if ([o_event type] == NSRightMouseDown)
173
        [NSMenu popUpContextMenu: [[VLCMainMenu sharedInstance] voutMenu] withEvent: o_event forView: self];
174 175

    [super mouseDown: o_event];
176 177 178 179
}

- (void)rightMouseUp:(NSEvent *)o_event
{
180
    if ([o_event type] == NSRightMouseUp)
181
        [NSMenu popUpContextMenu: [[VLCMainMenu sharedInstance] voutMenu] withEvent: o_event forView: self];
182 183

    [super mouseUp: o_event];
184 185 186 187
}

- (void)mouseMoved:(NSEvent *)o_event
{
188
    NSPoint ml = [self convertPoint: [o_event locationInWindow] fromView: nil];
189
    if ([self mouse: ml inRect: [self bounds]])
190 191
        [[VLCMain sharedInstance] showFullscreenController];

192
    [super mouseMoved: o_event];
193 194
}

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
- (void)resetScrollWheelDirection
{
    /* release the scroll direction 0.8 secs after the last event */
    if (([NSDate timeIntervalSinceReferenceDate] - t_lastScrollEvent) >= 0.80)
        i_lastScrollWheelDirection = 0;
}

- (void)scrollWheel:(NSEvent *)theEvent
{
    intf_thread_t * p_intf = VLCIntf;
    CGFloat f_deltaX = [theEvent deltaX];
    CGFloat f_deltaY = [theEvent deltaY];

    if (!OSX_SNOW_LEOPARD && [theEvent isDirectionInvertedFromDevice]) {
        f_deltaX = -f_deltaX;
        f_deltaY = -f_deltaY;
    }

    CGFloat f_yabsvalue = f_deltaY > 0.0f ? f_deltaY : -f_deltaY;
    CGFloat f_xabsvalue = f_deltaX > 0.0f ? f_deltaX : -f_deltaX;

    int i_yvlckey, i_xvlckey = 0;
    if (f_deltaY < 0.0f)
        i_yvlckey = KEY_MOUSEWHEELDOWN;
    else
        i_yvlckey = KEY_MOUSEWHEELUP;
    
    if (f_deltaX < 0.0f)
        i_xvlckey = KEY_MOUSEWHEELRIGHT;
    else
        i_xvlckey = KEY_MOUSEWHEELLEFT;

    /* in the following, we're forwarding either a x or a y event */
    /* Multiple key events are send depending on the intensity of the event */
    /* the opposite direction is being blocked for 0.8 secs */
    if (f_yabsvalue > 0.05) {
        if (i_lastScrollWheelDirection < 0) // last was a X
            return;

        i_lastScrollWheelDirection = 1; // Y
        for (NSUInteger i = 0; i < (int)(f_yabsvalue/4.+1.); i++)
            var_SetInteger(p_intf->p_libvlc, "key-pressed", i_yvlckey);

        t_lastScrollEvent = [NSDate timeIntervalSinceReferenceDate];
        [self performSelector:@selector(resetScrollWheelDirection)
                   withObject: NULL
                   afterDelay:1.00];
        return;
    }
    if (f_xabsvalue > 0.05) {
        if (i_lastScrollWheelDirection > 0) // last was a Y
            return;

        i_lastScrollWheelDirection = -1; // X
        for (NSUInteger i = 0; i < (int)(f_xabsvalue/6.+1.); i++)
            var_SetInteger(p_intf->p_libvlc, "key-pressed", i_xvlckey);

        t_lastScrollEvent = [NSDate timeIntervalSinceReferenceDate];
        [self performSelector:@selector(resetScrollWheelDirection)
                   withObject: NULL
                   afterDelay:1.00];
    }
}

259 260 261 262 263
- (BOOL)mouseDownCanMoveWindow
{
    return YES;
}

Eric Petit's avatar
Eric Petit committed
264 265 266
- (BOOL)acceptsFirstResponder
{
    return YES;
267 268
}

Eric Petit's avatar
Eric Petit committed
269
- (BOOL)becomeFirstResponder
270
{
Eric Petit's avatar
Eric Petit committed
271
    return YES;
272 273
}

Eric Petit's avatar
Eric Petit committed
274
- (BOOL)resignFirstResponder
275
{
276 277
    /* while we need to be the first responder most of the time, we need to give up that status when toggling the playlist */
    return YES;
Eric Petit's avatar
Eric Petit committed
278
}
279 280 281 282 283 284

-(void)didAddSubview:(NSView *)subview
{
    [[self window] makeFirstResponder: subview];
}

285 286 287
- (void)magnifyWithEvent:(NSEvent *)event
{
    f_cumulated_magnification += [event magnification];
288 289 290 291

    // This is the result of [NSEvent standardMagnificationThreshold].
    // Unfortunately, this is a private API, currently.
    CGFloat f_threshold = 0.3;
292
    BOOL b_fullscreen = [[VLCMainWindow sharedInstance] fullscreen];
293

294
    if ((f_cumulated_magnification > f_threshold && !b_fullscreen) || (f_cumulated_magnification < -f_threshold && b_fullscreen)) {
295 296 297 298 299 300 301 302 303 304
        f_cumulated_magnification = 0.0;
        [[VLCCoreInteraction sharedInstance] toggleFullscreen];
    }
}

- (void)beginGestureWithEvent:(NSEvent *)event
{
    f_cumulated_magnification = 0.0;
}

305
@end