blob: ef01dce69d7609a10cfe5aacf4d79891d6612ddf [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 Lision4a7b95e2015-02-20 10:06:43 -050051@end
52
53@implementation VideoPrefsVC
Alexandre Lisionb8a81162015-03-20 18:08:01 -040054@synthesize previewView;
55@synthesize videoDevicesList;
56@synthesize sizesList;
57@synthesize ratesList;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050058
Alexandre Lisionb8a81162015-03-20 18:08:01 -040059QMetaObject::Connection frameUpdated;
60QMetaObject::Connection previewStarted;
61QMetaObject::Connection previewStopped;
62
63- (void)loadView
64{
65 [super loadView];
66
67 Video::ConfigurationProxy::deviceModel()->rowCount();
68 Video::ConfigurationProxy::resolutionModel()->rowCount();
69 Video::ConfigurationProxy::rateModel()->rowCount();
70
71 QModelIndex qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel()->currentIndex();
72 qDeviceIdx = Video::ConfigurationProxy::deviceSelectionModel()->currentIndex();
73
74 [videoDevicesList addItemWithTitle:Video::ConfigurationProxy::deviceModel()->data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()];
75
76 QModelIndex qSizeIdx = Video::ConfigurationProxy::resolutionSelectionModel()->currentIndex();
77 [sizesList addItemWithTitle:Video::ConfigurationProxy::resolutionModel()->data(qSizeIdx, Qt::DisplayRole).toString().toNSString()];
78
79 if(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::resolutionModel())) {
80 QObject::connect(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::resolutionModel()),
81 &QAbstractProxyModel::modelReset,
82 [=]() {
83 NSLog(@"resolution Source model changed!!!");
84 });
85
86 }
87
88 QModelIndex qRate = Video::ConfigurationProxy::rateSelectionModel()->currentIndex();
89 [ratesList addItemWithTitle:Video::ConfigurationProxy::rateModel()->data(qDeviceIdx, Qt::DisplayRole).toString().toNSString()];
90
91 if(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::rateModel())) {
92 QObject::connect(qobject_cast<QAbstractProxyModel*>(Video::ConfigurationProxy::rateModel()),
93 &QAbstractProxyModel::modelReset,
94 [=]() {
95 NSLog(@"rates Source model changed!!!");
96 });
97
98 }
99
100
101 [previewView setWantsLayer:YES];
102 [previewView setLayer:[CALayer layer]];
103 [previewView.layer setBackgroundColor:[NSColor blackColor].CGColor];
104 [previewView.layer setContentsGravity:kCAGravityResizeAspect];
105 [previewView.layer setFrame:previewView.frame];
106 [previewView.layer setBounds:previewView.frame];
107
108 [self connectPreviewSignals];
109}
110
111- (IBAction)chooseDevice:(id)sender {
112 int index = [sender indexOfSelectedItem];
113 QModelIndex qIdx = Video::ConfigurationProxy::deviceModel()->index(index, 0);
114 Video::ConfigurationProxy::deviceSelectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
115}
116
117- (IBAction)chooseSize:(id)sender {
118 int index = [sender indexOfSelectedItem];
119 QModelIndex qIdx = Video::ConfigurationProxy::resolutionModel()->index(index, 0);
120 Video::ConfigurationProxy::resolutionSelectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
121}
122
123- (IBAction)chooseRate:(id)sender {
124 int index = [sender indexOfSelectedItem];
125 QModelIndex qIdx = Video::ConfigurationProxy::rateModel()->index(index, 0);
126 Video::ConfigurationProxy::rateSelectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
127}
128
129- (void) connectPreviewSignals
130{
131 QObject::disconnect(frameUpdated);
132 QObject::disconnect(previewStopped);
133 QObject::disconnect(previewStarted);
134 previewStarted = QObject::connect(Video::PreviewManager::instance(),
135 &Video::PreviewManager::previewStarted,
136 [=](Video::Renderer* renderer) {
137 NSLog(@"Preview started");
138 QObject::disconnect(frameUpdated);
139 frameUpdated = QObject::connect(renderer,
140 &Video::Renderer::frameUpdated,
141 [=]() {
142 [self renderer:Video::PreviewManager::instance()->previewRenderer() renderFrameForView:previewView];
143 });
144 });
145
146 previewStopped = QObject::connect(Video::PreviewManager::instance(),
147 &Video::PreviewManager::previewStopped,
148 [=](Video::Renderer* renderer) {
149 NSLog(@"Preview stopped");
150 QObject::disconnect(frameUpdated);
151 [previewView.layer setContents:nil];
152 });
153
154 frameUpdated = QObject::connect(Video::PreviewManager::instance()->previewRenderer(),
155 &Video::Renderer::frameUpdated,
156 [=]() {
157 [self renderer:Video::PreviewManager::instance()->previewRenderer()
158 renderFrameForView:previewView];
159 });
160}
161
162-(void) renderer: (Video::Renderer*)renderer renderFrameForView:(NSView*) view
163{
Alexandre Lision911e0072015-07-13 16:19:08 -0400164 auto data = renderer->currentSmartFrame();
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400165 QSize res = renderer->size();
166
Alexandre Lision911e0072015-07-13 16:19:08 -0400167 auto buf = reinterpret_cast<const unsigned char*>(data->data());
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400168
169 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
170 CGContextRef newContext = CGBitmapContextCreate((void *)buf,
171 res.width(),
172 res.height(),
173 8,
174 4*res.width(),
175 colorSpace,
176 kCGImageAlphaPremultipliedLast);
177
178
179 CGImageRef newImage = CGBitmapContextCreateImage(newContext);
180
181 /*We release some components*/
182 CGContextRelease(newContext);
183 CGColorSpaceRelease(colorSpace);
184
185 [CATransaction begin];
186 view.layer.contents = (__bridge id)newImage;
187 [CATransaction commit];
188
189 CFRelease(newImage);
190}
191
Alexandre Lisione78a09b2015-07-03 15:52:23 -0400192- (void) viewWillAppear
193{
194 Video::PreviewManager::instance()->startPreview();
Alexandre Lisionb8a81162015-03-20 18:08:01 -0400195}
196
197- (void)viewWillDisappear
198{
199 Video::PreviewManager::instance()->stopPreview();
200}
201
202#pragma mark - NSMenuDelegate methods
203
204- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
205{
206 QModelIndex qIdx;
207 if([menu.title isEqualToString:@"devices"]) {
208
209 qIdx = Video::ConfigurationProxy::deviceModel()->index(index, 0);
210 [item setTitle:Video::ConfigurationProxy::deviceModel()->data(qIdx, Qt::DisplayRole).toString().toNSString()];
211
212 } else if([menu.title isEqualToString:@"sizes"]) {
213
214 qIdx = Video::ConfigurationProxy::resolutionModel()->index(index, 0);
215 [item setTitle:Video::ConfigurationProxy::resolutionModel()->data(qIdx, Qt::DisplayRole).toString().toNSString()];
216
217 } else if([menu.title isEqualToString:@"rates"]) {
218
219 qIdx = Video::ConfigurationProxy::rateModel()->index(index, 0);
220 [item setTitle:Video::ConfigurationProxy::rateModel()->data(qIdx, Qt::DisplayRole).toString().toNSString()];
221
222 }
223 return YES;
224}
225
226- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
227{
228 if([menu.title isEqualToString:@"devices"]) {
229 return Video::ConfigurationProxy::deviceModel()->rowCount();
230 } else if([menu.title isEqualToString:@"sizes"]) {
231 return Video::ConfigurationProxy::resolutionModel()->rowCount();
232 } else if([menu.title isEqualToString:@"rates"]) {
233 return Video::ConfigurationProxy::rateModel()->rowCount();
234 }
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500235}
236
237@end