all repos — mgba @ daaa2fa5236df5e8976e7e0ba7ac39e0d9233422

mGBA Game Boy Advance Emulator

src/platform/qt/MessagePainter.cpp (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "MessagePainter.h"
  7
  8#include <QPainter>
  9
 10#include <QDebug>
 11
 12extern "C" {
 13#include "gba/video.h"
 14}
 15
 16using namespace QGBA;
 17
 18MessagePainter::MessagePainter(QObject* parent)
 19	: QObject(parent)
 20	, m_messageTimer(this)
 21	, m_scaleFactor(1)
 22{
 23	m_messageFont.setFamily("Source Code Pro");
 24	m_messageFont.setStyleHint(QFont::Monospace);
 25	m_messageFont.setPixelSize(13);
 26	connect(&m_messageTimer, SIGNAL(timeout()), this, SLOT(clearMessage()));
 27	m_messageTimer.setSingleShot(true);
 28	m_messageTimer.setInterval(5000);
 29
 30	clearMessage();
 31}
 32
 33void MessagePainter::resize(const QSize& size, bool lockAspectRatio, qreal scaleFactor) {
 34	int w = size.width();
 35	int h = size.height();
 36	int drawW = w;
 37	int drawH = h;
 38	if (lockAspectRatio) {
 39		if (w * 2 > h * 3) {
 40			drawW = h * 3 / 2;
 41		} else if (w * 2 < h * 3) {
 42			drawH = w * 2 / 3;
 43		}
 44	}
 45	m_world.reset();
 46	m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS);
 47	m_scaleFactor = scaleFactor;
 48	m_local = QPoint(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
 49	m_local = m_world.map(m_local);
 50	m_local += QPoint((w - drawW) / 2, (h - drawH) / 2);
 51	m_pixmapBuffer = QPixmap(drawW * m_scaleFactor,
 52		                     (m_messageFont.pixelSize() + 2) * m_world.m22() * m_scaleFactor);
 53	m_pixmapBuffer.setDevicePixelRatio(m_scaleFactor);
 54	m_mutex.lock();
 55	m_message.prepare(m_world, m_messageFont);
 56	redraw();
 57	m_mutex.unlock();
 58}
 59
 60void MessagePainter::redraw() {
 61	m_pixmapBuffer.fill(Qt::transparent);
 62	if (m_message.text().isEmpty()) {
 63		m_pixmap = m_pixmapBuffer;
 64		m_pixmap.setDevicePixelRatio(m_scaleFactor);
 65		return;
 66	}
 67	QPainter painter(&m_pixmapBuffer);
 68	painter.setWorldTransform(m_world);
 69	painter.setRenderHint(QPainter::Antialiasing);
 70	painter.setFont(m_messageFont);
 71	painter.setPen(Qt::black);
 72	const static int ITERATIONS = 11;
 73	for (int i = 0; i < ITERATIONS; ++i) {
 74		painter.save();
 75		painter.translate(cos(i * 2.0 * M_PI / ITERATIONS) * 0.8, sin(i * 2.0 * M_PI / ITERATIONS) * 0.8);
 76		painter.drawStaticText(0, 0, m_message);
 77		painter.restore();
 78	}
 79	painter.setPen(Qt::white);
 80	painter.drawStaticText(0, 0, m_message);
 81	m_pixmap = m_pixmapBuffer;
 82	m_pixmap.setDevicePixelRatio(m_scaleFactor);
 83}
 84
 85void MessagePainter::paint(QPainter* painter) {
 86	painter->drawPixmap(m_local, m_pixmap);
 87}
 88
 89
 90void MessagePainter::showMessage(const QString& message) {
 91	m_mutex.lock();
 92	m_message.setText(message);
 93	redraw();
 94	m_mutex.unlock();
 95	m_messageTimer.stop();
 96	m_messageTimer.start();
 97}
 98
 99void MessagePainter::clearMessage() {
100	m_mutex.lock();
101	m_message.setText(QString());
102	redraw();
103	m_mutex.unlock();
104	m_messageTimer.stop();
105}