diff --git a/src/tools/abstracttwopointtool.cpp b/src/tools/abstracttwopointtool.cpp index f7b31ad2..3061c98c 100644 --- a/src/tools/abstracttwopointtool.cpp +++ b/src/tools/abstracttwopointtool.cpp @@ -16,6 +16,29 @@ // along with Flameshot. If not, see . #include "abstracttwopointtool.h" +#include + +namespace { + +const double ADJ_UNIT = std::atan(1.0); +const int DIRS_NUMBER = 4; + +enum UNIT { + HORIZ_DIR = 0, + DIAG1_DIR = 1, + VERT_DIR = 2, + DIAG2_DIR = 3 +}; + +const double ADJ_DIAG_UNIT = 2 * ADJ_UNIT; +const int DIAG_DIRS_NUMBER = 2; + +enum DIAG_UNIT { + DIR1 = 0, + DIR2 = 1 +}; + +} AbstractTwoPointTool::AbstractTwoPointTool(QObject *parent) : CaptureTool(parent), m_thickness(0), m_padding(0) @@ -52,6 +75,10 @@ void AbstractTwoPointTool::drawMove(const QPoint &p) { m_points.second = p; } +void AbstractTwoPointTool::drawMoveWithAdjustment(const QPoint &p) { + m_points.second = m_points.first + adjustedVector(p - m_points.first); +} + void AbstractTwoPointTool::colorChanged(const QColor &c) { m_color = c; } @@ -70,3 +97,39 @@ QRect AbstractTwoPointTool::backupRect(const QRect &limits) const { r += QMargins(val, val, val, val); return r.intersected(limits); } + +QPoint AbstractTwoPointTool::adjustedVector(QPoint v) const { + if (m_supportsOrthogonalAdj && m_supportsDiagonalAdj) { + int dir = ( static_cast(round(atan2(-v.y(), v.x()) / ADJ_UNIT)) + DIRS_NUMBER ) % DIRS_NUMBER; + if (dir == UNIT::HORIZ_DIR) { + v.setY(0); + } else if (dir == UNIT::VERT_DIR) { + v.setX(0); + } else if (dir == UNIT::DIAG1_DIR) { + int newX = (v.x() - v.y()) / 2; + int newY = -newX; + v.setX(newX); + v.setY(newY); + } else { + int newX = (v.x() + v.y()) / 2; + int newY = newX; + v.setX(newX); + v.setY(newY); + } + } else if (m_supportsDiagonalAdj) { + int dir = ( static_cast(round((atan2(-v.y(), v.x()) - ADJ_DIAG_UNIT / 2) / ADJ_DIAG_UNIT)) + + DIAG_DIRS_NUMBER ) % DIAG_DIRS_NUMBER; + if (dir == DIAG_UNIT::DIR1) { + int newX = (v.x() - v.y()) / 2; + int newY = -newX; + v.setX(newX); + v.setY(newY); + } else { + int newX = (v.x() + v.y()) / 2; + int newY = newX; + v.setX(newX); + v.setY(newY); + } + } + return v; +} diff --git a/src/tools/abstracttwopointtool.h b/src/tools/abstracttwopointtool.h index d44f3b53..9a979ef3 100644 --- a/src/tools/abstracttwopointtool.h +++ b/src/tools/abstracttwopointtool.h @@ -34,6 +34,7 @@ public: public slots: void drawEnd(const QPoint &p) override; void drawMove(const QPoint &p) override; + void drawMoveWithAdjustment(const QPoint &p) override; void colorChanged(const QColor &c) override; void thicknessChanged(const int th) override; @@ -48,4 +49,9 @@ protected: // use m_padding to extend the area of the backup int m_padding; + bool m_supportsOrthogonalAdj = false; + bool m_supportsDiagonalAdj = false; + +private: + QPoint adjustedVector(QPoint v) const; }; diff --git a/src/tools/arrow/arrowtool.cpp b/src/tools/arrow/arrowtool.cpp index 91b2c8a0..dd854017 100644 --- a/src/tools/arrow/arrowtool.cpp +++ b/src/tools/arrow/arrowtool.cpp @@ -70,6 +70,8 @@ QLine getShorterLine(QPoint p1, QPoint p2, const int thickness) { ArrowTool::ArrowTool(QObject *parent) : AbstractTwoPointTool(parent) { m_padding = ArrowWidth / 2; + m_supportsOrthogonalAdj = true; + m_supportsDiagonalAdj = true; } QIcon ArrowTool::icon(const QColor &background, bool inEditor) const { diff --git a/src/tools/capturetool.h b/src/tools/capturetool.h index ccdd5c85..ae1a70c0 100644 --- a/src/tools/capturetool.h +++ b/src/tools/capturetool.h @@ -135,6 +135,11 @@ public slots: virtual void drawEnd(const QPoint &p) = 0; // Mouse pressed and moving, called once a pixel. virtual void drawMove(const QPoint &p) = 0; + // Called when drawMove is needed with an adjustment; + // should be overridden in case an adjustment is applicable. + virtual void drawMoveWithAdjustment(const QPoint &p) { + drawMove(p); + } // Called when the tool is activated. virtual void drawStart(const CaptureContext &context) = 0; // Called right after pressign the button which activates the tool. diff --git a/src/tools/circle/circletool.cpp b/src/tools/circle/circletool.cpp index 8cbf6653..ca6e187c 100644 --- a/src/tools/circle/circletool.cpp +++ b/src/tools/circle/circletool.cpp @@ -23,7 +23,7 @@ namespace { } CircleTool::CircleTool(QObject *parent) : AbstractTwoPointTool(parent) { - + m_supportsDiagonalAdj = true; } QIcon CircleTool::icon(const QColor &background, bool inEditor) const { diff --git a/src/tools/line/linetool.cpp b/src/tools/line/linetool.cpp index cbed9a77..343d3eb1 100644 --- a/src/tools/line/linetool.cpp +++ b/src/tools/line/linetool.cpp @@ -20,18 +20,13 @@ namespace { -#define ADJ_VALUE 13 #define PADDING_VALUE 2 -// Have to force horizontal position -bool needsAdjustment(const QPoint &p0, const QPoint &p1) { - return (p1.y() >= p0.y() - ADJ_VALUE) && (p1.y() <= p0.y() + ADJ_VALUE); -} - } LineTool::LineTool(QObject *parent) : AbstractTwoPointTool(parent) { - + m_supportsOrthogonalAdj = true; + m_supportsDiagonalAdj = true; } QIcon LineTool::icon(const QColor &background, bool inEditor) const { @@ -67,13 +62,6 @@ void LineTool::paintMousePreview(QPainter &painter, const CaptureContext &contex painter.drawLine(context.mousePos, context.mousePos); } -void LineTool::drawMove(const QPoint &p) { - m_points.second = p; - if (needsAdjustment(m_points.first, m_points.second)) { - m_points.second.setY(m_points.first.y()); - } -} - void LineTool::drawStart(const CaptureContext &context) { m_color = context.color; m_thickness = context.thickness + PADDING_VALUE; diff --git a/src/tools/line/linetool.h b/src/tools/line/linetool.h index ffb4a577..bb140656 100644 --- a/src/tools/line/linetool.h +++ b/src/tools/line/linetool.h @@ -35,7 +35,6 @@ public: void paintMousePreview(QPainter &painter, const CaptureContext &context) override; public slots: - void drawMove(const QPoint &p) override; void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; }; diff --git a/src/tools/marker/markertool.cpp b/src/tools/marker/markertool.cpp index b444076c..b5d027bb 100644 --- a/src/tools/marker/markertool.cpp +++ b/src/tools/marker/markertool.cpp @@ -20,18 +20,13 @@ namespace { -#define ADJ_VALUE 14 #define PADDING_VALUE 14 -// Have to force horizontal position -bool needsAdjustment(const QPoint &p0, const QPoint &p1) { - return (p1.y() >= p0.y() - ADJ_VALUE) && (p1.y() <= p0.y() + ADJ_VALUE); -} - } MarkerTool::MarkerTool(QObject *parent) : AbstractTwoPointTool(parent) { - + m_supportsOrthogonalAdj = true; + m_supportsDiagonalAdj = true; } QIcon MarkerTool::icon(const QColor &background, bool inEditor) const { @@ -71,13 +66,6 @@ void MarkerTool::paintMousePreview(QPainter &painter, const CaptureContext &cont painter.drawLine(context.mousePos, context.mousePos); } -void MarkerTool::drawMove(const QPoint &p) { - m_points.second = p; - if (needsAdjustment(m_points.first, m_points.second)) { - m_points.second.setY(m_points.first.y()); - } -} - void MarkerTool::drawStart(const CaptureContext &context) { m_color = context.color; m_thickness = context.thickness + PADDING_VALUE; diff --git a/src/tools/marker/markertool.h b/src/tools/marker/markertool.h index 69fdf45c..4d71e48e 100644 --- a/src/tools/marker/markertool.h +++ b/src/tools/marker/markertool.h @@ -35,7 +35,6 @@ public: void paintMousePreview(QPainter &painter, const CaptureContext &context) override; public slots: - void drawMove(const QPoint &p) override; void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; void thicknessChanged(const int th) override; diff --git a/src/tools/rectangle/rectangletool.cpp b/src/tools/rectangle/rectangletool.cpp index 1e0d2ee5..9d972582 100644 --- a/src/tools/rectangle/rectangletool.cpp +++ b/src/tools/rectangle/rectangletool.cpp @@ -23,7 +23,7 @@ namespace { } RectangleTool::RectangleTool(QObject *parent) : AbstractTwoPointTool(parent) { - + m_supportsDiagonalAdj = true; } QIcon RectangleTool::icon(const QColor &background, bool inEditor) const { diff --git a/src/tools/selection/selectiontool.cpp b/src/tools/selection/selectiontool.cpp index 8b344b8c..2717da9a 100644 --- a/src/tools/selection/selectiontool.cpp +++ b/src/tools/selection/selectiontool.cpp @@ -23,7 +23,7 @@ namespace { } SelectionTool::SelectionTool(QObject *parent) : AbstractTwoPointTool(parent) { - + m_supportsDiagonalAdj = true; } bool SelectionTool::closeOnButtonPressed() const { diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index c38fc3fe..1db615bb 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -52,7 +52,7 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, bool fullScreen, QWidget *parent) : QWidget(parent), m_mouseIsClicked(false), m_rightClick(false), m_newSelection(false), m_grabbing(false), m_captureDone(false), - m_previewEnabled(true), m_activeButton(nullptr), + m_previewEnabled(true), m_adjustmentButtonPressed(false), m_activeButton(nullptr), m_activeTool(nullptr), m_toolWidget(nullptr), m_mouseOverHandle(SelectionWidget::NO_SIDE), m_id(id) { @@ -398,7 +398,11 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) { } } else if (m_mouseIsClicked && m_activeTool) { // drawing with a tool - m_activeTool->drawMove(e->pos()); + if (m_adjustmentButtonPressed) { + m_activeTool->drawMoveWithAdjustment(e->pos()); + } else { + m_activeTool->drawMove(e->pos()); + } update(); // Hides the buttons under the mouse. If the mouse leaves, it shows them. if (m_buttonHandler->buttonsAreInside()) { @@ -494,6 +498,14 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) { m_context.selection = extendedRect(&newGeometry); m_buttonHandler->updatePosition(m_selection->geometry()); update(); + } else if (e->key() == Qt::Key_Control) { + m_adjustmentButtonPressed = true; + } +} + +void CaptureWidget::keyReleaseEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_Control) { + m_adjustmentButtonPressed = false; } } diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index a1c8b0e9..171ab33c 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -97,6 +97,7 @@ protected: void mouseMoveEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void keyPressEvent(QKeyEvent *); + void keyReleaseEvent(QKeyEvent *); void wheelEvent(QWheelEvent *); void resizeEvent(QResizeEvent *); void moveEvent(QMoveEvent *); @@ -119,6 +120,7 @@ protected: bool m_showInitialMsg; bool m_captureDone; bool m_previewEnabled; + bool m_adjustmentButtonPressed; private: void initContext(const QString &savePath, bool fullscreen);