From 2fe782704c3e3928a3eb7fdcdec62abcd6d4a5cb Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Wed, 6 Dec 2017 02:16:49 +0100 Subject: [PATCH] Common screenoverlay to make maintaining easy --- src/colorpicker/colorpickerscene.cpp | 63 +++------- src/colorpicker/colorpickerscene.hpp | 10 +- src/cropeditor/cropscene.cpp | 161 +++---------------------- src/cropeditor/cropscene.hpp | 44 +------ src/cropeditor/drawing/arrowitem.cpp | 8 +- src/cropeditor/drawing/bluritem.cpp | 8 +- src/cropeditor/drawing/ellipseitem.cpp | 6 +- src/cropeditor/drawing/eraseritem.cpp | 2 +- src/cropeditor/drawing/lineitem.cpp | 4 +- src/cropeditor/drawing/pathitem.cpp | 4 +- src/cropeditor/drawing/rectitem.cpp | 6 +- src/cropeditor/drawing/textitem.cpp | 6 +- src/screenoverlay.cpp | 146 ++++++++++++++++++++++ src/screenoverlay.hpp | 72 +++++++++++ src/src.pro | 6 +- 15 files changed, 283 insertions(+), 263 deletions(-) create mode 100644 src/screenoverlay.cpp create mode 100644 src/screenoverlay.hpp diff --git a/src/colorpicker/colorpickerscene.cpp b/src/colorpicker/colorpickerscene.cpp index 9920b88..32e33a1 100644 --- a/src/colorpicker/colorpickerscene.cpp +++ b/src/colorpicker/colorpickerscene.cpp @@ -10,69 +10,30 @@ #include ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) -: QGraphicsScene(), ScreenOverlayView(this, parentWidget) { - setFrameShape(QFrame::NoFrame); // Time taken to solve: A george99g and 38 minutes. - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Dialog); - setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); - setCursor(QCursor(Qt::CrossCursor)); - setMouseTracking(true); +: ScreenOverlay(pixmap, parentWidget), ScreenOverlayView(this, parentWidget), image(pixmap.toImage()) { setWindowTitle(tr("KShare Color Picker")); setAttribute(Qt::WA_DeleteOnClose); - - pItem = addPixmap(pixmap); - pItem->setZValue(-2); - ellipse = addEllipse(QRectF(QCursor::pos(), QSize(20, 20)), QPen(Qt::cyan), Qt::NoBrush); - QFont font("Monospace"); - font.setStyleHint(QFont::Monospace); - text = addText("#hiyouu", font); - textBackground = addRect(text->boundingRect(), Qt::NoPen, QBrush(Qt::black)); - text->setPos(QCursor::pos() + QPoint(25, 0)); - textBackground->setPos(text->pos()); - textBackground->setZValue(-1); - color = pItem->pixmap().toImage().pixelColor(QCursor::pos()); - text->setPlainText(color.name()); - ellipse->setBrush(color); - image = pixmap.toImage(); - - if (QApplication::screens().size() == 1) - showFullScreen(); - else - show(); + setCursor(Qt::BlankCursor); activateWindow(); setGeometry(pixmap.rect()); QPoint p = utils::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); move(p.x(), p.y()); + if (QApplication::screens().size() == 1) + showFullScreen(); + else + show(); } -void ColorPickerScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - color = image.pixelColor(event->scenePos().toPoint()); - text->setPlainText(color.name()); - ellipse->setBrush(color); - +void ColorPickerScene::mouseMoved(QGraphicsSceneMouseEvent *event, QPointF cursor, QPointF delta) { + color = image.pixelColor(cursorPos().toPoint()); qreal bottom = rect().bottom(); // max y qreal right = rect().right(); // max x - qreal width = text->boundingRect().width(); - qreal height = text->boundingRect().height(); - QPointF origPoint = event->scenePos() + QPoint(25, 0); - QPointF scopePoint = event->scenePos(); + QPointF origPoint = cursorPos() + QPoint(25, 0); + QPointF scopePoint = cursorPos(); QPointF resPoint = origPoint; - if (origPoint.x() + width > right) { - scopePoint -= QPoint(20, 0); - resPoint -= QPoint(50 + width, 0); - } - if (origPoint.y() + height > bottom) { - scopePoint -= QPoint(0, 20); - resPoint -= QPoint(0, height); - } - - ellipse->setRect(QRectF(scopePoint, QSize(20, 20))); - text->setPos(resPoint); - textBackground->setPos(text->pos()); } void ColorPickerScene::keyPressEvent(QKeyEvent *event) { @@ -88,3 +49,7 @@ void ColorPickerScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { close(); qInfo().noquote() << tr("Copied hex code to clipboard."); } + +QString ColorPickerScene::generateHint() { + return color.name(); +} diff --git a/src/colorpicker/colorpickerscene.hpp b/src/colorpicker/colorpickerscene.hpp index 8c39f4e..9f76604 100644 --- a/src/colorpicker/colorpickerscene.hpp +++ b/src/colorpicker/colorpickerscene.hpp @@ -8,15 +8,17 @@ #include #include #include +#include #include -class ColorPickerScene : public QGraphicsScene, public ScreenOverlayView { +class ColorPickerScene : public ScreenOverlay, public ScreenOverlayView { Q_DECLARE_TR_FUNCTIONS(ColorPickerScene) public: ColorPickerScene(QPixmap pixmap, QWidget *parent = nullptr); - void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; + void mouseMoved(QGraphicsSceneMouseEvent *event, QPointF cursorPos, QPointF delta) override; void keyPressEvent(QKeyEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *) override; + QString generateHint() override; static void showPicker() { new ColorPickerScene(utils::fullscreen()); } @@ -24,10 +26,6 @@ public: private: QImage image; QColor color; - QGraphicsEllipseItem *ellipse = 0; - QGraphicsPixmapItem *pItem = 0; - QGraphicsTextItem *text; - QGraphicsRectItem *textBackground; }; #endif // COLORPICKERSCENE_HPP diff --git a/src/cropeditor/cropscene.cpp b/src/cropeditor/cropscene.cpp index 8710058..cf935f9 100644 --- a/src/cropeditor/cropscene.cpp +++ b/src/cropeditor/cropscene.cpp @@ -26,16 +26,15 @@ #include CropScene::CropScene(QObject *parent, QPixmap pixmap) -: QGraphicsScene(parent), cursorPos(0, 0), drawingSelectionMaker([] { return nullptr; }), prevButtons(Qt::NoButton), +: ScreenOverlay(pixmap, parent), drawingSelectionMaker([] { return nullptr; }), prevButtons(Qt::NoButton), _brush(Qt::SolidPattern), _font(settings::settings().value("font", QFont()).value()) { - _pixmap = pixmap; pen().setColor(settings::settings().value("penColor", pen().color()).value()); pen().setCosmetic(settings::settings().value("penCosmetic", pen().isCosmetic()).toBool()); pen().setWidthF(settings::settings().value("penWidth", pen().widthF()).toReal()); brush().setColor(settings::settings().value("brushColor", brush().color()).value()); brush().setStyle( static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); - _highlight = settings::settings().value("highlightColor", QColor(Qt::cyan)).value(); + setHighlight(settings::settings().value("highlightColor", QColor(Qt::cyan)).value()); menu = new QMenuBar; addDrawingAction(menu, tr("Free draw"), ":/icons/pencil.png", [] { return new PathItem; }); @@ -54,10 +53,7 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) connect(clear, &QAction::triggered, [&] { auto its = items(); for (auto i : its) { - if (i != polyItem && i != rect && i != cursorItem && i->zValue() != -1 && i != proxyMenu && i != hint - && i != magnifier && i != magnifierBox && i != magnifierHint && i != magnifierHintBox - && gridRectsX.contains(dynamic_cast(i)) - && gridRectsY.contains(dynamic_cast(i))) { + if (i != polyItem && i != rect && i->zValue() != -1 && i != proxyMenu && i != hint && i->zValue() != 199) { removeItem(i); } } @@ -96,33 +92,6 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) connect(cancel, &QAction::triggered, [this] { done(false); }); menu->addAction(cancel); - 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(3); - - magnifier = addPixmap(QPixmap(110, 110)); - magnifierBox = addRect(magnifier->boundingRect(), QPen(_highlight)); - magnifier->setZValue(3); - magnifierBox->setZValue(1.1); - 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(1); - magnifierHint->setZValue(1.1); - updateMag(); - addItem(hint); hint->setPos(5, 5); hint->setZValue(2); @@ -147,10 +116,6 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) proxyMenu = widget; QTimer::singleShot(0, [&, widget] { - auto pf = views()[0]->mapFromGlobal(QCursor::pos()); - cursorPos = QPoint(pf.x(), pf.y()); - cursorItem->setPos(cursorPos); - updateMag(); auto screen = QApplication::primaryScreen(); int w = screen->geometry().width(); widget->setPos(views()[0]->mapToScene( @@ -175,20 +140,6 @@ QFont &CropScene::font() { return _font; } -void CropScene::setHighlight(QColor highlight) { - _highlight = highlight; - QColor c = highlight; - c.setAlphaF(.4); - magnifierHintBox->setBrush(c); - magnifierBox->setPen(c); - if (grid()) setGrid(true); - if (rect) rect->setPen(highlight); - int i = settings::settings().value("magnifierPixelCount", 11).toInt() / 2; - if (gridRectsX.isEmpty() || gridRectsY.isEmpty()) return; - gridRectsX[i]->setBrush(c); - gridRectsY[i]->setBrush(c); -} - void CropScene::setDrawingSelection(QString name, std::function drawAction) { if (drawingSelection) { delete drawingSelection; @@ -211,7 +162,7 @@ void CropScene::setDrawingSelection(QString name, std::function dr QGraphicsItem *CropScene::whichItem(QPointF scenePos) { for (auto item : items()) { if (item->sceneBoundingRect().contains(scenePos)) - if (item != polyItem && item != rect && item != cursorItem && item->zValue() != -1) return item; + if (item != polyItem && item != rect && item->zValue() != 199 && item->zValue() != -1) return item; } return nullptr; } @@ -246,17 +197,8 @@ void CropScene::fontAsk() { show(); } -void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { - QPointF delta = e->scenePos() - cursorPos; - if (e->modifiers() & Qt::ShiftModifier) { - cursorPos += delta / 2; - QCursor::setPos(views()[0]->mapToGlobal(cursorPos.toPoint())); - } else - cursorPos = e->scenePos(); +void CropScene::mouseMoved(QGraphicsSceneMouseEvent *e, QPointF cursorPos, QPointF delta) { hint->setVisible(settings::settings().value("crophint").toBool() && !hint->sceneBoundingRect().contains(cursorPos)); - cursorItem->setPos(cursorPos); - updateMag(); - if (rect && !drawingRect) { // qAbs(e->scenePos().() - rect->rect().()) < 10 bool close = false; @@ -308,7 +250,7 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { rect = new SelectionRectangle(p.x(), p.y(), 1, 1); initPos = p; QPen pen(Qt::NoBrush, 1); - pen.setColor(_highlight); + pen.setColor(highlight()); rect->setPen(pen); rect->setZValue(1); addItem(rect); @@ -344,33 +286,13 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { if (e->modifiers() & Qt::AltModifier) { - auto item = whichItem(cursorItem->scenePos()); + auto item = whichItem(cursorPos()); if (item && item != proxyMenu) removeItem(item); } if (!(e->modifiers() & Qt::ControlModifier)) QGraphicsScene::mousePressEvent(e); } -void CropScene::wheelEvent(QGraphicsSceneWheelEvent *event) { - int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt(); - if (pixCnt % 2 == 0) pixCnt++; - if (pixCnt > 20) return; - if (event->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()) initMagnifierGrid(); - updateMag(); - - if (!(event->modifiers() & Qt::ControlModifier)) QGraphicsScene::wheelEvent(event); -} - void CropScene::addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function item) { QAction *action = menu->addAction(""); action->setToolTip(name); @@ -390,37 +312,6 @@ void CropScene::keyReleaseEvent(QKeyEvent *event) { if (!(event->modifiers() & Qt::ControlModifier)) QGraphicsScene::keyReleaseEvent(event); } -void CropScene::updateMag() { - QString rectStr("(-1, -1, 0, 0)"); - if (rect) { - rectStr = "(%0, %1, %2, %3)"; - rectStr = rectStr.arg(rect->rect().x()).arg(rect->rect().y()).arg(rect->rect().width()).arg(rect->rect().height()); - } - magnifierHint->setPlainText(QString("ptr: (%0, %1)\nsel: %2").arg(qRound(cursorPos.x())).arg(qRound(cursorPos.y())).arg(rectStr)); - 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 CropScene::updatePoly() { QPolygonF poly; @@ -441,41 +332,23 @@ void CropScene::updatePoly() { this->polyItem->setPolygon(poly); } -void CropScene::initMagnifierGrid() { - if (!gridRectsX.isEmpty() || !gridRectsY.isEmpty()) return; - - QColor c(_highlight); - c.setAlphaF(.25); - int pixCnt = settings::settings().value("magnifierPixelCount", 11).toInt(); - if (pixCnt % 2 == 0) pixCnt++; - 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(5); - gridRectY->setZValue(5); - gridRectsX.append(gridRectX); - gridRectsY.append(gridRectY); - if (i == (pixCnt / 2)) { - gridRectX->setBrush(c); - gridRectY->setBrush(c); - } - } -} - void CropScene::done(bool notEsc) { if (notEsc && rect) { QRectF rect2 = rect->rect(); hint->setVisible(false); rect->setRect(QRect(-100, -100, 0, 0)); - magnifier->setVisible(false); proxyMenu->setVisible(false); - cursorItem->setVisible(false); - magnifierBox->setVisible(false); - magnifierHint->setVisible(false); - magnifierHintBox->setVisible(false); + hideMag(); emit closedWithRect(rect2.toRect()); } else emit closedWithRect(QRect()); } + +QString CropScene::generateHint() { + QString rectStr("(-1, -1, 0, 0)"); + if (rect) { + rectStr = "(%0, %1, %2, %3)"; + rectStr = rectStr.arg(rect->rect().x()).arg(rect->rect().y()).arg(rect->rect().width()).arg(rect->rect().height()); + } + return QString("ptr: (%0, %1)\nsel: %2").arg(qRound(cursorPos().x())).arg(qRound(cursorPos().y())).arg(rectStr); +} diff --git a/src/cropeditor/cropscene.hpp b/src/cropeditor/cropscene.hpp index 7755f25..7dd435a 100644 --- a/src/cropeditor/cropscene.hpp +++ b/src/cropeditor/cropscene.hpp @@ -1,6 +1,7 @@ #ifndef CROPSCENE_HPP #define CROPSCENE_HPP +#include "../screenoverlay.hpp" #include #include #include @@ -16,7 +17,7 @@ class CropScene; #include -class CropScene : public QGraphicsScene { +class CropScene : public ScreenOverlay { Q_OBJECT public: CropScene(QObject *parent, QPixmap pixmap); @@ -24,28 +25,7 @@ public: QPen &pen(); QBrush &brush(); QFont &font(); - QColor highlight() { - return _highlight; - } - void setHighlight(QColor highlight); - bool grid() { - return _grid; - } - void setGrid(bool grid) { - _grid = grid; - if (grid) { - initMagnifierGrid(); - } else { - for (auto r : gridRectsX) delete r; - gridRectsX.clear(); - for (auto r : gridRectsY) delete r; - gridRectsY.clear(); - } - } void setDrawingSelection(QString name, std::function drawAction); - QPixmap pixmap() { - return _pixmap; - } QGraphicsPolygonItem *polyItm() { return polyItem; } @@ -56,9 +36,6 @@ public: void hide(); void show(); void setVisible(bool visible); - QPointF cursorPosition() { - return cursorPos; - } public slots: void fontAsk(); @@ -67,45 +44,32 @@ signals: void closedWithRect(QRect rect); protected: - void mouseMoveEvent(QGraphicsSceneMouseEvent *e) override; + void mouseMoved(QGraphicsSceneMouseEvent *e, QPointF cursorPos, QPointF delta) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *e) override; void mousePressEvent(QGraphicsSceneMouseEvent *e) override; - void wheelEvent(QGraphicsSceneWheelEvent *event) override; // WHEEEEEEL void keyReleaseEvent(QKeyEvent *e) override; + QString generateHint() override; private slots: void done(bool notEsc = true); private: - void updateMag(); void updatePoly(); - void initMagnifierGrid(); void addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function item); - QPointF cursorPos; std::function drawingSelectionMaker; QFlags prevButtons; - QPixmap _pixmap; QGraphicsRectItem *rect = nullptr; bool drawingRect = true; - QGraphicsPixmapItem *magnifier = nullptr; - QGraphicsRectItem *magnifierBox = nullptr; - QGraphicsTextItem *magnifierHint = nullptr; - QGraphicsRectItem *magnifierHintBox = nullptr; QPointF initPos; QPen _pen; QBrush _brush; QFont _font; - QColor _highlight; - bool _grid; QGraphicsPolygonItem *polyItem = nullptr; DrawItem *drawingSelection = nullptr; QMenuBar *menu = nullptr; QGraphicsProxyWidget *proxyMenu = nullptr; QString drawingName = "None"; QAction *display; - QList gridRectsX; - QList gridRectsY; - QGraphicsPolygonItem *cursorItem = nullptr; QGraphicsPixmapItem *hint = new QGraphicsPixmapItem(utils::renderText(tr( // "Press F1 to toggle this hint\n" diff --git a/src/cropeditor/drawing/arrowitem.cpp b/src/cropeditor/drawing/arrowitem.cpp index c7b31f6..812e6a7 100644 --- a/src/cropeditor/drawing/arrowitem.cpp +++ b/src/cropeditor/drawing/arrowitem.cpp @@ -4,7 +4,7 @@ void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (init.isNull()) { - init = scene->cursorPosition(); + init = scene->cursorPos(); line = scene->addLine(QLineF(init, init), scene->pen()); QPainterPath poly; qreal w = settings::settings().value("arrow/width", 20).toDouble() / 2; @@ -14,9 +14,9 @@ void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { poly.lineTo(QPoint(w, h)); head = scene->addPath(poly, scene->pen(), scene->brush()); } else { - line->setLine(QLineF(init, scene->cursorPosition())); + line->setLine(QLineF(init, scene->cursorPos())); head->setRotation( - 270 + qRadiansToDegrees(qAtan2((init.y() - scene->cursorPosition().y()), (init.x() - scene->cursorPosition().x())))); + 270 + qRadiansToDegrees(qAtan2((init.y() - scene->cursorPos().y()), (init.x() - scene->cursorPos().x())))); } - head->setPos(scene->cursorPosition()); + head->setPos(scene->cursorPos()); } diff --git a/src/cropeditor/drawing/bluritem.cpp b/src/cropeditor/drawing/bluritem.cpp index 65f966a..4c706f1 100644 --- a/src/cropeditor/drawing/bluritem.cpp +++ b/src/cropeditor/drawing/bluritem.cpp @@ -15,13 +15,13 @@ bool BlurItem::init(CropScene *) { void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (pos.isNull()) { - pos = scene->cursorPosition(); - rect = scene->addRect(QRect(scene->cursorPosition().toPoint(), QSize(1, 1)), QPen(scene->highlight()), Qt::NoBrush); + pos = scene->cursorPos(); + rect = scene->addRect(QRect(scene->cursorPos().toPoint(), QSize(1, 1)), QPen(scene->highlight()), Qt::NoBrush); pixmap = scene->addPixmap(scene->pixmap().copy(rect->rect().toRect())); - pixmap->setPos(scene->cursorPosition()); + pixmap->setPos(scene->cursorPos()); pixmap->setGraphicsEffect(effect); } else { - QPointF p = scene->cursorPosition(); + QPointF p = scene->cursorPos(); rect->setRect(QRect(qMin(pos.x(), p.x()), qMin(pos.y(), p.y()), qAbs(pos.x() - p.x()), qAbs(pos.y() - p.y()))); auto area = rect->rect(); if (area.width() > 1 && area.height() > 1 && area.top() > 1 && area.left() > 1) diff --git a/src/cropeditor/drawing/ellipseitem.cpp b/src/cropeditor/drawing/ellipseitem.cpp index e21257c..bb8f4da 100644 --- a/src/cropeditor/drawing/ellipseitem.cpp +++ b/src/cropeditor/drawing/ellipseitem.cpp @@ -2,10 +2,10 @@ void EllipseItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (!ellie) { - ellie = scene->addEllipse(scene->cursorPosition().x(), scene->cursorPosition().y(), 0, 0, scene->pen(), scene->brush()); - initPos = scene->cursorPosition(); + ellie = scene->addEllipse(scene->cursorPos().x(), scene->cursorPos().y(), 0, 0, scene->pen(), scene->brush()); + initPos = scene->cursorPos(); } else { - auto p = scene->cursorPosition(); + auto p = scene->cursorPos(); ellie->setRect(QRectF(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); } diff --git a/src/cropeditor/drawing/eraseritem.cpp b/src/cropeditor/drawing/eraseritem.cpp index 89c8c56..43f31f0 100644 --- a/src/cropeditor/drawing/eraseritem.cpp +++ b/src/cropeditor/drawing/eraseritem.cpp @@ -8,7 +8,7 @@ EraserItem::~EraserItem() { void EraserItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { for (auto i : scene->items()) { - if (i->contains(scene->cursorPosition()) && i->zValue() != -1 && i != scene->polyItm() && i != scene->selRect()) { + if (i->contains(scene->cursorPos()) && i->zValue() != -1 && i != scene->polyItm() && i != scene->selRect()) { scene->removeItem(i); break; } diff --git a/src/cropeditor/drawing/lineitem.cpp b/src/cropeditor/drawing/lineitem.cpp index a8efb58..aa9bc5e 100644 --- a/src/cropeditor/drawing/lineitem.cpp +++ b/src/cropeditor/drawing/lineitem.cpp @@ -5,10 +5,10 @@ LineItem::LineItem() { void LineItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (init.isNull()) { - init = scene->cursorPosition(); + init = scene->cursorPos(); line = scene->addLine(QLineF(init, init), scene->pen()); } else { - line->setLine(QLineF(init, scene->cursorPosition())); + line->setLine(QLineF(init, scene->cursorPos())); } } diff --git a/src/cropeditor/drawing/pathitem.cpp b/src/cropeditor/drawing/pathitem.cpp index b4d8b7c..65f8796 100644 --- a/src/cropeditor/drawing/pathitem.cpp +++ b/src/cropeditor/drawing/pathitem.cpp @@ -11,11 +11,11 @@ PathItem::~PathItem() { void PathItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (path == nullptr) { - path = new QPainterPath(scene->cursorPosition()); + path = new QPainterPath(scene->cursorPos()); pathItem = scene->addPath(*path, scene->pen(), settings::settings().value("brushPath", false).toBool() ? scene->brush() : QBrush()); } else { - path->quadTo(path->currentPosition(), scene->cursorPosition()); + path->quadTo(path->currentPosition(), scene->cursorPos()); pathItem->setPath(*path); } } diff --git a/src/cropeditor/drawing/rectitem.cpp b/src/cropeditor/drawing/rectitem.cpp index aebf123..f862114 100644 --- a/src/cropeditor/drawing/rectitem.cpp +++ b/src/cropeditor/drawing/rectitem.cpp @@ -8,12 +8,12 @@ RectItem::~RectItem() { void RectItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (!rect) { - rect = scene->addRect(scene->cursorPosition().x(), scene->cursorPosition().y(), 0, 0); + rect = scene->addRect(scene->cursorPos().x(), scene->cursorPos().y(), 0, 0); rect->setBrush(scene->brush()); rect->setPen(scene->pen()); - initPos = scene->cursorPosition(); + initPos = scene->cursorPos(); } else { - auto p = scene->cursorPosition(); + auto p = scene->cursorPos(); rect->setRect( QRect(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); } diff --git a/src/cropeditor/drawing/textitem.cpp b/src/cropeditor/drawing/textitem.cpp index 294b45d..ae5a757 100644 --- a/src/cropeditor/drawing/textitem.cpp +++ b/src/cropeditor/drawing/textitem.cpp @@ -13,12 +13,12 @@ bool TextItem::init(CropScene *s) { void TextItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { if (!textItem) { textItem = scene->addSimpleText(text, scene->font()); - textItem->setPos(scene->cursorPosition()); + textItem->setPos(scene->cursorPos()); textItem->setPen(scene->pen().color()); textItem->setBrush(scene->pen().color()); } else { - auto ee = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - scene->cursorPosition().y()), - (textItem->pos().x() - scene->cursorPosition().x()))); + auto ee = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - scene->cursorPos().y()), + (textItem->pos().x() - scene->cursorPos().x()))); textItem->setRotation(ee); } } diff --git a/src/screenoverlay.cpp b/src/screenoverlay.cpp new file mode 100644 index 0000000..9d027ba --- /dev/null +++ b/src/screenoverlay.cpp @@ -0,0 +1,146 @@ +#include "screenoverlay.hpp" + +#include +#include +#include +#include +#include + +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(); +} + +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) { + _cursorPos += delta / 2; + QCursor::setPos(views()[0]->mapToGlobal(cursorPos().toPoint())); + } else + setCursorPos(e->scenePos()); + cursorItem->setPos(cursorPos()); + updateMag(); + mouseMoved(e, cursorPos(), 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); +} diff --git a/src/screenoverlay.hpp b/src/screenoverlay.hpp new file mode 100644 index 0000000..4ae7b82 --- /dev/null +++ b/src/screenoverlay.hpp @@ -0,0 +1,72 @@ +#ifndef SCREENOVERLAY_HPP +#define SCREENOVERLAY_HPP + +#include +#include +#include + +class ScreenOverlay : public QGraphicsScene { + Q_OBJECT +public: + explicit ScreenOverlay(QPixmap pixmap, QObject *parent = 0); + + void mouseMoveEvent(QGraphicsSceneMouseEvent *e) override; + void wheelEvent(QGraphicsSceneWheelEvent *e) override; + + virtual void mouseMoved(QGraphicsSceneMouseEvent *, QPointF, QPointF) { + } + virtual void highlightChanged(QColor) { + } + virtual QString generateHint() { + return QString(); + } + + QPixmap &pixmap() { + return _pixmap; + } + void updateMag(); + virtual QString generateMagHint() { + return QString(); + }; + void hideMag(); + void updateMagnifierGrid(); + QColor highlight() { + return _highlight; + } + void setHighlight(QColor highlight); + bool grid() { + return _grid; + } + void setGrid(bool grid) { + _grid = grid; + if (grid) { + updateMagnifierGrid(); + } else { + for (auto r : gridRectsX) delete r; + gridRectsX.clear(); + for (auto r : gridRectsY) delete r; + gridRectsY.clear(); + } + } + QPointF cursorPos() { + return _cursorPos; + } + void setCursorPos(QPointF cursorPos) { + _cursorPos = cursorPos; + } + +private: + QPointF _cursorPos = QPoint(0, 0); + QGraphicsPixmapItem *magnifier = nullptr; + QGraphicsRectItem *magnifierBox = nullptr; + QGraphicsTextItem *magnifierHint = nullptr; + QGraphicsRectItem *magnifierHintBox = nullptr; + QGraphicsPolygonItem *cursorItem = nullptr; + QList gridRectsX; + QList gridRectsY; + QColor _highlight = Qt::cyan; + bool _grid = true; + QPixmap _pixmap; +}; + +#endif /* SCREENOVERLAY_HPP */ diff --git a/src/src.pro b/src/src.pro index f009d9e..b2e03d6 100644 --- a/src/src.pro +++ b/src/src.pro @@ -68,7 +68,8 @@ SOURCES += main.cpp\ logs/historydialog.cpp \ monospacetextdialog.cpp \ screenoverlayview.cpp \ - cropeditor/selectionrectangle.cpp + cropeditor/selectionrectangle.cpp \ + screenoverlay.cpp HEADERS += mainwindow.hpp \ cropeditor/cropeditor.hpp \ @@ -118,7 +119,8 @@ HEADERS += mainwindow.hpp \ screenoverlayview.hpp \ screenoverlayview.hpp \ monospacetextdialog.hpp \ - cropeditor/selectionrectangle.hpp + cropeditor/selectionrectangle.hpp \ + screenoverlay.hpp nopkg { # win32 {