Common screenoverlay to make maintaining easy

This commit is contained in:
ArsenArsen 2017-12-06 02:16:49 +01:00
parent ea68c1a526
commit 2fe782704c
15 changed files with 283 additions and 263 deletions

View File

@ -10,69 +10,30 @@
#include <settings.hpp> #include <settings.hpp>
ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget)
: QGraphicsScene(), ScreenOverlayView(this, parentWidget) { : ScreenOverlay(pixmap, parentWidget), ScreenOverlayView(this, parentWidget), image(pixmap.toImage()) {
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);
setWindowTitle(tr("KShare Color Picker")); setWindowTitle(tr("KShare Color Picker"));
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
setCursor(Qt::BlankCursor);
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();
activateWindow(); activateWindow();
setGeometry(pixmap.rect()); setGeometry(pixmap.rect());
QPoint p = utils::smallestScreenCoordinate() QPoint p = utils::smallestScreenCoordinate()
+ QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt());
move(p.x(), p.y()); move(p.x(), p.y());
if (QApplication::screens().size() == 1)
showFullScreen();
else
show();
} }
void ColorPickerScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { void ColorPickerScene::mouseMoved(QGraphicsSceneMouseEvent *event, QPointF cursor, QPointF delta) {
color = image.pixelColor(event->scenePos().toPoint()); color = image.pixelColor(cursorPos().toPoint());
text->setPlainText(color.name());
ellipse->setBrush(color);
qreal bottom = rect().bottom(); // max y qreal bottom = rect().bottom(); // max y
qreal right = rect().right(); // max x qreal right = rect().right(); // max x
qreal width = text->boundingRect().width();
qreal height = text->boundingRect().height();
QPointF origPoint = event->scenePos() + QPoint(25, 0); QPointF origPoint = cursorPos() + QPoint(25, 0);
QPointF scopePoint = event->scenePos(); QPointF scopePoint = cursorPos();
QPointF resPoint = origPoint; 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) { void ColorPickerScene::keyPressEvent(QKeyEvent *event) {
@ -88,3 +49,7 @@ void ColorPickerScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *) {
close(); close();
qInfo().noquote() << tr("Copied hex code to clipboard."); qInfo().noquote() << tr("Copied hex code to clipboard.");
} }
QString ColorPickerScene::generateHint() {
return color.name();
}

View File

@ -8,15 +8,17 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QTimer> #include <QTimer>
#include <screenoverlayview.hpp> #include <screenoverlayview.hpp>
#include <screenoverlay.hpp>
#include <utils.hpp> #include <utils.hpp>
class ColorPickerScene : public QGraphicsScene, public ScreenOverlayView { class ColorPickerScene : public ScreenOverlay, public ScreenOverlayView {
Q_DECLARE_TR_FUNCTIONS(ColorPickerScene) Q_DECLARE_TR_FUNCTIONS(ColorPickerScene)
public: public:
ColorPickerScene(QPixmap pixmap, QWidget *parent = nullptr); 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 keyPressEvent(QKeyEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *) override;
QString generateHint() override;
static void showPicker() { static void showPicker() {
new ColorPickerScene(utils::fullscreen()); new ColorPickerScene(utils::fullscreen());
} }
@ -24,10 +26,6 @@ public:
private: private:
QImage image; QImage image;
QColor color; QColor color;
QGraphicsEllipseItem *ellipse = 0;
QGraphicsPixmapItem *pItem = 0;
QGraphicsTextItem *text;
QGraphicsRectItem *textBackground;
}; };
#endif // COLORPICKERSCENE_HPP #endif // COLORPICKERSCENE_HPP

View File

@ -26,16 +26,15 @@
#include <settings.hpp> #include <settings.hpp>
CropScene::CropScene(QObject *parent, QPixmap pixmap) 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<QFont>()) { _brush(Qt::SolidPattern), _font(settings::settings().value("font", QFont()).value<QFont>()) {
_pixmap = pixmap;
pen().setColor(settings::settings().value("penColor", pen().color()).value<QColor>()); pen().setColor(settings::settings().value("penColor", pen().color()).value<QColor>());
pen().setCosmetic(settings::settings().value("penCosmetic", pen().isCosmetic()).toBool()); pen().setCosmetic(settings::settings().value("penCosmetic", pen().isCosmetic()).toBool());
pen().setWidthF(settings::settings().value("penWidth", pen().widthF()).toReal()); pen().setWidthF(settings::settings().value("penWidth", pen().widthF()).toReal());
brush().setColor(settings::settings().value("brushColor", brush().color()).value<QColor>()); brush().setColor(settings::settings().value("brushColor", brush().color()).value<QColor>());
brush().setStyle( brush().setStyle(
static_cast<Qt::BrushStyle>(settings::settings().value("brushStyle", static_cast<int>(Qt::SolidPattern)).toInt())); static_cast<Qt::BrushStyle>(settings::settings().value("brushStyle", static_cast<int>(Qt::SolidPattern)).toInt()));
_highlight = settings::settings().value("highlightColor", QColor(Qt::cyan)).value<QColor>(); setHighlight(settings::settings().value("highlightColor", QColor(Qt::cyan)).value<QColor>());
menu = new QMenuBar; menu = new QMenuBar;
addDrawingAction(menu, tr("Free draw"), ":/icons/pencil.png", [] { return new PathItem; }); 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, [&] { connect(clear, &QAction::triggered, [&] {
auto its = items(); auto its = items();
for (auto i : its) { for (auto i : its) {
if (i != polyItem && i != rect && i != cursorItem && i->zValue() != -1 && i != proxyMenu && i != hint if (i != polyItem && i != rect && i->zValue() != -1 && i != proxyMenu && i != hint && i->zValue() != 199) {
&& i != magnifier && i != magnifierBox && i != magnifierHint && i != magnifierHintBox
&& gridRectsX.contains(dynamic_cast<QGraphicsRectItem *>(i))
&& gridRectsY.contains(dynamic_cast<QGraphicsRectItem *>(i))) {
removeItem(i); removeItem(i);
} }
} }
@ -96,33 +92,6 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap)
connect(cancel, &QAction::triggered, [this] { done(false); }); connect(cancel, &QAction::triggered, [this] { done(false); });
menu->addAction(cancel); 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); addItem(hint);
hint->setPos(5, 5); hint->setPos(5, 5);
hint->setZValue(2); hint->setZValue(2);
@ -147,10 +116,6 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap)
proxyMenu = widget; proxyMenu = widget;
QTimer::singleShot(0, [&, 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(); auto screen = QApplication::primaryScreen();
int w = screen->geometry().width(); int w = screen->geometry().width();
widget->setPos(views()[0]->mapToScene( widget->setPos(views()[0]->mapToScene(
@ -175,20 +140,6 @@ QFont &CropScene::font() {
return _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<DrawItem *()> drawAction) { void CropScene::setDrawingSelection(QString name, std::function<DrawItem *()> drawAction) {
if (drawingSelection) { if (drawingSelection) {
delete drawingSelection; delete drawingSelection;
@ -211,7 +162,7 @@ void CropScene::setDrawingSelection(QString name, std::function<DrawItem *()> dr
QGraphicsItem *CropScene::whichItem(QPointF scenePos) { QGraphicsItem *CropScene::whichItem(QPointF scenePos) {
for (auto item : items()) { for (auto item : items()) {
if (item->sceneBoundingRect().contains(scenePos)) 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; return nullptr;
} }
@ -246,17 +197,8 @@ void CropScene::fontAsk() {
show(); show();
} }
void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { void CropScene::mouseMoved(QGraphicsSceneMouseEvent *e, QPointF cursorPos, QPointF delta) {
QPointF delta = e->scenePos() - cursorPos;
if (e->modifiers() & Qt::ShiftModifier) {
cursorPos += delta / 2;
QCursor::setPos(views()[0]->mapToGlobal(cursorPos.toPoint()));
} else
cursorPos = e->scenePos();
hint->setVisible(settings::settings().value("crophint").toBool() && !hint->sceneBoundingRect().contains(cursorPos)); hint->setVisible(settings::settings().value("crophint").toBool() && !hint->sceneBoundingRect().contains(cursorPos));
cursorItem->setPos(cursorPos);
updateMag();
if (rect && !drawingRect) { if (rect && !drawingRect) {
// qAbs(e->scenePos().<axis>() - rect->rect().<edge>()) < 10 // qAbs(e->scenePos().<axis>() - rect->rect().<edge>()) < 10
bool close = false; bool close = false;
@ -308,7 +250,7 @@ void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
rect = new SelectionRectangle(p.x(), p.y(), 1, 1); rect = new SelectionRectangle(p.x(), p.y(), 1, 1);
initPos = p; initPos = p;
QPen pen(Qt::NoBrush, 1); QPen pen(Qt::NoBrush, 1);
pen.setColor(_highlight); pen.setColor(highlight());
rect->setPen(pen); rect->setPen(pen);
rect->setZValue(1); rect->setZValue(1);
addItem(rect); addItem(rect);
@ -344,33 +286,13 @@ void CropScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { void CropScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if (e->modifiers() & Qt::AltModifier) { if (e->modifiers() & Qt::AltModifier) {
auto item = whichItem(cursorItem->scenePos()); auto item = whichItem(cursorPos());
if (item && item != proxyMenu) removeItem(item); if (item && item != proxyMenu) removeItem(item);
} }
if (!(e->modifiers() & Qt::ControlModifier)) QGraphicsScene::mousePressEvent(e); 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<DrawItem *()> item) { void CropScene::addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function<DrawItem *()> item) {
QAction *action = menu->addAction(""); QAction *action = menu->addAction("");
action->setToolTip(name); action->setToolTip(name);
@ -390,37 +312,6 @@ void CropScene::keyReleaseEvent(QKeyEvent *event) {
if (!(event->modifiers() & Qt::ControlModifier)) QGraphicsScene::keyReleaseEvent(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() { void CropScene::updatePoly() {
QPolygonF poly; QPolygonF poly;
@ -441,41 +332,23 @@ void CropScene::updatePoly() {
this->polyItem->setPolygon(poly); 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) { void CropScene::done(bool notEsc) {
if (notEsc && rect) { if (notEsc && rect) {
QRectF rect2 = rect->rect(); QRectF rect2 = rect->rect();
hint->setVisible(false); hint->setVisible(false);
rect->setRect(QRect(-100, -100, 0, 0)); rect->setRect(QRect(-100, -100, 0, 0));
magnifier->setVisible(false);
proxyMenu->setVisible(false); proxyMenu->setVisible(false);
cursorItem->setVisible(false); hideMag();
magnifierBox->setVisible(false);
magnifierHint->setVisible(false);
magnifierHintBox->setVisible(false);
emit closedWithRect(rect2.toRect()); emit closedWithRect(rect2.toRect());
} else } else
emit closedWithRect(QRect()); 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);
}

View File

@ -1,6 +1,7 @@
#ifndef CROPSCENE_HPP #ifndef CROPSCENE_HPP
#define CROPSCENE_HPP #define CROPSCENE_HPP
#include "../screenoverlay.hpp"
#include <QFont> #include <QFont>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsSceneContextMenuEvent> #include <QGraphicsSceneContextMenuEvent>
@ -16,7 +17,7 @@ class CropScene;
#include <cropeditor/drawing/drawitem.hpp> #include <cropeditor/drawing/drawitem.hpp>
class CropScene : public QGraphicsScene { class CropScene : public ScreenOverlay {
Q_OBJECT Q_OBJECT
public: public:
CropScene(QObject *parent, QPixmap pixmap); CropScene(QObject *parent, QPixmap pixmap);
@ -24,28 +25,7 @@ public:
QPen &pen(); QPen &pen();
QBrush &brush(); QBrush &brush();
QFont &font(); 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<DrawItem *()> drawAction); void setDrawingSelection(QString name, std::function<DrawItem *()> drawAction);
QPixmap pixmap() {
return _pixmap;
}
QGraphicsPolygonItem *polyItm() { QGraphicsPolygonItem *polyItm() {
return polyItem; return polyItem;
} }
@ -56,9 +36,6 @@ public:
void hide(); void hide();
void show(); void show();
void setVisible(bool visible); void setVisible(bool visible);
QPointF cursorPosition() {
return cursorPos;
}
public slots: public slots:
void fontAsk(); void fontAsk();
@ -67,45 +44,32 @@ signals:
void closedWithRect(QRect rect); void closedWithRect(QRect rect);
protected: protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *e) override; void mouseMoved(QGraphicsSceneMouseEvent *e, QPointF cursorPos, QPointF delta) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *e) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *e) override;
void mousePressEvent(QGraphicsSceneMouseEvent *e) override; void mousePressEvent(QGraphicsSceneMouseEvent *e) override;
void wheelEvent(QGraphicsSceneWheelEvent *event) override; // WHEEEEEEL
void keyReleaseEvent(QKeyEvent *e) override; void keyReleaseEvent(QKeyEvent *e) override;
QString generateHint() override;
private slots: private slots:
void done(bool notEsc = true); void done(bool notEsc = true);
private: private:
void updateMag();
void updatePoly(); void updatePoly();
void initMagnifierGrid();
void addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function<DrawItem *()> item); void addDrawingAction(QMenuBar *menu, QString name, QString icon, std::function<DrawItem *()> item);
QPointF cursorPos;
std::function<DrawItem *()> drawingSelectionMaker; std::function<DrawItem *()> drawingSelectionMaker;
QFlags<Qt::MouseButton> prevButtons; QFlags<Qt::MouseButton> prevButtons;
QPixmap _pixmap;
QGraphicsRectItem *rect = nullptr; QGraphicsRectItem *rect = nullptr;
bool drawingRect = true; bool drawingRect = true;
QGraphicsPixmapItem *magnifier = nullptr;
QGraphicsRectItem *magnifierBox = nullptr;
QGraphicsTextItem *magnifierHint = nullptr;
QGraphicsRectItem *magnifierHintBox = nullptr;
QPointF initPos; QPointF initPos;
QPen _pen; QPen _pen;
QBrush _brush; QBrush _brush;
QFont _font; QFont _font;
QColor _highlight;
bool _grid;
QGraphicsPolygonItem *polyItem = nullptr; QGraphicsPolygonItem *polyItem = nullptr;
DrawItem *drawingSelection = nullptr; DrawItem *drawingSelection = nullptr;
QMenuBar *menu = nullptr; QMenuBar *menu = nullptr;
QGraphicsProxyWidget *proxyMenu = nullptr; QGraphicsProxyWidget *proxyMenu = nullptr;
QString drawingName = "None"; QString drawingName = "None";
QAction *display; QAction *display;
QList<QGraphicsRectItem *> gridRectsX;
QList<QGraphicsRectItem *> gridRectsY;
QGraphicsPolygonItem *cursorItem = nullptr;
QGraphicsPixmapItem *hint QGraphicsPixmapItem *hint
= new QGraphicsPixmapItem(utils::renderText(tr( // = new QGraphicsPixmapItem(utils::renderText(tr( //
"Press F1 to toggle this hint\n" "Press F1 to toggle this hint\n"

View File

@ -4,7 +4,7 @@
void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void ArrowItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (init.isNull()) { if (init.isNull()) {
init = scene->cursorPosition(); init = scene->cursorPos();
line = scene->addLine(QLineF(init, init), scene->pen()); line = scene->addLine(QLineF(init, init), scene->pen());
QPainterPath poly; QPainterPath poly;
qreal w = settings::settings().value("arrow/width", 20).toDouble() / 2; 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)); poly.lineTo(QPoint(w, h));
head = scene->addPath(poly, scene->pen(), scene->brush()); head = scene->addPath(poly, scene->pen(), scene->brush());
} else { } else {
line->setLine(QLineF(init, scene->cursorPosition())); line->setLine(QLineF(init, scene->cursorPos()));
head->setRotation( 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());
} }

View File

@ -15,13 +15,13 @@ bool BlurItem::init(CropScene *) {
void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (pos.isNull()) { if (pos.isNull()) {
pos = scene->cursorPosition(); pos = scene->cursorPos();
rect = scene->addRect(QRect(scene->cursorPosition().toPoint(), QSize(1, 1)), QPen(scene->highlight()), Qt::NoBrush); 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 = scene->addPixmap(scene->pixmap().copy(rect->rect().toRect()));
pixmap->setPos(scene->cursorPosition()); pixmap->setPos(scene->cursorPos());
pixmap->setGraphicsEffect(effect); pixmap->setGraphicsEffect(effect);
} else { } 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()))); 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(); auto area = rect->rect();
if (area.width() > 1 && area.height() > 1 && area.top() > 1 && area.left() > 1) if (area.width() > 1 && area.height() > 1 && area.top() > 1 && area.left() > 1)

View File

@ -2,10 +2,10 @@
void EllipseItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void EllipseItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (!ellie) { if (!ellie) {
ellie = scene->addEllipse(scene->cursorPosition().x(), scene->cursorPosition().y(), 0, 0, scene->pen(), scene->brush()); ellie = scene->addEllipse(scene->cursorPos().x(), scene->cursorPos().y(), 0, 0, scene->pen(), scene->brush());
initPos = scene->cursorPosition(); initPos = scene->cursorPos();
} else { } 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()), ellie->setRect(QRectF(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()),
qAbs(initPos.y() - p.y()))); qAbs(initPos.y() - p.y())));
} }

View File

@ -8,7 +8,7 @@ EraserItem::~EraserItem() {
void EraserItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void EraserItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
for (auto i : scene->items()) { 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); scene->removeItem(i);
break; break;
} }

View File

@ -5,10 +5,10 @@ LineItem::LineItem() {
void LineItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void LineItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (init.isNull()) { if (init.isNull()) {
init = scene->cursorPosition(); init = scene->cursorPos();
line = scene->addLine(QLineF(init, init), scene->pen()); line = scene->addLine(QLineF(init, init), scene->pen());
} else { } else {
line->setLine(QLineF(init, scene->cursorPosition())); line->setLine(QLineF(init, scene->cursorPos()));
} }
} }

View File

@ -11,11 +11,11 @@ PathItem::~PathItem() {
void PathItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void PathItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (path == nullptr) { if (path == nullptr) {
path = new QPainterPath(scene->cursorPosition()); path = new QPainterPath(scene->cursorPos());
pathItem = scene->addPath(*path, scene->pen(), pathItem = scene->addPath(*path, scene->pen(),
settings::settings().value("brushPath", false).toBool() ? scene->brush() : QBrush()); settings::settings().value("brushPath", false).toBool() ? scene->brush() : QBrush());
} else { } else {
path->quadTo(path->currentPosition(), scene->cursorPosition()); path->quadTo(path->currentPosition(), scene->cursorPos());
pathItem->setPath(*path); pathItem->setPath(*path);
} }
} }

View File

@ -8,12 +8,12 @@ RectItem::~RectItem() {
void RectItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void RectItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (!rect) { 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->setBrush(scene->brush());
rect->setPen(scene->pen()); rect->setPen(scene->pen());
initPos = scene->cursorPosition(); initPos = scene->cursorPos();
} else { } else {
auto p = scene->cursorPosition(); auto p = scene->cursorPos();
rect->setRect( rect->setRect(
QRect(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y()))); QRect(qMin(initPos.x(), p.x()), qMin(initPos.y(), p.y()), qAbs(initPos.x() - p.x()), qAbs(initPos.y() - p.y())));
} }

View File

@ -13,12 +13,12 @@ bool TextItem::init(CropScene *s) {
void TextItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) { void TextItem::mouseDragEvent(QGraphicsSceneMouseEvent *, CropScene *scene) {
if (!textItem) { if (!textItem) {
textItem = scene->addSimpleText(text, scene->font()); textItem = scene->addSimpleText(text, scene->font());
textItem->setPos(scene->cursorPosition()); textItem->setPos(scene->cursorPos());
textItem->setPen(scene->pen().color()); textItem->setPen(scene->pen().color());
textItem->setBrush(scene->pen().color()); textItem->setBrush(scene->pen().color());
} else { } else {
auto ee = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - scene->cursorPosition().y()), auto ee = 180 + qRadiansToDegrees(qAtan2((textItem->pos().y() - scene->cursorPos().y()),
(textItem->pos().x() - scene->cursorPosition().x()))); (textItem->pos().x() - scene->cursorPos().x())));
textItem->setRotation(ee); textItem->setRotation(ee);
} }
} }

146
src/screenoverlay.cpp Normal file
View File

@ -0,0 +1,146 @@
#include "screenoverlay.hpp"
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#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();
}
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);
}

72
src/screenoverlay.hpp Normal file
View File

@ -0,0 +1,72 @@
#ifndef SCREENOVERLAY_HPP
#define SCREENOVERLAY_HPP
#include <QGraphicsPixmapItem>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
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<QGraphicsRectItem *> gridRectsX;
QList<QGraphicsRectItem *> gridRectsY;
QColor _highlight = Qt::cyan;
bool _grid = true;
QPixmap _pixmap;
};
#endif /* SCREENOVERLAY_HPP */

View File

@ -68,7 +68,8 @@ SOURCES += main.cpp\
logs/historydialog.cpp \ logs/historydialog.cpp \
monospacetextdialog.cpp \ monospacetextdialog.cpp \
screenoverlayview.cpp \ screenoverlayview.cpp \
cropeditor/selectionrectangle.cpp cropeditor/selectionrectangle.cpp \
screenoverlay.cpp
HEADERS += mainwindow.hpp \ HEADERS += mainwindow.hpp \
cropeditor/cropeditor.hpp \ cropeditor/cropeditor.hpp \
@ -118,7 +119,8 @@ HEADERS += mainwindow.hpp \
screenoverlayview.hpp \ screenoverlayview.hpp \
screenoverlayview.hpp \ screenoverlayview.hpp \
monospacetextdialog.hpp \ monospacetextdialog.hpp \
cropeditor/selectionrectangle.hpp cropeditor/selectionrectangle.hpp \
screenoverlay.hpp
nopkg { nopkg {
# win32 { # win32 {