Shift keeps moved pixels on a line; Ctrl+A selects the canvas from the Layers panel (13.10)
This commit is contained in:
1 parent
765e071c0c
commit
51e373af4c
6 files changed
+54
-32
No files matched your search
@@ -85,7 +85,15 @@ bool CanvasView::moveSelectionTool(QPointF point, Qt::KeyboardModifiers modifier
|
||||
{
|
||||
if (m_pixelDragStart && m_session.document()) {
|
||||
const QPointF pixel = m_session.viewport.documentPoint(point, m_session.document()->size());
|
||||
m_session.movePixels(QSizeF(pixel.x() - m_pixelDragStart->x(), pixel.y() - m_pixelDragStart->y()));
|
||||
QSizeF offset(pixel.x() - m_pixelDragStart->x(), pixel.y() - m_pixelDragStart->y());
|
||||
// Shift keeps the pixels on a line, the longer way.
|
||||
if (modifiers.testFlag(Qt::ShiftModifier)) {
|
||||
if (std::abs(offset.width()) >= std::abs(offset.height()))
|
||||
offset.setHeight(0);
|
||||
else
|
||||
offset.setWidth(0);
|
||||
}
|
||||
m_session.movePixels(offset);
|
||||
updateCursor();
|
||||
synchronizeDisplay();
|
||||
return true;
|
||||
|
||||
@@ -2,20 +2,10 @@
|
||||
#include "IO/RecentProjects.h"
|
||||
#include "Logging.h"
|
||||
#include "UI/KeyboardShortcuts.h"
|
||||
#include "UI/NativeLayerList.h"
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
|
||||
namespace {
|
||||
// The layer list holding the keys, as Swift's table.
|
||||
NativeLayerList *focusedList()
|
||||
{
|
||||
for (QWidget *widget = QApplication::focusWidget(); widget; widget = widget->parentWidget())
|
||||
if (auto *list = qobject_cast<NativeLayerList *>(widget))
|
||||
return list;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// An entry's name: Hue/Saturation is newHueSaturationAdjustment.
|
||||
QString adjustmentName(AdjustmentKind kind)
|
||||
{
|
||||
@@ -186,8 +176,6 @@ CompositorMenus::CompositorMenus(ProjectWorkspace &workspace, QMenuBar &bar, QWi
|
||||
m_field->selectAll();
|
||||
else if (InlineTextEditor *text = typedText())
|
||||
text->selectAll();
|
||||
else if (NativeLayerList *list = focusedList())
|
||||
list->selectAllRows();
|
||||
else
|
||||
session().selectAll();
|
||||
});
|
||||
|
||||
@@ -261,13 +261,3 @@ void NativeLayerList::changeEvent(QEvent *event)
|
||||
if (event->type() == QEvent::PaletteChange)
|
||||
QMetaObject::invokeMethod(this, &NativeLayerList::update, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void NativeLayerList::selectAllRows()
|
||||
{
|
||||
if (m_rows.empty())
|
||||
return;
|
||||
QSet<QUuid> ids;
|
||||
for (const ImageLayer &row : m_rows)
|
||||
ids.insert(row.id);
|
||||
m_session.selectLayers(ids, m_rows.front().id);
|
||||
}
|
||||
@@ -215,8 +215,6 @@ public:
|
||||
QString dragToken() const { return m_dragToken; }
|
||||
|
||||
EditorSession &session() const { return m_session; }
|
||||
// The table's Select All: every row, the top one primary.
|
||||
void selectAllRows();
|
||||
void update();
|
||||
std::vector<LayerCell *> cells() const { return m_cells; }
|
||||
// The row under a point of this list, or -1.
|
||||
|
||||
@@ -121,17 +121,22 @@ void SelectMenuTests::selectAllInAFieldIsTheFields()
|
||||
QVERIFY(!bar.session().selection().has_value());
|
||||
QTest::keyClick(editor, Qt::Key_Escape);
|
||||
QTRY_VERIFY(!bar.session().renamingLayerID().has_value());
|
||||
// The list holds the keys: its rows, as Swift's table.
|
||||
// The list holds the keys: the canvas, never every layer.
|
||||
bar.session().addBlankLayer();
|
||||
NativeLayerList *list = bar.window.findChild<NativeLayerList *>();
|
||||
list->setFocus();
|
||||
QTRY_VERIFY(list->hasFocus());
|
||||
const std::vector<ImageLayer> &layers = bar.session().document().value().layers;
|
||||
bar.action("selectAll").trigger();
|
||||
QCOMPARE(bar.session().selectedLayerIDs(), (QSet<QUuid>{layers[0].id, layers[1].id}));
|
||||
QCOMPARE(bar.session().activeLayerID(), std::optional(layers[1].id));
|
||||
QVERIFY(!bar.session().selection().has_value());
|
||||
// Elsewhere it selects the canvas.
|
||||
const QSet<QUuid> selected = bar.session().selectedLayerIDs();
|
||||
const std::optional<QUuid> active = bar.session().activeLayerID();
|
||||
QCOMPARE(selected.size(), 1);
|
||||
QTest::keyClick(list, Qt::Key_A, Qt::ControlModifier);
|
||||
QCOMPARE(bar.session().selection().value().path.boundingRect(), QRectF(0, 0, 50, 50));
|
||||
QCOMPARE(bar.session().history.undoName(), QString("Select All"));
|
||||
QCOMPARE(bar.session().selectedLayerIDs(), selected);
|
||||
QCOMPARE(bar.session().activeLayerID(), active);
|
||||
QVERIFY(list->hasFocus());
|
||||
// Elsewhere it selects the canvas too.
|
||||
bar.session().deselect();
|
||||
bar.window.findChild<CanvasView *>()->setFocus();
|
||||
QTRY_VERIFY(!list->hasFocus());
|
||||
bar.action("selectAll").trigger();
|
||||
|
||||
@@ -11,6 +11,7 @@ private slots:
|
||||
void focusLossEndsAMarqueeDraftAndAnOutlineMove();
|
||||
void shiftDeleteBeginsAContentAwareFill();
|
||||
void aCtrlDragMovesSelectedPixelsAndCtrlArrowsNudgeThem();
|
||||
void shiftKeepsMovedPixelsOnALine();
|
||||
};
|
||||
|
||||
void SelectionCanvasTests::marqueeDragsSelectShiftAddsAltSubtractsAndAFreshShiftSquares()
|
||||
@@ -322,5 +323,37 @@ void SelectionCanvasTests::aCtrlDragMovesSelectedPixelsAndCtrlArrowsNudgeThem()
|
||||
QVERIFY(session.lassoDraft().has_value() && !session.pixelMove());
|
||||
}
|
||||
|
||||
void SelectionCanvasTests::shiftKeepsMovedPixelsOnALine()
|
||||
{
|
||||
Canvas shown;
|
||||
EditorSession &session = shown.session;
|
||||
QImage red = BrushRaster::context(400, 300, false);
|
||||
red.fill(Qt::red);
|
||||
session.insert(ImportedImage(red, red, "Red"));
|
||||
session.applySelection(rectPath(QRectF(20, 20, 40, 40)), SelectionMode::replace, "Select");
|
||||
shown.canvas->synchronizeDisplay();
|
||||
const auto box = [&] { return session.displayedSelection().value().path.boundingRect(); };
|
||||
shown.press(QPointF(40, 40), Qt::ControlModifier);
|
||||
QVERIFY(session.pixelMove());
|
||||
// Across: the drag went further that way.
|
||||
shown.move(QPointF(100, 55), Qt::ControlModifier | Qt::ShiftModifier);
|
||||
QCOMPARE(box(), QRectF(80, 20, 40, 40));
|
||||
// Down, then a tie keeps across.
|
||||
shown.move(QPointF(50, 100), Qt::ControlModifier | Qt::ShiftModifier);
|
||||
QCOMPARE(box(), QRectF(20, 80, 40, 40));
|
||||
shown.move(QPointF(10, 10), Qt::ControlModifier | Qt::ShiftModifier);
|
||||
QCOMPARE(box(), QRectF(-10, 20, 40, 40));
|
||||
// Lengths, not signs: left beats a shorter down.
|
||||
shown.move(QPointF(0, 50), Qt::ControlModifier | Qt::ShiftModifier);
|
||||
QCOMPARE(box(), QRectF(-20, 20, 40, 40));
|
||||
// Without Shift both ways.
|
||||
shown.move(QPointF(60, 55), Qt::ControlModifier);
|
||||
QCOMPARE(box(), QRectF(40, 35, 40, 40));
|
||||
shown.move(QPointF(70, 45), Qt::ControlModifier | Qt::ShiftModifier);
|
||||
shown.release(QPointF(70, 45), Qt::ControlModifier | Qt::ShiftModifier);
|
||||
QTRY_VERIFY(!session.pixelMove());
|
||||
QCOMPARE(session.selection().value().path.boundingRect(), QRectF(50, 20, 40, 40));
|
||||
}
|
||||
|
||||
QTEST_MAIN(SelectionCanvasTests)
|
||||
#include "SelectionCanvasTests.moc"
|
||||
Reference in new issue
Block a user