225 lines
7.6 KiB
C++
225 lines
7.6 KiB
C++
#include "screenoverlay.hpp"
|
|
|
|
#include "screenoverlaysettings.hpp"
|
|
#include <QApplication>
|
|
#include <QCursor>
|
|
#include <QGraphicsSceneMouseEvent>
|
|
#include <QGraphicsView>
|
|
#include <QKeyEvent>
|
|
#include <settings.hpp>
|
|
#include <utils.hpp>
|
|
|
|
ScreenOverlay::ScreenOverlay(QPixmap pixmap, QObject *parent) : QGraphicsScene(parent), _pixmap(pixmap) {
|
|
addPixmap(pixmap)->setZValue(-1);
|
|
QPolygonF cursorPoly;
|
|
cursorPoly << QPoint(-10, 0) //
|
|
<< QPoint(10, 0) //
|
|
<< QPoint(0, 0) //
|
|
<< QPoint(0, 10) //
|
|
<< QPoint(0, -10) //
|
|
<< QPoint(0, 0);
|
|
|
|
cursorItem = addPolygon(cursorPoly, QPen(Qt::white));
|
|
cursorItem->setZValue(199);
|
|
|
|
magnifier = addPixmap(QPixmap(110, 110));
|
|
magnifierBox = addRect(magnifier->boundingRect(), QPen(highlight()));
|
|
magnifier->setZValue(199);
|
|
magnifierBox->setZValue(199);
|
|
magnifierBox->setParentItem(magnifier);
|
|
magnifierHint = addText("ptr: (0, 0)\nsel: (-1, -1, 0, 0)");
|
|
magnifierHint->setParentItem(magnifier);
|
|
magnifierHint->setY(magnifier->boundingRect().height());
|
|
QColor c(highlight());
|
|
c.setAlphaF(.25);
|
|
magnifierHintBox = addRect(magnifierHint->boundingRect(), Qt::NoPen, c);
|
|
magnifierHintBox->setParentItem(magnifierHint);
|
|
magnifierHintBox->setZValue(199);
|
|
magnifierHint->setZValue(199);
|
|
updateMag();
|
|
loadSettings();
|
|
}
|
|
|
|
void ScreenOverlay::wheelEvent(QGraphicsSceneWheelEvent *e) {
|
|
int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt();
|
|
if (pixCnt % 2 == 0) pixCnt++;
|
|
if (pixCnt > 20) return;
|
|
if (e->delta() > 0 && pixCnt < 19)
|
|
settings::settings().setValue("magnifierPixelCount", pixCnt += 2);
|
|
else if (pixCnt > 1)
|
|
settings::settings().setValue("magnifierPixelCount", pixCnt -= 2);
|
|
|
|
for (auto item : gridRectsX) delete item;
|
|
gridRectsX.clear();
|
|
for (auto item : gridRectsY) delete item;
|
|
gridRectsY.clear();
|
|
|
|
if (grid()) updateMagnifierGrid();
|
|
updateMag();
|
|
|
|
QGraphicsScene::wheelEvent(e);
|
|
}
|
|
|
|
void ScreenOverlay::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
|
QPointF delta = e->scenePos() - cursorPos();
|
|
if (e->modifiers() & Qt::ShiftModifier) {
|
|
setCursorPos(cursorPos() + (delta / 2));
|
|
QCursor::setPos(views()[0]->mapToGlobal(cursorPos().toPoint()));
|
|
} else
|
|
setCursorPos(e->scenePos());
|
|
cursorItem->setPos(cursorPos());
|
|
updateMag();
|
|
mouseMoved(e, cursorPos(), delta);
|
|
}
|
|
|
|
void ScreenOverlay::moveMouse(QPoint newPos) {
|
|
QMouseEvent eve(QEvent::MouseMove, newPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
|
for (auto &v : views()) {
|
|
QCursor::setPos(v->mapToGlobal(newPos));
|
|
QApplication::sendEvent(v->viewport(), &eve);
|
|
}
|
|
}
|
|
|
|
void ScreenOverlay::moveMouseBy(QPoint delta) {
|
|
moveMouse(cursorPos().toPoint() + delta);
|
|
}
|
|
|
|
void ScreenOverlay::hideMag() {
|
|
magnifier->setVisible(false);
|
|
cursorItem->setVisible(false);
|
|
magnifierBox->setVisible(false);
|
|
magnifierHint->setVisible(false);
|
|
magnifierHintBox->setVisible(false);
|
|
}
|
|
|
|
void ScreenOverlay::updateMagnifierGrid() {
|
|
if (!grid()) return;
|
|
int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt();
|
|
if (pixCnt % 2 == 0) pixCnt++;
|
|
if (gridRectsX.size() == gridRectsY.size() && gridRectsY.size() == pixCnt) return;
|
|
|
|
QColor c(highlight());
|
|
c.setAlphaF(.25);
|
|
for (int i = 0; i < pixCnt; i++) {
|
|
auto gridRectX = addRect(0, i * 110. / pixCnt, 110, 110. / pixCnt, QPen(Qt::black, 0.5));
|
|
auto gridRectY = addRect(i * 110. / pixCnt, 0, 110. / pixCnt, 110, QPen(Qt::black, 0.5));
|
|
gridRectX->setParentItem(magnifierBox);
|
|
gridRectY->setParentItem(magnifierBox);
|
|
gridRectX->setZValue(199);
|
|
gridRectY->setZValue(199);
|
|
gridRectsX.append(gridRectX);
|
|
gridRectsY.append(gridRectY);
|
|
if (i == (pixCnt / 2)) {
|
|
gridRectX->setBrush(c);
|
|
gridRectY->setBrush(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScreenOverlay::updateMag() {
|
|
updateMagnifierGrid();
|
|
QString hint = generateHint();
|
|
magnifierHint->setVisible(!hint.isEmpty());
|
|
magnifierHintBox->setVisible(!hint.isEmpty());
|
|
magnifierHint->setPlainText(hint);
|
|
magnifierHintBox->setRect(magnifierHint->boundingRect());
|
|
|
|
int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt();
|
|
if (pixCnt % 2 == 0) pixCnt++;
|
|
QPointF magnifierTopLeft = cursorPos() - QPointF(pixCnt / 2, pixCnt / 2);
|
|
QPointF magnifierPos = cursorPos() + QPointF(5, 5);
|
|
|
|
magnifier->setPos(magnifierPos);
|
|
magnifier->setPixmap(utils::extend(pixmap(), pixCnt, utils::invertColor(highlight()))
|
|
.copy(magnifierTopLeft.x() + pixCnt, magnifierTopLeft.y() + pixCnt, pixCnt, pixCnt)
|
|
.scaled(110, 110));
|
|
QPointF bottomRight = magnifierHintBox->sceneBoundingRect().bottomRight();
|
|
if (magnifier->sceneBoundingRect().bottom() > bottomRight.y())
|
|
bottomRight.setY(magnifier->sceneBoundingRect().bottom());
|
|
|
|
if (magnifier->sceneBoundingRect().right() > bottomRight.x())
|
|
bottomRight.setX(magnifier->sceneBoundingRect().right());
|
|
|
|
if (bottomRight.x() > sceneRect().right())
|
|
magnifierPos -= QPointF(qMax(130., magnifierHintBox->boundingRect().width()), 0);
|
|
if (bottomRight.y() > sceneRect().bottom())
|
|
magnifierPos -= QPointF(0, 130 + magnifierHintBox->boundingRect().height());
|
|
magnifier->setPos(magnifierPos);
|
|
}
|
|
|
|
void ScreenOverlay::setHighlight(QColor highlight) {
|
|
_highlight = highlight;
|
|
QColor c = highlight;
|
|
c.setAlphaF(.4);
|
|
magnifierHintBox->setBrush(c);
|
|
magnifierBox->setPen(c);
|
|
if (grid()) setGrid(true);
|
|
int i = settings::settings().value("magnifierPixelCount", 11).toInt() / 2;
|
|
if (gridRectsX.isEmpty() || gridRectsY.isEmpty()) return;
|
|
gridRectsX[i]->setBrush(c);
|
|
gridRectsY[i]->setBrush(c);
|
|
highlightChanged(highlight);
|
|
}
|
|
|
|
void ScreenOverlay::keyPressEvent(QKeyEvent *e) {
|
|
switch (movementPattern()) {
|
|
case MP_JKL:
|
|
if (e->key() == Qt::Key_J)
|
|
moveMouseBy(QPoint(-1, 0));
|
|
else if (e->key() == Qt::Key_K)
|
|
moveMouseBy(QPoint(0, 1));
|
|
else if (e->key() == Qt::Key_L)
|
|
moveMouseBy(QPoint(0, -1));
|
|
else if (e->key() == Qt::Key_Semicolon)
|
|
moveMouseBy(QPoint(1, 0));
|
|
break;
|
|
case MP_HJKL:
|
|
if (e->key() == Qt::Key_H)
|
|
moveMouseBy(QPoint(-1, 0));
|
|
else if (e->key() == Qt::Key_J)
|
|
moveMouseBy(QPoint(0, 1));
|
|
else if (e->key() == Qt::Key_K)
|
|
moveMouseBy(QPoint(0, -1));
|
|
else if (e->key() == Qt::Key_L)
|
|
moveMouseBy(QPoint(1, 0));
|
|
break;
|
|
case MP_ARROWS:
|
|
if (e->key() == Qt::Key_Left)
|
|
moveMouseBy(QPoint(-1, 0));
|
|
else if (e->key() == Qt::Key_Down)
|
|
moveMouseBy(QPoint(0, 1));
|
|
else if (e->key() == Qt::Key_Up)
|
|
moveMouseBy(QPoint(0, -1));
|
|
else if (e->key() == Qt::Key_Right)
|
|
moveMouseBy(QPoint(1, 0));
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ScreenOverlay::hide() {
|
|
for (auto &v : views()) {
|
|
v->hide();
|
|
}
|
|
}
|
|
|
|
void ScreenOverlay::show() {
|
|
for (auto &v : views()) {
|
|
if (QApplication::screens().size() > 1)
|
|
v->show();
|
|
else
|
|
v->showFullScreen();
|
|
}
|
|
}
|
|
|
|
void ScreenOverlay::showSettings() {
|
|
hide();
|
|
ScreenOverlaySettings(this).exec();
|
|
show();
|
|
}
|
|
|
|
void ScreenOverlay::loadSettings() {
|
|
setHighlight(settings::settings().value("highlightColor", QColor(Qt::cyan)).value<QColor>());
|
|
setMovementPattern(settings::settings().value("movementPattern", MP_HJKL).value<MovementPattern>());
|
|
setGrid(settings::settings().value("gridEnabled", true).toBool());
|
|
}
|