Warning, /libraries/kirigami-addons/src/components/AlbumMaximizeComponent.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com> 0002 // SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0003 0004 import QtQuick 2.15 0005 import QtQuick.Controls 2.15 as QQC2 0006 import QtQuick.Layouts 1.15 0007 import Qt.labs.qmlmodels 1.0 0008 0009 import org.kde.kirigami 2.15 as Kirigami 0010 0011 /** 0012 * @brief A popup that covers the entire window to show an album of 1 or more media items. 0013 * 0014 * The component supports a model with one or more media components (images or 0015 * videos) which can be scrolled through. 0016 * 0017 * Example: 0018 * @code 0019 * Components.AlbumMaximizeComponent { 0020 * id: root 0021 * property list<AlbumModelItem> model: [ 0022 * AlbumModelItem { 0023 * type: AlbumModelItem.Image 0024 * source: "path/to/source" 0025 * tempSource: "path/to/tempSource" 0026 * caption: "caption text" 0027 * }, 0028 * AlbumModelItem { 0029 * type: AlbumModelItem.Video 0030 * source: "path/to/source" 0031 * tempSource: "path/to/tempSource" 0032 * caption: "caption text" 0033 * } 0034 * ] 0035 * initialIndex: 0 0036 * model: model 0037 * } 0038 * @endcode 0039 * 0040 * @note The model doesn't have to be create using AlbumModelItem, it just 0041 * requires the same roles (i.e. type, source, tempSource (optional) and 0042 * caption (optional)). 0043 * 0044 * @inherit AbstractMaximizeComponent 0045 */ 0046 AbstractMaximizeComponent { 0047 id: root 0048 0049 /** 0050 * @brief Model containing the media item to be shown. 0051 * 0052 * The model can be either a qml or a c++ model but each item needs to have the 0053 * values defined in AlbumModelItem.qml (note a list of these is the easiest 0054 * way to create a qml model). 0055 */ 0056 property var model 0057 0058 /** 0059 * @brief The index of the initial item that should be visible. 0060 */ 0061 property int initialIndex: -1 0062 0063 /** 0064 * @brief Whether the caption should be shown. 0065 */ 0066 property bool showCaption: true 0067 0068 /** 0069 * @brief Whether the caption is hidden by the user. 0070 */ 0071 property bool hideCaption: false 0072 0073 /** 0074 * @brief Whether any video media should auto-load. 0075 * 0076 * @deprecated due to changes in the Video API this will be removed in KF6. It 0077 * currently does nothing but is kept to avoid breakage. The loss 0078 * of this API has been worked around in a way that doesn't break KF5. 0079 */ 0080 property bool autoLoad: true 0081 0082 /** 0083 * @brief Whether any video media should auto-play. 0084 */ 0085 property bool autoPlay: true 0086 0087 /** 0088 * @brief The default action triggered when the video download button is pressed. 0089 * 0090 * The download button is only available when the video source is empty (i.e. QUrl() 0091 * or "") 0092 * 0093 * This exists as a property so that the default action can be overridden. The most 0094 * common use case for this is where a custom URI scheme is used for example. 0095 * 0096 * @sa DownloadAction 0097 */ 0098 property DownloadAction downloadAction 0099 0100 /** 0101 * @brief Emitted when the content image is right clicked. 0102 */ 0103 signal itemRightClicked() 0104 0105 /** 0106 * @brief Emitted when the save item button is pressed. 0107 * 0108 * The application needs use this signal to trigger the process to save the 0109 * file. 0110 */ 0111 signal saveItem() 0112 0113 actions: [ 0114 Kirigami.Action { 0115 text: i18nd("kirigami-addons", "Zoom in") 0116 icon.name: "zoom-in" 0117 onTriggered: view.currentItem.scaleFactor = Math.min(view.currentItem.scaleFactor + 0.25, 3) 0118 }, 0119 Kirigami.Action { 0120 text: i18nd("kirigami-addons", "Zoom out") 0121 icon.name: "zoom-out" 0122 onTriggered: view.currentItem.scaleFactor = Math.max(view.currentItem.scaleFactor - 0.25, 0.25) 0123 }, 0124 Kirigami.Action { 0125 visible: view.currentItem.type === AlbumModelItem.Image 0126 text: i18nd("kirigami-addons", "Rotate left") 0127 icon.name: "object-rotate-left" 0128 onTriggered: view.currentItem.rotationAngle = view.currentItem.rotationAngle - 90 0129 }, 0130 Kirigami.Action { 0131 visible: view.currentItem.type === AlbumModelItem.Image 0132 text: i18nd("kirigami-addons", "Rotate right") 0133 icon.name: "object-rotate-right" 0134 onTriggered: view.currentItem.rotationAngle = view.currentItem.rotationAngle + 90 0135 }, 0136 Kirigami.Action { 0137 text: hideCaption ? i18ndc("kirigami-addons", "@action:intoolbar", "Show caption") : i18ndc("kirigami-addons", "@action:intoolbar", "Hide caption") 0138 icon.name: "add-subtitle" 0139 visible: root.showCaption && view.currentItem.caption 0140 onTriggered: hideCaption = !hideCaption 0141 }, 0142 Kirigami.Action { 0143 text: i18nd("kirigami-addons", "Save as") 0144 icon.name: "document-save" 0145 onTriggered: saveItem() 0146 } 0147 ] 0148 0149 content: ListView { 0150 id: view 0151 Layout.fillWidth: true 0152 Layout.fillHeight: true 0153 interactive: !hoverHandler.hovered && count > 1 0154 snapMode: ListView.SnapOneItem 0155 highlightRangeMode: ListView.StrictlyEnforceRange 0156 highlightMoveDuration: 0 0157 focus: true 0158 keyNavigationEnabled: true 0159 keyNavigationWraps: false 0160 model: root.model 0161 orientation: ListView.Horizontal 0162 clip: true 0163 delegate: DelegateChooser { 0164 role: "type" 0165 DelegateChoice { 0166 roleValue: AlbumModelItem.Image 0167 ImageMaximizeDelegate { 0168 width: ListView.view.width 0169 height: ListView.view.height 0170 0171 onItemRightClicked: root.itemRightClicked() 0172 onBackgroundClicked: root.close() 0173 } 0174 } 0175 DelegateChoice { 0176 roleValue: AlbumModelItem.Video 0177 VideoMaximizeDelegate { 0178 width: ListView.view.width 0179 height: ListView.view.height 0180 0181 autoPlay: root.autoPlay 0182 // Make sure that the default action in the delegate is used if not overridden 0183 downloadAction: root.downloadAction ? root.downloadAction : undefined 0184 0185 onItemRightClicked: root.itemRightClicked() 0186 onBackgroundClicked: root.close() 0187 } 0188 } 0189 } 0190 0191 QQC2.RoundButton { 0192 anchors { 0193 left: parent.left 0194 leftMargin: Kirigami.Units.largeSpacing 0195 verticalCenter: parent.verticalCenter 0196 } 0197 width: Kirigami.Units.gridUnit * 2 0198 height: width 0199 icon.name: "arrow-left" 0200 visible: !Kirigami.Settings.isMobile && view.currentIndex > 0 0201 Keys.forwardTo: view 0202 Accessible.name: i18nd("kirigami-addons", "Previous image") 0203 onClicked: { 0204 view.currentItem.pause() 0205 view.currentIndex -= 1 0206 view.currentItem.play() 0207 } 0208 } 0209 QQC2.RoundButton { 0210 anchors { 0211 right: parent.right 0212 rightMargin: Kirigami.Units.largeSpacing 0213 verticalCenter: parent.verticalCenter 0214 } 0215 width: Kirigami.Units.gridUnit * 2 0216 height: width 0217 icon.name: "arrow-right" 0218 visible: !Kirigami.Settings.isMobile && view.currentIndex < view.count - 1 0219 Keys.forwardTo: view 0220 Accessible.name: i18nd("kirigami-addons", "Next image") 0221 onClicked: { 0222 view.currentItem.pause() 0223 view.currentIndex += 1 0224 view.currentItem.play() 0225 } 0226 } 0227 HoverHandler { 0228 id: hoverHandler 0229 acceptedDevices: PointerDevice.Mouse 0230 } 0231 } 0232 0233 footer: QQC2.Control { 0234 visible: root.showCaption && view.currentItem.caption && !root.hideCaption 0235 contentItem: QQC2.ScrollView { 0236 anchors.fill: parent 0237 QQC2.ScrollBar.vertical.policy: QQC2.ScrollBar.AlwaysOn 0238 QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AsNeeded 0239 contentWidth: captionLabel.width - captionLabel.padding * 2 0240 contentItem: Flickable { 0241 width: root.width 0242 height: parent.height 0243 contentWidth: captionLabel.width 0244 contentHeight: captionLabel.height - captionLabel.padding * 2 + Kirigami.Units.largeSpacing 0245 0246 QQC2.Label { 0247 id: captionLabel 0248 wrapMode: Text.WordWrap 0249 text: view.currentItem.caption 0250 padding: Kirigami.Units.largeSpacing 0251 width: root.width - padding * 2 0252 } 0253 } 0254 } 0255 0256 background: Rectangle { 0257 color: Kirigami.Theme.alternateBackgroundColor 0258 } 0259 0260 Kirigami.Separator { 0261 anchors { 0262 left: parent.left 0263 right: parent.right 0264 bottom: parent.top 0265 } 0266 height: 1 0267 } 0268 } 0269 0270 parent: applicationWindow().overlay 0271 closePolicy: QQC2.Popup.CloseOnEscape 0272 width: parent.width 0273 height: parent.height 0274 modal: true 0275 padding: 0 0276 background: Item {} 0277 0278 onAboutToShow: { 0279 if (root.initialIndex != -1 && root.initialIndex >= 0) { 0280 view.currentIndex = initialIndex 0281 } 0282 } 0283 }