Warning, /plasma/plasma-bigscreen/components/qml/TileRepeater.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * SPDX-FileCopyrightText: 2022 Aditya Mehra <aix.m@outlook.com>
0003 * SPDX-FileCopyrightText: 2020 Marco Martin <mart@kde.org>
0004 *
0005 * SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007
0008 import QtQuick 2.14
0009 import QtQuick.Layouts 1.14
0010 import QtQuick.Window 2.14
0011 import QtQuick.Controls 2.14 as Controls
0012 import org.kde.plasma.core 2.0 as PlasmaCore
0013 import org.kde.kirigami 2.12 as Kirigami
0014 import org.kde.mycroft.bigscreen 1.0 as BigScreen
0015
0016 FocusScope {
0017 id: root
0018 signal activated
0019 property string title
0020 property alias view: view
0021 property alias delegate: view.delegate
0022 property alias model: view.model
0023 property alias currentIndex: view.currentIndex
0024 property alias currentItem: view.currentItem
0025 property alias count: view.count
0026 Layout.fillWidth: true
0027
0028 implicitHeight: view.implicitHeight + header.implicitHeight
0029
0030 property real columns: {
0031 var v = root.compactMode ? 7.5 : 5.5
0032 if (view.Window.window.width <= 1280 && view.Window.window.width > 1024) {
0033 v = root.compactMode ? 6.5 : 4.5
0034 } else if (view.Window.window.width <= 1024 && view.Window.window.width > 800) {
0035 v = root.compactMode ? 5.5 : 3.5
0036 } else if (view.Window.window.width <= 800) {
0037 v = root.compactMode ? 4.5 : 2.5
0038 }
0039 return v
0040 }
0041
0042 property alias cellWidth: view.cellWidth
0043 property alias cellHeight: view.cellHeight
0044 readonly property real screenRatio: view.Window.window ? view.Window.window.width / view.Window.window.height : 1.6
0045
0046 property bool compactMode: false
0047 property Item navigationUp
0048 property Item navigationDown
0049
0050 onActiveFocusChanged: {
0051 if (!activeFocus) {
0052 return;
0053 }
0054
0055 // Update currentItem if needed
0056 view.currentIndexChanged();
0057
0058 if (!currentItem) {
0059 return;
0060 }
0061
0062 currentItem.forceActiveFocus();
0063 }
0064
0065 Kirigami.Heading {
0066 id: header
0067 anchors {
0068 left: parent.left
0069 right: parent.right
0070 top: parent.top
0071 }
0072 text: title
0073 layer.enabled: true
0074 color: "white"
0075 }
0076
0077 Flickable {
0078 id: view
0079 anchors {
0080 left: parent.left
0081 right: parent.right
0082 top: header.baseline
0083 bottom: parent.bottom
0084 topMargin: Kirigami.Units.largeSpacing*2
0085 leftMargin: -Kirigami.Units.largeSpacing
0086 }
0087 readonly property int cellWidth: root.width / columns + (Kirigami.Units.gridUnit / 1)
0088 property int cellHeight: root.compactMode ? cellWidth + Kirigami.Units.gridUnit * 2 : cellWidth * 0.75
0089 property int currentIndex: 0
0090 property alias count: repeater.count
0091 property alias model: repeater.model
0092 property alias delegate: repeater.delegate
0093 readonly property Item currentItem: layout.children[currentIndex]
0094
0095 function indexAt(x,y) {
0096 return Math.max(0, Math.min(count - 1, Math.round(x/cellWidth)));
0097 }
0098
0099 focus: true
0100
0101 implicitHeight: cellHeight
0102 contentWidth: layout.width
0103 contentHeight: height
0104 onCurrentItemChanged: {
0105 if (!currentItem) {
0106 return;
0107 }
0108
0109 currentItem.forceActiveFocus();
0110 slideAnim.slideToIndex(currentIndex);
0111 }
0112
0113 onMovementEnded: currentIndex = Math.min(count-1, Math.round((contentX + cellWidth) / cellWidth))
0114 onFlickEnded: movementEnded()
0115
0116 NumberAnimation {
0117 id: slideAnim
0118 target: view
0119 property: "contentX"
0120 duration: 250
0121
0122 function slideToIndex(index) {
0123 slideAnim.running = false;
0124 slideAnim.from = view.contentX;
0125 slideAnim.to = Math.max(0, view.cellWidth * view.currentIndex);
0126 slideAnim.restart();
0127 }
0128 }
0129
0130 Row {
0131 id: layout
0132 anchors {
0133 top: parent.top
0134 bottom: parent.bottom
0135 }
0136 spacing: 0
0137
0138 Repeater {
0139 id: repeater
0140 // Update currentItem if needed
0141 onChildrenChanged: view.currentIndexChanged();
0142 }
0143
0144 // Spacer
0145 Item {
0146 width: view.width - view.cellWidth*2
0147 height: 1
0148 }
0149 }
0150
0151 Keys.onLeftPressed: {
0152 if (currentIndex > 0) {
0153 BigScreen.NavigationSoundEffects.playMovingSound();
0154 currentIndex = Math.max(0, currentIndex - 1);
0155 }
0156 }
0157 Keys.onRightPressed: {
0158 if (currentIndex < count - 1) {
0159 BigScreen.NavigationSoundEffects.playMovingSound();
0160 currentIndex = Math.min(count - 1, currentIndex + 1);
0161 }
0162 }
0163
0164 Keys.onDownPressed: {
0165 if (!root.navigationDown) {
0166 return;
0167 }
0168
0169 BigScreen.NavigationSoundEffects.playMovingSound();
0170
0171 if (root.navigationDown instanceof TileView ||
0172 root.navigationDown instanceof TileRepeater) {
0173 root.navigationDown.currentIndex = Math.min(Math.floor(root.navigationDown.view.indexAt(root.navigationDown.view.contentX, height/2)), root.navigationDown.view.count - 1);
0174
0175 if (root.navigationDown.currentIndex < 0) {
0176 root.navigationDown.currentIndex = view.currentIndex > 0 ? root.navigationDown.view.count - 1 : 0
0177 }
0178 }
0179
0180 root.navigationDown.forceActiveFocus();
0181 }
0182
0183 Keys.onUpPressed: {
0184 if (!root.navigationUp) {
0185 return;
0186 }
0187
0188 BigScreen.NavigationSoundEffects.playMovingSound();
0189
0190 if (root.navigationUp instanceof TileView ||
0191 root.navigationUp instanceof TileRepeater) {
0192 root.navigationUp.currentIndex = Math.min(Math.floor(root.navigationUp.view.indexAt(root.navigationUp.view.contentX, height/2)), root.navigationUp.view.count - 1);
0193
0194 if (root.navigationUp.currentIndex < 0) {
0195 root.navigationUp.currentIndex = view.currentIndex > 0 ? root.navigationUp.view.count - 1 : 0
0196 }
0197 }
0198
0199 root.navigationUp.forceActiveFocus();
0200 }
0201 }
0202 }