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