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);