From 0cf3f2aa22db1a24b6d75fe6a30979dab2d460cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=AD=90=E6=A5=9A=5Czhuzi?= Date: Sun, 12 Mar 2023 14:26:03 +0800 Subject: [PATCH] update --- example/MainPage.qml | 7 + example/T_Buttons.qml | 6 +- example/T_DatePicker.qml | 61 +++++ example/qml.qrc | 1 + src/controls/FluAutoSuggestBox.qml | 93 +++++-- src/controls/FluButton.qml | 88 ++++--- src/controls/FluCheckBox.qml | 56 ++-- src/controls/FluDatePicker.qml | 396 ++++++++++++++++++++++++++++- src/controls/FluExpander.qml | 9 +- src/controls/FluFilledButton.qml | 76 +++--- src/controls/FluFocusRectangle.qml | 22 ++ src/controls/FluIconButton.qml | 90 ++++--- src/controls/FluNavigationView.qml | 3 +- src/controls/FluRadioButton.qml | 52 ++-- src/controls/FluTimePicker.qml | 45 +++- src/controls/FluToggleSwitch.qml | 26 +- src/res.qrc | 1 + 17 files changed, 836 insertions(+), 196 deletions(-) create mode 100644 example/T_DatePicker.qml create mode 100644 src/controls/FluFocusRectangle.qml diff --git a/example/MainPage.qml b/example/MainPage.qml index 1aa8a4b1..20408f39 100644 --- a/example/MainPage.qml +++ b/example/MainPage.qml @@ -66,6 +66,13 @@ FluWindow { } } + FluPaneItem{ + title:"DatePicker" + onTap:{ + nav_view.push("qrc:/T_DatePicker.qml") + } + } + FluPaneItemHeader{ title:"Surface" } diff --git a/example/T_Buttons.qml b/example/T_Buttons.qml index 6c6d96fe..6b1ac2cd 100644 --- a/example/T_Buttons.qml +++ b/example/T_Buttons.qml @@ -9,8 +9,12 @@ FluScrollablePage{ spacing: 20 + FluText{ + Layout.topMargin: 20 + text:"支持Tab键切换焦点,Enter键执行点击事件" + } + FluArea{ - Layout.topMargin: 20 width: parent.width height: 68 paddings: 10 diff --git a/example/T_DatePicker.qml b/example/T_DatePicker.qml new file mode 100644 index 00000000..2e2db6bd --- /dev/null +++ b/example/T_DatePicker.qml @@ -0,0 +1,61 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Window 2.15 +import FluentUI 1.0 + +FluScrollablePage{ + + title:"TimePicker" + + + FluArea{ + width: parent.width + Layout.topMargin: 20 + height: 80 + paddings: 10 + + ColumnLayout{ + + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + } + + FluText{ + text:"showYear=true" + } + + FluDatePicker{ + } + + } + } + + + FluArea{ + width: parent.width + Layout.topMargin: 20 + height: 80 + paddings: 10 + + ColumnLayout{ + + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + } + + FluText{ + text:"showYear=false" + } + + FluDatePicker{ + showYear:false + + } + + } + } + +} diff --git a/example/qml.qrc b/example/qml.qrc index 47389272..2f611d48 100644 --- a/example/qml.qrc +++ b/example/qml.qrc @@ -31,5 +31,6 @@ T_Expander.qml MainPage.qml T_TimePicker.qml + T_DatePicker.qml diff --git a/src/controls/FluAutoSuggestBox.qml b/src/controls/FluAutoSuggestBox.qml index 3b5f2ee9..0dc106e9 100644 --- a/src/controls/FluAutoSuggestBox.qml +++ b/src/controls/FluAutoSuggestBox.qml @@ -29,6 +29,20 @@ TextField{ } rightPadding: icon_right.visible ? 50 : 30 selectByMouse: true + + Keys.onUpPressed: { + list_view.currentIndex = Math.max(list_view.currentIndex-1,0) + } + + Keys.onDownPressed: { + list_view.currentIndex = Math.min(list_view.currentIndex+1,list_view.count-1) + } + + signal handleClicked + Keys.onEnterPressed:handleClicked() + Keys.onReturnPressed:handleClicked() + + font.bold: { switch (fontStyle) { case FluText.Display: @@ -118,6 +132,11 @@ TextField{ onClosed: { input.focus = false } + onVisibleChanged: { + if(visible){ + list_view.currentIndex = -1 + } + } background: Rectangle{ width: input.width radius: 4 @@ -132,6 +151,7 @@ TextField{ anchors.fill: parent boundsBehavior: ListView.StopAtBounds clip: true + currentIndex: -1 header: Item{ width: input.width height: visible ? 38 : 0 @@ -146,42 +166,81 @@ TextField{ } } ScrollBar.vertical: ScrollBar { } - delegate: Item{ - height: 38 + delegate:Control{ width: input.width - Rectangle{ - anchors.fill: parent - anchors.topMargin: 2 - anchors.bottomMargin: 2 - anchors.leftMargin: 5 - anchors.rightMargin: 5 + padding:10 + background: Rectangle{ color: { - if(item_mouse.containsMouse){ + if(list_view.currentIndex === index){ + return FluTheme.isDark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) + } + if(hovered){ return FluTheme.isDark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) } return FluTheme.isDark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0) } - radius: 3 MouseArea{ - id:item_mouse + id:mouse_area anchors.fill: parent - hoverEnabled: true - onClicked: { + Connections{ + target: input + function onHandleClicked(){ + if((list_view.currentIndex === index)){ + mouse_area.handleClick() + } + } + } + onClicked: handleClick() + function handleClick(){ input_popup.close() input.itemClicked(modelData) input.text = modelData } } - FluText{ - text:modelData + Rectangle{ + width: 3 + color:FluTheme.primaryColor.dark + visible: list_view.currentIndex === index + radius: 3 + height: 20 anchors{ - verticalCenter: parent.verticalCenter left: parent.left - leftMargin: 10 + verticalCenter: parent.verticalCenter } } } + contentItem: FluText{ + text:modelData + anchors{ + verticalCenter: parent.verticalCenter + } + } + } + // Item{ + // height: 38 + // width: input.width + // Rectangle{ + // anchors.fill: parent + // anchors.topMargin: 2 + // anchors.bottomMargin: 2 + // anchors.leftMargin: 5 + // anchors.rightMargin: 5 + + // radius: 3 + // MouseArea{ + // id:item_mouse + // anchors.fill: parent + // hoverEnabled: true + // onClicked: { + // input_popup.close() + // input.itemClicked(modelData) + // input.text = modelData + // } + // } + + // } + // } } } } diff --git a/src/controls/FluButton.qml b/src/controls/FluButton.qml index cd8ee4d5..7c150239 100644 --- a/src/controls/FluButton.qml +++ b/src/controls/FluButton.qml @@ -1,47 +1,62 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import FluentUI 1.0 -Rectangle { - id: button +Control { + id: control property string text: "Standard Button" - property int startPadding : 15 - property int endPadding : 15 - property int topPadding: 5 - property int bottomPadding: 5 property bool disabled: false - property color primaryColor : "#0064B0" - signal clicked - radius: 4 - color:{ - if(FluTheme.isDark){ + + property color normalColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1) + property color hoverColor: FluTheme.isDark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) + property color disableColor: FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1) + + signal clicked + + topPadding:5 + bottomPadding:5 + leftPadding:15 + rightPadding:15 + + focusPolicy:Qt.TabFocus + Keys.onEnterPressed:(visualFocus&&handleClick()) + Keys.onReturnPressed:(visualFocus&&handleClick()) + + MouseArea { + anchors.fill: parent + onClicked: handleClick() + } + + function handleClick(){ + if(disabled){ + return + } + control.clicked() + } + + background: Rectangle{ + border.color: FluTheme.isDark ? "#505050" : "#DFDFDF" + border.width: 1 + radius: 4 + FluFocusRectangle{ + visible: control.visualFocus + radius:8 + } + color:{ if(disabled){ - return Qt.rgba(59/255,59/255,59/255,1) + return disableColor } - return button_mouse.containsMouse ? "#444444" : "#3e3e3e" - }else{ - if(disabled){ - return Qt.rgba(252/255,252/255,252/255,1) - } - return button_mouse.containsMouse ? "#FBFBFB" : "#FFFFFF" + return hovered ? hoverColor :normalColor } } - width: button_text.implicitWidth - height: button_text.implicitHeight - border.color: FluTheme.isDark ? "#505050" : "#DFDFDF" - border.width: 1 - - - FluText { - id: button_text - text: button.text - leftPadding: button.startPadding - rightPadding: button.endPadding - topPadding: button.topPadding - bottomPadding: button.bottomPadding + contentItem: FluText { + text: control.text anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter color: { if(FluTheme.isDark){ if(disabled){ @@ -57,15 +72,4 @@ Rectangle { } } - MouseArea { - id:button_mouse - anchors.fill: parent - hoverEnabled: true - onClicked: { - if(disabled){ - return - } - button.clicked() - } - } } diff --git a/src/controls/FluCheckBox.qml b/src/controls/FluCheckBox.qml index d9fb254a..e52544aa 100644 --- a/src/controls/FluCheckBox.qml +++ b/src/controls/FluCheckBox.qml @@ -1,20 +1,17 @@ import QtQuick 2.15 +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import FluentUI 1.0 -Item { +Control { - id:root + id:control property bool checked: false property string text: "Check Box" property var checkClicked - property bool hovered: mouse_area.containsMouse property bool disabled: false - width: childrenRect.width - height: childrenRect.height - property color borderNormalColor: FluTheme.isDark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1) property color borderCheckedColor: FluTheme.isDark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color borderHoverColor: FluTheme.isDark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1) @@ -26,10 +23,36 @@ Item { property color checkedHoverColor: FluTheme.isDark ? Qt.darker(checkedColor,1.1) : Qt.lighter(checkedColor,1.1) property color checkedDisableColor: FluTheme.isDark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1) - property color disableColor: FluTheme.isDark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1) - RowLayout{ + + focusPolicy:Qt.TabFocus + Keys.onEnterPressed:(visualFocus&&handleClick()) + Keys.onReturnPressed:(visualFocus&&handleClick()) + + MouseArea { + anchors.fill: parent + onClicked: handleClick() + } + + function handleClick(){ + if(disabled){ + return + } + if(checkClicked){ + checkClicked() + return + } + checked = !checked + } + + background: Item{ + FluFocusRectangle{ + visible: control.visualFocus + } + } + + contentItem: RowLayout{ spacing: 4 Rectangle{ width: 20 @@ -73,22 +96,7 @@ Item { } } FluText{ - text:root.text - } - } - - - MouseArea{ - id:mouse_area - anchors.fill: parent - hoverEnabled: true - enabled: !disabled - onClicked: { - if(checkClicked){ - checkClicked() - return - } - checked = !checked + text:control.text } } diff --git a/src/controls/FluDatePicker.qml b/src/controls/FluDatePicker.qml index 68c21087..36895c54 100644 --- a/src/controls/FluDatePicker.qml +++ b/src/controls/FluDatePicker.qml @@ -1,5 +1,397 @@ -import QtQuick 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Window 2.15 +import FluentUI 1.0 + +Rectangle { + + id:root + + property color dividerColor: FluTheme.isDark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1) + property color hoverColor: FluTheme.isDark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) + property color normalColor: FluTheme.isDark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) + property var window : Window.window + + property bool showYear: true + + color: { + if(mouse_area.containsMouse){ + return hoverColor + } + return normalColor + } + height: 30 + width: 300 + radius: 4 + border.width: 1 + border.color: dividerColor + + MouseArea{ + id:mouse_area + hoverEnabled: true + anchors.fill: parent + onClicked: { + popup.showPopup() + } + } + + Rectangle{ + id:divider_1 + width: 1 + x: parent.width/3 + height: parent.height + color: dividerColor + visible: showYear + } + + + Rectangle{ + id:divider_2 + width: 1 + x: showYear ? parent.width*2/3 : parent.width/2 + height: parent.height + color: dividerColor + } + + FluText{ + id:text_year + anchors{ + left: parent.left + right: divider_1.left + top: parent.top + bottom: parent.bottom + } + visible: showYear + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text:"年" + } + + + FluText{ + id:text_month + anchors{ + left: showYear ? divider_1.right : parent.left + right: divider_2.left + top: parent.top + bottom: parent.bottom + } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text:"月" + } + + + FluText{ + id:text_day + anchors{ + left: divider_2.right + right: parent.right + top: parent.top + bottom: parent.bottom + } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text:"日" + } + + Popup{ + id:popup + background: Rectangle{ + width: 300 + radius: 4 + color: FluTheme.isDark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1) + height: 340 + MouseArea{ + anchors.fill: parent + } + FluShadow{ + radius: 4 + } + + RowLayout{ + id:layout_content + spacing: 0 + width: parent.width + height: 300 + + Component{ + id:list_delegate + + Item{ + height:38 + width:getListView().width + + function getListView(){ + if(type === 0) + return list_view_1 + if(type === 1) + return list_view_2 + if(type === 2) + return list_view_3 + } + + + Rectangle{ + anchors.fill: parent + anchors.topMargin: 2 + anchors.bottomMargin: 2 + anchors.leftMargin: 5 + anchors.rightMargin: 5 + color: { + if(getListView().currentIndex === position){ + if(FluTheme.isDark){ + return item_mouse.containsMouse ? Qt.darker(FluTheme.primaryColor.lighter,1.1) : FluTheme.primaryColor.lighter + }else{ + return item_mouse.containsMouse ? Qt.lighter(FluTheme.primaryColor.dark,1.1): FluTheme.primaryColor.dark + } + } + if(item_mouse.containsMouse){ + return FluTheme.isDark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) + } + return FluTheme.isDark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0) + } + radius: 3 + MouseArea{ + id:item_mouse + anchors.fill: parent + hoverEnabled: true + onClicked: { + getListView().currentIndex = position + if(type === 0){ + text_year.text = model + list_view_2.model = generateMonthArray(1,12) + text_month.text = list_view_2.model[list_view_2.currentIndex] + + list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex]) + text_day.text = list_view_3.model[list_view_3.currentIndex] + } + if(type === 1){ + text_month.text = model + list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex]) + text_day.text = list_view_3.model[list_view_3.currentIndex] + + } + if(type === 2){ + text_day.text = model + } + } + } + FluText{ + text:model + color: { + if(getListView().currentIndex === position){ + if(FluTheme.isDark){ + return Qt.rgba(0,0,0,1) + }else{ + return Qt.rgba(1,1,1,1) + } + }else{ + return FluTheme.isDark ? "#FFFFFF" : "#1A1A1A" + } + } + anchors.centerIn: parent + } + } + } + } + + ListView{ + id:list_view_1 + width: 100 + height: parent.height + boundsBehavior:Flickable.StopAtBounds + ScrollBar.vertical: ScrollBar { } + model: generateYearArray(1924,2048) + clip: true + visible: showYear + delegate: Loader{ + property var model: modelData + property int type:0 + property int position:index + sourceComponent: list_delegate + } + onCurrentIndexChanged: { + if(currentIndex!==-1){ + list_view_1.positionViewAtIndex(currentIndex, ListView.NoPosition) + } + } + } + Rectangle{ + width: 1 + height: parent.height + color: dividerColor + } + ListView{ + id:list_view_2 + width: showYear ? 100 : 150 + height: parent.height + clip: true + ScrollBar.vertical: ScrollBar { } + boundsBehavior:Flickable.StopAtBounds + delegate: Loader{ + property var model: modelData + property int type:1 + property int position:index + sourceComponent: list_delegate + } + onCurrentIndexChanged: { + if(currentIndex!==-1){ + list_view_2.positionViewAtIndex(currentIndex, ListView.NoPosition) + } + } + } + Rectangle{ + width: 1 + height: parent.height + color: dividerColor + } + ListView{ + id:list_view_3 + width: showYear ? 100 : 150 + height: parent.height + clip: true + ScrollBar.vertical: ScrollBar { } + Layout.alignment: Qt.AlignVCenter + boundsBehavior:Flickable.StopAtBounds + delegate: Loader{ + property var model: modelData + property int type:2 + property int position:index + sourceComponent: list_delegate + } + onCurrentIndexChanged: { + list_view_3.positionViewAtIndex(currentIndex, ListView.NoPosition) + } + } + } + + Rectangle{ + width: parent.width + height: 1 + anchors.top: layout_content.bottom + color: dividerColor + } + + Rectangle{ + id:layout_actions + height: 40 + radius: 5 + color: FluTheme.isDark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1) + anchors{ + bottom:parent.bottom + left: parent.left + right: parent.right + } + + Item { + id:divider + width: 1 + height: parent.height + anchors.centerIn: parent + } + + FluButton{ + anchors{ + left: parent.left + leftMargin: 20 + rightMargin: 10 + right: divider.left + verticalCenter: parent.verticalCenter + } + text: "取消" + onClicked: { + popup.close() + } + } + + FluFilledButton{ + anchors{ + right: parent.right + left: divider.right + rightMargin: 20 + leftMargin: 10 + verticalCenter: parent.verticalCenter + } + text: "确定" + onClicked: { + changeFlag = false + popup.close() + } + } + + } + + } + y:35 + function showPopup() { + changeFlag = true + rowData[0] = text_year.text + rowData[1] = text_month.text + rowData[2] = text_day.text + + const now = new Date(); + var year = text_year.text === "年"? now.getFullYear() : Number(text_year.text); + var month = text_month.text === "月"? now.getMonth() + 1 : Number(text_month.text); + var day = text_day.text === "日" ? now.getDate() : Number(text_day.text); + + list_view_1.currentIndex = list_view_1.model.indexOf(year) + text_year.text = year + + list_view_2.model = generateMonthArray(1,12) + list_view_2.currentIndex = list_view_2.model.indexOf(month) + text_month.text = month + + list_view_3.model = generateMonthDaysArray(year,month) + list_view_3.currentIndex = list_view_3.model.indexOf(day) + text_day.text = day + + var pos = root.mapToItem(null, 0, 0) + if(window.height>pos.y+35+340){ + popup.y = 35 + }else{ + popup.y = window.height-(pos.y+340) + } + popup.open() + } + + onClosed: { + if(changeFlag){ + text_year.text = rowData[0] + text_month.text = rowData[1] + text_day.text = rowData[2] + } + } + } + + property bool changeFlag: true + readonly property var rowData: ["","",""] + + function generateYearArray(startYear, endYear) { + const yearArray = []; + for (let year = startYear; year <= endYear; year++) { + yearArray.push(year); + } + return yearArray; + } + + function generateMonthArray(startMonth, endMonth) { + const monthArray = []; + for (let month = startMonth; month <= endMonth; month++) { + monthArray.push(month); + } + return monthArray; + } + + function generateMonthDaysArray(year, month) { + const monthDaysArray = []; + const lastDayOfMonth = new Date(year, month, 0).getDate(); + for (let day = 1; day <= lastDayOfMonth; day++) { + monthDaysArray.push(day); + } + return monthDaysArray; + } -Item { } diff --git a/src/controls/FluExpander.qml b/src/controls/FluExpander.qml index 2bd954b9..23098007 100644 --- a/src/controls/FluExpander.qml +++ b/src/controls/FluExpander.qml @@ -49,9 +49,12 @@ Item { right: parent.right rightMargin: 15 } - hoverColor: FluTheme.isDark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(245/255,245/255,245/255,1) - normalColor: FluTheme.isDark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) - hovered: root_mouse.containsMouse + color:{ + if(root_mouse.containsMouse){ + return FluTheme.isDark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(245/255,245/255,245/255,1) + } + return FluTheme.isDark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) + } iconSize: 15 icon: expand ? FluentIcons.ChevronUp : FluentIcons.ChevronDown onClicked: { diff --git a/src/controls/FluFilledButton.qml b/src/controls/FluFilledButton.qml index c3f07bed..ba978a3a 100644 --- a/src/controls/FluFilledButton.qml +++ b/src/controls/FluFilledButton.qml @@ -2,37 +2,53 @@ import QtQuick.Controls 2.15 import FluentUI 1.0 -Rectangle { - id: button +Control { + id: control property string text: "Filled Button" - property int startPadding : 15 - property int endPadding : 15 - property int topPadding: 5 - property int bottomPadding: 5 property bool disabled: false - + property color normalColor: FluTheme.isDark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark + property color hoverColor: FluTheme.isDark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1) + property color disableColor: FluTheme.isDark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1) signal clicked - radius: 4 - color:{ - if(FluTheme.isDark){ + + topPadding:5 + bottomPadding:5 + leftPadding:15 + rightPadding:15 + focusPolicy:Qt.TabFocus + Keys.onEnterPressed:(visualFocus&&handleClick()) + Keys.onReturnPressed:(visualFocus&&handleClick()) + + MouseArea { + anchors.fill: parent + onClicked: handleClick() + } + + function handleClick(){ + if(disabled) + return + control.clicked() + } + + background: Rectangle{ + radius: 4 + FluFocusRectangle{ + visible: control.visualFocus + radius:8 + } + color:{ if(disabled){ - return Qt.rgba(199/255,199/255,199/255,1) + return disableColor } - return button_mouse.containsMouse ? Qt.darker(FluTheme.primaryColor.lighter,1.1) : FluTheme.primaryColor.lighter - }else{ - if(disabled){ - return Qt.rgba(199/255,199/255,199/255,1) - } - return button_mouse.containsMouse ? Qt.lighter(FluTheme.primaryColor.dark,1.1): FluTheme.primaryColor.dark + return hovered ? hoverColor :normalColor } } - width: button_text.implicitWidth - height: button_text.implicitHeight - FluText { - id: button_text - text: button.text + contentItem: FluText { + text: control.text + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter color: { if(FluTheme.isDark){ if(disabled){ @@ -44,21 +60,7 @@ Rectangle { } } font.pixelSize: 14 - leftPadding: button.startPadding - rightPadding: button.endPadding - topPadding: button.topPadding - bottomPadding: button.bottomPadding - anchors.centerIn: parent } - MouseArea { - id:button_mouse - anchors.fill: parent - hoverEnabled: true - onClicked: { - if(disabled) - return - button.clicked() - } - } + } diff --git a/src/controls/FluFocusRectangle.qml b/src/controls/FluFocusRectangle.qml new file mode 100644 index 00000000..1a4d9cd3 --- /dev/null +++ b/src/controls/FluFocusRectangle.qml @@ -0,0 +1,22 @@ +import QtQuick 2.15 +import FluentUI 1.0 + +Item { + id:root + anchors.fill: parent + anchors.margins: -3 + + property var radius: 4 + + Rectangle{ + width: root.width + height: root.height + anchors.centerIn: parent + color: "#00000000" + border.width: 3 + radius: root.radius + border.color: FluTheme.isDark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) + z: 65535 + } + +} diff --git a/src/controls/FluIconButton.qml b/src/controls/FluIconButton.qml index e2734161..bd3d99f6 100644 --- a/src/controls/FluIconButton.qml +++ b/src/controls/FluIconButton.qml @@ -1,9 +1,10 @@ import QtQuick 2.15 +import QtQuick.Controls 2.15 import FluentUI 1.0 -Rectangle { +Control { - id:button + id:control width: 30 height: 30 @@ -12,12 +13,18 @@ Rectangle { property alias text: tool_tip.text signal clicked property bool disabled: false - property bool hovered: button_mouse.containsMouse property color hoverColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(0,0,0,0.03) property color normalColor: FluTheme.isDark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) property color disableColor: FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(0,0,0,0) + property color color: { + if(disabled){ + return disableColor + } + return hovered ? hoverColor : normalColor + } + property color textColor: { if(FluTheme.isDark){ if(disabled){ @@ -31,47 +38,56 @@ Rectangle { return Qt.rgba(0,0,0,1) } } - radius: 4 - color: { - if(disabled){ - return disableColor - } - return (hovered || button_mouse.containsMouse) ? hoverColor : normalColor - } + focusPolicy:Qt.TabFocus + Keys.onEnterPressed:(visualFocus&&handleClick()) + Keys.onReturnPressed:(visualFocus&&handleClick()) - Text { - id:text_icon - font.family: "Segoe Fluent Icons" - font.pixelSize: iconSize - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - anchors.centerIn: parent - color:button.textColor - text: (String.fromCharCode(icon).toString(16)); - } - - MouseArea{ - id:button_mouse + MouseArea { anchors.fill: parent - hoverEnabled: true - onClicked: { - if(disabled){ - return - } - button.clicked() + onClicked: handleClick() + } + + function handleClick(){ + if(disabled){ + return + } + control.clicked() + } + + background: Rectangle{ + radius: 4 + color:control.color + FluFocusRectangle{ + visible: control.visualFocus } } - FluTooltip{ - id:tool_tip - visible: { - if(button.text === ""){ - return false - } - return (hovered || button_mouse.containsMouse) + contentItem: Item{ + Text { + id:text_icon + font.family: "Segoe Fluent Icons" + font.pixelSize: iconSize + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.centerIn: parent + color:control.textColor + text: (String.fromCharCode(icon).toString(16)); + } + + FluTooltip{ + id:tool_tip + visible: { + if(control.text === ""){ + return false + } + return hovered + } + delay: 1000 } - delay: 1000 } + + + } diff --git a/src/controls/FluNavigationView.qml b/src/controls/FluNavigationView.qml index fdc6b1ef..f724dab3 100644 --- a/src/controls/FluNavigationView.qml +++ b/src/controls/FluNavigationView.qml @@ -195,7 +195,7 @@ Item { Item{ anchors{ left: displayMode === FluNavigationView.Minimal ? parent.left : layout_list.right - leftMargin: 2 + leftMargin: 10 top: nav_app_bar.bottom right: parent.right rightMargin: 10 @@ -207,7 +207,6 @@ Item { id:nav_swipe anchors.fill: parent clip: true - anchors.margins: 10 popEnter : Transition{} popExit : Transition { NumberAnimation { properties: "y"; from: 0; to: nav_swipe.height; duration: 200 } diff --git a/src/controls/FluRadioButton.qml b/src/controls/FluRadioButton.qml index b1a35904..dd09511f 100644 --- a/src/controls/FluRadioButton.qml +++ b/src/controls/FluRadioButton.qml @@ -1,19 +1,42 @@ import QtQuick 2.15 +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import FluentUI 1.0 -Item { +Control { - id:root - width: childrenRect.width - height: childrenRect.height + id:control property bool checked: false property string text: "RodioButton" signal clicked property bool disabled: false - RowLayout{ + focusPolicy:Qt.TabFocus + Keys.onEnterPressed:(visualFocus&&handleClick()) + Keys.onReturnPressed:(visualFocus&&handleClick()) + + MouseArea { + anchors.fill: parent + onClicked: handleClick() + } + + function handleClick(){ + if(disabled){ + return + } + + control.clicked() + } + + + background: Item{ + FluFocusRectangle{ + visible: control.visualFocus + } + } + + contentItem: RowLayout{ Rectangle{ id:rect_check width: 20 @@ -26,13 +49,13 @@ Item { if(checked&&disabled){ return 3 } - if(root_mouse.containsPress){ + if(hovered){ if(checked){ return 5 } return 1 } - if(root_mouse.containsMouse){ + if(hovered){ if(checked){ return 3 } @@ -74,12 +97,12 @@ Item { return Qt.rgba(159/255,159/255,159/255,1) } if(FluTheme.isDark){ - if(root_mouse.containsMouse){ + if(hovered){ return Qt.rgba(43/255,43/255,43/255,1) } return Qt.rgba(50/255,50/255,50/255,1) }else{ - if(root_mouse.containsMouse){ + if(hovered){ if(checked){ return Qt.rgba(1,1,1,1) } @@ -91,21 +114,12 @@ Item { } FluText{ - text: root.text + text: control.text Layout.alignment: Qt.AlignVCenter } } - MouseArea{ - id:root_mouse - hoverEnabled: true - anchors.fill: parent - enabled: !disabled - onClicked: { - root.clicked() - } - } } diff --git a/src/controls/FluTimePicker.qml b/src/controls/FluTimePicker.qml index 04e7d0af..deec95e6 100644 --- a/src/controls/FluTimePicker.qml +++ b/src/controls/FluTimePicker.qml @@ -100,7 +100,7 @@ Rectangle { } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - text:"上午" + text:"AM/PM" } Popup{ @@ -210,6 +210,9 @@ Rectangle { property int position:index sourceComponent: list_delegate } + onCurrentIndexChanged: { + list_view_1.positionViewAtIndex(currentIndex, ListView.NoPosition) + } } Rectangle{ width: 1 @@ -230,12 +233,15 @@ Rectangle { property int position:index sourceComponent: list_delegate } + onCurrentIndexChanged: { + list_view_2.positionViewAtIndex(currentIndex, ListView.NoPosition) + } } Rectangle{ width: 1 height: parent.height color: dividerColor - visible: isH + visible: isH } ListView{ id:list_view_3 @@ -253,6 +259,9 @@ Rectangle { property int position:index sourceComponent: list_delegate } + onCurrentIndexChanged: { + list_view_3.positionViewAtIndex(currentIndex, ListView.NoPosition) + } } } @@ -319,9 +328,35 @@ Rectangle { rowData[0] = text_hour.text rowData[1] = text_minute.text rowData[2] = text_ampm.text - list_view_1.currentIndex = -1 - list_view_2.currentIndex = -1 - list_view_3.currentIndex = -1 + + var now = new Date(); + + var hour + var ampm; + if(isH){ + hour = now.getHours(); + if(hour>12){ + ampm = "下午" + hour = hour-12 + }else{ + ampm = "上午" + } + }else{ + hour = now.getHours(); + } + hour = text_hour.text === "时"? hour.toString().padStart(2, '0') : text_hour.text + var minute = text_minute.text === "分"? now.getMinutes().toString().padStart(2, '0') : text_minute.text + ampm = text_ampm.text === "AM/PM"?ampm:text_ampm.text + list_view_1.currentIndex = list_view_1.model.indexOf(hour); + list_view_2.currentIndex = list_view_2.model.indexOf(minute); + list_view_3.currentIndex = list_view_3.model.indexOf(ampm); + + text_hour.text = hour + text_minute.text = minute + if(isH){ + text_ampm.text = ampm + } + var pos = root.mapToItem(null, 0, 0) if(window.height>pos.y+35+340){ popup.y = 35 diff --git a/src/controls/FluToggleSwitch.qml b/src/controls/FluToggleSwitch.qml index bd028dba..7884db5f 100644 --- a/src/controls/FluToggleSwitch.qml +++ b/src/controls/FluToggleSwitch.qml @@ -10,6 +10,15 @@ Switch { height: 20 implicitHeight: 20 checkable: false + + background:FluFocusRectangle{ + visible: root.visualFocus + radius: 20 + } + + Keys.onEnterPressed:(visualFocus&&handleClick()) + Keys.onReturnPressed:(visualFocus&&handleClick()) + indicator: Rectangle { width: root.width height: root.height @@ -44,7 +53,7 @@ Switch { scale: switch_mouse.containsMouse ? 1.2 : 1.0 anchors.verticalCenter: parent.verticalCenter color: root.checked ? "#FFFFFF" : "#666666" -// border.color: "#D5D5D5" + // border.color: "#D5D5D5" Behavior on x { NumberAnimation { duration: 200 } } @@ -54,12 +63,15 @@ Switch { id:switch_mouse anchors.fill: parent hoverEnabled: true - onClicked: { - if(root.onClickFunc){ - root.onClickFunc() - }else{ - root.checked = !root.checked - } + onClicked: handleClick() + } + + function handleClick(){ + if(root.onClickFunc){ + root.onClickFunc() + }else{ + root.checked = !root.checked } } + } diff --git a/src/res.qrc b/src/res.qrc index 8591738a..91576ea5 100644 --- a/src/res.qrc +++ b/src/res.qrc @@ -46,5 +46,6 @@ controls/FluDatePicker.qml controls/FluCalenderView.qml controls/FluCalendarDatePicker.qml + controls/FluFocusRectangle.qml