mirror of
https://github.com/fergalmoran/flameshot.git
synced 2026-01-06 17:13:58 +00:00
Add 45-multiple degree adjustment for line, arrow and marker tools (#439)
* Add 45-multiple degree adjustment for line, arrow and marker tools * Adjustment: Ctrl press is checked + widened functionality for two-point tools
This commit is contained in:
committed by
Dharkael
parent
bd83eea7af
commit
b42f1cf01d
@@ -16,6 +16,29 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "abstracttwopointtool.h"
|
||||
#include <cmath>
|
||||
|
||||
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<int>(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<int>(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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
}
|
||||
|
||||
CircleTool::CircleTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon CircleTool::icon(const QColor &background, bool inEditor) const {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
}
|
||||
|
||||
RectangleTool::RectangleTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon RectangleTool::icon(const QColor &background, bool inEditor) const {
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
}
|
||||
|
||||
SelectionTool::SelectionTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
bool SelectionTool::closeOnButtonPressed() const {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user