diff --git a/example/qml/global/ItemsOriginal.qml b/example/qml/global/ItemsOriginal.qml index dd22104..31e1ac3 100644 --- a/example/qml/global/ItemsOriginal.qml +++ b/example/qml/global/ItemsOriginal.qml @@ -166,6 +166,12 @@ FluObject{ navigationView.push("qrc:/example/qml/page/T_Dialog.qml") } } + FluPaneItem{ + title:"ComboBox" + onTap:{ + navigationView.push("qrc:/example/qml/page/T_ComboBox.qml") + } + } FluPaneItem{ title:"Tooltip" onTap:{ diff --git a/example/qml/page/T_ComboBox.qml b/example/qml/page/T_ComboBox.qml new file mode 100644 index 0000000..5b083dc --- /dev/null +++ b/example/qml/page/T_ComboBox.qml @@ -0,0 +1,85 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Window +import QtQuick.Controls +import FluentUI +import "../component" + +FluScrollablePage{ + + title:"ComboBox" + + FluArea{ + Layout.fillWidth: true + height: 80 + paddings: 5 + Layout.topMargin: 20 + Column{ + spacing: 5 + anchors.verticalCenter: parent.verticalCenter + FluText{ + text: "editable=false" + x:10 + } + FluComboBox { + model: ListModel { + id: model_1 + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model_1.append({text: editText}) + } + } + } + } + + + FluArea{ + Layout.fillWidth: true + height: 80 + paddings: 10 + Layout.topMargin: 20 + Column{ + spacing: 5 + anchors.verticalCenter: parent.verticalCenter + FluText{ + text: "editable=true" + x:5 + } + FluComboBox { + editable: true + model: ListModel { + id: model_2 + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model_2.append({text: editText}) + } + } + } + } + CodeExpander{ + Layout.fillWidth: true + Layout.topMargin: -1 + code:'FluComboBox{ + editable: true + model: ListModel { + id: model + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model.append({text: editText}) + } +}' + } + +} diff --git a/src/imports/FluentUI/Controls/FluComboBox.qml b/src/imports/FluentUI/Controls/FluComboBox.qml index 303638a..01b4890 100644 --- a/src/imports/FluentUI/Controls/FluComboBox.qml +++ b/src/imports/FluentUI/Controls/FluComboBox.qml @@ -1,7 +1,122 @@ import QtQuick import QtQuick.Controls +import QtQuick.Controls.Basic import FluentUI +import QtQuick.Templates as T -Item { +ComboBox { + id: control + property bool disabled: false + property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1) + property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) + property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1) + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + enabled: !disabled + delegate: FluItemDelegate { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + palette.text: control.palette.text + palette.highlightedText: control.palette.highlightedText + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: FluIcon { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + width: 28 + iconSource:FluentIcons.ChevronDown + iconSize: 15 + opacity: enabled ? 1 : 0.3 + } + + contentItem: T.TextField { + leftPadding: !control.mirrored ? 12 : control.editable && activeFocus ? 3 : 1 + rightPadding: control.mirrored ? 12 : control.editable && activeFocus ? 3 : 1 + topPadding: 6 - control.padding + bottomPadding: 6 - control.padding + renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering + selectionColor: FluTheme.primaryColor.lightest + text: control.editable ? control.editText : control.displayText + enabled: control.editable + autoScroll: control.editable + font:FluTextStyle.Body + readOnly: control.down + color: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1) + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + verticalAlignment: Text.AlignVCenter + background: FluTextBoxBackground{ + inputItem: contentItem + } + } + + background: Rectangle { + implicitWidth: 140 + implicitHeight: 28 + border.color: FluTheme.dark ? "#505050" : "#DFDFDF" + border.width: 1 + visible: !control.flat || control.down + radius: 4 + FluFocusRectangle{ + visible: control.visualFocus + radius:8 + } + color:{ + if(disabled){ + return disableColor + } + return hovered ? hoverColor :normalColor + } + } + + popup: T.Popup { + y: control.height + width: control.width + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + topMargin: 6 + bottomMargin: 6 + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + T.ScrollIndicator.vertical: ScrollIndicator { } + } + enter: Transition { + NumberAnimation { + property: "opacity" + from:0 + to:1 + duration: 83 + } + } + exit:Transition { + NumberAnimation { + property: "opacity" + from:1 + to:0 + duration: 83 + } + } + background:Rectangle{ + color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1) + border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1) + border.width: 1 + radius: 5 + FluShadow{ + radius: 5 + } + } + } } diff --git a/src/imports/FluentUI/Controls/FluItemDelegate.qml b/src/imports/FluentUI/Controls/FluItemDelegate.qml new file mode 100644 index 0000000..7536d2d --- /dev/null +++ b/src/imports/FluentUI/Controls/FluItemDelegate.qml @@ -0,0 +1,39 @@ +import QtQuick +import QtQuick.Controls.Basic +import QtQuick.Templates as T +import FluentUI + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 8 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + contentItem: FluText { + text: control.text + font: control.font + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color:{ + if(FluTheme.dark){ + return Qt.rgba(1,1,1,0.05) + }else{ + return Qt.rgba(0,0,0,0.05) + } + } + visible: control.down || control.highlighted || control.visualFocus + } +}