1/*
2 * SPDX-FileCopyrightText: 2017 Marco Martin <notmart@gmail.com>
3 * SPDX-FileCopyrightText: 2020 Nate Graham <nate@kde.org>
4 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7import QtQuick 2.12
8import QtQuick.Controls @QQC2_VERSION@
9import QtQuick.Templates @QQC2_VERSION@ as T
10import org.kde.plasma.core 2.0 as PlasmaCore
11import org.kde.plasma.components 3.0 as PlasmaComponents3
12import "private" as P
13
14T.SpinBox {
15    id: control
16
17    implicitWidth: Math.max(
18        implicitBackgroundWidth + leftInset + rightInset,
19        Math.max(implicitContentWidth, PlasmaCore.Units.gridUnit)
20            + spacing * 2 + leftPadding + rightPadding,
21        up.implicitIndicatorWidth + down.implicitIndicatorWidth
22    )
23    implicitHeight: Math.max(
24        implicitBackgroundHeight + topInset + bottomInset,
25        implicitContentHeight + topPadding + bottomPadding,
26        up.implicitIndicatorHeight,
27        down.implicitIndicatorHeight
28    )
29
30    leftPadding: !mirrored ? down.implicitIndicatorWidth : up.implicitIndicatorWidth
31    rightPadding: mirrored ? down.implicitIndicatorWidth : up.implicitIndicatorWidth
32    topPadding: bgLoader.topMargin
33    bottomPadding: bgLoader.bottomMargin
34    spacing: bgLoader.leftMargin
35    editable: true
36    inputMethodHints: Qt.ImhFormattedNumbersOnly
37    validator: IntValidator {
38        locale: control.locale.name
39        bottom: Math.min(control.from, control.to)
40        top: Math.max(control.from, control.to)
41    }
42    wheelEnabled: true
43    hoverEnabled: Qt.styleHints.useHoverEffects
44
45    PlasmaCore.Svg {
46        id: lineSvg
47        imagePath: "widgets/line"
48    }
49
50    up.indicator: P.FlatButtonBackground {
51        x: control.mirrored ? 0 : parent.width - width
52        implicitHeight: PlasmaCore.Units.gridUnit + bgLoader.topMargin + bgLoader.bottomMargin
53        implicitWidth: PlasmaCore.Units.gridUnit + bgLoader.leftMargin + bgLoader.rightMargin
54        height: parent.height
55        hovered: control.up.hovered
56        pressed: control.up.pressed
57        focused: false
58        checked: false
59        PlasmaCore.IconItem {
60            anchors.centerIn: parent
61            implicitWidth: PlasmaCore.Units.iconSizes.sizeForLabels
62            implicitHeight: PlasmaCore.Units.iconSizes.sizeForLabels
63            colorGroup: PlasmaCore.ColorScope.colorGroup
64            source: "list-add"
65        }
66        PlasmaCore.SvgItem {
67            x: control.mirrored ? parent.width - width : 0
68            z: -1
69            anchors {
70                top: parent.top
71                bottom: parent.bottom
72                topMargin: bgLoader.topMargin
73                bottomMargin: bgLoader.bottomMargin
74            }
75            implicitWidth: naturalSize.width
76            implicitHeight: implicitWidth
77            elementId: "vertical-line"
78            svg: lineSvg
79        }
80    }
81
82    down.indicator: P.FlatButtonBackground {
83        x: control.mirrored ? parent.width - width : 0
84        implicitHeight: PlasmaCore.Units.gridUnit + bgLoader.topMargin + bgLoader.bottomMargin
85        implicitWidth: PlasmaCore.Units.gridUnit + bgLoader.leftMargin + bgLoader.rightMargin
86        height: parent.height
87        hovered: control.down.hovered
88        pressed: control.down.pressed
89        focused: false
90        checked: false
91        PlasmaCore.IconItem {
92            anchors.centerIn: parent
93            implicitWidth: PlasmaCore.Units.iconSizes.sizeForLabels
94            implicitHeight: PlasmaCore.Units.iconSizes.sizeForLabels
95            colorGroup: PlasmaCore.ColorScope.colorGroup
96            source: "list-remove"
97        }
98        PlasmaCore.SvgItem {
99            x: control.mirrored ? 0 : parent.width - width
100            z: -1
101            anchors {
102                top: parent.top
103                bottom: parent.bottom
104                topMargin: bgLoader.topMargin
105                bottomMargin: bgLoader.bottomMargin
106            }
107            implicitWidth: naturalSize.width
108            implicitHeight: implicitWidth
109            elementId: "vertical-line"
110            svg: lineSvg
111        }
112    }
113
114    contentItem: T.TextField {
115        id: textField
116        opacity: enabled ? 1 : 0.5
117        implicitWidth: Math.ceil(contentWidth) + leftPadding + rightPadding
118        implicitHeight: Math.ceil(contentHeight) + topPadding + bottomPadding
119        palette: control.palette
120        text: control.displayText
121        font: control.font
122        color: PlasmaCore.Theme.viewTextColor
123        selectionColor: PlasmaCore.Theme.highlightColor
124        selectedTextColor: PlasmaCore.Theme.highlightedTextColor
125        horizontalAlignment: Qt.AlignHCenter
126        verticalAlignment: Qt.AlignVCenter
127        readOnly: !control.editable
128        validator: control.validator
129        inputMethodHints: control.inputMethodHints
130        selectByMouse: true
131        hoverEnabled: false
132    }
133
134    background: Loader {
135        id: bgLoader
136        readonly property real leftMargin: item.leftMargin
137        readonly property real rightMargin: item.rightMargin
138        readonly property real topMargin: item.topMargin
139        readonly property real bottomMargin: item.bottomMargin
140        sourceComponent: control.editable ? editableBg : noneditableBg
141        Component {
142            id: noneditableBg
143            P.RaisedButtonBackground {
144                hovered: control.hovered
145                focused: control.visualFocus || (control.contentItem.activeFocus && (
146                    control.contentItem.focusReason == Qt.TabFocusReason ||
147                    control.contentItem.focusReason == Qt.BacktabFocusReason ||
148                    control.contentItem.focusReason == Qt.ShortcutFocusReason
149                ))
150                checked: false
151                pressed: false
152            }
153        }
154        Component {
155            id: editableBg
156            PlasmaCore.FrameSvgItem {
157                readonly property real leftMargin: margins.left
158                readonly property real rightMargin: margins.right
159                readonly property real topMargin: margins.top
160                readonly property real bottomMargin: margins.bottom
161                imagePath: "widgets/lineedit"
162                prefix: "base"
163                PlasmaCore.FrameSvgItem {
164                    anchors {
165                        fill: parent
166                        leftMargin: -margins.left
167                        topMargin: -margins.top
168                        rightMargin: -margins.right
169                        bottomMargin: -margins.bottom
170                    }
171                    imagePath: "widgets/lineedit"
172                    prefix: "hover"
173                    visible: opacity > 0
174                    opacity: control.hovered
175                    Behavior on opacity {
176                        enabled: control.hovered
177                        NumberAnimation {
178                            duration: PlasmaCore.Units.longDuration
179                            easing.type: Easing.OutCubic
180                        }
181                    }
182                }
183                PlasmaCore.FrameSvgItem {
184                    property bool visualFocus: control.visualFocus || (control.contentItem.activeFocus
185                        && (control.contentItem.focusReason == Qt.TabFocusReason ||
186                            control.contentItem.focusReason == Qt.BacktabFocusReason ||
187                            control.contentItem.focusReason == Qt.ShortcutFocusReason)
188                    )
189                    z: lineEditSvg.hasElement("hint-focus-over-base") ? 0 : -1
190                    anchors {
191                        fill: parent
192                        leftMargin: -margins.left
193                        topMargin: -margins.top
194                        rightMargin: -margins.right
195                        bottomMargin: -margins.bottom
196                    }
197                    imagePath: "widgets/lineedit"
198                    prefix: visualFocus && lineEditSvg.hasElement("focusframe-center") ? "focusframe" : "focus"
199                    visible: opacity > 0
200                    opacity: visualFocus || control.activeFocus || control.contentItem.activeFocus
201                    Behavior on opacity {
202                        NumberAnimation {
203                            duration: PlasmaCore.Units.longDuration
204                            easing.type: Easing.OutCubic
205                        }
206                    }
207                }
208                PlasmaCore.Svg {
209                    id: lineEditSvg
210                    imagePath: "widgets/lineedit"
211                }
212            }
213        }
214    }
215}
216