Commit 74dd47f9 authored by Alexandre Lision's avatar Alexandre Lision

video: add incall features

- fullscreen
- drag and drop of video files
- switch cameras

Refs #67611

Change-Id: I7c6ec7662d7064675a87054d1cf450e2ff3fa2b6
parent e6dbf094
......@@ -48,7 +48,9 @@ SET(ringclient_SRCS
src/GeneralPrefsVC.mm
src/RingWizardWC.mm
src/HistoryViewController.mm
src/views/CallView.mm
src/backends/MinimalHistoryBackend.mm)
SET(ringclient_XIBS
......@@ -87,7 +89,9 @@ SET(ringclient_HDRS
src/HistoryViewController.h
src/RingWizardWC.h
src/QNSTreeController.h
src/views/CallView.h
src/backends/MinimalHistoryBackend.h)
# Icons
......
......@@ -38,10 +38,11 @@
#import <qabstractitemmodel.h>
#import <QItemSelectionModel>
#import <QItemSelection>
#import <video/previewmanager.h>
#import <video/renderer.h>
#import "views/CallView.h"
/** FrameReceiver class - delegate for AVCaptureSession
*/
@interface RendererConnectionsHolder : NSObject
......@@ -70,7 +71,7 @@
@property QHash<int, NSButton*> actionHash;
// Video
@property (assign) IBOutlet NSView *videoView;
@property (assign) IBOutlet CallView *videoView;
@property CALayer* videoLayer;
@property (assign) IBOutlet NSView *previewView;
@property CALayer* previewLayer;
......@@ -141,27 +142,36 @@
break;
case Call::State::INITIALIZATION:
[stateLabel setStringValue:@"Initializing"];
[videoView setShouldAcceptInteractions:NO];
break;
case Call::State::RINGING:
[stateLabel setStringValue:@"Ringing"];
[videoView setShouldAcceptInteractions:NO];
break;
case Call::State::CURRENT:
[stateLabel setStringValue:@"Current"];
[videoView setShouldAcceptInteractions:YES];
break;
case Call::State::HOLD:
[stateLabel setStringValue:@"On Hold"];
[videoView setShouldAcceptInteractions:NO];
break;
case Call::State::BUSY:
[stateLabel setStringValue:@"Busy"];
[videoView setShouldAcceptInteractions:NO];
break;
case Call::State::OVER:
[stateLabel setStringValue:@"Finished"];
[videoView setShouldAcceptInteractions:NO];
if(videoView.isInFullScreenMode)
[videoView exitFullScreenModeWithOptions:nil];
break;
case Call::State::ABORTED:
[stateLabel setStringValue:@"Aborted"];
break;
case Call::State::FAILURE:
[stateLabel setStringValue:@"Failure"];
[videoView setShouldAcceptInteractions:NO];
break;
case Call::State::INCOMING:
[stateLabel setStringValue:@"Incoming"];
......
/*
* Copyright (C) 2015 Savoir-Faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.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 3 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.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#import <Cocoa/Cocoa.h>
@interface CallView : NSView <NSDraggingDestination, NSOpenSavePanelDelegate>
{
//highlight the drop zone
BOOL highlight;
}
- (id)initWithCoder:(NSCoder *)coder;
/**
* Sets weither this view allow first click interactions
*/
@property BOOL shouldAcceptInteractions;
@end
/*
* Copyright (C) 2015 Savoir-Faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.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 3 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.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#import "CallView.h"
#import <QItemSelectionModel>
#import <QAbstractProxyModel>
#import <QUrl>
#import <video/configurationproxy.h>
#import <video/sourcemodel.h>
#import <video/previewmanager.h>
#import <video/renderer.h>
#import <video/device.h>
#import <video/devicemodel.h>
@interface CallView ()
@property NSMenu *contextualMenu;
@end
@implementation CallView
@synthesize contextualMenu;
@synthesize shouldAcceptInteractions;
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
}
return self;
}
#pragma mark - Destination Operations
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
/*------------------------------------------------------
method called whenever a drag enters our drop zone
--------------------------------------------------------*/
NSLog(@"Dragging entered");
NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
CFStringRef fileExtension = (CFStringRef) [fileURL.path pathExtension];
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
// Check if the pasteboard contains image data and source/user wants it copied
if ( [sender draggingSourceOperationMask] & NSDragOperationCopy &&
(UTTypeConformsTo(fileUTI, kUTTypeVideo)) || (UTTypeConformsTo(fileUTI, kUTTypeMovie))) {
//highlight our drop zone
highlight=YES;
[self setNeedsDisplay: YES];
/* When an image from one window is dragged over another, we want to resize the dragging item to
* preview the size of the image as it would appear if the user dropped it in. */
[sender enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:self
classes:[NSArray arrayWithObject:[NSPasteboardItem class]]
searchOptions:nil
usingBlock:^(NSDraggingItem *draggingItem, NSInteger idx, BOOL *stop) {
*stop = YES;
}];
//accept data as a copy operation
return NSDragOperationCopy;
}
return NSDragOperationNone;
}
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
/*------------------------------------------------------
method called whenever a drag exits our drop zone
--------------------------------------------------------*/
//remove highlight of the drop zone
highlight=NO;
[self setNeedsDisplay: YES];
}
-(void)drawRect:(NSRect)rect
{
/*------------------------------------------------------
draw method is overridden to do drop highlighing
--------------------------------------------------------*/
//do the usual draw operation to display the image
[super drawRect:rect];
if ( highlight ) {
//highlight by overlaying a gray border
[[NSColor blueColor] set];
[NSBezierPath setDefaultLineWidth: 5];
[NSBezierPath strokeRect: rect];
}
}
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
/*------------------------------------------------------
method to determine if we can accept the drop
--------------------------------------------------------*/
//finished with the drag so remove any highlighting
highlight=NO;
[self setNeedsDisplay: YES];
NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
CFStringRef fileExtension = (CFStringRef) [fileURL.path pathExtension];
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
//check to see if we can accept the data
return (UTTypeConformsTo(fileUTI, kUTTypeVideo)) || (UTTypeConformsTo(fileUTI, kUTTypeMovie));
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
/*------------------------------------------------------
method that should handle the drop data
--------------------------------------------------------*/
if ( [sender draggingSource] != self ) {
NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
Video::SourceModel::instance()->setFile(QUrl::fromLocalFile(QString::fromUtf8([fileURL.path UTF8String])));
}
return YES;
}
- (void)showContextualMenu:(NSEvent *)theEvent {
contextualMenu = [[NSMenu alloc] initWithTitle:@"Switch camera"];
for(int i = 0 ; i < Video::DeviceModel::instance()->devices().size() ; ++i) {
Video::Device* device = Video::DeviceModel::instance()->devices()[i];
[contextualMenu insertItemWithTitle:device->name().toNSString() action:@selector(switchInput:) keyEquivalent:@"" atIndex:i];
}
[contextualMenu addItem:[NSMenuItem separatorItem]];
[contextualMenu insertItemWithTitle:@"Choose file" action:@selector(chooseFile:) keyEquivalent:@"" atIndex:contextualMenu.itemArray.count];
[NSMenu popUpContextMenu:contextualMenu withEvent:theEvent forView:self];
}
- (void)mouseUp:(NSEvent *)theEvent
{
if([theEvent clickCount] == 1 && shouldAcceptInteractions) {
if(!contextualMenu)
[self performSelector:@selector(showContextualMenu:) withObject:theEvent afterDelay:[NSEvent doubleClickInterval]];
else
contextualMenu = nil;
}
else if([theEvent clickCount] == 2)
{
[NSObject cancelPreviousPerformRequestsWithTarget:self]; // cancel showContextualMenu
if(self.isInFullScreenMode)
[self exitFullScreenModeWithOptions:nil];
else {
NSApplicationPresentationOptions options = NSApplicationPresentationDefault + NSApplicationPresentationAutoHideDock +
NSApplicationPresentationAutoHideMenuBar + NSApplicationPresentationAutoHideToolbar;
NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:options], NSFullScreenModeApplicationPresentationOptions, nil];
[self enterFullScreenMode:[NSScreen mainScreen] withOptions:opts];
}
}
}
- (void) switchInput:(NSMenuItem*) sender
{
int index = [contextualMenu indexOfItem:sender];
Video::SourceModel::instance()->switchTo(Video::DeviceModel::instance()->devices()[index]);
}
- (void) chooseFile:(NSMenuItem*) sender
{
NSOpenPanel *browsePanel = [[NSOpenPanel alloc] init];
[browsePanel setDirectoryURL:[NSURL URLWithString:NSHomeDirectory()]];
[browsePanel setCanChooseFiles:YES];
[browsePanel setCanChooseDirectories:NO];
[browsePanel setCanCreateDirectories:NO];
//NSMutableArray* fileTypes = [[NSMutableArray alloc] initWithArray:[NSImage imageTypes]];
NSMutableArray* fileTypes = [NSMutableArray array];
[fileTypes addObject:(__bridge NSString *)kUTTypeVideo];
[fileTypes addObject:(__bridge NSString *)kUTTypeMovie];
[browsePanel setAllowedFileTypes:fileTypes];
[browsePanel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton) {
NSURL* theDoc = [[browsePanel URLs] objectAtIndex:0];
Video::SourceModel::instance()->setFile(QUrl::fromLocalFile(QString::fromUtf8([theDoc.path UTF8String])));
}
}];
}
@end
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment