Skip to content

Instantly share code, notes, and snippets.

@tronical
Created September 28, 2010 13:20
Show Gist options
  • Save tronical/600975 to your computer and use it in GitHub Desktop.
Save tronical/600975 to your computer and use it in GitHub Desktop.
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Name=animationtest
Exec=/opt/usr/bin/animationtest
Icon=animationtest
X-Window-Icon=
X-HildonDesk-ShowInToolbar=true
X-Osso-Type=application/x-executable
#-------------------------------------------------
#
# Project created by QtCreator 2010-09-28T12:18:32
#
#-------------------------------------------------
QT += core gui
TARGET = animationtest
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
fpstimer.cpp
HEADERS += mainwindow.h \
fpstimer.h
OTHER_FILES += \
debian/changelog \
debian/compat \
debian/control \
debian/copyright \
debian/README \
debian/rules \
animationtest.desktop
unix:!symbian {
maemo5 {
target.path = /opt/usr/bin
} else {
target.path = /usr/local/bin
}
INSTALLS += target
}
unix:!symbian {
desktopfile.files = $${TARGET}.desktop
maemo5 {
desktopfile.path = /usr/share/applications/hildon
} else {
desktopfile.path = /usr/share/applications
}
INSTALLS += desktopfile
}
RESOURCES += \
resources.qrc
/*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fpstimer.h"
#include <QDateTime>
#include <QTimerEvent>
// We save a maximum of 10000 frames, and purge 2000 at a time
#define MAX_FRAMES_SAVED 10000
#define FRAMES_TO_PURGE_WHEN_FULL 2000
// 60 FPS
#define FPS_MEASURE_INTERVAL 1000 / 60
FpsTimer::FpsTimer(QObject* parent)
: QObject(parent)
{
}
int FpsTimer::numFrames(int spanMillis)
{
const QTime now = QTime::currentTime();
int count = 0;
for (int i = m_frames.length() - 1; i >= 0; --i, ++count) {
int msecs = m_frames[i].msecsTo(now);
if (msecs < 0)
msecs += 24 * 60 * 60 * 1000;
if (msecs > spanMillis)
break;
}
return count;
}
void FpsTimer::start()
{
m_timer = startTimer(FPS_MEASURE_INTERVAL);
}
void FpsTimer::stop()
{
killTimer(m_timer);
m_frames.clear();
}
void FpsTimer::timerEvent(QTimerEvent* event)
{
if (event->timerId() != m_timer)
return;
m_frames.append(QTime::currentTime());
if (m_frames.length() > MAX_FRAMES_SAVED)
m_frames.erase(m_frames.begin(), m_frames.begin() + FRAMES_TO_PURGE_WHEN_FULL);
}
/*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef fpstimer_h
#define fpstimer_h
#include <QObject>
#include <QSet>
#include <QTime>
class FpsTimer : public QObject {
Q_OBJECT
public:
FpsTimer(QObject* parent = 0);
int numFrames(int spanMillis = 1000);
public Q_SLOTS:
void start();
void stop();
protected slots:
virtual void timerEvent(QTimerEvent*);
private:
int m_timer;
QList<QTime> m_frames;
};
#endif // FPSMEASURE_H
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
PosterItem::PosterItem(const QPixmap& pixmap)
: m_pixmap(pixmap)
{
m_size = m_pixmap.size();
}
void PosterItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawPixmap(QRect(QPoint(0, 0), m_size), m_pixmap);
}
QRectF PosterItem::boundingRect() const
{
return QRectF(QPointF(), m_size);
}
void PosterItem::setSize(const QSize& size)
{
prepareGeometryChange();
m_size = size;
}
GraphicsView::GraphicsView(QWidget* parent)
: QGraphicsView(parent)
{
}
void GraphicsView::updateBackground()
{
// save some memory first
m_background = QPixmap();
m_background = QPixmap::grabWindow(QApplication::desktop()->winId());
}
void GraphicsView::drawBackground(QPainter *painter, QRectF &rect)
{
painter->drawPixmap(0, 0, m_background);
}
const int animationDuration = 3000;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
view = new GraphicsView;
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setOptimizationFlag(QGraphicsView::DontClipPainter);
view->setOptimizationFlag(QGraphicsView::DontSavePainterState);
view->updateBackground();
setCentralWidget(view);
scene = new QGraphicsScene(this);
view->setScene(scene);
QPixmap pm(":/picture.jpg");
posterItem = new PosterItem(pm);
scene->addItem(posterItem);
QParallelAnimationGroup *animation = new QParallelAnimationGroup(this);
zoomAnimation = animation;
positionChange = new QPropertyAnimation(posterItem, "pos", this);
positionChange->setDuration(animationDuration);
animation->addAnimation(positionChange);
sizeChange = new QPropertyAnimation(posterItem, "size", this);
sizeChange->setDuration(animationDuration);
animation->addAnimation(sizeChange);
zoomSmall();
showFullScreen();
fpsUpdateTimer.start(1000, this);
fpsTimer.start();
}
MainWindow::~MainWindow()
{
}
void MainWindow::mousePressEvent(QMouseEvent*)
{
if (posterItem->x() < 10)
zoomSmall();
else
zoomBig();
}
void MainWindow::zoomSmall()
{
QSize desktopSize = QApplication::desktop()->screenGeometry().size();
QSize initialSize = desktopSize / 4;
positionChange->setStartValue(posterItem->pos());
positionChange->setEndValue(QPointF(initialSize.width(), initialSize.height()));
sizeChange->setStartValue(posterItem->size());
sizeChange->setEndValue(initialSize);
zoomAnimation->start();
}
void MainWindow::zoomBig()
{
positionChange->setStartValue(posterItem->pos());
positionChange->setEndValue(QPointF(0, 0));
sizeChange->setStartValue(posterItem->size());
sizeChange->setEndValue(size());
zoomAnimation->start();
}
void MainWindow::keyPressEvent(QKeyEvent *)
{
close();
}
void MainWindow::resizeEvent(QResizeEvent *)
{
view->setSceneRect(QRectF(QPointF(0, 0), size()));
}
void MainWindow::timerEvent(QTimerEvent *event)
{
if (event->timerId() == fpsUpdateTimer.timerId()) {
const QTime now = QTime::currentTime();
if (m_lastConsultTime.isValid()) {
int interval = m_lastConsultTime.msecsTo(now);
int frames = fpsTimer.numFrames(interval);
if (interval) {
int fps = frames * 1000 / interval;
qWarning("FPS %d", fps);
}
}
m_lastConsultTime = now;
} else {
QMainWindow::timerEvent(event);
}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
#include "fpstimer.h"
class PosterItem : public QGraphicsObject
{
Q_OBJECT
Q_PROPERTY(QSize size READ size WRITE setSize)
public:
PosterItem(const QPixmap& pixmap);
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual QRectF boundingRect() const;
QSize size() const { return m_size; }
void setSize(const QSize& size);
private:
QPixmap m_pixmap;
QSize m_size;
};
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
GraphicsView(QWidget* parent = 0);
void updateBackground();
protected:
virtual void drawBackground(QPainter *painter, QRectF &rect);
private:
QPixmap m_background;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
virtual void mousePressEvent(QMouseEvent*);
virtual void keyPressEvent(QKeyEvent *);
virtual void resizeEvent(QResizeEvent *);
virtual void timerEvent(QTimerEvent *);
private:
void zoomSmall();
void zoomBig();
GraphicsView* view;
QGraphicsScene* scene;
PosterItem* posterItem;
QAbstractAnimation* zoomAnimation;
QPropertyAnimation* positionChange;
QPropertyAnimation* sizeChange;
FpsTimer fpsTimer;
QBasicTimer fpsUpdateTimer;
QTime m_lastConsultTime;
};
#endif // MAINWINDOW_H
<RCC>
<qresource prefix="/">
<file>picture.jpg</file>
</qresource>
</RCC>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment