Kirigami-addons

AlbumMaximizeComponent.qml
1// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
2// SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
3
4import QtQuick
5import QtQuick.Controls as QQC2
6import QtQuick.Layouts
7import Qt.labs.qmlmodels
8
9import org.kde.kirigami as Kirigami
10import org.kde.kirigamiaddons.components as KirigamiComponents
11
12/**
13 * @brief A popup that covers the entire window to show an album of 1 or more media items.
14 *
15 * The component supports a model with one or more media components (images or
16 * videos) which can be scrolled through.
17 *
18 * Example:
19 * @code
20 * Components.AlbumMaximizeComponent {
21 * id: root
22 * property list<AlbumModelItem> model: [
23 * AlbumModelItem {
24 * type: AlbumModelItem.Image
25 * source: "path/to/source"
26 * tempSource: "path/to/tempSource"
27 * caption: "caption text"
28 * },
29 * AlbumModelItem {
30 * type: AlbumModelItem.Video
31 * source: "path/to/source"
32 * tempSource: "path/to/tempSource"
33 * caption: "caption text"
34 * }
35 * ]
36 * initialIndex: 0
37 * model: model
38 * }
39 * @endcode
40 *
41 * @note The model doesn't have to be create using AlbumModelItem, it just
42 * requires the same roles (i.e. type, source, tempSource (optional) and
43 * caption (optional)).
44 *
45 * @inherit AbstractMaximizeComponent
46 */
47AbstractMaximizeComponent {
48 id: root
49
50 /**
51 * @brief Model containing the media item to be shown.
52 *
53 * The model can be either a qml or a c++ model but each item needs to have the
54 * values defined in AlbumModelItem.qml (note a list of these is the easiest
55 * way to create a qml model).
56 */
57 property var model
58
59 /**
60 * @brief The index of the initial item that should be visible.
61 */
62 property int initialIndex: -1
63
64 /**
65 * @brief Whether the caption should be shown.
66 */
67 property bool showCaption: true
68
69 /**
70 * @brief Whether the caption is hidden by the user.
71 */
72 property bool hideCaption: false
74 /**
75 * @brief Whether any video media should auto-load.
76 *
77 * @deprecated due to changes in the Video API this will be removed in KF6. It
78 * currently does nothing but is kept to avoid breakage. The loss
79 * of this API has been worked around in a way that doesn't break KF5.
80 */
81 property bool autoLoad: true
82
83 /**
84 * @brief Whether any video media should auto-play.
85 */
86 property bool autoPlay: true
87
88 /**
89 * @brief The default action triggered when the video download button is pressed.
90 *
91 * The download button is only available when the video source is empty (i.e. QUrl()
92 * or "")
93 *
94 * This exists as a property so that the default action can be overridden. The most
95 * common use case for this is where a custom URI scheme is used for example.
96 *
97 * @sa DownloadAction
98 */
99 property DownloadAction downloadAction
100
101 /**
102 * @brief The default action triggered when the play button is pressed.
104 * This exists as a property so that the action can be overridden. For example
105 * if you want to be able to interface with a media manager.
106 */
107 property Kirigami.Action playAction
108
109 /**
110 * @brief The default action triggered when the pause button is pressed.
111 *
112 * This exists as a property so that the action can be overridden. For example
113 * if you want to be able to interface with a media manager.
114 */
115 property Kirigami.Action pauseAction
117 /**
118 * @brief The current item in the view.
119 */
120 property alias currentItem: view.currentItem
121
122 /**
123 * @brief The current index in the view.
124 * @since 1.7.0
125 */
126 property alias currentIndex: view.currentIndex
127
128 /**
129 * @brief Emitted when the content image is right clicked.
130 */
131 signal itemRightClicked()
132
133 /**
134 * @brief Emitted when the save item button is pressed.
135 *
136 * The application needs use this signal to trigger the process to save the
137 * file.
138 */
139 signal saveItem()
140
141 actions: [
142 Kirigami.Action {
143 text: i18nd("kirigami-addons6", "Zoom in")
144 icon.name: "zoom-in"
145 onTriggered: view.currentItem.scaleFactor = Math.min(view.currentItem.scaleFactor + 0.25, 3)
146 },
147 Kirigami.Action {
148 text: i18nd("kirigami-addons6", "Zoom out")
149 icon.name: "zoom-out"
150 onTriggered: view.currentItem.scaleFactor = Math.max(view.currentItem.scaleFactor - 0.25, 0.25)
151 },
152 Kirigami.Action {
153 visible: view.currentItem.type === AlbumModelItem.Image
154 text: i18nd("kirigami-addons6", "Rotate left")
155 icon.name: "object-rotate-left"
156 onTriggered: view.currentItem.rotationAngle = view.currentItem.rotationAngle - 90
157 },
158 Kirigami.Action {
159 visible: view.currentItem.type === AlbumModelItem.Image
160 text: i18nd("kirigami-addons6", "Rotate right")
161 icon.name: "object-rotate-right"
162 onTriggered: view.currentItem.rotationAngle = view.currentItem.rotationAngle + 90
163 },
164 Kirigami.Action {
165 text: hideCaption ? i18ndc("kirigami-addons6", "@action:intoolbar", "Show caption") : i18ndc("kirigami-addons6", "@action:intoolbar", "Hide caption")
166 icon.name: "add-subtitle"
167 visible: root.showCaption && view.currentItem.caption
168 onTriggered: hideCaption = !hideCaption
169 },
170 Kirigami.Action {
171 text: i18nd("kirigami-addons6", "Save as")
172 icon.name: "document-save"
173 onTriggered: saveItem()
174 }
175 ]
176
177 content: ListView {
178 id: view
179 Layout.fillWidth: true
180 Layout.fillHeight: true
181 interactive: !hoverHandler.hovered && count > 1
182 snapMode: ListView.SnapOneItem
183 highlightRangeMode: ListView.StrictlyEnforceRange
184 highlightMoveDuration: 0
185 focus: true
186 keyNavigationEnabled: true
187 keyNavigationWraps: false
188 model: root.model
189 orientation: ListView.Horizontal
190 clip: true
191 delegate: DelegateChooser {
192 role: "type"
193 DelegateChoice {
194 roleValue: AlbumModelItem.Image
195 ImageMaximizeDelegate {
196 width: ListView.view.width
197 height: ListView.view.height
198
199 onItemRightClicked: root.itemRightClicked()
200 onBackgroundClicked: root.close()
201 }
202 }
203 DelegateChoice {
204 roleValue: AlbumModelItem.Video
205 VideoMaximizeDelegate {
206 id: videoMaximizeDelegate
207 width: ListView.view.width
208 height: ListView.view.height
209
210 autoPlay: root.autoPlay
211 // Make sure that the default action in the delegate is used if not overridden
212 downloadAction: root.downloadAction ? root.downloadAction : undefined
213 StateGroup {
214 states: State {
215 when: root.playAction
216 PropertyChanges {
217 target: videoMaximizeDelegate
219 }
220 }
221 }
222 StateGroup {
223 states: State {
224 when: root.pauseAction
225 PropertyChanges {
226 target: videoMaximizeDelegate
228 }
229 }
230 }
231
232 onItemRightClicked: root.itemRightClicked()
233 onBackgroundClicked: root.close()
234 }
235 }
236 }
237
238 KirigamiComponents.FloatingButton {
239 anchors {
240 left: parent.left
241 leftMargin: Kirigami.Units.largeSpacing
242 verticalCenter: parent.verticalCenter
243 }
244 width: Kirigami.Units.gridUnit * 2
245 height: width
246 icon.name: "arrow-left"
247 visible: !Kirigami.Settings.isMobile && view.currentIndex > 0
248 Keys.forwardTo: view
249 Accessible.name: i18nd("kirigami-addons6", "Previous image")
250 onClicked: {
251 view.currentItem.pause()
252 view.currentIndex -= 1
253 if (root.autoPlay && view.currentItem.playAction) {
254 view.currentItem.playAction.trigger()
255 }
256 }
257 }
258 KirigamiComponents.FloatingButton {
259 anchors {
260 right: parent.right
261 rightMargin: Kirigami.Units.largeSpacing
262 verticalCenter: parent.verticalCenter
263 }
264 width: Kirigami.Units.gridUnit * 2
265 height: width
266 icon.name: "arrow-right"
267 visible: !Kirigami.Settings.isMobile && view.currentIndex < view.count - 1
268 Keys.forwardTo: view
269 Accessible.name: i18nd("kirigami-addons6", "Next image")
270 onClicked: {
271 view.currentItem.pause()
272 view.currentIndex += 1
273 if (root.autoPlay && view.currentItem.playAction) {
274 view.currentItem.playAction.trigger()
275 }
276 }
277 }
278 HoverHandler {
279 id: hoverHandler
280 acceptedDevices: PointerDevice.Mouse
281 }
282 }
283
284 footer: QQC2.Control {
285 visible: root.showCaption && view.currentItem.caption && !root.hideCaption
286 contentItem: QQC2.ScrollView {
287 anchors.fill: parent
288 QQC2.ScrollBar.vertical.policy: QQC2.ScrollBar.AlwaysOn
289 QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AsNeeded
290 contentWidth: captionLabel.width - captionLabel.padding * 2
291 contentItem: Flickable {
292 width: root.width
293 height: parent.height
294 contentWidth: captionLabel.width
295 contentHeight: captionLabel.height - captionLabel.padding * 2 + Kirigami.Units.largeSpacing
296
297 Kirigami.SelectableLabel {
298 id: captionLabel
299 wrapMode: Text.WordWrap
300 text: view.currentItem.caption
301 padding: Kirigami.Units.largeSpacing
302 width: root.width - padding * 2
303 }
304 }
305 }
306
307 background: Rectangle {
308 color: Kirigami.Theme.alternateBackgroundColor
309 }
310
311 Kirigami.Separator {
312 anchors {
313 left: parent.left
314 right: parent.right
315 bottom: parent.top
316 }
317 height: 1
318 }
319 }
320
321 parent: applicationWindow().overlay
322 closePolicy: QQC2.Popup.CloseOnEscape
323 width: parent.width
324 height: parent.height
325 modal: true
326 padding: 0
327 background: Item {}
328
329 onAboutToShow: {
330 if (root.initialIndex != -1 && root.initialIndex >= 0) {
331 view.currentIndex = initialIndex
332 }
333 }
334}
Item content
The main content item in the view.
alias currentIndex
The current index in the view.
alias currentItem
The current item in the view.
KirigamiAction playAction
The default action triggered when the play button is pressed.
KirigamiAction pauseAction
The default action triggered when the pause button is pressed.
bool autoPlay
Whether any video media should auto-play.
bool hideCaption
Whether the caption is hidden by the user.
bool showCaption
Whether the caption should be shown.
void saveItem()
Emitted when the save item button is pressed.
void itemRightClicked()
Emitted when the content image is right clicked.
DownloadAction downloadAction
The default action triggered when the video download button is pressed.
var model
Model containing the media item to be shown.
An object container for defining content items to show in a AlbumMaximizeComponent.
This component is a button that can be displayed at the bottom of a page.
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:49:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.