Files
86Box/src/qt/qt_renderercommon.cpp

204 lines
6.8 KiB
C++
Raw Normal View History

2022-02-07 15:00:02 +06:00
/*
2023-01-06 15:36:05 -05:00
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86Box distribution.
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Program settings UI module.
2022-02-07 15:00:02 +06:00
*
*
*
* Authors: Joakim L. Gilje <jgilje@jgilje.net>
*
2023-01-06 15:36:05 -05:00
* Copyright 2021 Joakim L. Gilje
2022-02-07 15:00:02 +06:00
*/
#include "qt_renderercommon.hpp"
#include "qt_mainwindow.hpp"
#include "qt_machinestatus.hpp"
2021-12-07 13:47:42 +01:00
#include <QPainter>
#include <QWidget>
#include <QEvent>
#include <QApplication>
#include <QFontMetrics>
#include <QStatusBar>
#include <QLayout>
2021-12-07 13:47:42 +01:00
#include <cmath>
extern "C" {
#include <86box/86box.h>
#include <86box/plat.h>
2021-12-07 13:47:42 +01:00
#include <86box/video.h>
int status_icons_fullscreen = 0;
2021-12-07 13:47:42 +01:00
}
RendererCommon::RendererCommon() = default;
2022-11-19 08:49:04 -05:00
extern MainWindow *main_window;
2021-12-07 13:47:42 +01:00
2022-11-19 08:49:04 -05:00
static void
integer_scale(double *d, double *g)
{
2021-12-07 13:47:42 +01:00
double ratio;
if (*d > *g) {
ratio = std::floor(*d / *g);
2022-11-19 08:49:04 -05:00
*d = *g * ratio;
2021-12-07 13:47:42 +01:00
} else {
ratio = std::ceil(*d / *g);
2022-11-19 08:49:04 -05:00
*d = *g / ratio;
2021-12-07 13:47:42 +01:00
}
}
2022-11-19 08:49:04 -05:00
void
RendererCommon::onResize(int width, int height)
{
/* This is needed so that the if below does not take like, 5 lines. */
bool is_fs = (video_fullscreen == 0);
bool parent_max = (parentWidget->isMaximized() == false);
bool main_is_ancestor = main_window->isAncestorOf(parentWidget);
bool main_max = main_window->isMaximized();
bool main_is_max = (main_is_ancestor && main_max == false);
if (is_fs && (video_fullscreen_scale_maximized ? (parent_max && main_is_max) : 1))
2021-12-07 13:47:42 +01:00
destination.setRect(0, 0, width, height);
else {
double dx;
double dy;
double dw;
double dh;
double gsr;
2021-12-07 13:47:42 +01:00
double hw = width;
double hh = height;
double gw = source.width();
double gh = source.height();
double hsr = hw / hh;
2023-10-14 23:42:02 +02:00
double r43 = 4.0 / 3.0;
2021-12-07 13:47:42 +01:00
switch (video_fullscreen_scale) {
case FULLSCR_SCALE_INT:
case FULLSCR_SCALE_INT43:
2023-10-14 23:42:02 +02:00
gsr = gw / gh;
2023-10-16 01:41:57 +02:00
if (video_fullscreen_scale == FULLSCR_SCALE_INT43) {
gh = gw / r43;
gw = gw;
2021-12-07 13:47:42 +01:00
2023-10-16 01:41:57 +02:00
gsr = r43;
}
if (gsr <= hsr) {
dw = hh * gsr;
dh = hh;
} else {
dw = hw;
dh = hw / gsr;
}
2023-10-14 23:42:02 +02:00
integer_scale(&dw, &gw);
integer_scale(&dh, &gh);
2023-10-14 23:42:02 +02:00
dx = (hw - dw) / 2.0;
dy = (hh - dh) / 2.0;
destination.setRect((int) dx, (int) dy, (int) dw, (int) dh);
break;
case FULLSCR_SCALE_43:
case FULLSCR_SCALE_KEEPRATIO:
if (video_fullscreen_scale == FULLSCR_SCALE_43)
2023-10-14 23:42:02 +02:00
gsr = r43;
else
gsr = gw / gh;
2021-12-07 13:47:42 +01:00
if (gsr <= hsr) {
dw = hh * gsr;
dh = hh;
} else {
dw = hw;
dh = hw / gsr;
}
dx = (hw - dw) / 2.0;
dy = (hh - dh) / 2.0;
destination.setRect((int) dx, (int) dy, (int) dw, (int) dh);
break;
case FULLSCR_SCALE_FULL:
default:
destination.setRect(0, 0, (int) hw, (int) hh);
break;
2021-12-07 13:47:42 +01:00
}
}
monitors[r_monitor_index].mon_res_x = (double) destination.width();
monitors[r_monitor_index].mon_res_y = (double) destination.height();
2021-12-07 13:47:42 +01:00
}
void RendererCommon::drawStatusBarIcons(QPainter* painter)
{
uint32_t x = 0;
auto prevcompositionMode = painter->compositionMode();
painter->setCompositionMode(QPainter::CompositionMode::CompositionMode_SourceOver);
for (int i = 0; i < main_window->statusBar()->children().count(); i++) {
QLabel* label = qobject_cast<QLabel*>(main_window->statusBar()->children()[i]);
if (label) {
2022-02-16 14:37:09 +06:00
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
const QPixmap pixmap = label->pixmap();
#else
const QPixmap pixmap = label->pixmap() ? *label->pixmap() : QPixmap();
2022-02-16 14:37:09 +06:00
#endif
if (!pixmap.isNull()) {
painter->setBrush(QColor::fromRgbF(0, 0, 0, 1.));
painter->fillRect(x, painter->device()->height() - pixmap.height() - 5,
pixmap.width(), pixmap.height() + 5, QColor::fromRgbF(0, 0, 0, .5));
painter->drawPixmap(x + main_window->statusBar()->layout()->spacing() / 2,
painter->device()->height() - pixmap.height() - 3, pixmap);
x += pixmap.width();
if (i <= main_window->statusBar()->children().count() - 3) {
painter->fillRect(x, painter->device()->height() - pixmap.height() - 5,
main_window->statusBar()->layout()->spacing(), pixmap.height() + 5,
QColor::fromRgbF(0, 0, 0, .5));
x += main_window->statusBar()->layout()->spacing();
} else
painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4,
pixmap.height() + 4, QColor::fromRgbF(0, 0, 0, .5));
}
}
}
if (main_window->status->getMessage().isEmpty() == false) {
auto curStatusMsg = main_window->status->getMessage();
auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' '));
painter->setPen(QColor(0, 0, 0, 127));
painter->fillRect(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(),
textSize.width(), textSize.height(), QColor(0, 0, 0, 127));
painter->setPen(QColor(255, 255, 255, 255));
painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(),
textSize.width(), textSize.height()), Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' '));
}
painter->setCompositionMode(prevcompositionMode);
}
2022-11-19 08:49:04 -05:00
bool
RendererCommon::eventDelegate(QEvent *event, bool &result)
{
2022-11-19 08:49:04 -05:00
switch (event->type()) {
default:
return false;
case QEvent::KeyPress:
case QEvent::KeyRelease:
result = QApplication::sendEvent(main_window, event);
return true;
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
case QEvent::Wheel:
case QEvent::Enter:
case QEvent::Leave:
result = QApplication::sendEvent(parentWidget, event);
return true;
}
}