mirror of https://github.com/mgba-emu/mgba.git
Qt: Use MessagePainter with GL and Qt messages
This commit is contained in:
parent
4469a9a05f
commit
fe845d1ee8
|
@ -67,6 +67,7 @@ set(SOURCE_FILES
|
||||||
LogView.cpp
|
LogView.cpp
|
||||||
MemoryModel.cpp
|
MemoryModel.cpp
|
||||||
MemoryView.cpp
|
MemoryView.cpp
|
||||||
|
MessagePainter.cpp
|
||||||
MultiplayerController.cpp
|
MultiplayerController.cpp
|
||||||
OverrideView.cpp
|
OverrideView.cpp
|
||||||
PaletteView.cpp
|
PaletteView.cpp
|
||||||
|
|
|
@ -135,8 +135,8 @@ void DisplayGL::resizePainter() {
|
||||||
PainterGL::PainterGL(QGLWidget* parent)
|
PainterGL::PainterGL(QGLWidget* parent)
|
||||||
: m_gl(parent)
|
: m_gl(parent)
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_messageTimer(this)
|
|
||||||
, m_context(nullptr)
|
, m_context(nullptr)
|
||||||
|
, m_messagePainter(nullptr)
|
||||||
{
|
{
|
||||||
GBAGLContextCreate(&m_backend);
|
GBAGLContextCreate(&m_backend);
|
||||||
m_backend.d.swap = [](VideoBackend* v) {
|
m_backend.d.swap = [](VideoBackend* v) {
|
||||||
|
@ -146,14 +146,6 @@ PainterGL::PainterGL(QGLWidget* parent)
|
||||||
m_backend.d.user = this;
|
m_backend.d.user = this;
|
||||||
m_backend.d.filter = false;
|
m_backend.d.filter = false;
|
||||||
m_backend.d.lockAspectRatio = false;
|
m_backend.d.lockAspectRatio = false;
|
||||||
m_messageFont.setFamily("Source Code Pro");
|
|
||||||
m_messageFont.setStyleHint(QFont::Monospace);
|
|
||||||
m_messageFont.setPixelSize(13);
|
|
||||||
connect(&m_messageTimer, SIGNAL(timeout()), this, SLOT(clearMessage()));
|
|
||||||
m_messageTimer.setSingleShot(true);
|
|
||||||
m_messageTimer.setInterval(5000);
|
|
||||||
|
|
||||||
clearMessage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::setContext(GBAThread* context) {
|
void PainterGL::setContext(GBAThread* context) {
|
||||||
|
@ -171,22 +163,8 @@ void PainterGL::setBacking(const uint32_t* backing) {
|
||||||
|
|
||||||
void PainterGL::resize(const QSize& size) {
|
void PainterGL::resize(const QSize& size) {
|
||||||
m_size = size;
|
m_size = size;
|
||||||
int w = m_size.width();
|
|
||||||
int h = m_size.height();
|
|
||||||
int drawW = w;
|
|
||||||
int drawH = h;
|
|
||||||
if (m_backend.d.lockAspectRatio) {
|
|
||||||
if (w * 2 > h * 3) {
|
|
||||||
drawW = h * 3 / 2;
|
|
||||||
} else if (w * 2 < h * 3) {
|
|
||||||
drawH = w * 2 / 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_world.reset();
|
|
||||||
m_world.translate((w - drawW) / 2, (h - drawH) / 2);
|
|
||||||
m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS);
|
|
||||||
m_message.prepare(m_world, m_messageFont);
|
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
|
m_messagePainter->resize(size, m_backend.d.lockAspectRatio);
|
||||||
forceDraw();
|
forceDraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +172,7 @@ void PainterGL::resize(const QSize& size) {
|
||||||
void PainterGL::lockAspectRatio(bool lock) {
|
void PainterGL::lockAspectRatio(bool lock) {
|
||||||
m_backend.d.lockAspectRatio = lock;
|
m_backend.d.lockAspectRatio = lock;
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
|
m_messagePainter->resize(m_size, m_backend.d.lockAspectRatio);
|
||||||
forceDraw();
|
forceDraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +185,8 @@ void PainterGL::filter(bool filter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::start() {
|
void PainterGL::start() {
|
||||||
|
m_messagePainter = new MessagePainter(this);
|
||||||
|
m_messagePainter->resize(m_size, m_backend.d.lockAspectRatio);
|
||||||
m_gl->makeCurrent();
|
m_gl->makeCurrent();
|
||||||
m_backend.d.init(&m_backend.d, reinterpret_cast<WHandle>(m_gl->winId()));
|
m_backend.d.init(&m_backend.d, reinterpret_cast<WHandle>(m_gl->winId()));
|
||||||
m_gl->doneCurrent();
|
m_gl->doneCurrent();
|
||||||
|
@ -239,6 +220,9 @@ void PainterGL::stop() {
|
||||||
m_backend.d.deinit(&m_backend.d);
|
m_backend.d.deinit(&m_backend.d);
|
||||||
m_gl->doneCurrent();
|
m_gl->doneCurrent();
|
||||||
m_gl->context()->moveToThread(m_gl->thread());
|
m_gl->context()->moveToThread(m_gl->thread());
|
||||||
|
m_messagePainter->clearMessage();
|
||||||
|
delete m_messagePainter;
|
||||||
|
m_messagePainter = nullptr;
|
||||||
moveToThread(m_gl->thread());
|
moveToThread(m_gl->thread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,28 +243,9 @@ void PainterGL::performDraw() {
|
||||||
m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r);
|
m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r);
|
||||||
m_backend.d.drawFrame(&m_backend.d);
|
m_backend.d.drawFrame(&m_backend.d);
|
||||||
m_painter.endNativePainting();
|
m_painter.endNativePainting();
|
||||||
m_painter.setWorldTransform(m_world);
|
m_messagePainter->paint(&m_painter);
|
||||||
m_painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
m_painter.setFont(m_messageFont);
|
|
||||||
m_painter.setPen(Qt::black);
|
|
||||||
m_painter.translate(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
m_painter.save();
|
|
||||||
m_painter.translate(cos(i * M_PI / 8.0) * 0.8, sin(i * M_PI / 8.0) * 0.8);
|
|
||||||
m_painter.drawStaticText(0, 0, m_message);
|
|
||||||
m_painter.restore();
|
|
||||||
}
|
|
||||||
m_painter.setPen(Qt::white);
|
|
||||||
m_painter.drawStaticText(0, 0, m_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::showMessage(const QString& message) {
|
void PainterGL::showMessage(const QString& message) {
|
||||||
m_message.setText(message);
|
m_messagePainter->showMessage(message);
|
||||||
m_message.prepare(m_world, m_messageFont);
|
|
||||||
m_messageTimer.stop();
|
|
||||||
m_messageTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PainterGL::clearMessage() {
|
|
||||||
m_message.setText(QString());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include "MessagePainter.h"
|
||||||
|
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
#include <QStaticText>
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
@ -86,21 +87,17 @@ public slots:
|
||||||
void filter(bool filter);
|
void filter(bool filter);
|
||||||
|
|
||||||
void showMessage(const QString& message);
|
void showMessage(const QString& message);
|
||||||
void clearMessage();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void performDraw();
|
void performDraw();
|
||||||
|
|
||||||
QPainter m_painter;
|
QPainter m_painter;
|
||||||
QStaticText m_message;
|
|
||||||
QGLWidget* m_gl;
|
QGLWidget* m_gl;
|
||||||
bool m_active;
|
bool m_active;
|
||||||
QTimer m_messageTimer;
|
|
||||||
GBAThread* m_context;
|
GBAThread* m_context;
|
||||||
GBAGLContext m_backend;
|
GBAGLContext m_backend;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
QTransform m_world;
|
MessagePainter* m_messagePainter;
|
||||||
QFont m_messageFont;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,10 @@ void DisplayQt::framePosted(const uint32_t* buffer) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayQt::showMessage(const QString& message) {
|
||||||
|
m_messagePainter.showMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayQt::paintEvent(QPaintEvent*) {
|
void DisplayQt::paintEvent(QPaintEvent*) {
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.fillRect(QRect(QPoint(), size()), Qt::black);
|
painter.fillRect(QRect(QPoint(), size()), Qt::black);
|
||||||
|
@ -54,11 +58,13 @@ void DisplayQt::paintEvent(QPaintEvent*) {
|
||||||
}
|
}
|
||||||
QSize s = size();
|
QSize s = size();
|
||||||
QSize ds = s;
|
QSize ds = s;
|
||||||
|
if (m_lockAspectRatio) {
|
||||||
if (s.width() * 2 > s.height() * 3) {
|
if (s.width() * 2 > s.height() * 3) {
|
||||||
ds.setWidth(s.height() * 3 / 2);
|
ds.setWidth(s.height() * 3 / 2);
|
||||||
} else if (s.width() * 2 < s.height() * 3) {
|
} else if (s.width() * 2 < s.height() * 3) {
|
||||||
ds.setHeight(s.width() * 2 / 3);
|
ds.setHeight(s.width() * 2 / 3);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2);
|
QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2);
|
||||||
QRect full(origin, ds);
|
QRect full(origin, ds);
|
||||||
|
|
||||||
|
@ -67,4 +73,9 @@ void DisplayQt::paintEvent(QPaintEvent*) {
|
||||||
#else
|
#else
|
||||||
painter.drawImage(full, m_backing.rgbSwapped(), QRect(0, 0, 240, 160));
|
painter.drawImage(full, m_backing.rgbSwapped(), QRect(0, 0, 240, 160));
|
||||||
#endif
|
#endif
|
||||||
|
m_messagePainter.paint(&painter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayQt::resizeEvent(QResizeEvent*) {
|
||||||
|
m_messagePainter.resize(size(), m_lockAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define QGBA_DISPLAY_QT
|
#define QGBA_DISPLAY_QT
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "MessagePainter.h"
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
@ -31,15 +32,17 @@ public slots:
|
||||||
void filter(bool filter) override;
|
void filter(bool filter) override;
|
||||||
void framePosted(const uint32_t*) override;
|
void framePosted(const uint32_t*) override;
|
||||||
|
|
||||||
void showMessage(const QString& message) override {};
|
void showMessage(const QString& message) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void paintEvent(QPaintEvent*) override;
|
virtual void paintEvent(QPaintEvent*) override;
|
||||||
|
virtual void resizeEvent(QResizeEvent*) override;;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QImage m_backing;
|
QImage m_backing;
|
||||||
bool m_lockAspectRatio;
|
bool m_lockAspectRatio;
|
||||||
bool m_filter;
|
bool m_filter;
|
||||||
|
MessagePainter m_messagePainter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "MessagePainter.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "gba/video.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace QGBA;
|
||||||
|
|
||||||
|
MessagePainter::MessagePainter(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_messageTimer(this)
|
||||||
|
{
|
||||||
|
m_messageFont.setFamily("Source Code Pro");
|
||||||
|
m_messageFont.setStyleHint(QFont::Monospace);
|
||||||
|
m_messageFont.setPixelSize(13);
|
||||||
|
connect(&m_messageTimer, SIGNAL(timeout()), this, SLOT(clearMessage()));
|
||||||
|
m_messageTimer.setSingleShot(true);
|
||||||
|
m_messageTimer.setInterval(5000);
|
||||||
|
|
||||||
|
clearMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagePainter::resize(const QSize& size, bool lockAspectRatio) {
|
||||||
|
int w = size.width();
|
||||||
|
int h = size.height();
|
||||||
|
int drawW = w;
|
||||||
|
int drawH = h;
|
||||||
|
if (lockAspectRatio) {
|
||||||
|
if (w * 2 > h * 3) {
|
||||||
|
drawW = h * 3 / 2;
|
||||||
|
} else if (w * 2 < h * 3) {
|
||||||
|
drawH = w * 2 / 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_world.reset();
|
||||||
|
m_world.translate((w - drawW) / 2, (h - drawH) / 2);
|
||||||
|
m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS);
|
||||||
|
m_message.prepare(m_world, m_messageFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagePainter::paint(QPainter* painter) {
|
||||||
|
painter->setWorldTransform(m_world);
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter->setFont(m_messageFont);
|
||||||
|
painter->setPen(Qt::black);
|
||||||
|
painter->translate(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
|
||||||
|
const static int ITERATIONS = 11;
|
||||||
|
for (int i = 0; i < ITERATIONS; ++i) {
|
||||||
|
painter->save();
|
||||||
|
painter->translate(cos(i * 2.0 * M_PI / ITERATIONS) * 0.8, sin(i * 2.0 * M_PI / ITERATIONS) * 0.8);
|
||||||
|
painter->drawStaticText(0, 0, m_message);
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
painter->setPen(Qt::white);
|
||||||
|
painter->drawStaticText(0, 0, m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagePainter::showMessage(const QString& message) {
|
||||||
|
m_message.setText(message);
|
||||||
|
m_message.prepare(m_world, m_messageFont);
|
||||||
|
m_messageTimer.stop();
|
||||||
|
m_messageTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagePainter::clearMessage() {
|
||||||
|
m_message.setText(QString());
|
||||||
|
m_messageTimer.stop();
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef QGBA_MESSAGE_PAINTER
|
||||||
|
#define QGBA_MESSAGE_PAINTER
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QStaticText>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
namespace QGBA {
|
||||||
|
|
||||||
|
class MessagePainter : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MessagePainter(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
void resize(const QSize& size, bool lockAspectRatio);
|
||||||
|
void paint(QPainter* painter);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void showMessage(const QString& message);
|
||||||
|
void clearMessage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStaticText m_message;
|
||||||
|
QTimer m_messageTimer;
|
||||||
|
QTransform m_world;
|
||||||
|
QFont m_messageFont;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue