2020-05-02 22:25:35 +01:00
|
|
|
#include "overlay.h"
|
2021-12-07 19:44:40 +00:00
|
|
|
#include "scripting.h"
|
2021-11-22 04:14:15 +00:00
|
|
|
#include "log.h"
|
2020-05-02 22:25:35 +01:00
|
|
|
|
2021-12-09 17:32:19 +00:00
|
|
|
void OverlayText::render(QPainter *painter, int x, int y) {
|
2020-05-02 22:25:35 +01:00
|
|
|
QFont font = painter->font();
|
|
|
|
font.setPixelSize(this->fontSize);
|
|
|
|
painter->setFont(font);
|
|
|
|
painter->setPen(this->color);
|
2022-10-11 04:47:42 +01:00
|
|
|
painter->drawStaticText(this->x + x, this->y + y, this->text);
|
2020-05-02 22:25:35 +01:00
|
|
|
}
|
|
|
|
|
2022-10-11 15:34:09 +01:00
|
|
|
void OverlayPath::render(QPainter *painter, int x, int y) {
|
|
|
|
if (x != this->prevX || y != this->prevY) {
|
|
|
|
// Overlay has moved since the path was last drawn
|
|
|
|
path.translate(x - prevX, y - prevY);
|
|
|
|
}
|
|
|
|
this->prevX = x;
|
|
|
|
this->prevY = y;
|
2022-10-11 19:52:52 +01:00
|
|
|
painter->setPen(this->borderColor);
|
2022-10-11 15:34:09 +01:00
|
|
|
painter->drawPath(this->path);
|
2022-10-11 19:52:52 +01:00
|
|
|
painter->fillPath(this->path, this->fillColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OverlayImage::render(QPainter *painter, int x, int y) {
|
|
|
|
painter->drawImage(this->x + x, this->y + y, this->image);
|
2022-10-11 15:34:09 +01:00
|
|
|
}
|
|
|
|
|
2021-11-30 17:58:39 +00:00
|
|
|
void Overlay::renderItems(QPainter *painter) {
|
2021-11-30 18:38:06 +00:00
|
|
|
if (this->hidden) return;
|
|
|
|
|
2022-10-10 17:22:38 +01:00
|
|
|
if (this->clippingRect) {
|
|
|
|
painter->setClipping(true);
|
|
|
|
painter->setClipRect(*this->clippingRect);
|
|
|
|
}
|
|
|
|
|
2022-08-02 23:53:05 +01:00
|
|
|
qreal oldOpacity = painter->opacity();
|
2021-12-31 21:12:04 +00:00
|
|
|
painter->setOpacity(this->opacity);
|
2021-11-30 18:38:06 +00:00
|
|
|
for (auto item : this->items)
|
2021-12-09 17:32:19 +00:00
|
|
|
item->render(painter, this->x, this->y);
|
2022-08-02 23:53:05 +01:00
|
|
|
painter->setOpacity(oldOpacity);
|
2022-10-10 17:22:38 +01:00
|
|
|
|
|
|
|
if (this->clippingRect) {
|
|
|
|
painter->setClipping(false);
|
|
|
|
}
|
2021-11-30 17:58:39 +00:00
|
|
|
}
|
|
|
|
|
2020-05-02 22:25:35 +01:00
|
|
|
void Overlay::clearItems() {
|
|
|
|
for (auto item : this->items) {
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
this->items.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<OverlayItem*> Overlay::getItems() {
|
|
|
|
return this->items;
|
|
|
|
}
|
|
|
|
|
2021-12-09 17:32:19 +00:00
|
|
|
bool Overlay::getHidden() {
|
|
|
|
return this->hidden;
|
|
|
|
}
|
|
|
|
|
2021-11-30 18:38:06 +00:00
|
|
|
void Overlay::setHidden(bool hidden) {
|
|
|
|
this->hidden = hidden;
|
|
|
|
}
|
|
|
|
|
2021-12-31 21:12:04 +00:00
|
|
|
int Overlay::getOpacity() {
|
|
|
|
return this->opacity * 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Overlay::setOpacity(int opacity) {
|
|
|
|
if (opacity < 0 || opacity > 100) {
|
2022-10-11 19:52:52 +01:00
|
|
|
logError(QString("Invalid overlay opacity '%1', must be in range 0-100").arg(opacity));
|
2021-12-31 21:12:04 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
this->opacity = static_cast<qreal>(opacity) / 100;
|
|
|
|
}
|
|
|
|
|
2021-12-09 17:32:19 +00:00
|
|
|
int Overlay::getX() {
|
|
|
|
return this->x;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Overlay::getY() {
|
|
|
|
return this->y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Overlay::setX(int x) {
|
|
|
|
this->x = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Overlay::setY(int y) {
|
|
|
|
this->y = y;
|
|
|
|
}
|
|
|
|
|
2022-10-10 17:22:38 +01:00
|
|
|
void Overlay::setClippingRect(QRectF rect) {
|
|
|
|
if (this->clippingRect) {
|
|
|
|
delete this->clippingRect;
|
|
|
|
}
|
|
|
|
this->clippingRect = new QRectF(rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Overlay::clearClippingRect() {
|
|
|
|
if (this->clippingRect) {
|
|
|
|
delete this->clippingRect;
|
|
|
|
}
|
|
|
|
this->clippingRect = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-09 17:32:19 +00:00
|
|
|
void Overlay::setPosition(int x, int y) {
|
|
|
|
this->x = x;
|
|
|
|
this->y = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Overlay::move(int deltaX, int deltaY) {
|
|
|
|
this->x += deltaX;
|
|
|
|
this->y += deltaY;
|
|
|
|
}
|
|
|
|
|
2022-10-11 19:52:52 +01:00
|
|
|
QColor Overlay::getColor(QString colorStr) {
|
2022-10-11 18:30:27 +01:00
|
|
|
if (colorStr.isEmpty())
|
|
|
|
colorStr = "transparent";
|
|
|
|
QColor color = QColor(colorStr);
|
|
|
|
if (!color.isValid()) {
|
2022-10-11 19:52:52 +01:00
|
|
|
logWarn(QString("Invalid overlay color \"%1\". Colors can be in the format \"#RRGGBB\" or \"#AARRGGBB\"").arg(colorStr));
|
|
|
|
color = QColor("transparent");
|
2022-10-11 18:30:27 +01:00
|
|
|
}
|
|
|
|
return color;
|
2020-05-02 22:25:35 +01:00
|
|
|
}
|
|
|
|
|
2022-10-11 19:52:52 +01:00
|
|
|
void Overlay::addText(const QString text, int x, int y, QString colorStr, int fontSize) {
|
|
|
|
this->items.append(new OverlayText(text, x, y, getColor(colorStr), fontSize));
|
2022-10-11 18:30:27 +01:00
|
|
|
}
|
|
|
|
|
2022-10-11 19:52:52 +01:00
|
|
|
bool Overlay::addRect(int x, int y, int width, int height, QString borderColorStr, QString fillColorStr, int rounding) {
|
|
|
|
if (rounding < 0 || rounding > 100) {
|
|
|
|
logError(QString("Invalid rectangle rounding '%1', must be in range 0-100").arg(rounding));
|
|
|
|
return false;
|
|
|
|
}
|
2022-10-11 18:30:27 +01:00
|
|
|
|
2022-10-11 19:52:52 +01:00
|
|
|
QPainterPath path;
|
|
|
|
path.addRoundedRect(QRectF(x, y, width, height), rounding, rounding, Qt::RelativeSize);
|
|
|
|
this->items.append(new OverlayPath(path, getColor(borderColorStr), getColor(fillColorStr)));
|
2022-10-11 18:30:27 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-10-11 19:52:52 +01:00
|
|
|
bool Overlay::addPath(QList<int> x, QList<int> y, QString borderColorStr, QString fillColorStr) {
|
2022-10-11 18:30:27 +01:00
|
|
|
int numPoints = qMin(x.length(), y.length());
|
|
|
|
if (numPoints < 2) {
|
|
|
|
logError("Overlay path must have at least two points.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QPainterPath path;
|
|
|
|
path.moveTo(x.at(0), y.at(0));
|
|
|
|
|
|
|
|
for (int i = 1; i < numPoints; i++)
|
|
|
|
path.lineTo(x.at(i), y.at(i));
|
|
|
|
|
2022-10-11 19:52:52 +01:00
|
|
|
this->items.append(new OverlayPath(path, getColor(borderColorStr), getColor(fillColorStr)));
|
2022-10-11 18:30:27 +01:00
|
|
|
return true;
|
2020-05-02 22:25:35 +01:00
|
|
|
}
|
|
|
|
|
2022-10-01 22:38:50 +01:00
|
|
|
bool Overlay::addImage(int x, int y, QString filepath, bool useCache, int width, int height, int xOffset, int yOffset, qreal hScale, qreal vScale, QList<QRgb> palette, bool setTransparency) {
|
2021-12-10 16:55:21 +00:00
|
|
|
QImage image = useCache ? Scripting::getImage(filepath) : QImage(filepath);
|
2021-11-22 04:14:15 +00:00
|
|
|
if (image.isNull()) {
|
|
|
|
logError(QString("Failed to load image '%1'").arg(filepath));
|
|
|
|
return false;
|
|
|
|
}
|
2021-11-28 04:50:44 +00:00
|
|
|
|
|
|
|
int fullWidth = image.width();
|
|
|
|
int fullHeight = image.height();
|
|
|
|
|
2022-10-01 22:38:50 +01:00
|
|
|
// Negative values used as an indicator for "use full dimension"
|
2021-11-28 04:50:44 +00:00
|
|
|
if (width <= 0)
|
|
|
|
width = fullWidth;
|
|
|
|
if (height <= 0)
|
|
|
|
height = fullHeight;
|
|
|
|
|
2022-10-01 22:38:50 +01:00
|
|
|
if (xOffset < 0) xOffset = 0;
|
|
|
|
if (yOffset < 0) yOffset = 0;
|
|
|
|
|
|
|
|
if (width + xOffset > fullWidth || height + yOffset > fullHeight) {
|
|
|
|
logError(QString("%1x%2 image starting at (%3,%4) exceeds the image size for '%5'")
|
2021-11-28 04:50:44 +00:00
|
|
|
.arg(width)
|
|
|
|
.arg(height)
|
2022-10-01 22:38:50 +01:00
|
|
|
.arg(xOffset)
|
|
|
|
.arg(yOffset)
|
2021-11-28 04:50:44 +00:00
|
|
|
.arg(filepath));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get specified subset of image
|
|
|
|
if (width != fullWidth || height != fullHeight)
|
2022-10-01 22:38:50 +01:00
|
|
|
image = image.copy(xOffset, yOffset, width, height);
|
2021-11-28 04:50:44 +00:00
|
|
|
|
2022-08-31 15:52:43 +01:00
|
|
|
if (hScale != 1 || vScale != 1)
|
|
|
|
image = image.transformed(QTransform().scale(hScale, vScale));
|
2021-12-08 14:20:17 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < palette.size(); i++)
|
|
|
|
image.setColor(i, palette.at(i));
|
2021-11-28 04:50:44 +00:00
|
|
|
|
|
|
|
if (setTransparency)
|
|
|
|
image.setColor(0, qRgba(0, 0, 0, 0));
|
|
|
|
|
2021-11-22 04:14:15 +00:00
|
|
|
this->items.append(new OverlayImage(x, y, image));
|
|
|
|
return true;
|
2020-05-02 22:25:35 +01:00
|
|
|
}
|
2021-12-01 21:06:14 +00:00
|
|
|
|
|
|
|
bool Overlay::addImage(int x, int y, QImage image) {
|
|
|
|
if (image.isNull()) {
|
|
|
|
logError(QString("Failed to load custom image"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this->items.append(new OverlayImage(x, y, image));
|
|
|
|
return true;
|
|
|
|
}
|