Warning, /plasma/plasma-systemmonitor/src/page/PageEditor.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 import QtQuick 2.12
0008 import QtQuick.Controls 2.12
0009 import QtQuick.Layouts 1.12
0010 
0011 import org.kde.kirigami 2.12 as Kirigami
0012 
0013 import org.kde.ksysguard.page 1.0
0014 
0015 Column {
0016     id: root
0017 
0018     property Page parentPage
0019     property PageDataObject pageData
0020     property Item activeItem
0021     property var actionsFace
0022 
0023     property var missingSensors: []
0024     signal showMissingSensors()
0025 
0026     spacing: rowSpacing // From parent loader
0027 
0028     move: Transition {
0029         NumberAnimation { properties: "x,y"; duration: Kirigami.Units.shortDuration }
0030     }
0031 
0032     function relayout() {
0033         let reservedHeight = missingMessage.visible ? missingMessage.height : 0;
0034         let minimumHeight = 0;
0035         let balancedCount = 0;
0036         let maximumCount = 0;
0037 
0038         for (let i = 0; i < repeater.count; ++i) {
0039             let child = repeater.itemAt(i)
0040             if (!child || !child.hasOwnProperty("heightMode")) {
0041                 // Apparently not a RowControl, ignore it.
0042                 continue;
0043             }
0044 
0045             switch(child.heightMode) {
0046                 case "minimum":
0047                     reservedHeight += child.minimumHeight
0048                     break;
0049                 case "balanced":
0050                     minimumHeight = Math.max(child.minimumHeight, minimumHeight)
0051                     balancedCount += 1
0052                     break;
0053                 case "maximum":
0054                     maximumCount += 1
0055                     break;
0056             }
0057         }
0058 
0059         let layoutHeight = availableHeight - reservedHeight - root.spacing * (repeater.count - 1)
0060 
0061         let balancedHeight = balancedCount > 0 ? layoutHeight / balancedCount : 0
0062         let maximumHeight = maximumCount > 0 ? (layoutHeight - minimumHeight * balancedCount) / maximumCount : 0
0063 
0064         let minimumTotalHeight = 0
0065 
0066         for (let i = 0; i < repeater.count; ++i) {
0067             let child = repeater.itemAt(i)
0068             if (!child || !child.hasOwnProperty("heightMode")) {
0069                 continue;
0070             }
0071 
0072             minimumTotalHeight += root.spacing;
0073 
0074             switch (child.heightMode) {
0075                 case "minimum":
0076                     child.height = child.minimumHeight
0077                     break
0078                 case "balanced":
0079                     if (maximumCount > 0) {
0080                         child.height = child.minimumHeight
0081                     } else {
0082                         child.height = Math.max(minimumHeight, balancedHeight)
0083                     }
0084                     break
0085                 case "maximum":
0086                     // The last "balanced" here is to make sure if the user
0087                     // selects "maximum" it is visually distinct from "balanced".
0088                     child.height = Math.max(child.minimumHeight, maximumHeight, balancedHeight * 1.25)
0089                     break
0090             }
0091 
0092             minimumTotalHeight += child.height
0093         }
0094 
0095         Layout.minimumHeight = minimumTotalHeight
0096     }
0097 
0098     function updateMissingSensors(id, title, sensors) {
0099         for (let sensor of sensors) {
0100             missingSensors.push({
0101                 "face": id,
0102                 "title": title,
0103                 "sensor": sensor
0104             })
0105         }
0106         missingSensorsChanged()
0107     }
0108 
0109     function replaceSensors(replacement) {
0110         if (!replacement) {
0111             return
0112         }
0113 
0114         missingSensors = []
0115 
0116         for (let i = 0; i < repeater.count; ++i) {
0117             repeater.itemAt(i).replaceSensors(replacement)
0118         }
0119     }
0120 
0121     onWidthChanged: Qt.callLater(relayout)
0122     onHeightChanged: Qt.callLater(relayout)
0123 
0124     Kirigami.InlineMessage {
0125         id: missingMessage
0126 
0127         width: parent.width
0128 
0129         visible: root.missingSensors.length > 0
0130         type: Kirigami.MessageType.Error
0131         text: i18n("This page is missing some sensors and will not display correctly.");
0132 
0133         actions: Kirigami.Action {
0134             icon.name: "document-edit"
0135             text: i18nc("@action:button", "Fix…")
0136             onTriggered: root.showMissingSensors()
0137         }
0138     }
0139 
0140     Repeater {
0141         id: repeater
0142         model: PageDataModel { data: root.pageData }
0143 
0144         onItemAdded: Qt.callLater(root.relayout)
0145         onItemRemoved: Qt.callLater(root.relayout)
0146 
0147         RowControl {
0148             width: parent.width
0149 
0150             onHeightChanged: Qt.callLater(root.relayout)
0151             onMinimumContentHeightChanged: Qt.callLater(root.relayout)
0152             onMinimumHeightChanged: Qt.callLater(root.relayout)
0153             onHeightModeChanged: Qt.callLater(root.relayout)
0154 
0155             rowData: model.data
0156 
0157             activeItem: root.activeItem
0158             single: root.pageData.children.length == 1
0159 
0160             index: model.index
0161 
0162             page: root.parentPage
0163 
0164             onSelect: root.activeItem = item
0165 
0166             onRemove: pageData.removeChild(index)
0167             onMove: pageData.moveChild(from, to)
0168 
0169             onMissingSensorsChanged: root.updateMissingSensors(id, title, sensors)
0170         }
0171     }
0172 
0173     function addTitle(index) {
0174         if (index < 0) {
0175             index = pageData.children.length
0176         }
0177 
0178         pageData.insertChild(index, {
0179             name: "row-" + index,
0180             isTitle: true,
0181             title: i18n("New Title"),
0182             heightMode: "minimum"
0183         })
0184     }
0185 
0186     function addRow(index) {
0187         if (index < 0) {
0188             index = pageData.children.length
0189         }
0190 
0191         pageData.insertChild(index, {
0192             name: "row-" + index,
0193             isTitle: false,
0194             title: "",
0195             heightMode: "balanced"
0196         })
0197     }
0198 
0199     Component.onCompleted: {
0200         if (pageData.children.length == 0) {
0201             addRow(0)
0202         }
0203     }
0204 }