6c9c36fd27673ab9f775c4a79f87a365db6dcce7
[harmattan/cameraplus] / declarative / viewfinder.cpp
1 // -*- c++ -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #include "viewfinder.h"
24 #include "camera.h"
25 #include "cameraconfig.h"
26 #include "qtcamviewfinderrenderer.h"
27 #if defined(QT4)
28 #include <QDeclarativeInfo>
29 #elif defined(QT5)
30 #include <QQmlInfo>
31 #endif
32 #include <QPainter>
33 #include "qtcamdevice.h"
34 #include <QMatrix4x4>
35
36 #if defined(QT4)
37 Viewfinder::Viewfinder(QDeclarativeItem *parent) :
38   QDeclarativeItem(parent),
39 #elif defined(QT5)
40 Viewfinder::Viewfinder(QQuickItem *parent) :
41   QQuickPaintedItem(parent),
42 #endif
43   m_renderer(0),
44   m_cam(0),
45   m_conf(0),
46   m_enabled(true) {
47
48 #if defined(QT4)
49   setFlag(QGraphicsItem::ItemHasNoContents, false);
50 #endif
51
52 #if defined(QT5)
53   setRenderTarget(QQuickPaintedItem::FramebufferObject);
54   setSmooth(false);
55   setAntialiasing(false);
56 #endif
57 }
58
59 Viewfinder::~Viewfinder() {
60
61 }
62
63 bool Viewfinder::isRenderingEnabled() const {
64   return m_enabled;
65 }
66
67 void Viewfinder::setRenderingEnabled(bool enabled) {
68   if (m_enabled != enabled) {
69     m_enabled = enabled;
70     emit renderingEnabledChanged();
71   }
72 }
73
74 Camera *Viewfinder::camera() const {
75   return m_cam;
76 }
77
78 void Viewfinder::setCamera(Camera *camera) {
79   if (m_cam == camera) {
80     return;
81   }
82
83   if (m_cam && m_cam != camera) {
84     qmlInfo(this) << "Cannot reset Camera";
85     return;
86   }
87
88   if (!camera) {
89     qmlInfo(this) << "Camera cannot be empty";
90     return;
91   }
92
93   if (m_cam) {
94     QObject::disconnect(m_cam, SIGNAL(deviceChanged()), this, SLOT(deviceChanged()));
95   }
96
97   m_cam = camera;
98
99   if (m_cam) {
100     QObject::connect(m_cam, SIGNAL(deviceChanged()), this, SLOT(deviceChanged()));
101   }
102
103   if (isComponentComplete()) {
104     deviceChanged();
105   }
106
107   emit cameraChanged();
108 }
109
110 CameraConfig *Viewfinder::cameraConfig() const {
111   return m_conf;
112 }
113
114 void Viewfinder::setCameraConfig(CameraConfig *config) {
115   if (m_conf && m_conf != config) {
116     qmlInfo(this) << "Cannot reset CameraConfig";
117     return;
118   }
119
120   if (!config) {
121     qmlInfo(this) << "CameraConfig cannot be empty";
122     return;
123   }
124
125   if (m_conf == config) {
126     return;
127   }
128
129   m_conf = config;
130
131   if (isComponentComplete()) {
132     deviceChanged();
133   }
134
135   emit cameraConfigChanged();
136 }
137
138 #if defined(QT4)
139 void Viewfinder::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
140                        QWidget *widget) {
141
142   Q_UNUSED(widget);
143   Q_UNUSED(option);
144   painter->fillRect(boundingRect(), Qt::black);
145 #elif defined(QT5)
146 void Viewfinder::paint(QPainter *painter) {
147   painter->fillRect(contentsBoundingRect(), Qt::black);
148 #endif
149
150   if (!m_renderer || !m_enabled) {
151     return;
152   }
153
154   bool needsNativePainting = m_renderer->needsNativePainting();
155
156   if (needsNativePainting) {
157     painter->beginNativePainting();
158   }
159
160   m_renderer->paint(QMatrix4x4(painter->combinedTransform()), painter->viewport());
161
162   if (needsNativePainting) {
163     painter->endNativePainting();
164   }
165 }
166
167 QRectF Viewfinder::renderArea() const {
168   return m_renderer ? m_renderer->renderArea() : QRectF();
169 }
170
171 QSizeF Viewfinder::videoResolution() const {
172   return m_renderer ? m_renderer->videoResolution() : QSizeF();
173 }
174
175 void Viewfinder::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) {
176 #if defined(QT4)
177   QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
178 #elif defined(QT5)
179   QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);
180 #endif
181
182   if (m_renderer) {
183     m_renderer->resize(newGeometry.size());
184   }
185 }
186
187 void Viewfinder::componentComplete() {
188 #if defined(QT4)
189   QDeclarativeItem::componentComplete();
190 #elif defined(QT5)
191   QQuickPaintedItem::componentComplete();
192 #endif
193
194   if (!m_cam) {
195     qmlInfo(this) << "Camera not set";
196     return;
197   }
198
199   if (!m_conf) {
200     qmlInfo(this) << "CameraConfig not set";
201     return;
202   }
203
204   m_renderer = QtCamViewfinderRenderer::create(m_conf->config(), this);
205   if (!m_renderer) {
206     qmlInfo(this) << "Failed to create viewfinder renderer";
207     return;
208   }
209
210   m_renderer->resize(QSizeF(width(), height()));
211   QObject::connect(m_renderer, SIGNAL(updateRequested()), this, SLOT(updateRequested()));
212   QObject::connect(m_renderer, SIGNAL(renderAreaChanged()), this, SIGNAL(renderAreaChanged()));
213   QObject::connect(m_renderer, SIGNAL(videoResolutionChanged()), this, SIGNAL(videoResolutionChanged()));
214 }
215
216 void Viewfinder::deviceChanged() {
217   if (!m_renderer) {
218     qmlInfo(this) << "No renderer";
219     return;
220   }
221
222   QtCamDevice *dev = m_cam->device();
223
224   if (dev) {
225     dev->setViewfinder(this);
226   }
227
228   emit renderAreaChanged();
229   emit videoResolutionChanged();
230 }
231
232 GstElement *Viewfinder::sinkElement() {
233   return m_renderer ? m_renderer->sinkElement() : 0;
234 }
235
236 bool Viewfinder::setDevice(QtCamDevice *device) {
237   Q_UNUSED(device);
238
239   return true;
240 }
241
242 void Viewfinder::stop() {
243   if (m_renderer) {
244     m_renderer->reset();
245   }
246 }
247
248 void Viewfinder::updateRequested() {
249   if (m_enabled) {
250     update();
251   }
252 }