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