Warning, /frameworks/kcmutils/src/qml/components/AbstractKCM.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2020 Marco Martin <mart@kde.org>
0003     SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 import QtQuick
0009 import QtQuick.Controls as QQC2
0010 import org.kde.kirigami as Kirigami
0011 
0012 /**
0013  * This component is intended to be used as root item for
0014  * KCMs with arbitrary content. Unlike SimpleKCM this does NOT
0015  * provide a scrollable view, The developer will have to manage
0016  * their own scrollviews.
0017  * Most of the times SimpleKCM should be used instead
0018  * @code
0019  * import QtQuick
0020  * import QtQuick.Controls as QQC2
0021  * import QtQuick.Layouts
0022  * import org.kde.kcmutils as KCM
0023  *
0024  * KCM.AbstractKCM {
0025  *     RowLayout {
0026  *         QQC2.ScrollView {
0027  *             // ...
0028  *         }
0029  *         QQC2.ScrollView {
0030  *             // ...
0031  *         }
0032  *     }
0033  *     footer: QQC2.ToolBar {
0034  *         // ...
0035  *     }
0036  * }
0037  * @endcode
0038  * @inherits org.kde.kirigami.Page
0039  * @since 6.0
0040  */
0041 Kirigami.Page {
0042     id: root
0043 
0044     readonly property int margins: 6 // Layout_ChildMarginWidth from Breeze
0045 
0046     /**
0047      * framedView: bool
0048      * Whether to use this component as the base of a "framed" KCM with an
0049      * inner scrollview that draws its own frame.
0050      * Default: true
0051      */
0052     property bool framedView: true
0053 
0054     /**
0055      * extraFooterTopPadding: bool
0056      * @deprecated unused
0057      * Default: false
0058      */
0059     property bool extraFooterTopPadding: false
0060 
0061     property bool sidebarMode: false
0062 
0063     function __itemVisible(item: Item): bool {
0064         return item !== null && item.visible && item.implicitHeight > 0;
0065     }
0066 
0067     function __headerContentVisible(): bool {
0068         return __itemVisible(headerParent.contentItem);
0069     }
0070     function __footerContentVisible(): bool {
0071         return __itemVisible(footerParent.contentItem);
0072     }
0073 
0074     // Deliberately not checking for __footerContentVisible because
0075     // we always want the footer line to be visible when the scrollview
0076     // doesn't have a frame of its own, because System Settings always
0077     // adds its own footer for the Apply, Help, and Defaults buttons
0078     function __headerSeparatorVisible(): bool {
0079         return !framedView && __headerContentVisible();
0080     }
0081     function __footerSeparatorVisible(): bool {
0082         return !framedView && extraFooterTopPadding;
0083     }
0084 
0085     title: (typeof kcm !== "undefined") ? kcm.name : ""
0086 
0087     // Make pages fill the whole view by default
0088     Kirigami.ColumnView.fillWidth: sidebarMode
0089                                    ? Kirigami.ColumnView.view
0090                                          && (Kirigami.ColumnView.view.width < Kirigami.Units.gridUnit * 36
0091                                              || Kirigami.ColumnView.index >= Kirigami.ColumnView.view.count - 1)
0092                                    : true
0093 
0094     padding: 0
0095     topPadding: framedView && !__headerContentVisible() ? margins : 0
0096     leftPadding: undefined
0097     rightPadding: undefined
0098     bottomPadding: framedView && !__footerContentVisible() ? margins : 0
0099     verticalPadding: undefined
0100     horizontalPadding: framedView ? margins : 0
0101 
0102     header: Kirigami.Padding {
0103         id: headerParent
0104 
0105         height: root.__headerContentVisible()
0106             ? undefined
0107             : (root.__headerSeparatorVisible()
0108                 ? headerSeparator.implicitHeight
0109                 : 0)
0110 
0111         padding: root.margins
0112         bottomPadding: root.__headerSeparatorVisible()
0113             ? verticalPadding + headerSeparator.implicitHeight
0114             : undefined
0115 
0116         // When the scrollview isn't drawing its own frame, we need to add a
0117         // line below the header (when visible) to separate it from the view
0118         Kirigami.Separator {
0119             id: headerSeparator
0120             anchors {
0121                 left: parent.left
0122                 right: parent.right
0123                 bottom: parent.bottom
0124             }
0125             visible: root.__headerSeparatorVisible()
0126         }
0127     }
0128 
0129     // View background, shown when the scrollview isn't drawing its own frame
0130     Rectangle {
0131         anchors.fill: parent
0132         visible: !root.framedView
0133         Kirigami.Theme.colorSet: Kirigami.Theme.View
0134         Kirigami.Theme.inherit: false
0135         color: Kirigami.Theme.backgroundColor
0136     }
0137 
0138     footer: Kirigami.Padding {
0139         id: footerParent
0140 
0141         height: root.__footerContentVisible()
0142             ? undefined
0143             : (root.__footerSeparatorVisible()
0144                 ? footerSeparator.implicitHeight
0145                 : 0)
0146 
0147         padding: root.margins
0148         topPadding: root.__footerSeparatorVisible()
0149             ? verticalPadding + footerSeparator.implicitHeight
0150             : undefined
0151 
0152         // When the scrollview isn't drawing its own frame, we need to add a
0153         // line above the footer ourselves to separate it from the view
0154         Kirigami.Separator {
0155             id: footerSeparator
0156             anchors {
0157                 top: parent.top
0158                 left: parent.left
0159                 right: parent.right
0160             }
0161             visible: root.__footerSeparatorVisible()
0162         }
0163     }
0164 
0165     function __swapContentIntoContainer(property: string, container: Item) {
0166         const content = this[property];
0167 
0168         if (content && content !== container) {
0169             // Revert the effect of repeated onHeaderChanged invocations
0170             // during initialization in Page super-type.
0171             content.anchors.top = undefined;
0172 
0173             this[property] = container;
0174             container.contentItem = content;
0175             container.visible = true;
0176         }
0177     }
0178 
0179     Component.onCompleted: {
0180         __swapContentIntoContainer("header", headerParent);
0181         __swapContentIntoContainer("footer", footerParent);
0182 
0183         //Search overlaysheets in contentItem, parent to root if found
0184         for (const obj of contentItem.data) {
0185             if (obj instanceof Kirigami.OverlaySheet) {
0186                 if (!obj.parent) {
0187                     obj.parent = this;
0188                 }
0189                 data.push(obj);
0190             }
0191         }
0192     }
0193 }