| /* |
| * Copyright (C) 2015-2016 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. |
| */ |
| #import "VideoPrefsVC.h" |
| |
| #import <QuartzCore/QuartzCore.h> |
| |
| #import <QItemSelectionModel> |
| #import <QAbstractProxyModel> |
| |
| #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 VideoPrefsVC () |
| |
| @property (assign) IBOutlet NSView *previewView; |
| @property (assign) IBOutlet NSPopUpButton *videoDevicesList; |
| @property (assign) IBOutlet NSPopUpButton *sizesList; |
| @property (assign) IBOutlet NSPopUpButton *ratesList; |
| |
| @property BOOL shouldHandlePreview; |
| |
| @end |
| |
| @implementation VideoPrefsVC |
| @synthesize previewView; |
| @synthesize videoDevicesList; |
| @synthesize sizesList; |
| @synthesize ratesList; |
| |
| QMetaObject::Connection frameUpdated; |
| QMetaObject::Connection previewStarted; |
| QMetaObject::Connection previewStopped; |
| |
| - (void)loadView |
| { |
| [super loadView]; |
| |
| Video::ConfigurationProxy::deviceModel().rowCount(); |
| Video::ConfigurationProxy::resolutionModel().rowCount(); |
| Video::ConfigurationProxy::rateModel().rowCount(); |
| |
| QModelIndex qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel().currentIndex(); |
| qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel().currentIndex(); |
| |
| [videoDevicesList addItemWithTitle:Video::ConfigurationProxy::deviceModel().data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()]; |
| |
| QModelIndex qSizeIdx = Video::ConfigurationProxy::resolutionSelectionModel().currentIndex(); |
| [sizesList addItemWithTitle:Video::ConfigurationProxy::resolutionModel().data(qSizeIdx, Qt::DisplayRole).toString().toNSString()]; |
| |
| if(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::resolutionModel())) { |
| QObject::connect(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::resolutionModel()), |
| &QAbstractProxyModel::modelReset, |
| [=]() { |
| NSLog(@"resolution Source model changed!!!"); |
| }); |
| |
| } |
| |
| QModelIndex qRate = Video::ConfigurationProxy::rateSelectionModel().currentIndex(); |
| [ratesList addItemWithTitle:Video::ConfigurationProxy::rateModel().data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()]; |
| |
| if(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::rateModel())) { |
| QObject::connect(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::rateModel()), |
| &QAbstractProxyModel::modelReset, |
| [=]() { |
| NSLog(@"rates Source model changed!!!"); |
| }); |
| |
| } |
| |
| [previewView setWantsLayer:YES]; |
| [previewView setLayer:[CALayer layer]]; |
| [previewView.layer setBackgroundColor:[NSColor blackColor].CGColor]; |
| [previewView.layer setContentsGravity:kCAGravityResizeAspect]; |
| [previewView.layer setFrame:previewView.frame]; |
| [previewView.layer setBounds:previewView.frame]; |
| } |
| |
| - (IBAction)chooseDevice:(id)sender { |
| int index = [sender indexOfSelectedItem]; |
| QModelIndex qIdx = Video::ConfigurationProxy::deviceModel().index(index, 0); |
| Video::ConfigurationProxy::deviceSelectionModel().setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect); |
| } |
| |
| - (IBAction)chooseSize:(id)sender { |
| int index = [sender indexOfSelectedItem]; |
| QModelIndex qIdx = Video::ConfigurationProxy::resolutionModel().index(index, 0); |
| Video::ConfigurationProxy::resolutionSelectionModel().setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect); |
| } |
| |
| - (IBAction)chooseRate:(id)sender { |
| int index = [sender indexOfSelectedItem]; |
| QModelIndex qIdx = Video::ConfigurationProxy::rateModel().index(index, 0); |
| Video::ConfigurationProxy::rateSelectionModel().setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect); |
| } |
| |
| - (void) connectPreviewSignals |
| { |
| QObject::disconnect(frameUpdated); |
| QObject::disconnect(previewStopped); |
| QObject::disconnect(previewStarted); |
| |
| previewStarted = QObject::connect(&Video::PreviewManager::instance(), |
| &Video::PreviewManager::previewStarted, |
| [=](Video::Renderer* renderer) { |
| NSLog(@"Preview started"); |
| QObject::disconnect(frameUpdated); |
| frameUpdated = QObject::connect(renderer, |
| &Video::Renderer::frameUpdated, |
| [=]() { |
| [self renderer:Video::PreviewManager::instance().previewRenderer() renderFrameForView:previewView]; |
| }); |
| }); |
| |
| previewStopped = QObject::connect(&Video::PreviewManager::instance(), |
| &Video::PreviewManager::previewStopped, |
| [=](Video::Renderer* renderer) { |
| NSLog(@"Preview stopped"); |
| QObject::disconnect(frameUpdated); |
| [previewView.layer setContents:nil]; |
| }); |
| |
| frameUpdated = QObject::connect(Video::PreviewManager::instance().previewRenderer(), |
| &Video::Renderer::frameUpdated, |
| [=]() { |
| [self renderer:Video::PreviewManager::instance().previewRenderer() |
| renderFrameForView:previewView]; |
| }); |
| } |
| |
| -(void) renderer: (Video::Renderer*)renderer renderFrameForView:(NSView*) view |
| { |
| QSize res = renderer->size(); |
| |
| auto frame_ptr = renderer->currentFrame(); |
| auto frame_data = frame_ptr.ptr; |
| if (!frame_data) |
| return; |
| |
| CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
| CGContextRef newContext = CGBitmapContextCreate(frame_data, |
| res.width(), |
| res.height(), |
| 8, |
| 4*res.width(), |
| colorSpace, |
| kCGImageAlphaPremultipliedLast); |
| |
| |
| CGImageRef newImage = CGBitmapContextCreateImage(newContext); |
| |
| /*We release some components*/ |
| CGContextRelease(newContext); |
| CGColorSpaceRelease(colorSpace); |
| |
| [CATransaction begin]; |
| view.layer.contents = (__bridge id)newImage; |
| [CATransaction commit]; |
| |
| CFRelease(newImage); |
| } |
| |
| - (void) viewWillAppear |
| { |
| // check if preview has to be started/stopped by this controller |
| self.shouldHandlePreview = !Video::PreviewManager::instance().previewRenderer()->isRendering(); |
| |
| [self connectPreviewSignals]; |
| if (self.shouldHandlePreview) { |
| Video::PreviewManager::instance().startPreview(); |
| } |
| } |
| |
| - (void)viewWillDisappear |
| { |
| QObject::disconnect(frameUpdated); |
| QObject::disconnect(previewStopped); |
| QObject::disconnect(previewStarted); |
| if (self.shouldHandlePreview) { |
| Video::PreviewManager::instance().stopPreview(); |
| } |
| } |
| |
| #pragma mark - NSMenuDelegate methods |
| |
| - (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel |
| { |
| QModelIndex qIdx; |
| if(self.videoDevicesList.menu == menu) { |
| |
| qIdx = Video::ConfigurationProxy::deviceModel().index(index, 0); |
| [item setTitle:Video::ConfigurationProxy::deviceModel().data(qIdx, Qt::DisplayRole).toString().toNSString()]; |
| |
| } else if(self.sizesList.menu == menu) { |
| |
| qIdx = Video::ConfigurationProxy::resolutionModel().index(index, 0); |
| [item setTitle:Video::ConfigurationProxy::resolutionModel().data(qIdx, Qt::DisplayRole).toString().toNSString()]; |
| |
| } else if(self.ratesList.menu == menu) { |
| |
| qIdx = Video::ConfigurationProxy::rateModel().index(index, 0); |
| [item setTitle:Video::ConfigurationProxy::rateModel().data(qIdx, Qt::DisplayRole).toString().toNSString()]; |
| |
| } |
| return YES; |
| } |
| |
| - (NSInteger)numberOfItemsInMenu:(NSMenu *)menu |
| { |
| if(self.videoDevicesList.menu == menu) { |
| return Video::ConfigurationProxy::deviceModel().rowCount(); |
| } else if(self.sizesList.menu == menu) { |
| return Video::ConfigurationProxy::resolutionModel().rowCount(); |
| } else if(self.ratesList.menu == menu) { |
| return Video::ConfigurationProxy::rateModel().rowCount(); |
| } |
| return 0; |
| } |
| |
| @end |