Warning, /libraries/kquickimageeditor/examples/KirigamiExample.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: (C) 2020 Carl Schwan <carl@carlschwan.eu>
0003  *
0004  * SPDX-License-Identifier: BSD-2-Clause
0005  */
0006 
0007 import QtQuick 2.10
0008 import QtQuick.Controls 2.1 as QQC2
0009 import QtQuick.Layouts 1.12
0010 import org.kde.kirigami 2.12 as Kirigami
0011 import QtQuick.Dialogs 1.2
0012 import org.kde.kquickimageeditor 1.0 as KQuickImageEditor
0013 import QtGraphicalEffects 1.12
0014 
0015 Kirigami.ApplicationWindow {
0016     id: root
0017     Component.onCompleted: {
0018         pageStack.layers.push(editorComponent);
0019     }
0020     
0021     pageStack.initialPage: Kirigami.Page {
0022         QQC2.Button {
0023             text: "Open Editor"
0024             onClicked: root.pageStack.layers.push(editorComponent);
0025         }
0026     }
0027     
0028     Component { 
0029         id: editorComponent
0030 
0031         Kirigami.Page {
0032             id: rootEditorView
0033 
0034             property bool resizing: false;
0035             property string imagePath: '/usr/share/wallpapers/Next/contents/images/5120x2880.jpg'
0036 
0037             signal imageEdited();
0038 
0039             title: "Edit"
0040             leftPadding: 0
0041             rightPadding: 0
0042             topPadding: 0
0043             bottomPadding: 0
0044 
0045             function crop() {
0046                 rootEditorView.resizing = false
0047                 imageDoc.crop(selectionTool.selectionX / editImage.ratioX,
0048                               selectionTool.selectionY / editImage.ratioY,
0049                               selectionTool.selectionWidth / editImage.ratioX,
0050                               selectionTool.selectionHeight / editImage.ratioY);
0051             }
0052 
0053             actions {
0054                 main: Kirigami.Action {
0055                     id: saveAction
0056                     visible: imageDoc.edited
0057                     text: "Save"
0058                     iconName: "document-save"
0059                     onTriggered: {
0060                         if (!imageDoc.save()) {
0061                             msg.type = Kirigami.MessageType.Error
0062                             msg.text = "Unable to save file. Check if you have the correct permission to edit this file."
0063                             msg.visible = true;
0064                         }
0065                         rootEditorView.imageEdited();
0066                         applicationWindow().pageStack.layers.pop();
0067                     }
0068                 }
0069                 left: Kirigami.Action {
0070                     id: undoAction
0071                     text: "Undo"
0072                     iconName: "edit-undo"
0073                     onTriggered: {
0074                         if (imageDoc.edited) {
0075                             imageDoc.undo();
0076                         }
0077                     }
0078                     visible: imageDoc.edited
0079                 }
0080                 contextualActions: [
0081                     Kirigami.Action {
0082                         iconName: rootEditorView.resizing ? "dialog-ok" : "transform-crop"
0083                         text: rootEditorView.resizing ? "Accept" : "Crop"
0084                         onTriggered: rootEditorView.resizing = !rootEditorView.resizing;
0085                     },
0086                     Kirigami.Action {
0087                         iconName: "dialog-cancel"
0088                         visible: rootEditorView.resizing
0089                         text: "Cancel"
0090                         onTriggered: rootEditorView.resizing = !rootEditorView.resizing
0091                     },
0092                     Kirigami.Action {
0093                         iconName: "object-rotate-left"
0094                         text: "Rotate left";
0095                         onTriggered: imageDoc.rotate(-90);
0096                         visible: !rootEditorView.resizing
0097                     },
0098                     Kirigami.Action {
0099                         iconName: "object-rotate-right"
0100                         text: "@action:button Rotate an image to the right", "Rotate right";
0101                         onTriggered: imageDoc.rotate(90);
0102                         visible: !rootEditorView.resizing
0103                     },
0104                     Kirigami.Action {
0105                         iconName: "object-flip-vertical"
0106                         text: "Flip"
0107                         onTriggered: imageDoc.mirror(false, true);
0108                         visible: !rootEditorView.resizing
0109                     },
0110                     Kirigami.Action {
0111                         iconName: "object-flip-horizontal"
0112                         text: "Mirror"
0113                         onTriggered: imageDoc.mirror(true, false);
0114                         visible: !rootEditorView.resizing
0115                     },
0116                     Kirigami.Action {
0117                         visible: rootEditorView.resizing
0118                         displayComponent: QQC2.ToolSeparator {
0119                             leftPadding: Kirigami.Units.largeSpacing
0120                             rightPadding: leftPadding
0121                         }
0122                     },
0123                     Kirigami.Action {
0124                         visible: rootEditorView.resizing
0125                         displayComponent: QQC2.Label {
0126                             text: "Size:"
0127                         }
0128                     },
0129                     Kirigami.Action {
0130                         visible: rootEditorView.resizing
0131                         displayComponent: EditorSpinBox {
0132                             minimumContentWidth: widthTextMetrics.width
0133                             from: 1
0134                             to: editImage.nativeWidth
0135                             value: selectionTool.selectionWidth / editImage.ratioX
0136                             onValueModified: selectionTool.selectionWidth = value * editImage.ratioX
0137                         }
0138                     },
0139                     Kirigami.Action {
0140                         visible: rootEditorView.resizing
0141                         displayComponent: EditorSpinBox {
0142                             minimumContentWidth: heightTextMetrics.width
0143                             from: 1
0144                             to: editImage.nativeHeight
0145                             value: selectionTool.selectionHeight / editImage.ratioY
0146                             onValueModified: selectionTool.selectionHeight = value * editImage.ratioY
0147                         }
0148                     },
0149                     Kirigami.Action {
0150                         visible: rootEditorView.resizing
0151                         displayComponent: Item {
0152                             implicitWidth: Kirigami.Units.largeSpacing
0153                         }
0154                     },
0155                     Kirigami.Action {
0156                         visible: rootEditorView.resizing
0157                         displayComponent: QQC2.Label {
0158                             text: "Position:"
0159                         }
0160                     },
0161                     Kirigami.Action {
0162                         visible: rootEditorView.resizing
0163                         displayComponent: EditorSpinBox {
0164                             minimumContentWidth: widthTextMetrics.width
0165                             from: 0
0166                             to: editImage.nativeWidth - (selectionTool.selectionWidth / editImage.ratioX)
0167                             value: selectionTool.selectionX / editImage.ratioX
0168                             onValueModified: selectionTool.selectionX = value * editImage.ratioX
0169                         }
0170                     },
0171                     Kirigami.Action {
0172                         visible: rootEditorView.resizing
0173                         displayComponent: EditorSpinBox {
0174                             minimumContentWidth: heightTextMetrics.width
0175                             from: 0
0176                             to: editImage.nativeHeight - (selectionTool.selectionHeight / editImage.ratioY)
0177                             value: selectionTool.selectionY / editImage.ratioY
0178                             onValueModified: selectionTool.selectionY = value * editImage.ratioY
0179                         }
0180                     }
0181                 ]
0182             }
0183 
0184             TextMetrics {
0185                 id: widthTextMetrics
0186                 text: editImage.nativeWidth.toLocaleString(rootEditorView.locale, 'f', 0)
0187             }
0188 
0189             TextMetrics {
0190                 id: heightTextMetrics
0191                 text: editImage.nativeHeight.toLocaleString(rootEditorView.locale, 'f', 0)
0192             }
0193 
0194             component EditorSpinBox : QQC2.SpinBox {
0195                 id: control
0196                 property real minimumContentWidth: 0
0197                 contentItem: QQC2.TextField {
0198                     id: textField
0199                     implicitWidth: control.minimumContentWidth + leftPadding + rightPadding + 2
0200                     implicitHeight: Math.ceil(contentHeight) + topPadding + bottomPadding
0201                     palette: control.palette
0202                     leftPadding: control.spacing
0203                     rightPadding: control.spacing
0204                     topPadding: 0
0205                     bottomPadding: 0
0206                     text: control.displayText
0207                     font: control.font
0208                     color: Kirigami.Theme.textColor
0209                     selectionColor: Kirigami.Theme.highlightColor
0210                     selectedTextColor: Kirigami.Theme.highlightedTextColor
0211                     horizontalAlignment: Qt.AlignHCenter
0212                     verticalAlignment: Qt.AlignVCenter
0213                     readOnly: !control.editable
0214                     validator: control.validator
0215                     inputMethodHints: control.inputMethodHints
0216                     selectByMouse: true
0217                     background: null
0218                 }
0219             }
0220 
0221             FileDialog {
0222                 id: fileDialog
0223                 title: "Save As"
0224                 folder: shortcuts.home
0225                 selectMultiple: false
0226                 selectExisting: false
0227                 onAccepted: {
0228                     if (imageDoc.saveAs(fileDialog.fileUrl)) {;
0229                         imagePath = fileDialog.fileUrl;
0230                         msg.type = Kirigami.MessageType.Information
0231                         msg.text = "You are now editing a new file."
0232                         msg.visible = true;
0233                     } else {
0234                         msg.type = Kirigami.MessageType.Error
0235                         msg.text = "Unable to save file. Check if you have the correct permission to edit this file."
0236                         msg.visible = true;
0237                     }
0238                     fileDialog.close()
0239                 }
0240                 onRejected: {
0241                     fileDialog.close()
0242                 }
0243                 Component.onCompleted: visible = false
0244             }
0245 
0246             KQuickImageEditor.ImageItem {
0247                 id: editImage
0248                 readonly property real ratioX: editImage.paintedWidth / editImage.nativeWidth;
0249                 readonly property real ratioY: editImage.paintedHeight / editImage.nativeHeight;
0250 
0251                 // Assigning this to the contentItem and setting the padding causes weird positioning issues
0252                 anchors.fill: parent
0253                 anchors.margins: Kirigami.Units.gridUnit
0254                 fillMode: KQuickImageEditor.ImageItem.PreserveAspectFit
0255                 image: imageDoc.image
0256 
0257                 Shortcut {
0258                     sequence: StandardKey.Undo
0259                     onActivated: undoAction.trigger();
0260                 }
0261 
0262                 Shortcut {
0263                     sequences: [StandardKey.Save, "Enter"]
0264                     onActivated: saveAction.trigger();
0265                 }
0266 
0267                 Shortcut {
0268                     sequence: StandardKey.SaveAs
0269                     onActivated: saveAsAction.trigger();
0270                 }
0271 
0272                 KQuickImageEditor.ImageDocument {
0273                     id: imageDoc
0274                     path: rootEditorView.imagePath
0275                 }
0276 
0277                 KQuickImageEditor.SelectionTool {
0278                     id: selectionTool
0279                     visible: rootEditorView.resizing
0280                     width: editImage.paintedWidth
0281                     height: editImage.paintedHeight
0282                     x: editImage.horizontalPadding
0283                     y: editImage.verticalPadding
0284                     KQuickImageEditor.CropBackground {
0285                         anchors.fill: parent
0286                         z: -1
0287                         insideX: selectionTool.selectionX
0288                         insideY: selectionTool.selectionY
0289                         insideWidth: selectionTool.selectionWidth
0290                         insideHeight: selectionTool.selectionHeight
0291                     }
0292                     Connections {
0293                         target: selectionTool.selectionArea
0294                         function onDoubleClicked() {
0295                             rootEditorView.crop()
0296                         }
0297                     }
0298                 }
0299                 onImageChanged: {
0300                     selectionTool.selectionX = 0
0301                     selectionTool.selectionY = 0
0302                     selectionTool.selectionWidth = Qt.binding(() => selectionTool.width)
0303                     selectionTool.selectionHeight = Qt.binding(() => selectionTool.height)
0304                 }
0305             }
0306 
0307 
0308             footer: Kirigami.InlineMessage {
0309                 id: msg
0310                 type: Kirigami.MessageType.Error
0311                 showCloseButton: true
0312                 visible: false
0313             }
0314         }
0315     }
0316 }