blob: 791fac082f4d3cd0a8b3bad731c61fcb54157b50 [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
2 * Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
3 * 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.
18 *
19 * Additional permission under GNU GPL version 3 section 7:
20 *
21 * If you modify this program, or any covered work, by linking or
22 * combining it with the OpenSSL project's OpenSSL library (or a
23 * modified version of that library), containing parts covered by the
24 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
25 * grants you additional permission to convey the resulting work.
26 * Corresponding Source for a non-source form of such a combination
27 * shall include the source code for the parts of OpenSSL used as well
28 * as that of the covered work.
29 */
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050030#import "VideoPrefsVC.h"
31
Alexandre Lisionb8a81162015-03-20 18:08:01 -040032#import <QuartzCore/QuartzCore.h>
33
34#import <QItemSelectionModel>
35#import <QAbstractProxyModel>
36
37#import <video/configurationproxy.h>
38#import <video/sourcemodel.h>
39#import <video/previewmanager.h>
40#import <video/renderer.h>
41#import <video/device.h>
42#import <video/devicemodel.h>
43
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050044@interface VideoPrefsVC ()
45
Alexandre Lisionb8a81162015-03-20 18:08:01 -040046@property (assign) IBOutlet NSView *previewView;
47@property (assign) IBOutlet NSPopUpButton *videoDevicesList;
48@property (assign) IBOutlet NSPopUpButton *sizesList;
49@property (assign) IBOutlet NSPopUpButton *ratesList;
50
Alexandre Lisione0c7e332015-07-30 11:11:33 -040051@property BOOL shouldHandlePreview;
52
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050053@end
54
55@implementation VideoPrefsVC
Alexandre Lisionb8a81162015-03-20 18:08:01 -040056@synthesize previewView;
57@synthesize videoDevicesList;
58@synthesize sizesList;
59@synthesize ratesList;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050060
Alexandre Lisionb8a81162015-03-20 18:08:01 -040061QMetaObject::Connection frameUpdated;
62QMetaObject::Connection previewStarted;
63QMetaObject::Connection previewStopped;
64
65- (void)loadView
66{
67 [super loadView];
68
69 Video::ConfigurationProxy::deviceModel()->rowCount();
70 Video::ConfigurationProxy::resolutionModel()->rowCount();
71 Video::ConfigurationProxy::rateModel()->rowCount();
72
73 QModelIndex qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel()->currentIndex();
74 qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel()->currentIndex();
75
76 [videoDevicesList addItemWithTitle:Video::ConfigurationProxy::deviceModel()->data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()];
77
78 QModelIndex qSizeIdx = Video::ConfigurationProxy::resolutionSelectionModel()->currentIndex();
79 [sizesList addItemWithTitle:Video::ConfigurationProxy::resolutionModel()->data(qSizeIdx, Qt::DisplayRole).toString().toNSString()];
80
81 if(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::resolutionModel())) {
82 QObject::connect(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::resolutionModel()),
83 &QAbstractProxyModel::modelReset,
84 [=]() {
85 NSLog(@"resolution Source model changed!!!");
86 });
87
88 }
89
90 QModelIndex qRate = Video::ConfigurationProxy::rateSelectionModel()->currentIndex();
91 [ratesList addItemWithTitle:Video::ConfigurationProxy::rateModel()->data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()];
92
93 if(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::rateModel())) {
94 QObject::connect(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::rateModel()),
95 &QAbstractProxyModel::modelReset,
96 [=]() {
97 NSLog(@"rates Source model changed!!!");
98 });
99
100 }
101
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400102 // check if preview has to be started/stopped by this controller
103 self.shouldHandlePreview = !Video::PreviewManager::instance()->isPreviewing();
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400104
105 [previewView setWantsLayer:YES];
106 [previewView setLayer:[CALayer layer]];
107 [previewView.layer setBackgroundColor:[NSColor blackColor].CGColor];
108 [previewView.layer setContentsGravity:kCAGravityResizeAspect];
109 [previewView.layer setFrame:previewView.frame];
110 [previewView.layer setBounds:previewView.frame];
111
112 [self connectPreviewSignals];
113}
114
115- (IBAction)chooseDevice:(id)sender {
116 int index = [sender indexOfSelectedItem];
117 QModelIndex qIdx = Video::ConfigurationProxy::deviceModel()->index(index, 0);
118 Video::ConfigurationProxy::deviceSelectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
119}
120
121- (IBAction)chooseSize:(id)sender {
122 int index = [sender indexOfSelectedItem];
123 QModelIndex qIdx = Video::ConfigurationProxy::resolutionModel()->index(index, 0);
124 Video::ConfigurationProxy::resolutionSelectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
125}
126
127- (IBAction)chooseRate:(id)sender {
128 int index = [sender indexOfSelectedItem];
129 QModelIndex qIdx = Video::ConfigurationProxy::rateModel()->index(index, 0);
130 Video::ConfigurationProxy::rateSelectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
131}
132
133- (void) connectPreviewSignals
134{
135 QObject::disconnect(frameUpdated);
136 QObject::disconnect(previewStopped);
137 QObject::disconnect(previewStarted);
138 previewStarted = QObject::connect(Video::PreviewManager::instance(),
139 &Video::PreviewManager::previewStarted,
140 [=](Video::Renderer* renderer) {
141 NSLog(@"Preview started");
142 QObject::disconnect(frameUpdated);
143 frameUpdated = QObject::connect(renderer,
144 &Video::Renderer::frameUpdated,
145 [=]() {
146 [self renderer:Video::PreviewManager::instance()->previewRenderer() renderFrameForView:previewView];
147 });
148 });
149
150 previewStopped = QObject::connect(Video::PreviewManager::instance(),
151 &Video::PreviewManager::previewStopped,
152 [=](Video::Renderer* renderer) {
153 NSLog(@"Preview stopped");
154 QObject::disconnect(frameUpdated);
155 [previewView.layer setContents:nil];
156 });
157
158 frameUpdated = QObject::connect(Video::PreviewManager::instance()->previewRenderer(),
159 &Video::Renderer::frameUpdated,
160 [=]() {
161 [self renderer:Video::PreviewManager::instance()->previewRenderer()
162 renderFrameForView:previewView];
163 });
164}
165
166-(void) renderer: (Video::Renderer*)renderer renderFrameForView:(NSView*) view
167{
Alexandre Lision911e0072015-07-13 16:19:08 -0400168 auto data = renderer->currentSmartFrame();
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400169 QSize res = renderer->size();
170
Alexandre Lision911e0072015-07-13 16:19:08 -0400171 auto buf = reinterpret_cast<const unsigned char*>(data->data());
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400172
173 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
174 CGContextRef newContext = CGBitmapContextCreate((void *)buf,
175 res.width(),
176 res.height(),
177 8,
178 4*res.width(),
179 colorSpace,
180 kCGImageAlphaPremultipliedLast);
181
182
183 CGImageRef newImage = CGBitmapContextCreateImage(newContext);
184
185 /*We release some components*/
186 CGContextRelease(newContext);
187 CGColorSpaceRelease(colorSpace);
188
189 [CATransaction begin];
190 view.layer.contents = (__bridge id)newImage;
191 [CATransaction commit];
192
193 CFRelease(newImage);
194}
195
Alexandre Lisione78a09b2015-07-03 15:52:23 -0400196- (void) viewWillAppear
197{
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400198 if (self.shouldHandlePreview) {
199 Video::PreviewManager::instance()->startPreview();
200 }
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400201}
202
203- (void)viewWillDisappear
204{
Alexandre Lisione0c7e332015-07-30 11:11:33 -0400205 if (self.shouldHandlePreview) {
206 Video::PreviewManager::instance()->stopPreview();
207 }
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400208}
209
210#pragma mark - NSMenuDelegate methods
211
212- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
213{
214 QModelIndex qIdx;
215 if([menu.title isEqualToString:@"devices"]) {
216
217 qIdx = Video::ConfigurationProxy::deviceModel()->index(index, 0);
218 [item setTitle:Video::ConfigurationProxy::deviceModel()->data(qIdx, Qt::DisplayRole).toString().toNSString()];
219
220 } else if([menu.title isEqualToString:@"sizes"]) {
221
222 qIdx = Video::ConfigurationProxy::resolutionModel()->index(index, 0);
223 [item setTitle:Video::ConfigurationProxy::resolutionModel()->data(qIdx, Qt::DisplayRole).toString().toNSString()];
224
225 } else if([menu.title isEqualToString:@"rates"]) {
226
227 qIdx = Video::ConfigurationProxy::rateModel()->index(index, 0);
228 [item setTitle:Video::ConfigurationProxy::rateModel()->data(qIdx, Qt::DisplayRole).toString().toNSString()];
229
230 }
231 return YES;
232}
233
234- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
235{
236 if([menu.title isEqualToString:@"devices"]) {
237 return Video::ConfigurationProxy::deviceModel()->rowCount();
238 } else if([menu.title isEqualToString:@"sizes"]) {
239 return Video::ConfigurationProxy::resolutionModel()->rowCount();
240 } else if([menu.title isEqualToString:@"rates"]) {
241 return Video::ConfigurationProxy::rateModel()->rowCount();
242 }
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500243}
244
245@end