diff --git a/declarativeimports/components/ComboBox.qml b/declarativeimports/components/ComboBox.qml index 08c12299..4727b46c 100644 --- a/declarativeimports/components/ComboBox.qml +++ b/declarativeimports/components/ComboBox.qml @@ -1,392 +1,397 @@ /* * Copyright 2016 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Window 2.2 import QtQuick.Templates 2.2 as T import QtQuick.Controls 2.2 as Controls import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.kirigami 2.5 as Kirigami import "private" as Private T.ComboBox { id: control implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) + indicator.implicitWidth + rightPadding implicitHeight: units.gridUnit * 1.6 baselineOffset: contentItem.y + contentItem.baselineOffset hoverEnabled: true topPadding: surfaceNormal.margins.top leftPadding: surfaceNormal.margins.left rightPadding: surfaceNormal.margins.right + units.gridUnit * 2 bottomPadding: surfaceNormal.margins.bottom wheelEnabled: false + property bool hideDisplayText: false + property bool hideSelectedItemIcon: false + property bool blankSpaceForEmptyIcons: false property bool forcePressed: false property bool popUpAlignRight: true property int minimumPopUpWidth: 150 property int popUpRelativeX: 0 property string enabledRole property string iconRole property string iconToolTipRole property string iconOnlyWhenHoveredRole signal iconClicked(int index); delegate: ItemDelegate { width: control.popup.width enabled: control.enabledRole ? (Array.isArray(control.model) ? modelData[control.enabledRole] : model[control.enabledRole]) : true text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData icon: control.iconRole ? (Array.isArray(control.model) ? modelData[control.iconRole] : model[control.iconRole]) : '' iconToolTip: control.iconToolTipRole ? (Array.isArray(control.model) ? modelData[control.iconToolTipRole] : model[control.iconToolTipRole]) : '' iconOnlyWhenHovered: control.iconOnlyWhenHoveredRole ? (Array.isArray(control.model) ? modelData[control.iconOnlyWhenHoveredRole] : model[control.iconOnlyWhenHoveredRole]) : '' highlighted: mouseArea.pressed ? listView.currentIndex == index : control.currentIndex == index blankSpaceForEmptyIcons: control.blankSpaceForEmptyIcons property bool separatorVisible: false } indicator: PlasmaCore.SvgItem { implicitWidth: units.iconSizes.small implicitHeight: implicitWidth anchors { right: parent.right rightMargin: surfaceNormal.margins.right verticalCenter: parent.verticalCenter } svg: PlasmaCore.Svg { imagePath: "widgets/arrows" colorGroup: PlasmaCore.Theme.ButtonColorGroup } elementId: "down-arrow" } // contentItem: Label { // text: control.displayText // font: control.font // color: theme.buttonTextColor // horizontalAlignment: Text.AlignLeft // verticalAlignment: Text.AlignVCenter // elide: Text.ElideRight // } contentItem: MouseArea { id: mouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton preventStealing: true property int indexUnderMouse: -1 onWheel: { if (!control.wheelEnabled) { return; } if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) { control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1); } else { control.currentIndex = Math.max(control.currentIndex - 1, 0); } control.activated(control.currentIndex); } onPressed: { indexUnderMouse = -1; listView.currentIndex = control.highlightedIndex control.down = true; control.pressed = true; control.popup.visible = !control.popup.visible; } onReleased: { if (!containsMouse) { control.down = false; control.pressed = false; control.popup.visible = false; } if (indexUnderMouse > -1) { control.currentIndex = indexUnderMouse; } } onCanceled: { control.down = false; control.pressed = false; } onPositionChanged: { var pos = listView.mapFromItem(this, mouse.x, mouse.y); indexUnderMouse = listView.indexAt(pos.x, pos.y); listView.currentIndex = indexUnderMouse; control.activated(indexUnderMouse); } Connections { target: popup onClosed: { control.down = false; control.pressed = false; } } RowLayout { anchors.fill: parent spacing: 0 anchors { leftMargin: !control.mirrored ? 1 : 0 rightMargin: control.mirrored ? 1 : 0 } PlasmaCore.IconItem { id: selectedIcon width: textLabel.height height: textLabel.height colorGroup: PlasmaCore.Theme.ButtonColorGroup source: { if (control && control.currentIndex>=0 && control.iconRole && control.iconRole === "icon" && control.model && control.model.get(control.currentIndex) && control.model.get(control.currentIndex)) { return control.model.get(control.currentIndex).icon; } return ""; } - visible: source !== '' + visible: source !== '' && !control.hideSelectedItemIcon } Label { id: textLabel Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: !selectedIcon.visible && !control.mirrored ? units.smallSpacing : 0 Layout.rightMargin: !selectedIcon.visible && control.mirrored ? units.smallSpacing : 0 text: control.displayText font: control.font color: control.pressed ? theme.highlightedTextColor : theme.buttonTextColor horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter opacity: control.enabled ? 1 : 0.6 + + visible: !control.hideDisplayText } /* T.TextField { id: textField padding: 0 Layout.fillWidth: true Layout.fillHeight: true text: control.editable ? control.editText : control.displayText enabled: control.editable autoScroll: control.editable readOnly: control.down || !control.hasOwnProperty("editable") || !control.editable inputMethodHints: control.inputMethodHints validator: control.validator // Work around Qt bug where NativeRendering breaks for non-integer scale factors // https://bugreports.qt.io/browse/QTBUG-67007 renderType: Screen.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering color: theme.buttonTextColor //control.enabled ? theme.textColor : theme.disabledTextColor selectionColor: Kirigami.Theme.highlightColor selectedTextColor: Kirigami.Theme.highlightedTextColor selectByMouse: !Kirigami.Settings.tabletMode cursorDelegate: Kirigami.Settings.tabletMode ? mobileCursor : undefinedCursor font: control.font horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter opacity: control.enabled ? 1 : 0.6 onFocusChanged: { if (focus) { Private.MobileTextActionsToolBar.controlRoot = textField; } } onPressAndHold: { if (!Kirigami.Settings.tabletMode) { return; } forceActiveFocus(); cursorPosition = positionAt(event.x, event.y); selectWord(); } }*/ } } /* Component { id: mobileCursor Private.MobileCursor { target: textField } }*/ Component { id: undefinedCursor Item{} } /* Private.MobileCursor { target: textField selectionStartHandle: true property var rect: textField.positionToRectangle(textField.selectionStart) //FIXME: this magic values seem to be always valid, for every font,every dpi, every scaling x: rect.x + 5 y: rect.y + 6 }*/ background: PlasmaCore.FrameSvgItem { id: surfaceNormal //retrocompatibility with old controls implicitWidth: units.gridUnit * 6 anchors.fill: parent readonly property bool editable: control.hasOwnProperty("editable") && control.editable imagePath: editable ? "widgets/lineedit" : "widgets/button" prefix: editable ? "base" : (control.pressed || control.forcePressed ? "pressed" : "normal") Private.TextFieldFocus { visible: parent.editable z: -1 state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "hidden") anchors.fill: parent } Private.ButtonShadow { z: -1 visible: !parent.editable anchors.fill: parent state: { if (control.pressed) { return "hidden" } else if (control.hovered) { return "hover" } else if (control.activeFocus) { return "focus" } else { return "shadow" } } } MouseArea { anchors { fill: parent leftMargin: control.leftPadding rightMargin: control.rightPadding } acceptedButtons: Qt.NoButton onWheel: { if (!control.wheelEnabled) { return; } if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) { control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1); } else { control.currentIndex = Math.max(control.currentIndex - 1, 0); } control.activated(control.currentIndex); } } } popup: T.Popup { x: { if (!control.mirrored) { if (popUpRelativeX !== 0) { var adjustedX = exceedsContent && control.popUpAlignRight ? -(width - control.width) : popUpRelativeX; return adjustedX; } else { return 0; } } else { //! mirrored case if (exceedsContent && control.popUpAlignRight) { var adjustedX = width - control.width - popUpRelativeX; return -adjustedX; } else { return 0; } } } y: control.height width: Math.max(control.width, control.minimumPopUpWidth) implicitHeight: contentItem.implicitHeight topMargin: 6 bottomMargin: 6 readonly property bool exceedsContent: control.width < width /*onVisibleChanged: { if (visible) { console.log(" mirrored:" + control.mirrored); console.log(" exceeds: " + exceedsContent); console.log(" popupAR: " + control.popUpAlignRight); console.log(" popupRX: " + popUpRelativeX); } }*/ contentItem: ListView { id: listView clip: true implicitHeight: contentHeight model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex highlightRangeMode: ListView.ApplyRange highlightMoveDuration: 0 // HACK: When the ComboBox is not inside a top-level Window, it's Popup does not inherit // the LayoutMirroring options. This is a workaround to fix this by enforcing // the LayoutMirroring options properly. // QTBUG: https://bugreports.qt.io/browse/QTBUG-66446 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true T.ScrollBar.vertical: Controls.ScrollBar { } signal iconClicked(int index); onIconClicked: control.iconClicked(index); } background: Rectangle { anchors { fill: parent margins: -1 } radius: 2 color: theme.viewBackgroundColor border.color: Qt.rgba(theme.textColor.r, theme.textColor.g, theme.textColor.b, 0.3) layer.enabled: true layer.effect: DropShadow { transparentBorder: true radius: 4 samples: 8 horizontalOffset: 2 verticalOffset: 2 color: Qt.rgba(0, 0, 0, 0.3) } } } } diff --git a/declarativeimports/components/ComboBoxButton.qml b/declarativeimports/components/ComboBoxButton.qml index 5209f31d..e9d4d283 100644 --- a/declarativeimports/components/ComboBoxButton.qml +++ b/declarativeimports/components/ComboBoxButton.qml @@ -1,131 +1,134 @@ /* * Copyright 2019 Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * Latte-Dock is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.1 import QtQuick.Layouts 1.3 import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.components 3.0 as PlasmaComponents3 import org.kde.latte 0.2 as Latte import org.kde.latte.components 1.0 as LatteComponents Rectangle { id: root color: "transparent" implicitWidth: buttonMetrics.implicitWidth implicitHeight: buttonMetrics.implicitHeight readonly property Item comboBox: mainComboBox readonly property Item button: mainButton property bool buttonEnabled: true property string buttonText:"" property string buttonIconSource:"" property string buttonToolTip: "" property QtObject buttonExclusiveGroup: null property bool checked: false property bool checkable: false property bool comboBoxEnabled: true property bool comboBoxBlankSpaceForEmptyIcons: false property bool comboBoxForcePressed: false property bool comboBoxPopUpAlignRight: true property int comboBoxMinimumPopUpWidth: 150 property string comboBoxEnabledRole: "" property string comboBoxTextRole: "" property string comboBoxIconRole: "" property string comboBoxIconToolTipRole: "" property string comboBoxIconOnlyWhenHoveredRole: "" signal iconClicked(int index); PlasmaComponents.Button { id: mainButton anchors.left: Qt.application.layoutDirection === Qt.RightToLeft ? undefined : parent.left anchors.right: Qt.application.layoutDirection === Qt.RightToLeft ? parent.right : undefined LayoutMirroring.enabled: false enabled: buttonEnabled checked: root.checked checkable: root.checkable exclusiveGroup: buttonExclusiveGroup width: parent.width height: mainComboBox.height text: checkable ? " " : buttonText iconSource: buttonIconSource tooltip: buttonToolTip } //overlayed combobox LatteComponents.ComboBox { id: mainComboBox anchors.right: mainButton.right anchors.top: parent.top width: units.iconSizes.medium - units.smallSpacing height: parent.height enabled: comboBoxEnabled enabledRole: comboBoxEnabledRole iconRole: comboBoxIconRole textRole: comboBoxTextRole iconToolTipRole: comboBoxIconToolTipRole iconOnlyWhenHoveredRole: comboBoxIconOnlyWhenHoveredRole blankSpaceForEmptyIcons: comboBoxBlankSpaceForEmptyIcons forcePressed: comboBoxForcePressed popUpAlignRight: comboBoxPopUpAlignRight popUpRelativeX: Qt.application.layoutDirection === Qt.RightToLeft ? (popUpAlignRight ? root.width - width : 0) : (popUpAlignRight ? width : -(root.width - width)) + hideDisplayText: true + hideSelectedItemIcon: true + minimumPopUpWidth: Math.max(comboBoxMinimumPopUpWidth, root.width) onIconClicked: root.iconClicked(index); } Label{ width: labelMetrics.exceeds ? parent.width-mainComboBox.width : parent.width height: parent.height text: buttonText font: mainButton.font color: theme.buttonTextColor visible: root.checkable elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } Label{ id: labelMetrics text: root.buttonText opacity: 0 elide: Text.ElideNone horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - readonly property bool exceeds: width>(mainButton.width-mainComboBox.width) + readonly property bool exceeds: width>(mainButton.width-2*mainComboBox.width) } }