#include <QKeyEvent>
#include <QLabel>
#include <QPainter>
#include <QSound>
#include <QSettings>
#include <QTimer>
#include <QGraphicsBlurEffect>
#include <QPixmapCache>
#include <QApplication>
#include <QEasingCurve>
#include "mainmenu.h"
#include "image.h"
const char *iconMap[] = {
"slideshow",
"photos",
"music",
"videos",
"info",
"settings",
"shutdown"
};
const char *nameMap[] = {
QT_TRANSLATE_NOOP("DPF", " Slide Show"),
QT_TRANSLATE_NOOP("DPF", " Photos"),
QT_TRANSLATE_NOOP("DPF", " Music"),
QT_TRANSLATE_NOOP("DPF", " Videos"),
QT_TRANSLATE_NOOP("DPF", " Information"),
QT_TRANSLATE_NOOP("DPF", " Settings"),
QT_TRANSLATE_NOOP("DPF", " Shut Down")
};
const char *menuItems[] = {
QT_TRANSLATE_NOOP("DPF", "Slide Show"),
QT_TRANSLATE_NOOP("DPF", "Browse Photos"),
QT_TRANSLATE_NOOP("DPF", "Browse Music"),
QT_TRANSLATE_NOOP("DPF", "Browse Videos"),
QT_TRANSLATE_NOOP("DPF", "Information"),
QT_TRANSLATE_NOOP("DPF", "Settings"),
QT_TRANSLATE_NOOP("DPF", "Shut Down")
};
const int menuSize = sizeof(menuItems) / sizeof(const char *);
QT_BEGIN_NAMESPACE
extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter* p, QImage& blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
QT_END_NAMESPACE
QPixmap blurPixmap(const QPixmap& inPixmap)
{
QImage srcImg = inPixmap.toImage(); //source image
QPixmap pxDst(srcImg.size());//blurred destination
pxDst.fill(Qt::transparent);
{
QPainter painter(&pxDst);
qt_blurImage(&painter, srcImg, 10, true, false);//blur radius: 2px
}
return pxDst;
}
static const int frames = 15;
class AnimatedIcon : public QWidget
{
public:
AnimatedIcon(QWidget *p) : QWidget(p) {
// nothing
}
~AnimatedIcon() {
// nothing
}
template <typename F>
void loadPixmp(std::string _name, QPixmap* _pix, F _loader)
{
if (!cache.find(_name.c_str(), _pix)) {
*_pix = _loader(_name.c_str());
cache.insert(_name.c_str(), *_pix);
}
}
void setPixmaps(int _a, int _b) {
std::string blurSuffix = "_blur";
loadPixmp(iconMap[_a], &a, [](const char* _name) { return Image::icon(_name, 256); });
loadPixmp(iconMap[_b], &b, [](const char* _name) { return Image::icon(_name, 256); });
loadPixmp(iconMap[_a] + blurSuffix, &ablur, [this](const char* _name) { return blurPixmap(a); });
loadPixmp(iconMap[_b] + blurSuffix, &bblur, [this](const char* _name) { return blurPixmap(b); });
}
void setFrame(int f, int d) {
frame = f;
dir = d;
}
void paintEvent(QPaintEvent *pe) {
QPainter p(this);
QTransform trans;
// QEasingCurve curve((dir == 1) ? QEasingCurve::OutInBack : QEasingCurve::InOutBack);
QEasingCurve curve((dir == 1) ? QEasingCurve::OutExpo: QEasingCurve::InExpo);
float curveValue = curve.valueForProgress(frame / float(frames));
float invCurveValue = 1.0 - curveValue;
float scale = 1.0;
float pos = invCurveValue * 200;
// Draw icon 'a'
trans.reset();
scale = 0.5 + 0.5 * invCurveValue;
trans.scale(scale, scale);
p.setWorldTransform(trans);
p.setOpacity(invCurveValue);
p.drawPixmap(360 * (1.0 - scale) - 40 + pos, 0, a);
p.resetTransform();
// Draw icon 'a' reflected
trans.reset();
trans.scale(scale, -scale);
p.setWorldTransform(trans);
p.setOpacity(0.3 * invCurveValue);
p.drawPixmap(360 * (1.0 - scale) - 40 + pos, -2.0 * a.height(), ablur);
p.resetTransform();
// Draw icon 'b'
trans.reset();
scale = 0.5 + 0.5 * curveValue;
trans.scale(scale, scale);
p.setWorldTransform(trans);
p.setOpacity(curveValue);
p.drawPixmap(700 * (1.0 - scale) + 160 + pos, 0, b);
p.resetTransform();
// Draw icon 'b' reflected
trans.reset();
trans.scale(scale, -scale);
p.setWorldTransform(trans);
p.setOpacity(0.3 * curveValue);
p.drawPixmap(700 * (1.0 - scale) + 160 + pos, -2.0 * b.height(), bblur);
p.resetTransform();
}
QPixmapCache cache;
QPixmap a, b;
QPixmap ablur, bblur;
int frame, dir;
};
MainMenu::MainMenu(QWidget *parent) : Stage(parent)
{
static const bool labelAbove = true;
static const bool menuLeft = false;
animateIcons = QSettings("dpf.ini", QSettings::IniFormat).value("AnimateIcons", true).toBool();
curItem = 0;
icon = new AnimatedIcon(this);
icon->setFrame(0, 0);
icon->setPixmaps(1,0);
icon->setGeometry(menuLeft ? 320 : -70, labelAbove ? 150 : 80, 640, 600);
icon->show();
icon->setPixmaps(0, 0);
icon->setFrame(0, 0);
icon->update();
item1 = new Text(this, menuLeft ? 432 : 82, labelAbove ? 52: 342, "", 40, QColor(0, 0, 0, 128));
item1->setText(nameMap[curItem]);
item2 = new Text(this, menuLeft ? 430 : 80, labelAbove ? 50 : 340, "", 40, QColor(255, 255, 255));
item2->setText(nameMap[curItem]);
items = new MenuItem * [menuSize];
for (int i = 0; i < menuSize; i++)
items[i] = new MenuItem(this, menuLeft ? 60 : 450, 80 + i * 50, menuItems[i]);
items[curItem]->select();
timerId = 0;
frame = 0;
QTimer::singleShot(0, this, SLOT(init()));
QTimer* timer = new QTimer(this);
timer->setTimerType(Qt::PreciseTimer);
timer->setInterval(35);
timer->callOnTimeout([this]() {
if (animating)
{
frame += direction;
icon->setFrame(frame, direction);
//icon->update();
//update();
//qApp->processEvents();
icon->repaint();
if (frame >= frames || frame <= 0)
animating = false;
//killTimer(timerId);
}
});
timer->start();
//timerId = startTimer(20, Qt::PreciseTimer);
animating = false;
}
MainMenu::~MainMenu()
{
for (int i = 0; i < menuSize; i++)
delete items[i];
killTimer(timerId);
}
void MainMenu::init()
{
changeBackground("any");
}
void MainMenu::changeBackground(QString backg)
{
QSettings settings("dpf.ini", QSettings::IniFormat);
QString background = settings.value("Background", "image").toString();
bg->setPixmap(QPixmap("pics/" + background + "_bg0.png"));
}
void MainMenu::animate(int dir, int before, int now)
{
direction = dir;
//killTimer(timerId);
animating = false;
if (dir == -1)
frame = frames - 1;// 19;
else
frame = 1;// 1;
if (dir == -1) {
item1->setText(nameMap[before]);
item2->setText(nameMap[before]);
} else {
item1->setText(nameMap[now]);
item2->setText(nameMap[now]);
}
icon->setPixmaps(before, now);
icon->setFrame(frame, direction);
//update();
//qApp->processEvents();
//icon->repaint();
animating = true;
}
void MainMenu::timerEvent(QTimerEvent *te)
{
if (animating)
{
frame += direction;
icon->setFrame(frame, direction);
icon->update();
//icon->repaint();
if (frame >= frames || frame <= 0)
animating = false;
//killTimer(timerId);
}
}
void MainMenu::keyPressEvent(QKeyEvent *ke)
{
int prevItem = curItem;
if ( ke->key() == Qt::Key_Up ) {
items[curItem]->unselect();
curItem--;
if (curItem < 0)
curItem = menuSize - 1;
if (curItem == 0)
QSound::play("sounds/Prev.wav");
else
QSound::play("sounds/Next.wav");
items[curItem]->select();
animate(-1, curItem, prevItem);
if (!animateIcons) {
icon->setFrame(0, -1);
icon->update();
killTimer(timerId);
}
} else if ( ke->key() == Qt::Key_Down ) {
items[curItem]->unselect();
curItem++;
if (curItem > (menuSize-1))
curItem = 0;
if (curItem == (menuSize-1))
QSound::play("sounds/Prev.wav");
else
QSound::play("sounds/Next.wav");
items[curItem]->select();
animate(1, prevItem, curItem);
if (!animateIcons) {
icon->setFrame(frames, 1);
icon->update();
killTimer(timerId);
}
// } else if ( ke->key() == Qt::Key_Select ) {
} else if ( ke->key() == Qt::Key_Return ) {
QSound::play("sounds/Select.wav");
emit setStage(curItem);
}
}