Improve resizing in flameshot (#2931)
* Allow symmetrical resizing using arrow keys when pressing ctrl * Add feature to preserve aspect ratio while resizing selection window * Format according to clang-format
This commit is contained in:
@@ -203,6 +203,7 @@ These shortcuts are available in GUI mode:
|
|||||||
| <kbd>B</kbd> | Set Pixalate as the paint tool |
|
| <kbd>B</kbd> | Set Pixalate as the paint tool |
|
||||||
| <kbd>←</kbd>, <kbd>↓</kbd>, <kbd>↑</kbd>, <kbd>→</kbd> | Move selection 1px |
|
| <kbd>←</kbd>, <kbd>↓</kbd>, <kbd>↑</kbd>, <kbd>→</kbd> | Move selection 1px |
|
||||||
| <kbd>Shift</kbd> + <kbd>←</kbd>, <kbd>↓</kbd>, <kbd>↑</kbd>, <kbd>→</kbd> | Resize selection 1px |
|
| <kbd>Shift</kbd> + <kbd>←</kbd>, <kbd>↓</kbd>, <kbd>↑</kbd>, <kbd>→</kbd> | Resize selection 1px |
|
||||||
|
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>←</kbd>, <kbd>↓</kbd>, <kbd>↑</kbd>, <kbd>→</kbd> | Symmetrically resize selection 2px |
|
||||||
| <kbd>Esc</kbd> | Quit capture |
|
| <kbd>Esc</kbd> | Quit capture |
|
||||||
| <kbd>Ctrl</kbd> + <kbd>M</kbd> | Move the selection area |
|
| <kbd>Ctrl</kbd> + <kbd>M</kbd> | Move the selection area |
|
||||||
| <kbd>Ctrl</kbd> + <kbd>C</kbd> | Copy to clipboard |
|
| <kbd>Ctrl</kbd> + <kbd>C</kbd> | Copy to clipboard |
|
||||||
|
|||||||
@@ -113,6 +113,10 @@
|
|||||||
;TYPE_RESIZE_LEFT=Shift+Left
|
;TYPE_RESIZE_LEFT=Shift+Left
|
||||||
;TYPE_RESIZE_RIGHT=Shift+Right
|
;TYPE_RESIZE_RIGHT=Shift+Right
|
||||||
;TYPE_RESIZE_UP=Shift+Up
|
;TYPE_RESIZE_UP=Shift+Up
|
||||||
|
;TYPE_SYM_RESIZE_DOWN=Ctrl+Shift+Down
|
||||||
|
;TYPE_SYM_RESIZE_LEFT=Ctrl+Shift+Left
|
||||||
|
;TYPE_SYM_RESIZE_RIGHT=Ctrl+Shift+Right
|
||||||
|
;TYPE_SYM_RESIZE_UP=Ctrl+Shift+Up
|
||||||
;TYPE_SAVE=Ctrl+S
|
;TYPE_SAVE=Ctrl+S
|
||||||
;TYPE_SELECTION=S
|
;TYPE_SELECTION=S
|
||||||
;TYPE_SELECTIONINDICATOR=
|
;TYPE_SELECTIONINDICATOR=
|
||||||
|
|||||||
@@ -176,6 +176,14 @@ void ShortcutsWidget::loadShortcuts()
|
|||||||
appendShortcut("TYPE_RESIZE_RIGHT", tr("Resize selection right 1px"));
|
appendShortcut("TYPE_RESIZE_RIGHT", tr("Resize selection right 1px"));
|
||||||
appendShortcut("TYPE_RESIZE_UP", tr("Resize selection up 1px"));
|
appendShortcut("TYPE_RESIZE_UP", tr("Resize selection up 1px"));
|
||||||
appendShortcut("TYPE_RESIZE_DOWN", tr("Resize selection down 1px"));
|
appendShortcut("TYPE_RESIZE_DOWN", tr("Resize selection down 1px"));
|
||||||
|
appendShortcut("TYPE_SYM_RESIZE_LEFT",
|
||||||
|
tr("Symmetrically decrease width by 2px"));
|
||||||
|
appendShortcut("TYPE_SYM_RESIZE_RIGHT",
|
||||||
|
tr("Symmetrically increase width by 2px"));
|
||||||
|
appendShortcut("TYPE_SYM_RESIZE_UP",
|
||||||
|
tr("Symmetrically increase height by 2px"));
|
||||||
|
appendShortcut("TYPE_SYM_RESIZE_DOWN",
|
||||||
|
tr("Symmetrically decrease height by 2px"));
|
||||||
appendShortcut("TYPE_SELECT_ALL", tr("Select entire screen"));
|
appendShortcut("TYPE_SELECT_ALL", tr("Select entire screen"));
|
||||||
appendShortcut("TYPE_MOVE_LEFT", tr("Move selection left 1px"));
|
appendShortcut("TYPE_MOVE_LEFT", tr("Move selection left 1px"));
|
||||||
appendShortcut("TYPE_MOVE_RIGHT", tr("Move selection right 1px"));
|
appendShortcut("TYPE_MOVE_RIGHT", tr("Move selection right 1px"));
|
||||||
|
|||||||
@@ -155,6 +155,10 @@ static QMap<QString, QSharedPointer<KeySequence>> recognizedShortcuts = {
|
|||||||
SHORTCUT("TYPE_RESIZE_RIGHT" , "Shift+Right" ),
|
SHORTCUT("TYPE_RESIZE_RIGHT" , "Shift+Right" ),
|
||||||
SHORTCUT("TYPE_RESIZE_UP" , "Shift+Up" ),
|
SHORTCUT("TYPE_RESIZE_UP" , "Shift+Up" ),
|
||||||
SHORTCUT("TYPE_RESIZE_DOWN" , "Shift+Down" ),
|
SHORTCUT("TYPE_RESIZE_DOWN" , "Shift+Down" ),
|
||||||
|
SHORTCUT("TYPE_SYM_RESIZE_LEFT" , "Ctrl+Shift+Left" ),
|
||||||
|
SHORTCUT("TYPE_SYM_RESIZE_RIGHT" , "Ctrl+Shift+Right" ),
|
||||||
|
SHORTCUT("TYPE_SYM_RESIZE_UP" , "Ctrl+Shift+Up" ),
|
||||||
|
SHORTCUT("TYPE_SYM_RESIZE_DOWN" , "Ctrl+Shift+Down" ),
|
||||||
SHORTCUT("TYPE_SELECT_ALL" , "Ctrl+A" ),
|
SHORTCUT("TYPE_SELECT_ALL" , "Ctrl+A" ),
|
||||||
SHORTCUT("TYPE_MOVE_LEFT" , "Left" ),
|
SHORTCUT("TYPE_MOVE_LEFT" , "Left" ),
|
||||||
SHORTCUT("TYPE_MOVE_RIGHT" , "Right" ),
|
SHORTCUT("TYPE_MOVE_RIGHT" , "Right" ),
|
||||||
|
|||||||
@@ -1505,6 +1505,18 @@ void CaptureWidget::initShortcuts()
|
|||||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")),
|
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")),
|
||||||
m_selection,
|
m_selection,
|
||||||
SLOT(resizeDown()));
|
SLOT(resizeDown()));
|
||||||
|
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_SYM_RESIZE_LEFT")),
|
||||||
|
m_selection,
|
||||||
|
SLOT(symResizeLeft()));
|
||||||
|
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_SYM_RESIZE_RIGHT")),
|
||||||
|
m_selection,
|
||||||
|
SLOT(symResizeRight()));
|
||||||
|
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_SYM_RESIZE_UP")),
|
||||||
|
m_selection,
|
||||||
|
SLOT(symResizeUp()));
|
||||||
|
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_SYM_RESIZE_DOWN")),
|
||||||
|
m_selection,
|
||||||
|
SLOT(symResizeDown()));
|
||||||
|
|
||||||
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")),
|
newShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")),
|
||||||
m_selection,
|
m_selection,
|
||||||
|
|||||||
@@ -215,58 +215,149 @@ void SelectionWidget::parentMouseMoveEvent(QMouseEvent* e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto geom = geometry();
|
auto geom = geometry();
|
||||||
|
float aspectRatio = (float)geom.width() / (float)geom.height();
|
||||||
bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier;
|
bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier;
|
||||||
|
bool preserveAspect = qApp->keyboardModifiers() & Qt::ControlModifier;
|
||||||
|
|
||||||
QPoint newTopLeft = geom.topLeft(), newBottomRight = geom.bottomRight();
|
QPoint newTopLeft = geom.topLeft(), newBottomRight = geom.bottomRight();
|
||||||
|
int oldLeft = newTopLeft.rx(), oldRight = newBottomRight.rx(),
|
||||||
|
oldTop = newTopLeft.ry(), oldBottom = newBottomRight.ry();
|
||||||
int &newLeft = newTopLeft.rx(), &newRight = newBottomRight.rx(),
|
int &newLeft = newTopLeft.rx(), &newRight = newBottomRight.rx(),
|
||||||
&newTop = newTopLeft.ry(), &newBottom = newBottomRight.ry();
|
&newTop = newTopLeft.ry(), &newBottom = newBottomRight.ry();
|
||||||
switch (mouseSide) {
|
switch (mouseSide) {
|
||||||
case TOPLEFT_SIDE:
|
case TOPLEFT_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newTopLeft = pos;
|
if (preserveAspect) {
|
||||||
|
if ((float)(oldRight - pos.x()) /
|
||||||
|
(float)(oldBottom - pos.y()) >
|
||||||
|
aspectRatio) {
|
||||||
|
/* width longer than expected width, hence increase
|
||||||
|
* height to compensate for the aspect ratio */
|
||||||
|
newLeft = pos.x();
|
||||||
|
newTop =
|
||||||
|
oldBottom -
|
||||||
|
(int)(((float)(oldRight - pos.x())) / aspectRatio);
|
||||||
|
} else {
|
||||||
|
/* height longer than expected height, hence increase
|
||||||
|
* width to compensate for the aspect ratio */
|
||||||
|
newTop = pos.y();
|
||||||
|
newLeft =
|
||||||
|
oldRight -
|
||||||
|
(int)(((float)(oldBottom - pos.y())) * aspectRatio);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newTopLeft = pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOTTOMRIGHT_SIDE:
|
case BOTTOMRIGHT_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newBottomRight = pos;
|
if (preserveAspect) {
|
||||||
|
if ((float)(pos.x() - oldLeft) / (float)(pos.y() - oldTop) >
|
||||||
|
aspectRatio) {
|
||||||
|
newRight = pos.x();
|
||||||
|
newBottom =
|
||||||
|
oldTop +
|
||||||
|
(int)(((float)(pos.x() - oldLeft)) / aspectRatio);
|
||||||
|
} else {
|
||||||
|
newBottom = pos.y();
|
||||||
|
newRight = oldLeft + (int)(((float)(pos.y() - oldTop)) *
|
||||||
|
aspectRatio);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newBottomRight = pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOPRIGHT_SIDE:
|
case TOPRIGHT_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newTop = pos.y();
|
if (preserveAspect) {
|
||||||
newRight = pos.x();
|
if ((float)(pos.x() - oldLeft) /
|
||||||
|
(float)(oldBottom - pos.y()) >
|
||||||
|
aspectRatio) {
|
||||||
|
newRight = pos.x();
|
||||||
|
newTop =
|
||||||
|
oldBottom -
|
||||||
|
(int)(((float)(pos.x() - oldLeft)) / aspectRatio);
|
||||||
|
} else {
|
||||||
|
newTop = pos.y();
|
||||||
|
newRight =
|
||||||
|
oldLeft +
|
||||||
|
(int)(((float)(oldBottom - pos.y())) * aspectRatio);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newTop = pos.y();
|
||||||
|
newRight = pos.x();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOTTOMLEFT_SIDE:
|
case BOTTOMLEFT_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newBottom = pos.y();
|
if (preserveAspect) {
|
||||||
newLeft = pos.x();
|
if ((float)(oldRight - pos.x()) /
|
||||||
|
(float)(pos.y() - oldTop) >
|
||||||
|
aspectRatio) {
|
||||||
|
newLeft = pos.x();
|
||||||
|
newBottom =
|
||||||
|
oldTop +
|
||||||
|
(int)(((float)(oldRight - pos.x())) / aspectRatio);
|
||||||
|
} else {
|
||||||
|
newBottom = pos.y();
|
||||||
|
newLeft = oldRight - (int)(((float)(pos.y() - oldTop)) *
|
||||||
|
aspectRatio);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newBottom = pos.y();
|
||||||
|
newLeft = pos.x();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LEFT_SIDE:
|
case LEFT_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newLeft = pos.x();
|
newLeft = pos.x();
|
||||||
|
if (preserveAspect) {
|
||||||
|
/* By default bottom edge moves when dragging sides, this
|
||||||
|
* behavior feels natural */
|
||||||
|
newBottom = oldTop + (int)(((float)(oldRight - pos.x())) /
|
||||||
|
aspectRatio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RIGHT_SIDE:
|
case RIGHT_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newRight = pos.x();
|
newRight = pos.x();
|
||||||
|
if (preserveAspect) {
|
||||||
|
newBottom = oldTop + (int)(((float)(pos.x() - oldLeft)) /
|
||||||
|
aspectRatio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOP_SIDE:
|
case TOP_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newTop = pos.y();
|
newTop = pos.y();
|
||||||
|
if (preserveAspect) {
|
||||||
|
/* By default right edge moves when dragging sides, this
|
||||||
|
* behavior feels natural */
|
||||||
|
newRight =
|
||||||
|
oldLeft +
|
||||||
|
(int)(((float)(oldBottom - pos.y()) * aspectRatio));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOTTOM_SIDE:
|
case BOTTOM_SIDE:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
newBottom = pos.y();
|
newBottom = pos.y();
|
||||||
|
if (preserveAspect) {
|
||||||
|
newRight = oldLeft +
|
||||||
|
(int)(((float)(pos.y() - oldTop) * aspectRatio));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (m_activeSide) {
|
if (m_activeSide) {
|
||||||
move(this->pos() + pos - m_dragStartPos);
|
move(this->pos() + pos - m_dragStartPos);
|
||||||
m_dragStartPos = pos;
|
m_dragStartPos = pos;
|
||||||
|
/* do nothing special in case of preserveAspect */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -369,6 +460,26 @@ void SelectionWidget::resizeDown()
|
|||||||
setGeometryByKeyboard(geometry().adjusted(0, 0, 0, 1));
|
setGeometryByKeyboard(geometry().adjusted(0, 0, 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SelectionWidget::symResizeLeft()
|
||||||
|
{
|
||||||
|
setGeometryByKeyboard(geometry().adjusted(1, 0, -1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionWidget::symResizeRight()
|
||||||
|
{
|
||||||
|
setGeometryByKeyboard(geometry().adjusted(-1, 0, 1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionWidget::symResizeUp()
|
||||||
|
{
|
||||||
|
setGeometryByKeyboard(geometry().adjusted(0, -1, 0, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionWidget::symResizeDown()
|
||||||
|
{
|
||||||
|
setGeometryByKeyboard(geometry().adjusted(0, 1, 0, -1));
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionWidget::updateAreas()
|
void SelectionWidget::updateAreas()
|
||||||
{
|
{
|
||||||
QRect r = rect();
|
QRect r = rect();
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ public slots:
|
|||||||
void resizeUp();
|
void resizeUp();
|
||||||
void resizeDown();
|
void resizeDown();
|
||||||
|
|
||||||
|
void symResizeLeft();
|
||||||
|
void symResizeRight();
|
||||||
|
void symResizeUp();
|
||||||
|
void symResizeDown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateAreas();
|
void updateAreas();
|
||||||
void updateCursor();
|
void updateCursor();
|
||||||
|
|||||||
Reference in New Issue
Block a user