Qt: Start adding background/bezel image support

This commit is contained in:
Vicki Pfau 2023-02-13 15:13:33 -08:00
parent d6c3b012d1
commit bd6edce5cf
9 changed files with 143 additions and 3 deletions

View File

@ -54,6 +54,7 @@ public:
virtual VideoShader* shaders() = 0;
virtual int framebufferHandle() { return -1; }
virtual void setVideoScale(int) {}
virtual void setBackgroundImage(const QImage&) = 0;
virtual void setVideoProxy(std::shared_ptr<VideoProxy> proxy) { m_videoProxy = proxy; }
std::shared_ptr<VideoProxy> videoProxy() { return m_videoProxy; }

View File

@ -396,6 +396,10 @@ void DisplayGL::setVideoScale(int scale) {
QMetaObject::invokeMethod(m_painter.get(), "resizeContext");
}
void DisplayGL::setBackgroundImage(const QImage& image) {
// TODO
}
void DisplayGL::resizeEvent(QResizeEvent* event) {
Display::resizeEvent(event);
resizePainter();

View File

@ -107,6 +107,8 @@ public slots:
void clearShaders() override;
void resizeContext() override;
void setVideoScale(int scale) override;
void setBackgroundImage(const QImage&) override;
protected:
virtual void paintEvent(QPaintEvent*) override { forceDraw(); }

View File

@ -92,19 +92,93 @@ void DisplayQt::resizeContext() {
}
}
void DisplayQt::setBackgroundImage(const QImage& image) {
m_background = image;
update();
}
void DisplayQt::paintEvent(QPaintEvent*) {
QPainter painter(this);
painter.fillRect(QRect(QPoint(), size()), Qt::black);
if (isFiltered()) {
painter.setRenderHint(QPainter::SmoothPixmapTransform);
}
QRect full(clampSize(QSize(m_width, m_height), size(), isAspectRatioLocked(), isIntegerScalingLocked()));
QRect bgRect(0, 0, m_background.width(), m_background.height());
QRect imRect(0, 0, m_width, m_height);
QSize outerFrame;
if (bgRect.width() > imRect.width()) {
imRect.moveLeft(bgRect.width() - imRect.width());
outerFrame.setWidth(bgRect.width());
} else {
bgRect.moveLeft(imRect.width() - bgRect.width());
outerFrame.setWidth(imRect.width());
}
if (bgRect.height() > imRect.height()) {
imRect.moveTop(bgRect.height() - imRect.height());
outerFrame.setHeight(bgRect.height());
} else {
bgRect.moveTop(imRect.height() - bgRect.height());
outerFrame.setHeight(imRect.height());
}
QRect full(clampSize(outerFrame, size(), isAspectRatioLocked(), isIntegerScalingLocked()));
if (m_background.isNull()) {
imRect = full;
} else {
if (imRect.x()) {
imRect.moveLeft(imRect.x() * full.width() / bgRect.width() / 2);
imRect.setWidth(imRect.width() * full.width() / bgRect.width());
bgRect.setWidth(full.width());
} else {
bgRect.moveLeft(bgRect.x() * full.width() / imRect.width() / 2);
bgRect.setWidth(bgRect.width() * full.width() / imRect.width());
imRect.setWidth(full.width());
}
if (imRect.y()) {
imRect.moveTop(imRect.y() * full.height() / bgRect.height() / 2);
imRect.setHeight(imRect.height() * full.height() / bgRect.height());
bgRect.setHeight(full.height());
} else {
bgRect.moveTop(bgRect.y() * full.height() / imRect.height() / 2);
bgRect.setHeight(bgRect.height() * full.height() / imRect.height());
imRect.setHeight(full.height());
}
if (bgRect.right() > imRect.right()) {
if (bgRect.right() < full.right()) {
imRect.translate((full.right() - bgRect.right()), 0);
bgRect.translate((full.right() - bgRect.right()), 0);
}
} else {
if (imRect.right() < full.right()) {
bgRect.translate((full.right() - imRect.right()), 0);
imRect.translate((full.right() - imRect.right()), 0);
}
}
if (bgRect.bottom() > imRect.bottom()) {
if (bgRect.bottom() < full.bottom()) {
imRect.translate(0, (full.bottom() - bgRect.bottom()));
bgRect.translate(0, (full.bottom() - bgRect.bottom()));
}
} else {
if (imRect.bottom() < full.bottom()) {
bgRect.translate(0, (full.bottom() - imRect.bottom()));
imRect.translate(0, (full.bottom() - imRect.bottom()));
}
}
painter.drawImage(bgRect, m_background);
}
if (hasInterframeBlending()) {
painter.drawImage(full, m_oldBacking, QRect(0, 0, m_width, m_height));
painter.drawImage(imRect, m_oldBacking, QRect(0, 0, m_width, m_height));
painter.setOpacity(0.5);
}
painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height));
painter.drawImage(imRect, m_backing, QRect(0, 0, m_width, m_height));
painter.setOpacity(1);
if (isShowOSD() || isShowFrameCounter()) {
messagePainter()->paint(&painter);

View File

@ -36,6 +36,7 @@ public slots:
void setShaders(struct VDir*) override {}
void clearShaders() override {}
void resizeContext() override;
void setBackgroundImage(const QImage&) override;
protected:
virtual void paintEvent(QPaintEvent*) override;
@ -46,6 +47,7 @@ private:
int m_height;
QImage m_backing{nullptr};
QImage m_oldBacking{nullptr};
QImage m_background;
std::shared_ptr<CoreController> m_context = nullptr;
};

View File

@ -143,6 +143,9 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC
connect(m_ui.cheatsBrowse, &QAbstractButton::pressed, [this] () {
selectPath(m_ui.cheatsPath, m_ui.cheatsSameDir);
});
connect(m_ui.bgImageBrowse, &QAbstractButton::pressed, [this] () {
selectImage(m_ui.bgImage);
});
connect(m_ui.clearCache, &QAbstractButton::pressed, this, &SettingsView::libraryCleared);
// TODO: Move to reloadConfig()
@ -445,6 +448,13 @@ void SettingsView::selectPath(QLineEdit* field, QCheckBox* sameDir) {
}
}
void SettingsView::selectImage(QLineEdit* field) {
QString path = GBAApp::app()->getOpenFileName(this, tr("Select image"), tr("Image file (*.png *.jpg *.jpeg)"));
if (!path.isNull()) {
field->setText(makePortablePath(path));
}
}
void SettingsView::updateConfig() {
saveSetting("gba.bios", m_ui.gbaBios);
saveSetting("gb.bios", m_ui.gbBios);
@ -501,6 +511,7 @@ void SettingsView::updateConfig() {
saveSetting("vbaBugCompat", m_ui.vbaBugCompat);
saveSetting("updateAutoCheck", m_ui.updateAutoCheck);
saveSetting("showFilenameInLibrary", m_ui.showFilenameInLibrary);
saveSetting("backgroundImage", m_ui.bgImage);
if (m_ui.audioBufferSize->currentText().toInt() > 8192) {
m_ui.audioBufferSize->setCurrentText("8192");
@ -725,6 +736,7 @@ void SettingsView::reloadConfig() {
loadSetting("vbaBugCompat", m_ui.vbaBugCompat, true);
loadSetting("updateAutoCheck", m_ui.updateAutoCheck);
loadSetting("showFilenameInLibrary", m_ui.showFilenameInLibrary);
loadSetting("backgroundImage", m_ui.bgImage);
m_ui.libraryStyle->setCurrentIndex(loadSetting("libraryStyle").toInt());

View File

@ -71,6 +71,7 @@ public slots:
private slots:
void selectBios(QLineEdit*);
void selectPath(QLineEdit*, QCheckBox*);
void selectImage(QLineEdit*);
void updateConfig();
void reloadConfig();
void updateChecked();

View File

@ -907,6 +907,41 @@
</item>
</layout>
</item>
<item row="19" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_22">
<item>
<widget class="QLineEdit" name="bgImage">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="bgImageBrowse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="18" column="0" colspan="2">
<widget class="Line" name="line_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="19" column="0">
<widget class="QLabel" name="label_53">
<property name="text">
<string>Custom border:</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="update">

View File

@ -1053,6 +1053,8 @@ void Window::reloadDisplayDriver() {
#elif defined(M_CORE_GBA)
m_display->setMinimumSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS);
#endif
m_display->setBackgroundImage(QImage{m_config->getOption("backgroundImage")});
}
void Window::reloadAudioDriver() {
@ -1875,6 +1877,13 @@ void Window::setupOptions() {
updateTitle();
}, this);
ConfigOption* backgroundImage = m_config->addOption("backgroundImage");
backgroundImage->connect([this](const QVariant& value) {
if (m_display) {
m_display->setBackgroundImage(QImage{value.toString()});
}
}, this);
m_config->updateOption("backgroundImage");
}
void Window::attachWidget(QWidget* widget) {