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