Warning, /plasma/qqc2-breeze-style/style/impl/CheckIndicator.qml is written in an unsupported language. File is not indexed.

0001 /* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
0002  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0003  */
0004 
0005 import QtQuick
0006 import QtQuick.Templates as T
0007 import org.kde.kirigami as Kirigami
0008 import org.kde.breeze
0009 
0010 import "." as Impl
0011 
0012 Rectangle {
0013     id: root
0014 
0015     property T.AbstractButton control: root.parent
0016     property int checkState: control.checkState
0017     property int symbolSize: Impl.Units.symbolSize(Math.min(width, height))
0018     property bool mirrored: control.mirrored
0019     readonly property bool controlHasContent: control.contentItem && control.contentItem.width > 0
0020 
0021     property bool highlightBackground: root.checkState !== Qt.Unchecked || (control.down && !(control instanceof T.CheckDelegate))
0022     property bool highlightBorder: control.down || root.checkState !== Qt.Unchecked || control.highlighted || control.visualFocus || control.hovered
0023 
0024     visible: control.checkable
0025 
0026     x: controlHasContent ? (root.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2
0027     y: control.topPadding + (control.availableHeight - height) / 2
0028 
0029     implicitWidth: implicitHeight
0030     implicitHeight: Impl.Units.inlineControlHeight
0031 
0032     Kirigami.Theme.colorSet: Kirigami.Theme.Button
0033     Kirigami.Theme.inherit: false
0034     color: highlightBackground ? Kirigami.Theme.alternateBackgroundColor : Kirigami.Theme.backgroundColor
0035 
0036     radius: Impl.Units.smallRadius
0037 
0038     border {
0039         width: Impl.Units.smallBorder
0040         color: highlightBorder ?
0041             Kirigami.Theme.focusColor : Impl.Theme.separatorColor()
0042             //Kirigami.ColorUtils.tintWithAlpha(root.color, Kirigami.Theme.textColor, 0.3)
0043     }
0044 
0045     Behavior on color {
0046         enabled: highlightBackground
0047         ColorAnimation {
0048             duration: Kirigami.Units.shortDuration
0049             easing.type: Easing.OutCubic
0050         }
0051     }
0052     Behavior on border.color {
0053         enabled: highlightBorder
0054         ColorAnimation {
0055             duration: Kirigami.Units.shortDuration
0056             easing.type: Easing.OutCubic
0057         }
0058     }
0059 
0060     SmallBoxShadow {
0061         id: shadow
0062         opacity: control.down ? 0 : 1
0063         visible: control.enabled
0064         radius: parent.radius
0065     }
0066 
0067     PaintedSymbol {
0068         id: checkmark
0069         anchors.centerIn: parent
0070         // Should reliably create pixel aligned checkmarks that don't get cut off on the sides.
0071         height: root.symbolSize + penWidth*2
0072         width: height
0073         color: Kirigami.Theme.textColor
0074         symbolType: PaintedSymbol.Checkmark
0075         visible: root.checkState === Qt.Checked
0076 
0077         /* RTL support. Horizontally flips the checkmark.
0078          * Is this actually a good idea for checkmarks?
0079         transform: control.mirrored ? horizontalFlipMatrix : null
0080 
0081         Matrix4x4 {
0082             id: horizontalFlipMatrix
0083             matrix: Qt.matrix4x4(
0084                 -1, 0, 0, checkmark.width,
0085                 0, 1, 0, 0,
0086                 0, 0, 1, 0,
0087                 0, 0, 0, 1
0088             )
0089         }
0090         */
0091     }
0092 
0093     Item {
0094         id: partialCheckmark
0095         visible: root.checkState === Qt.PartiallyChecked
0096         anchors.centerIn: parent
0097         width: root.symbolSize
0098         height: 2
0099 
0100         Rectangle {
0101             id: leftRect
0102             anchors.left: parent.left
0103             anchors.verticalCenter: parent.verticalCenter
0104             height: parent.height
0105             width: height
0106             color: Kirigami.Theme.textColor
0107         }
0108 
0109         Rectangle {
0110             id: middleRect
0111             anchors.centerIn: parent
0112             height: parent.height
0113             width: height
0114             color: Kirigami.Theme.textColor
0115         }
0116 
0117         Rectangle {
0118             id: rightRect
0119             anchors.right: parent.right
0120             anchors.verticalCenter: parent.verticalCenter
0121             height: parent.height
0122             width: height
0123             color: Kirigami.Theme.textColor
0124         }
0125     }
0126 
0127     FocusRect {
0128         baseRadius: root.radius
0129         visible: control.visualFocus
0130     }
0131 
0132     Rectangle {
0133         id: sidewaysRevealRect
0134         antialiasing: true
0135         anchors {
0136             right: checkmark.right
0137             top: checkmark.top
0138             bottom: checkmark.bottom
0139         }
0140         width: 0
0141         visible: width > 0
0142         color: root.color
0143     }
0144 
0145     NumberAnimation {
0146         id: sidewaysRevealAnimation
0147         target: sidewaysRevealRect
0148         property: "width"
0149         from: checkmark.width
0150         to: 0
0151         duration: Kirigami.Units.shortDuration
0152         //Intentionally not using an easing curve
0153     }
0154 
0155     states: [
0156         State {
0157             name: "unchecked"
0158             when: root.checkState === Qt.Unchecked
0159         },
0160         State {
0161             name: "checked"
0162             when: root.checkState === Qt.Checked
0163         },
0164         State {
0165             name: "partiallychecked"
0166             when: root.checkState === Qt.PartiallyChecked
0167         }
0168     ]
0169 
0170     property bool loaded: false
0171     Component.onCompleted: {
0172         loaded = true
0173     }
0174 
0175     /* I'm using this instead of transitions because I couldn't reliably
0176      * trigger the animation when going from the partiallychecked state to the
0177      * checked state.
0178      */
0179     onStateChanged: {
0180         /* Prevents the transition from running when the parent control is created.
0181          * This can reduce resource usage spikes on pages that have way too many checkboxes.
0182          */
0183         if (root.loaded
0184             && (state == "checked" || state == "partiallychecked")
0185             && !Kirigami.Settings.isMobile //TODO: make the animation look better on mobile
0186         ) {
0187             // equivalent to stop(), then start()
0188             sidewaysRevealAnimation.restart()
0189         }
0190     }
0191 }