1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QDebug>
43 #include <QApplication>
44 #include <QGraphicsLinearLayout>
45 #ifndef QT_NO_OPENGL
46 #include <QGLWidget>
47 #endif
48 #include <QObject>
49 
50 #include "button.h"
51 #include "label.h"
52 #include "menu.h"
53 #include "topbar.h"
54 #include "backgrounditem.h"
55 #include "theme.h"
56 #include "mainview.h"
57 #include "gvbwidget.h"
58 
MainView(const bool enableOpenGL,const bool outputFps,const bool imageRendering,QWidget * parent)59 MainView::MainView(const bool enableOpenGL, const bool outputFps, const bool imageRendering, QWidget *parent)
60     : QGraphicsView(parent)
61     , m_scene(0)
62     , m_mainLayout(0)
63     , m_mainWidget(0)
64     , m_testWidget(0)
65     , m_imageBasedRendering(imageRendering)
66     , m_pixmapToRender(0)
67     , m_OutputFps(outputFps)
68     , m_fpsUpdated()
69     , m_Fpss()
70     , m_angle(0)
71     , m_enableOpenGL(enableOpenGL)
72 {
73     construct();
74 }
75 
~MainView()76 MainView::~MainView()
77 {
78     if (!m_scene->parent())
79         delete m_scene;
80 
81     delete m_pixmapToRender;
82 }
83 
setTestWidget(QGraphicsWidget * testWidget)84 void MainView::setTestWidget(QGraphicsWidget *testWidget)
85 {
86     if (!testWidget)
87         return;
88 
89     if (m_testWidget) {
90         m_mainLayout->removeItem(m_testWidget);
91         if (!m_testWidget->parent() && !m_testWidget->parentLayoutItem())
92             delete m_testWidget;
93     }
94     m_testWidget = testWidget;
95     m_mainLayout->addItem(m_testWidget);
96     resizeContent(size());
97 }
98 
takeTestWidget()99 QGraphicsWidget *MainView::takeTestWidget()
100 {
101     if (m_testWidget) {
102         m_mainLayout->removeItem(m_testWidget);
103         QGraphicsWidget *tmp = m_testWidget;
104         m_testWidget = 0;
105         return tmp;
106     }
107     return 0;
108 }
109 
testWidget()110 QGraphicsWidget *MainView::testWidget()
111 {
112     return m_testWidget;
113 }
114 
setImageBasedRendering(const bool imageBasedRendering)115 void MainView::setImageBasedRendering(const bool imageBasedRendering)
116 {
117     m_imageBasedRendering = imageBasedRendering;
118     delete m_pixmapToRender;
119     m_pixmapToRender = 0;
120     viewport()->update();
121 }
122 
imageBasedRendering() const123 bool MainView::imageBasedRendering() const
124 {
125     return m_imageBasedRendering;
126 }
127 
fps()128 qreal MainView::fps()
129 {
130     if (m_Fpss.count() <= 0)
131         updateFps();
132 
133     if (m_Fpss.count() <= 0)
134         return 0.0;
135 
136     qreal sum = 0;
137     int count = m_Fpss.count();
138     for (int i = 0; i<count; ++i)
139         sum += m_Fpss.at(i);
140     m_Fpss.clear();
141     fpsReset();
142     return sum/qreal(count);
143 }
144 
fpsReset()145 void MainView::fpsReset()
146 {
147     m_frameCount = 0;
148     m_fpsFirstTs.start();
149     m_fpsLatestTs = m_fpsFirstTs;
150     m_fpsUpdated.start();
151 }
152 
rotateContent(int angle)153 void MainView::rotateContent(int angle)
154 {
155     bool portrait = ((m_angle+angle)%90 == 0) && ((m_angle+angle)%180 != 0);
156     bool landscape = ((m_angle+angle)%180 == 0);
157     if (!portrait && !landscape)
158         return;
159 
160     m_angle = (m_angle + angle)%360;
161 
162     rotate(angle);
163 
164     resizeContent(size());
165 }
166 
rotationAngle() const167 int MainView::rotationAngle() const
168 {
169     return m_angle;
170 }
171 
resizeContent(const QSize & s)172 void MainView::resizeContent(const QSize &s)
173 {
174     QSizeF l_size(s);
175     QSizeF p_size(l_size.height(), l_size.width());
176     bool portrait = (m_angle%90 == 0) && (m_angle%180 != 0);
177     if (portrait) {
178         m_mainWidget->resize(p_size);
179         m_backGround->resize(p_size);
180     }
181     else {
182         m_mainWidget->resize(l_size);
183         m_backGround->resize(l_size);
184     }
185     m_menu->setPos(m_topBar->getStatusBarLocation());
186     setSceneRect(QRectF(m_mainWidget->pos(), m_mainWidget->size()));
187 }
188 
resizeEvent(QResizeEvent * event)189 void MainView::resizeEvent(QResizeEvent * event)
190 {
191     QGraphicsView::resizeEvent(event);
192     resizeContent(event->size());
193 }
194 
paintEvent(QPaintEvent * event)195 void MainView::paintEvent (QPaintEvent *event)
196 {
197     if (m_imageBasedRendering) {
198         if (!m_pixmapToRender)
199             m_pixmapToRender = new QPixmap(size());
200 
201         if (m_pixmapToRender->size() != size()) {
202             delete m_pixmapToRender;
203             m_pixmapToRender = new QPixmap(size());
204         }
205         QPainter p(m_pixmapToRender);
206         render(&p);
207         p.end();
208     }
209     else {
210         QGraphicsView::paintEvent(event);
211     }
212 
213     if (!m_OutputFps)
214         emit repainted();
215 
216     m_frameCount++;
217     m_fpsLatestTs.start();
218     if(m_fpsUpdated.elapsed() > 2000) {
219         updateFps();
220         m_fpsUpdated.start();
221     }
222 }
223 
keyPressEvent(QKeyEvent * event)224 void MainView::keyPressEvent(QKeyEvent *event)
225 {
226     if (event->key() == Qt::Key_F) {
227         if (isFullScreen())
228             showNormal();
229         else
230             showFullScreen();
231     }
232 
233     //S60 3.x specific
234     if(m_menu->menuVisible()) {
235         m_menu->keyPressEvent(event);
236         return;
237     }
238 
239     if(event->key() == 16777235 ) { //Up Arrow
240         GvbWidget* widget = qobject_cast<GvbWidget*>(m_testWidget);
241         if(widget)
242             widget->keyPressEvent(event);
243     }
244 
245     if(event->key() == 16777237 ) { //Down Arrow
246         GvbWidget* widget = qobject_cast<GvbWidget*>(m_testWidget);
247         if(widget)
248             widget->keyPressEvent(event);
249     }
250 
251     if(event->key() == 17825792 ) { //LSK
252         if(!m_menu->menuVisible())
253             m_menu->menuShowHide();
254     }
255 
256     if(event->key() == 17825793 ) { //RSK
257         QApplication::quit();
258     }
259 }
260 
construct()261 void MainView::construct()
262 {
263     m_scene = new QGraphicsScene;
264 
265 #ifndef QT_NO_OPENGL
266     if (m_enableOpenGL) {
267         qDebug() << "OpenGL enabled";
268         m_scene->setSortCacheEnabled(false);
269         setViewport(new QGLWidget);
270 
271         // Qt doc says: This is the preferred update mode for
272         // viewports that do not support partial updates, such as QGLWidget...
273         setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
274     } else
275 #endif
276         setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
277 
278     setScene(m_scene);
279     m_scene->setItemIndexMethod(QGraphicsScene::NoIndex);
280 
281     //setCacheMode(QGraphicsView::CacheBackground);
282     setAlignment(Qt::AlignLeft | Qt::AlignTop);
283 
284     // Turn off automatic background
285     setAttribute(Qt::WA_OpaquePaintEvent);
286     setAttribute(Qt::WA_NoBackground);
287     setAttribute(Qt::WA_NoSystemBackground);
288     setAutoFillBackground(false);
289 
290     //Background
291     m_backGround = new BackgroundItem("background.svg");
292     m_scene->addItem(m_backGround);
293     m_backGround->setZValue(0);
294 
295     //Menu
296     m_menu = new Menu(this);
297     m_scene->addItem(m_menu); //Add menu to the scene directly
298     m_menu->setZValue(10); //Bring to front
299 
300     m_mainLayout = new QGraphicsLinearLayout(Qt::Vertical);
301     m_mainLayout->setContentsMargins(0,0,0,0);
302     m_mainLayout->setSpacing(0);
303 
304     m_mainWidget = new QGraphicsWidget;
305     m_mainWidget->setLayout(m_mainLayout);
306     m_mainWidget->setZValue(1);
307     m_scene->addItem(m_mainWidget);
308 
309     //Topbar
310     m_topBar = new TopBar(this, 0);
311     m_mainLayout->addItem(m_topBar);
312     m_topBar->setZValue(1);
313     connect(m_topBar, SIGNAL(clicked(bool)), m_menu, SLOT(menuShowHide()));
314 
315     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
316     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
317     setContentsMargins(0,0,0,0);
318     setViewportMargins(0,0,0,0);
319     setFrameShape(QFrame::NoFrame);
320 
321     fpsReset();
322     m_fpsUpdated.start();
323 }
324 
updateFps()325 void MainView::updateFps()
326 {
327     int msecs =  m_fpsFirstTs.msecsTo(m_fpsLatestTs);
328     qreal fps = 0;
329     if (msecs > 0) {
330         fps = m_frameCount * 1000.0 / msecs;
331 
332         if (m_OutputFps)
333             qDebug() << "FPS: " << fps;
334 
335         m_Fpss.append(fps);
336     }
337     m_fpsFirstTs = m_fpsLatestTs;
338     m_frameCount = 0;
339 }
340 
menu()341 Menu *MainView::menu()
342 {
343     return m_menu;
344 }
345