blob: e401cfa10284165ee1c98614c5330fdebb02593a [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
Alexandre Lision9fe374b2016-01-06 10:17:31 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Alexandre Lision8521baa2015-03-13 11:08:00 -04003 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Alexandre Lision8521baa2015-03-13 11:08:00 -040018 */
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050019#import "VideoPrefsVC.h"
20
Alexandre Lisionb8a81162015-03-20 18:08:01 -040021#import <QuartzCore/QuartzCore.h>
22
23#import <QItemSelectionModel>
24#import <QAbstractProxyModel>
25
26#import <video/configurationproxy.h>
27#import <video/sourcemodel.h>
28#import <video/previewmanager.h>
29#import <video/renderer.h>
30#import <video/device.h>
31#import <video/devicemodel.h>
32
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050033@interface VideoPrefsVC ()
34
Alexandre Lisionb8a81162015-03-20 18:08:01 -040035@property (assign) IBOutlet NSView *previewView;
36@property (assign) IBOutlet NSPopUpButton *videoDevicesList;
37@property (assign) IBOutlet NSPopUpButton *sizesList;
38@property (assign) IBOutlet NSPopUpButton *ratesList;
39
Alexandre Lisione0c7e332015-07-30 11:11:33 -040040@property BOOL shouldHandlePreview;
41
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050042@end
43
44@implementation VideoPrefsVC
Alexandre Lisionb8a81162015-03-20 18:08:01 -040045@synthesize previewView;
46@synthesize videoDevicesList;
47@synthesize sizesList;
48@synthesize ratesList;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050049
Alexandre Lisionb8a81162015-03-20 18:08:01 -040050QMetaObject::Connection frameUpdated;
51QMetaObject::Connection previewStarted;
52QMetaObject::Connection previewStopped;
53
54- (void)loadView
55{
56 [super loadView];
57
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040058 Video::ConfigurationProxy::deviceModel().rowCount();
59 Video::ConfigurationProxy::resolutionModel().rowCount();
60 Video::ConfigurationProxy::rateModel().rowCount();
Alexandre Lisionb8a81162015-03-20 18:08:01 -040061
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040062 QModelIndex qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel().currentIndex();
63 qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel().currentIndex();
Alexandre Lisionb8a81162015-03-20 18:08:01 -040064
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040065 [videoDevicesList addItemWithTitle:Video::ConfigurationProxy::deviceModel().data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lisionb8a81162015-03-20 18:08:01 -040066
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040067 QModelIndex qSizeIdx = Video::ConfigurationProxy::resolutionSelectionModel().currentIndex();
68 [sizesList addItemWithTitle:Video::ConfigurationProxy::resolutionModel().data(qSizeIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lisionb8a81162015-03-20 18:08:01 -040069
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040070 if(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::resolutionModel())) {
71 QObject::connect(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::resolutionModel()),
Alexandre Lisionb8a81162015-03-20 18:08:01 -040072 &QAbstractProxyModel::modelReset,
73 [=]() {
74 NSLog(@"resolution Source model changed!!!");
75 });
76
77 }
78
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040079 QModelIndex qRate = Video::ConfigurationProxy::rateSelectionModel().currentIndex();
80 [ratesList addItemWithTitle:Video::ConfigurationProxy::rateModel().data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lisionb8a81162015-03-20 18:08:01 -040081
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040082 if(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::rateModel())) {
83 QObject::connect(qobject_cast<QAbstractProxyModel*>(&Video::ConfigurationProxy::rateModel()),
Alexandre Lisionb8a81162015-03-20 18:08:01 -040084 &QAbstractProxyModel::modelReset,
85 [=]() {
86 NSLog(@"rates Source model changed!!!");
87 });
88
89 }
90
Alexandre Lisionb8a81162015-03-20 18:08:01 -040091 [previewView setWantsLayer:YES];
92 [previewView setLayer:[CALayer layer]];
93 [previewView.layer setBackgroundColor:[NSColor blackColor].CGColor];
94 [previewView.layer setContentsGravity:kCAGravityResizeAspect];
95 [previewView.layer setFrame:previewView.frame];
96 [previewView.layer setBounds:previewView.frame];
Alexandre Lisionb8a81162015-03-20 18:08:01 -040097}
98
99- (IBAction)chooseDevice:(id)sender {
100 int index = [sender indexOfSelectedItem];
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400101 QModelIndex qIdx = Video::ConfigurationProxy::deviceModel().index(index, 0);
102 Video::ConfigurationProxy::deviceSelectionModel().setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400103}
104
105- (IBAction)chooseSize:(id)sender {
106 int index = [sender indexOfSelectedItem];
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400107 QModelIndex qIdx = Video::ConfigurationProxy::resolutionModel().index(index, 0);
108 Video::ConfigurationProxy::resolutionSelectionModel().setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400109}
110
111- (IBAction)chooseRate:(id)sender {
112 int index = [sender indexOfSelectedItem];
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400113 QModelIndex qIdx = Video::ConfigurationProxy::rateModel().index(index, 0);
114 Video::ConfigurationProxy::rateSelectionModel().setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400115}
116
117- (void) connectPreviewSignals
118{
119 QObject::disconnect(frameUpdated);
120 QObject::disconnect(previewStopped);
121 QObject::disconnect(previewStarted);
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500122
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400123 previewStarted = QObject::connect(&Video::PreviewManager::instance(),
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500124 &Video::PreviewManager::previewStarted,
125 [=](Video::Renderer* renderer) {
126 NSLog(@"Preview started");
127 QObject::disconnect(frameUpdated);
128 frameUpdated = QObject::connect(renderer,
129 &Video::Renderer::frameUpdated,
130 [=]() {
131 [self renderer:Video::PreviewManager::instance().previewRenderer() renderFrameForView:previewView];
132 });
133 });
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400134
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400135 previewStopped = QObject::connect(&Video::PreviewManager::instance(),
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500136 &Video::PreviewManager::previewStopped,
137 [=](Video::Renderer* renderer) {
138 NSLog(@"Preview stopped");
139 QObject::disconnect(frameUpdated);
140 [previewView.layer setContents:nil];
141 });
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400142
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400143 frameUpdated = QObject::connect(Video::PreviewManager::instance().previewRenderer(),
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500144 &Video::Renderer::frameUpdated,
145 [=]() {
146 [self renderer:Video::PreviewManager::instance().previewRenderer()
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400147 renderFrameForView:previewView];
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500148 });
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400149}
150
151-(void) renderer: (Video::Renderer*)renderer renderFrameForView:(NSView*) view
152{
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400153 QSize res = renderer->size();
154
Alexandre Lision6731e132015-10-14 14:29:06 -0400155 auto frame_ptr = renderer->currentFrame();
156 auto frame_data = frame_ptr.ptr;
157 if (!frame_data)
158 return;
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400159
160 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
Alexandre Lision6731e132015-10-14 14:29:06 -0400161 CGContextRef newContext = CGBitmapContextCreate(frame_data,
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400162 res.width(),
163 res.height(),
164 8,
165 4*res.width(),
166 colorSpace,
167 kCGImageAlphaPremultipliedLast);
168
169
170 CGImageRef newImage = CGBitmapContextCreateImage(newContext);
171
172 /*We release some components*/
173 CGContextRelease(newContext);
174 CGColorSpaceRelease(colorSpace);
175
176 [CATransaction begin];
177 view.layer.contents = (__bridge id)newImage;
178 [CATransaction commit];
179
180 CFRelease(newImage);
181}
182
Alexandre Lisione78a09b2015-07-03 15:52:23 -0400183- (void) viewWillAppear
184{
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500185 // check if preview has to be started/stopped by this controller
186 self.shouldHandlePreview = !Video::PreviewManager::instance().previewRenderer()->isRendering();
187
188 [self connectPreviewSignals];
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400189 if (self.shouldHandlePreview) {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400190 Video::PreviewManager::instance().startPreview();
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400191 }
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400192}
193
194- (void)viewWillDisappear
195{
Alexandre Lisiond7b85462015-11-10 17:14:29 -0500196 QObject::disconnect(frameUpdated);
197 QObject::disconnect(previewStopped);
198 QObject::disconnect(previewStarted);
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400199 if (self.shouldHandlePreview) {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400200 Video::PreviewManager::instance().stopPreview();
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400201 }
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400202}
203
204#pragma mark - NSMenuDelegate methods
205
206- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
207{
208 QModelIndex qIdx;
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400209 if(self.videoDevicesList.menu == menu) {
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400210
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400211 qIdx = Video::ConfigurationProxy::deviceModel().index(index, 0);
212 [item setTitle:Video::ConfigurationProxy::deviceModel().data(qIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400213
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400214 } else if(self.sizesList.menu == menu) {
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400215
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400216 qIdx = Video::ConfigurationProxy::resolutionModel().index(index, 0);
217 [item setTitle:Video::ConfigurationProxy::resolutionModel().data(qIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400218
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400219 } else if(self.ratesList.menu == menu) {
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400220
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400221 qIdx = Video::ConfigurationProxy::rateModel().index(index, 0);
222 [item setTitle:Video::ConfigurationProxy::rateModel().data(qIdx, Qt::DisplayRole).toString().toNSString()];
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400223
224 }
225 return YES;
226}
227
228- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
229{
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400230 if(self.videoDevicesList.menu == menu) {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400231 return Video::ConfigurationProxy::deviceModel().rowCount();
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400232 } else if(self.sizesList.menu == menu) {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400233 return Video::ConfigurationProxy::resolutionModel().rowCount();
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400234 } else if(self.ratesList.menu == menu) {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400235 return Video::ConfigurationProxy::rateModel().rowCount();
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400236 }
Alexandre Lisione1cf4462015-10-08 15:44:38 -0400237 return 0;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500238}
239
240@end