Warning, /plasma/discover/discover/qml/ApplicationScreenshots.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 0009 import QtQuick 2.15 0010 import QtQuick.Layouts 1.15 0011 import QtQuick.Controls 2.15 0012 import org.kde.discover 2.0 0013 import org.kde.kirigami 2.19 as Kirigami 0014 0015 ListView { 0016 id: root 0017 readonly property alias count: screenshotsModel.count 0018 property bool showNavigationArrows: true 0019 property alias resource: screenshotsModel.application 0020 property var resource 0021 property int failedCount: 0 0022 readonly property bool hasFailed: count !== 0 && failedCount === count 0023 0024 spacing: Kirigami.Units.largeSpacing 0025 focus: overlay.visible 0026 orientation: Qt.Horizontal 0027 cacheBuffer: 10 // keep some screenshots in memory 0028 0029 Keys.onLeftPressed: if (leftAction.visible) leftAction.trigger() 0030 Keys.onRightPressed: if (rightAction.visible) rightAction.trigger() 0031 0032 model: ScreenshotsModel { 0033 id: screenshotsModel 0034 } 0035 0036 property real delegateHeight: Kirigami.Units.gridUnit * 4 0037 0038 delegate: AbstractButton { 0039 readonly property bool animated: isAnimated 0040 readonly property url imageSource: large_image_url 0041 readonly property real proportion: thumbnail.status === Image.Ready && thumbnail.sourceSize.width>1 ? thumbnail.sourceSize.height/thumbnail.sourceSize.width : 1 0042 0043 implicitWidth: root.delegateHeight / proportion 0044 implicitHeight: root.delegateHeight 0045 opacity: hovered ? 0.7 : 1 0046 0047 hoverEnabled: true 0048 onClicked: { 0049 root.currentIndex = model.row 0050 overlay.open() 0051 } 0052 0053 HoverHandler { 0054 cursorShape: Qt.PointingHandCursor 0055 } 0056 0057 background: Item { 0058 BusyIndicator { 0059 visible: running 0060 running: thumbnail.status === Image.Loading 0061 anchors.centerIn: parent 0062 } 0063 Kirigami.Icon { 0064 anchors.fill: parent 0065 anchors.margins: Kirigami.Units.gridUnit 0066 visible: thumbnail.status === Image.Error 0067 source: "emblem-error" 0068 } 0069 ConditionalLoader { 0070 id: thumbnail 0071 anchors.fill: parent 0072 readonly property var status: item.status 0073 readonly property var sourceSize: item.sourceSize 0074 condition: isAnimated 0075 0076 componentFalse: Component { 0077 Image { 0078 source: small_image_url 0079 } 0080 } 0081 componentTrue: Component { 0082 AnimatedImage { 0083 source: small_image_url 0084 } 0085 } 0086 0087 onStatusChanged: { 0088 if (status === Image.Error) { 0089 root.failedCount += 1; 0090 } 0091 } 0092 } 0093 } 0094 } 0095 0096 Popup { 0097 id: overlay 0098 parent: applicationWindow().overlay 0099 z: applicationWindow().globalDrawer.z + 10 0100 modal: true 0101 clip: false 0102 0103 x: (parent.width - width)/2 0104 y: (parent.height - height)/2 0105 readonly property real proportion: overlayImage.sourceSize.width>1 ? overlayImage.sourceSize.height/overlayImage.sourceSize.width : 1 0106 height: overlayImage.status >= Image.Loading ? Kirigami.Units.gridUnit * 5 : Math.min(parent.height * 0.9, (parent.width * 0.9) * proportion, overlayImage.sourceSize.height) 0107 width: (height - 2 * padding)/proportion 0108 0109 BusyIndicator { 0110 id: indicator 0111 visible: running 0112 running: overlayImage.status === Image.Loading 0113 anchors.centerIn: parent 0114 } 0115 0116 Kirigami.Icon { 0117 anchors.fill: parent 0118 visible: overlayImage.status === Image.Error 0119 source: "emblem-error" 0120 } 0121 0122 ConditionalLoader { 0123 id: overlayImage 0124 anchors.fill: parent 0125 readonly property var status: item.status 0126 readonly property var sourceSize: item.sourceSize 0127 condition: root.currentItem.animated 0128 0129 componentFalse: Component { 0130 Image { 0131 source: root.currentItem ? root.currentItem.imageSource : "" 0132 fillMode: Image.PreserveAspectFit 0133 smooth: true 0134 } 0135 } 0136 componentTrue: Component { 0137 AnimatedImage { 0138 source: root.currentItem ? root.currentItem.imageSource : "" 0139 fillMode: Image.PreserveAspectFit 0140 smooth: true 0141 } 0142 } 0143 0144 onStatusChanged: { 0145 if (status === Image.Error) { 0146 root.failedCount += 1; 0147 } 0148 } 0149 } 0150 0151 Button { 0152 anchors { 0153 left: parent.right 0154 bottom: parent.top 0155 } 0156 icon.name: "window-close" 0157 onClicked: overlay.close() 0158 } 0159 0160 0161 RoundButton { 0162 anchors { 0163 right: parent.left 0164 verticalCenter: parent.verticalCenter 0165 } 0166 visible: leftAction.visible 0167 icon.name: leftAction.iconName 0168 onClicked: leftAction.triggered(null) 0169 } 0170 0171 RoundButton { 0172 anchors { 0173 left: parent.right 0174 verticalCenter: parent.verticalCenter 0175 } 0176 visible: rightAction.visible 0177 icon.name: rightAction.iconName 0178 onClicked: rightAction.triggered(null) 0179 } 0180 0181 Kirigami.Action { 0182 id: leftAction 0183 icon.name: root.LayoutMirroring.enabled ? "arrow-right" : "arrow-left" 0184 enabled: overlay.visible && visible 0185 visible: root.currentIndex >= 1 && !indicator.running 0186 onTriggered: root.currentIndex = (root.currentIndex - 1) % screenshotsModel.count 0187 } 0188 0189 Kirigami.Action { 0190 id: rightAction 0191 icon.name: root.LayoutMirroring.enabled ? "arrow-left" : "arrow-right" 0192 enabled: overlay.visible && visible 0193 visible: root.currentIndex < (root.count - 1) && !indicator.running 0194 onTriggered: root.currentIndex = (root.currentIndex + 1) % screenshotsModel.count 0195 } 0196 } 0197 0198 0199 clip: true 0200 0201 RoundButton { 0202 anchors { 0203 left: parent.left 0204 leftMargin: Kirigami.Units.largeSpacing 0205 verticalCenter: parent.verticalCenter 0206 } 0207 width: Kirigami.Units.gridUnit * 2 0208 height: width 0209 icon.name: root.LayoutMirroring.enabled ? "arrow-right" : "arrow-left" 0210 visible: !Kirigami.Settings.isMobile 0211 && root.count > 1 0212 && root.currentIndex > 0 0213 && root.showNavigationArrows 0214 Keys.forwardTo: [root] 0215 onClicked: root.currentIndex -= 1 0216 } 0217 0218 RoundButton { 0219 anchors { 0220 right: parent.right 0221 rightMargin: Kirigami.Units.largeSpacing 0222 verticalCenter: parent.verticalCenter 0223 } 0224 width: Kirigami.Units.gridUnit * 2 0225 height: width 0226 icon.name: root.LayoutMirroring.enabled ? "arrow-left" : "arrow-right" 0227 visible: !Kirigami.Settings.isMobile 0228 && root.count > 1 0229 && root.currentIndex < root.count - 1 0230 && root.showNavigationArrows 0231 Keys.forwardTo: [root] 0232 onClicked: root.currentIndex += 1 0233 } 0234 }