diff --git a/src/QuickEditor/EditorRoot.qml b/src/QuickEditor/EditorRoot.qml --- a/src/QuickEditor/EditorRoot.qml +++ b/src/QuickEditor/EditorRoot.qml @@ -38,6 +38,8 @@ property int magZoom: 5; property int magPixels: 16; property int magOffset: 32; + property int largeChange: 15 / Screen.devicePixelRatio; + property int smallChange: -1 / Screen.devicePixelRatio SystemPalette { id: systemPalette; @@ -49,10 +51,10 @@ } selection = cropRectangle.createObject(parent, { - "x": xx, - "y": yy, - "height": hh, - "width": ww + "x": xx, + "y": yy, + "height": hh, + "width": ww }); cropDisplayCanvas.requestPaint(); @@ -78,11 +80,195 @@ } Keys.onPressed: { + + var delta; // valid for either direction + + // shift key alone = magnifier toggle if (event.modifiers & Qt.ShiftModifier) { toggleMagnifier = true; - cropDisplayCanvas.requestPaint(); } - } + + // nested switches for arrow keys based on modifier keys + switch(event.modifiers) { + + case Qt.NoModifier: + switch(event.key) { + case Qt.Key_Left: + delta = checkBounds(smallChange, 0, "left"); + selection.x = selection.x + delta; + break; + case Qt.Key_Right: + delta = checkBounds(-smallChange, 0, "right"); + selection.x = selection.x + delta; + break; + case Qt.Key_Up: + delta = checkBounds(0, smallChange, "up"); + selection.y = selection.y + delta; + break; + case Qt.Key_Down: + delta = checkBounds(0, -smallChange, "down"); + selection.y = selection.y + delta; + break; + } + + break; // end no modifier (just arrows) + + case Qt.ShiftModifier: + switch(event.key) { + case Qt.Key_Left: + delta = checkBounds(-largeChange, 0, "left"); + selection.x = selection.x + delta; + break; + + case Qt.Key_Right: + delta = checkBounds(largeChange, 0, "right"); + selection.x = selection.x + delta; + break; + + case Qt.Key_Up: + delta = checkBounds(0, -largeChange, "up"); + selection.y = selection.y + delta; + break; + + case Qt.Key_Down: + delta = checkBounds(0, largeChange, "down"); + selection.y = selection.y + delta; + break; + } + + break; // end Shift + arrows (large move) + + case Qt.AltModifier: + switch(event.key) { + case Qt.Key_Left: + delta = checkBounds(smallChange, 0, "left"); + if (selection.width + delta <= 0) { + selection.width = 0; + } else { + selection.width = selection.width + delta; + } + break; + + case Qt.Key_Right: + delta = checkBounds(-smallChange, 0, "right"); + selection.width = selection.width + delta; + break; + + case Qt.Key_Up: + delta = checkBounds(0, smallChange, "up"); + if (selection.height + delta <= 0) { + selection.height = 0; + } else { + selection.height = selection.height + delta; + } + break; + + case Qt.Key_Down: + delta = checkBounds(0, -smallChange, "down"); + selection.height = selection.height + delta; + break; + } + break; // end ALT + arrows (resize rectangle) + + case(Qt.ShiftModifier + Qt.AltModifier): + switch(event.key) { + case Qt.Key_Left: + delta = checkBounds(-largeChange, 0, "left"); + if (selection.width + delta <= 0) { + selection.width = 0; + } else { + selection.width = selection.width + delta; + } + break; + + case Qt.Key_Right: + delta = checkBounds(largeChange, 0, "right"); + selection.width = selection.width + delta; + break; + + case Qt.Key_Up: + delta = checkBounds(0, -largeChange, "up"); + if (selection.height + delta <= 0) { + selection.height = 0; + } else { + selection.height = selection.height + delta + } + break; + + case Qt.Key_Down: + delta = checkBounds(0, largeChange, "down"); + selection.height = selection.height + delta; + break; + } + break; // end Shift + ALT + arrows (large resize rectangle) + + } + + // all switches done; repaint on any keypress + cropDisplayCanvas.requestPaint(); + + function checkBounds(deltaX, deltaY, direction) { + + var leftEdge = selection.x; + var rightEdge = selection.x + selection.width; + var topEdge = selection.y; + var bottomEdge = selection.y + selection.height; + + const screenMaxX = cropDisplayCanvas.width; + const screenMaxY = cropDisplayCanvas.height; + + var newX; + var newY; + + var overlap; + + newX = selection.x + deltaX; + newY = selection.y + deltaY; + + switch (direction) { + + case "left": + if (leftEdge + deltaX >= 0) { + return deltaX; + } + + if (leftEdge + deltaX <= 0) { + return -leftEdge; + } + break; + + case "right": + newX = newX + selection.width; + if (newX <= screenMaxX) { + return deltaX; + } + if (newX >= screenMaxX) { + overlap = newX - screenMaxX; + return deltaX - overlap; + } + break; + + case "up": + if (topEdge + deltaY >= 0) { + return deltaY; + } else { + return -topEdge; + } + + case "down": + newY = newY + selection.height; + if (newY <= screenMaxY) { + return deltaY; + } + if (newY >= screenMaxY) { + overlap = newY - screenMaxY; + return deltaY - overlap; + } + break; + } + } + } // end Keys.onPressed + Keys.onReleased: { if (toggleMagnifier && !(event.modifiers & Qt.ShiftModifier)) { @@ -254,8 +440,8 @@ id: midHelpText; objectName: "midHelpText"; - height: midHelpTextElement.height + 40; - width: midHelpTextElement.width + 40; + height: midHelpTextElement.height + 20; + width: midHelpTextElement.width + 20; radius: 4; border.color: systemPalette.windowText; color: labelBackgroundColour; @@ -277,46 +463,61 @@ id: bottomHelpText; objectName: "bottomHelpText"; - height: bottomHelpTextElement.height + 20; - width: bottomHelpTextElement.width + 20; + height: bottomHelpTextElement.height + width: bottomHelpTextElement.width radius: 4; border.color: systemPalette.windowText; color: labelBackgroundColour; visible: false; anchors.bottom: parent.bottom; anchors.horizontalCenter: parent.horizontalCenter; + RowLayout { + id: bottomHelpTextElement + GridLayout { - id: bottomHelpTextElement; columns: 2 - anchors.centerIn: parent; + Layout.alignment: Qt.AlignLeft && Qt.AlignHCenter + Layout.leftMargin: 10 + Layout.topMargin: 5 + Layout.bottomMargin: 5 + Layout.rightMargin: 10 Label { text: i18n("Enter, double-click:"); - Layout.alignment: Qt.AlignRight; + Layout.alignment: Qt.AlignLeft; } Label { text: i18n("Take screenshot"); } Label { text: i18n("Shift:"); - Layout.alignment: Qt.AlignRight; + Layout.alignment: Qt.AlignLeft; } Label { text: i18n("Hold to toggle magnifier"); } Label { text: i18n("Right-click:"); - Layout.alignment: Qt.AlignRight; + Layout.alignment: Qt.AlignLeft; } Label { text: i18n("Reset selection"); } Label { text: i18n("Esc:"); - Layout.alignment: Qt.AlignRight; + Layout.alignment: Qt.AlignLeft; } Label { text: i18n("Cancel"); } + + Label { + text: i18n("Arrow Keys:"); + Layout.alignment: Qt.AlignLeft && Qt.AlignTop; + } + Label { text: i18n("Move/resize selection rectangle \n" + + "ALT to resize, Shift for %1px change", largeChange); } } } + } + // Use Rectangle so that the background is white when cursor nearby edge Rectangle { @@ -368,7 +569,6 @@ color: crossColour; } } - } MouseArea {