all repos — mgba @ 40c3fc63ccad3ab59b6b37399cd6fe8ea1de3f3e

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 "GBAApp.h"
  9
 10#include <QPainter>
 11
 12#include <mgba/gba/interface.h>
 13
 14using namespace QGBA;
 15
 16MessagePainter::MessagePainter(QObject* parent)
 17	: QObject(parent)
 18{
 19	m_messageFont = GBAApp::monospaceFont();
 20	m_messageFont.setPixelSize(13);
 21	connect(&m_messageTimer, &QTimer::timeout, this, &MessagePainter::clearMessage);
 22	m_messageTimer.setSingleShot(true);
 23	m_messageTimer.setInterval(5000);
 24
 25	clearMessage();
 26}
 27
 28void MessagePainter::resize(const QSize& size, bool lockAspectRatio, qreal scaleFactor) {
 29	int w = size.width();
 30	int h = size.height();
 31	int drawW = w;
 32	int drawH = h;
 33	if (lockAspectRatio) {
 34		if (w * 2 > h * 3) {
 35			drawW = h * 3 / 2;
 36		} else if (w * 2 < h * 3) {
 37			drawH = w * 2 / 3;
 38		}
 39	}
 40	m_world.reset();
 41	m_world.scale(qreal(drawW) / GBA_VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / GBA_VIDEO_VERTICAL_PIXELS);
 42	m_scaleFactor = scaleFactor;
 43	m_local = QPoint(1, GBA_VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
 44	m_local = m_world.map(m_local);
 45	m_local += QPoint((w - drawW) / 2, (h - drawH) / 2);
 46	m_pixmapBuffer = QPixmap(drawW * m_scaleFactor,
 47		                     (m_messageFont.pixelSize() + 2) * m_world.m22() * m_scaleFactor);
 48	m_pixmapBuffer.setDevicePixelRatio(m_scaleFactor);
 49	m_mutex.lock();
 50	m_message.prepare(m_world, m_messageFont);
 51	redraw();
 52	m_mutex.unlock();
 53}
 54
 55void MessagePainter::redraw() {
 56	m_pixmapBuffer.fill(Qt::transparent);
 57	if (m_message.text().isEmpty()) {
 58		m_pixmap = m_pixmapBuffer;
 59		m_pixmap.setDevicePixelRatio(m_scaleFactor);
 60		return;
 61	}
 62	QPainter painter(&m_pixmapBuffer);
 63	painter.setWorldTransform(m_world);
 64	painter.setRenderHint(QPainter::Antialiasing);
 65	painter.setFont(m_messageFont);
 66	painter.setPen(Qt::black);
 67	const static int ITERATIONS = 11;
 68	for (int i = 0; i < ITERATIONS; ++i) {
 69		painter.save();
 70		painter.translate(cos(i * 2.0 * M_PI / ITERATIONS) * 0.8, sin(i * 2.0 * M_PI / ITERATIONS) * 0.8);
 71		painter.drawStaticText(0, 0, m_message);
 72		painter.restore();
 73	}
 74	painter.setPen(Qt::white);
 75	painter.drawStaticText(0, 0, m_message);
 76	m_pixmap = m_pixmapBuffer;
 77	m_pixmap.setDevicePixelRatio(m_scaleFactor);
 78}
 79
 80void MessagePainter::paint(QPainter* painter) {
 81	if (!m_message.text().isEmpty()) {
 82		painter->drawPixmap(m_local, m_pixmap);
 83	}
 84}
 85
 86
 87void MessagePainter::showMessage(const QString& message) {
 88	m_mutex.lock();
 89	m_message.setText(message);
 90	redraw();
 91	m_mutex.unlock();
 92	m_messageTimer.stop();
 93	m_messageTimer.start();
 94}
 95
 96void MessagePainter::clearMessage() {
 97	m_mutex.lock();
 98	m_message.setText(QString());
 99	redraw();
100	m_mutex.unlock();
101	m_messageTimer.stop();
102}