Warning, /plasma/latte-dock/declarativeimports/components/ComboBox.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
0003
0004 SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006
0007 import QtQuick 2.7
0008 import QtQuick.Window 2.2
0009 import QtQuick.Templates 2.2 as T
0010 import QtQuick.Controls 2.2 as Controls
0011 import QtQuick.Layouts 1.3
0012 import QtGraphicalEffects 1.0
0013 import org.kde.plasma.core 2.0 as PlasmaCore
0014 import org.kde.plasma.components 2.0 as PlasmaComponents
0015 import org.kde.kirigami 2.2 as Kirigami
0016 import "private" as Private
0017
0018 T.ComboBox {
0019 id: control
0020
0021 implicitWidth: Math.max(background ? background.implicitWidth : 0,
0022 contentItem.implicitWidth + leftPadding + rightPadding) + indicator.implicitWidth + rightPadding
0023 implicitHeight: units.gridUnit * 1.6
0024 baselineOffset: contentItem.y + contentItem.baselineOffset
0025
0026 hoverEnabled: true
0027 topPadding: surfaceNormal.margins.top
0028 leftPadding: surfaceNormal.margins.left
0029 rightPadding: surfaceNormal.margins.right + units.gridUnit * 2
0030 bottomPadding: surfaceNormal.margins.bottom
0031
0032 wheelEnabled: false
0033
0034 property bool hideDisplayText: false
0035 property bool hideSelectedItemIcon: false
0036
0037 property bool blankSpaceForEmptyIcons: false
0038 property bool forcePressed: false
0039 property bool popUpAlignRight: true
0040 property bool buttonIsTransparent: false
0041 property int minimumPopUpWidth: 150
0042 property int popUpRelativeX: 0
0043 property int popUpTextHorizontalAlignment: Text.AlignLeft
0044
0045 property string enabledRole
0046 property string iconRole
0047 property string iconToolTipRole
0048 property string iconOnlyWhenHoveredRole
0049 property string isSeparatorRole
0050 property string toolTipRole
0051
0052 signal iconClicked(int index);
0053
0054 delegate: ItemDelegate {
0055 width: control.popup.width
0056 enabled: !isSeparator && (control.enabledRole.length>0 ? (isArray ? modelData[control.enabledRole] : model[control.enabledRole]) : true)
0057 text: control.textRole.length>0 ? (isArray ? modelData[control.textRole] : model[control.textRole]) : modelData
0058 icon: control.iconRole.length>0 ? (isArray ? modelData[control.iconRole] : model[control.iconRole]) : ''
0059 iconToolTip: control.iconToolTipRole.length>0 ? (isArray ? modelData[control.iconToolTipRole] : model[control.iconToolTipRole]) : ''
0060 iconOnlyWhenHovered: control.iconOnlyWhenHoveredRole.length>0 ? (isArray ? modelData[control.iconOnlyWhenHoveredRole] : model[control.iconOnlyWhenHoveredRole]) : ''
0061 isSeparator: control.isSeparatorRole.length>0 ? (isArray ? modelData[control.isSeparatorRole] : model[control.isSeparatorRole]) : false
0062 toolTip: control.toolTipRole.length>0 ? (isArray ? modelData[control.toolTipRole] : model[control.toolTipRole]) : ''
0063
0064 highlighted: mouseArea.pressed ? listView.currentIndex == index : control.currentIndex == index
0065 blankSpaceForEmptyIcons: control.blankSpaceForEmptyIcons
0066 textHorizontalAlignment: popUpTextHorizontalAlignment
0067
0068 readonly property bool isArray: Array.isArray(control.model)
0069 property bool separatorVisible: false
0070
0071 PlasmaComponents.Button {
0072 id: tooltipBtn
0073 anchors.fill: parent
0074 opacity: 0
0075 tooltip: parent.toolTip
0076 visible: tooltip !== ''
0077
0078 onPressedChanged: {
0079 if (!pressed) {
0080 control.currentIndex = index;
0081 control.down = false;
0082 control.pressed = false;
0083 control.popup.visible = false;
0084 }
0085 }
0086 }
0087 }
0088
0089 indicator: PlasmaCore.SvgItem {
0090 implicitWidth: units.iconSizes.small
0091 implicitHeight: implicitWidth
0092 anchors {
0093 right: parent.right
0094 rightMargin: control.buttonIsTransparent ? 0 : surfaceNormal.margins.right
0095 verticalCenter: parent.verticalCenter
0096 }
0097 svg: PlasmaCore.Svg {
0098 imagePath: "widgets/arrows"
0099 colorGroup: PlasmaCore.Theme.ButtonColorGroup
0100 }
0101 elementId: "down-arrow"
0102 }
0103
0104 // contentItem: Label {
0105 // text: control.displayText
0106 // font: control.font
0107 // color: theme.buttonTextColor
0108 // horizontalAlignment: Text.AlignLeft
0109 // verticalAlignment: Text.AlignVCenter
0110 // elide: Text.ElideRight
0111 // }
0112 contentItem: MouseArea {
0113 id: mouseArea
0114 anchors.fill: parent
0115 acceptedButtons: Qt.LeftButton
0116 preventStealing: true
0117 property int indexUnderMouse: -1
0118 onWheel: {
0119 if (!control.wheelEnabled) {
0120 return;
0121 }
0122
0123 if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) {
0124 control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1);
0125 } else {
0126 control.currentIndex = Math.max(control.currentIndex - 1, 0);
0127 }
0128 control.activated(control.currentIndex);
0129 }
0130 onPressed: onGenericPressed()
0131 onReleased: onGenericReleased()
0132 onCanceled: {
0133 control.down = false;
0134 control.pressed = false;
0135 }
0136 onPositionChanged: {
0137 var pos = listView.mapFromItem(this, mouse.x, mouse.y);
0138 indexUnderMouse = listView.indexAt(pos.x, pos.y);
0139 listView.currentIndex = indexUnderMouse;
0140 control.activated(indexUnderMouse);
0141 }
0142
0143 Connections {
0144 target: popup
0145 onClosed: {
0146 control.down = false;
0147 control.pressed = false;
0148 }
0149 }
0150
0151 function onGenericPressed() {
0152 indexUnderMouse = -1;
0153 listView.currentIndex = control.highlightedIndex;
0154 control.down = true;
0155 control.pressed = true;
0156 control.popup.visible = !control.popup.visible;
0157 }
0158
0159 function onGenericReleased() {
0160 if (!containsMouse && !hiddenTooltipButton.hovered) {
0161 control.down = false;
0162 control.pressed = false;
0163 control.popup.visible = false;
0164 }
0165 if (indexUnderMouse > -1) {
0166 control.currentIndex = indexUnderMouse;
0167 }
0168 }
0169
0170 PlasmaComponents.Button {
0171 id: hiddenTooltipButton
0172 anchors.fill: parent
0173 opacity: 0
0174 visible: control && control.currentIndex>=0 && control.toolTipRole.length>0
0175 tooltip: {
0176 if (!visible) {
0177 return "";
0178 }
0179
0180 if (Array.isArray(control.model)) {
0181 return control.model[control.currentIndex][control.toolTipRole];
0182 } else {
0183 return control.model.get(control.currentIndex)[control.toolTipRole];
0184 }
0185 }
0186
0187 onPressedChanged: {
0188 if (pressed) {
0189 mouseArea.onGenericPressed();
0190 } else {
0191 mouseArea.onGenericReleased();
0192 }
0193 }
0194 }
0195
0196 RowLayout {
0197 anchors.fill: parent
0198 spacing: 0
0199
0200 anchors {
0201 leftMargin: !control.mirrored ? 1 : 0
0202 rightMargin: control.mirrored ? 1 : 0
0203 }
0204
0205 PlasmaCore.IconItem {
0206 id: selectedIcon
0207 implicitWidth: textLabel.height
0208 implicitHeight: textLabel.height
0209
0210 colorGroup: PlasmaCore.Theme.ButtonColorGroup
0211 source: {
0212 if (control
0213 && control.currentIndex>=0
0214 && control.iconRole.length>0) {
0215
0216 if (Array.isArray(control.model)) {
0217 return control.model[control.currentIndex][control.iconRole];
0218 } else {
0219 return control.model.get(control.currentIndex)[control.iconRole];
0220 }
0221 }
0222
0223 return "";
0224 }
0225
0226 visible: source !== '' && !control.hideSelectedItemIcon
0227 }
0228
0229 Label {
0230 id: textLabel
0231 Layout.fillWidth: true
0232 Layout.fillHeight: true
0233 Layout.leftMargin: !selectedIcon.visible && !control.mirrored ? units.smallSpacing : 0
0234 Layout.rightMargin: !selectedIcon.visible && control.mirrored ? units.smallSpacing : 0
0235
0236 text: control.displayText
0237 font: control.font
0238 color: control.pressed ? theme.highlightedTextColor : theme.buttonTextColor
0239 horizontalAlignment: Text.AlignLeft
0240 verticalAlignment: Text.AlignVCenter
0241 opacity: control.enabled ? 1 : 0.6
0242
0243 visible: !control.hideDisplayText
0244 }
0245
0246 /* T.TextField {
0247 id: textField
0248 padding: 0
0249 Layout.fillWidth: true
0250 Layout.fillHeight: true
0251
0252 text: control.editable ? control.editText : control.displayText
0253
0254 enabled: control.editable
0255 autoScroll: control.editable
0256
0257 readOnly: control.down || !control.hasOwnProperty("editable") || !control.editable
0258 inputMethodHints: control.inputMethodHints
0259 validator: control.validator
0260
0261 // Work around Qt bug where NativeRendering breaks for non-integer scale factors
0262 // https://bugreports.qt.io/browse/QTBUG-67007
0263 renderType: Screen.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering
0264 color: theme.buttonTextColor //control.enabled ? theme.textColor : theme.disabledTextColor
0265 selectionColor: Kirigami.Theme.highlightColor
0266 selectedTextColor: Kirigami.Theme.highlightedTextColor
0267
0268 selectByMouse: !Kirigami.Settings.tabletMode
0269 cursorDelegate: Kirigami.Settings.tabletMode ? mobileCursor : undefinedCursor
0270
0271 font: control.font
0272 horizontalAlignment: Text.AlignLeft
0273 verticalAlignment: Text.AlignVCenter
0274 opacity: control.enabled ? 1 : 0.6
0275 onFocusChanged: {
0276 if (focus) {
0277 Private.MobileTextActionsToolBar.controlRoot = textField;
0278 }
0279 }
0280
0281 onPressAndHold: {
0282 if (!Kirigami.Settings.tabletMode) {
0283 return;
0284 }
0285 forceActiveFocus();
0286 cursorPosition = positionAt(event.x, event.y);
0287 selectWord();
0288 }
0289 }*/
0290 }
0291 }
0292
0293 /* Component {
0294 id: mobileCursor
0295 Private.MobileCursor {
0296 target: textField
0297 }
0298 }*/
0299
0300 Component {
0301 id: undefinedCursor
0302 Item{}
0303 }
0304
0305 /* Private.MobileCursor {
0306 target: textField
0307 selectionStartHandle: true
0308 property var rect: textField.positionToRectangle(textField.selectionStart)
0309 //FIXME: this magic values seem to be always valid, for every font,every dpi, every scaling
0310 x: rect.x + 5
0311 y: rect.y + 6
0312 }*/
0313
0314 background: PlasmaCore.FrameSvgItem {
0315 id: surfaceNormal
0316 //retrocompatibility with old controls
0317 implicitWidth: units.gridUnit * 6
0318 width: parent.width
0319 height: parent.height
0320
0321 anchors.right: parent.right
0322 anchors.verticalCenter: parent.verticalCenter
0323 anchors.rightMargin: control.buttonIsTransparent ? -margins.right : 0
0324 readonly property bool editable: control.hasOwnProperty("editable") && control.editable
0325 imagePath: editable ? "widgets/lineedit" : "widgets/button"
0326 prefix: editable
0327 ? "base"
0328 : (control.pressed || control.forcePressed ? "pressed" : "normal")
0329
0330 opacity: control.buttonIsTransparent && prefix !== "pressed" && textFieldPrivate.state !== "hover" && !control.popup.visible ? 0 : 1
0331
0332 Private.TextFieldFocus {
0333 id: textFieldPrivate
0334 visible: parent.editable
0335 z: -1
0336 state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "hidden")
0337 anchors.fill: parent
0338 }
0339 Private.ButtonShadow {
0340 z: -1
0341 visible: !parent.editable
0342 anchors.fill: parent
0343 state: {
0344 if (control.pressed) {
0345 return "hidden"
0346 } else if (control.hovered) {
0347 return "hover"
0348 } else if (control.activeFocus) {
0349 return "focus"
0350 } else {
0351 return "shadow"
0352 }
0353 }
0354 }
0355
0356 MouseArea {
0357 anchors {
0358 fill: parent
0359 leftMargin: control.leftPadding
0360 rightMargin: control.rightPadding
0361 }
0362 acceptedButtons: Qt.NoButton
0363 onWheel: {
0364 if (!control.wheelEnabled) {
0365 return;
0366 }
0367
0368 if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) {
0369 control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1);
0370 } else {
0371 control.currentIndex = Math.max(control.currentIndex - 1, 0);
0372 }
0373 control.activated(control.currentIndex);
0374 }
0375 }
0376 }
0377
0378 popup: T.Popup {
0379 x: {
0380 if (!control.mirrored) {
0381 if (popUpRelativeX !== 0) {
0382 var adjustedX = exceedsContent && control.popUpAlignRight ? -(width - control.width) : popUpRelativeX;
0383 return adjustedX;
0384 } else {
0385 return 0;
0386 }
0387 } else {
0388 //! mirrored case
0389 if (exceedsContent && control.popUpAlignRight) {
0390 var adjustedX = width - control.width - popUpRelativeX;
0391 return -adjustedX;
0392 } else {
0393 return 0;
0394 }
0395 }
0396 }
0397 y: control.height
0398 width: Math.max(control.width, control.minimumPopUpWidth)
0399 implicitHeight: contentItem.implicitHeight
0400 topMargin: 6
0401 bottomMargin: 6
0402
0403 readonly property bool exceedsContent: control.width < width
0404
0405 /*onVisibleChanged: {
0406 if (visible) {
0407 console.log(" mirrored:" + control.mirrored);
0408 console.log(" exceeds: " + exceedsContent);
0409 console.log(" popupAR: " + control.popUpAlignRight);
0410 console.log(" popupRX: " + popUpRelativeX);
0411 }
0412 }*/
0413
0414 contentItem: ListView {
0415 id: listView
0416 clip: true
0417 implicitHeight: contentHeight
0418 model: control.popup.visible ? control.delegateModel : null
0419 currentIndex: control.highlightedIndex
0420 highlightRangeMode: ListView.ApplyRange
0421 highlightMoveDuration: 0
0422 // HACK: When the ComboBox is not inside a top-level Window, it's Popup does not inherit
0423 // the LayoutMirroring options. This is a workaround to fix this by enforcing
0424 // the LayoutMirroring options properly.
0425 // QTBUG: https://bugreports.qt.io/browse/QTBUG-66446
0426 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
0427 LayoutMirroring.childrenInherit: true
0428 T.ScrollBar.vertical: Controls.ScrollBar { }
0429
0430 signal iconClicked(int index);
0431
0432 onIconClicked: control.iconClicked(index);
0433 }
0434 background: Rectangle {
0435 anchors {
0436 fill: parent
0437 margins: -1
0438 }
0439 radius: 2
0440 color: theme.viewBackgroundColor
0441 border.color: Qt.rgba(theme.textColor.r, theme.textColor.g, theme.textColor.b, 0.3)
0442 layer.enabled: true
0443
0444 layer.effect: DropShadow {
0445 transparentBorder: true
0446 radius: 4
0447 samples: 8
0448 horizontalOffset: 2
0449 verticalOffset: 2
0450 color: Qt.rgba(0, 0, 0, 0.3)
0451 }
0452 }
0453 }
0454 }