From 479e21097c297241ba476470a71959ea497efe9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=AD=90=E6=A5=9A=5Czhuzi?= Date: Fri, 15 Mar 2024 00:04:15 +0800 Subject: [PATCH] update FluCalendarPicker --- example/qml-Qt6/page/T_CalendarPicker.qml | 17 - example/qml/page/T_CalendarPicker.qml | 17 - src/FluApp.cpp | 3 +- src/FluApp.h | 1 + src/FluentUI.cpp | 1 - .../FluentUI/Controls/FluCalendarPicker.qml | 590 +++++++++++++++++- .../FluentUI/Controls/FluCalendarView.qml | 433 ------------- src/Qt5/imports/FluentUI/plugins.qmltypes | 247 +------- src/Qt5/imports/FluentUI/qmldir | 1 - src/Qt5/imports/fluentui.qrc | 1 - .../FluentUI/Controls/FluCalendarPicker.qml | 589 ++++++++++++++++- .../FluentUI/Controls/FluCalendarView.qml | 433 ------------- src/fluentuiplugin_en_US.ts | 6 +- src/fluentuiplugin_zh_CN.ts | 6 +- 14 files changed, 1145 insertions(+), 1200 deletions(-) delete mode 100644 src/Qt5/imports/FluentUI/Controls/FluCalendarView.qml delete mode 100644 src/Qt6/imports/FluentUI/Controls/FluCalendarView.qml diff --git a/example/qml-Qt6/page/T_CalendarPicker.qml b/example/qml-Qt6/page/T_CalendarPicker.qml index b2ff3fd8..1b28b644 100644 --- a/example/qml-Qt6/page/T_CalendarPicker.qml +++ b/example/qml-Qt6/page/T_CalendarPicker.qml @@ -9,22 +9,6 @@ FluScrollablePage{ title: qsTr("CalendarPicker") - FluArea{ - Layout.fillWidth: true - Layout.topMargin: 20 - height: 350 - paddings: 10 - FluCalendarView{ - } - } - CodeExpander{ - Layout.fillWidth: true - Layout.topMargin: -1 - code:'FluCalendarView{ - -}' - } - FluArea{ Layout.fillWidth: true Layout.topMargin: 20 @@ -36,7 +20,6 @@ FluScrollablePage{ left: parent.left } FluCalendarPicker{ - current:new Date() onAccepted:{ showSuccess(current.toLocaleString()) } diff --git a/example/qml/page/T_CalendarPicker.qml b/example/qml/page/T_CalendarPicker.qml index 637ddc28..29497473 100644 --- a/example/qml/page/T_CalendarPicker.qml +++ b/example/qml/page/T_CalendarPicker.qml @@ -9,22 +9,6 @@ FluScrollablePage{ title: qsTr("CalendarPicker") - FluArea{ - Layout.fillWidth: true - Layout.topMargin: 20 - height: 350 - paddings: 10 - FluCalendarView{ - } - } - CodeExpander{ - Layout.fillWidth: true - Layout.topMargin: -1 - code:'FluCalendarView{ - -}' - } - FluArea{ Layout.fillWidth: true Layout.topMargin: 20 @@ -36,7 +20,6 @@ FluScrollablePage{ left: parent.left } FluCalendarPicker{ - current:new Date() onAccepted:{ showSuccess(current.toLocaleString()) } diff --git a/src/FluApp.cpp b/src/FluApp.cpp index 9edbae3d..982828ad 100644 --- a/src/FluApp.cpp +++ b/src/FluApp.cpp @@ -18,10 +18,11 @@ FluApp::~FluApp(){ } void FluApp::init(QObject *target,QLocale locale){ + _locale = locale; _engine = qmlEngine(target); _translator = new QTranslator(this); qApp->installTranslator(_translator); - const QStringList uiLanguages = locale.uiLanguages(); + const QStringList uiLanguages = _locale.uiLanguages(); for (const QString &name : uiLanguages) { const QString baseName = "fluentuiplugin_" + QLocale(name).name(); if (_translator->load(":/qt/qml/FluentUI/i18n/"+ baseName)) { diff --git a/src/FluApp.h b/src/FluApp.h index fffc5495..10f49e4a 100644 --- a/src/FluApp.h +++ b/src/FluApp.h @@ -23,6 +23,7 @@ class FluApp : public QObject Q_PROPERTY_AUTO(QJsonObject,routes); Q_PROPERTY_AUTO(bool,useSystemAppBar); Q_PROPERTY_AUTO(QString,windowIcon); + Q_PROPERTY_AUTO(QLocale,locale); QML_NAMED_ELEMENT(FluApp) QML_SINGLETON private: diff --git a/src/FluentUI.cpp b/src/FluentUI.cpp index 8b36a6cd..6eba010b 100644 --- a/src/FluentUI.cpp +++ b/src/FluentUI.cpp @@ -49,7 +49,6 @@ void FluentUI::registerTypes(const char *uri){ qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluBreadcrumbBar.qml"),uri,major,minor,"FluBreadcrumbBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluButton.qml"),uri,major,minor,"FluButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCalendarPicker.qml"),uri,major,minor,"FluCalendarPicker"); - qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCalendarView.qml"),uri,major,minor,"FluCalendarView"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCarousel.qml"),uri,major,minor,"FluCarousel"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluChart.qml"),uri,major,minor,"FluChart"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCheckBox.qml"),uri,major,minor,"FluCheckBox"); diff --git a/src/Qt5/imports/FluentUI/Controls/FluCalendarPicker.qml b/src/Qt5/imports/FluentUI/Controls/FluCalendarPicker.qml index 20b30e02..121d8493 100644 --- a/src/Qt5/imports/FluentUI/Controls/FluCalendarPicker.qml +++ b/src/Qt5/imports/FluentUI/Controls/FluCalendarPicker.qml @@ -3,12 +3,13 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import QtQuick.Window 2.15 import FluentUI 1.0 +import Qt.labs.calendar 1.0 Rectangle { property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/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 normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) - property string text: qsTr("Please select a date") + property string text: qsTr("Pick a date") property var current signal accepted() id:control @@ -23,15 +24,6 @@ Rectangle { radius: 4 border.width: 1 border.color: dividerColor - Component.onCompleted: { - if(current){ - const date = current - var year = date.getFullYear() - var month = date.getMonth() - var day = date.getDate() - text_date.text = year+"-"+(month+1)+"-"+day - } - } MouseArea{ id:mouse_area hoverEnabled: true @@ -40,9 +32,25 @@ Rectangle { popup.showPopup() } } + CalendarModel { + id:calender_model + from: new Date(1924, 0, 1) + to: new Date(2124, 11, 31) + } Item{ id:d property var window : Window.window + property date displayDate: { + if(control.current){ + return control.current + } + return new Date() + } + property date toDay : new Date() + property int pageIndex: 0 + signal nextButton + signal previousButton + property point yearRing : Qt.point(0,0) } FluText{ id:text_date @@ -55,7 +63,12 @@ Rectangle { } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - text:control.text + text:{ + if(control.current){ + return control.current.toLocaleDateString(FluApp.locale,"yyyy/M/d") + } + return control.text + } } FluIcon{ iconSource: FluentIcons.Calendar @@ -92,18 +105,548 @@ Rectangle { } contentItem: Item{ clip: true - FluCalendarView{ + FluArea{ id:container - onDateClicked: - (date)=>{ - popup.close() - var year = date.getFullYear() - var month = date.getMonth() - var day = date.getDate() - text_date.text = year+"-"+(month+1)+"-"+day - current= date - control.accepted() + width: 300 + height: 360 + ColumnLayout { + anchors.fill: parent + spacing: 0 + Item{ + Layout.fillWidth: true + Layout.preferredHeight: 50 + RowLayout{ + anchors.fill: parent + spacing: 10 + Item{ + Layout.leftMargin: parent.spacing + Layout.fillWidth: true + Layout.fillHeight: true + FluTextButton{ + width: parent.width + anchors.centerIn: parent + contentItem: FluText { + text: d.displayDate.toLocaleString(FluApp.locale, "MMMM yyyy") + verticalAlignment: Text.AlignVCenter + } + visible: d.pageIndex === 0 + onClicked: { + d.pageIndex = 1 + } + } + FluTextButton{ + width: parent.width + anchors.centerIn: parent + contentItem: FluText { + text: d.displayDate.toLocaleString(FluApp.locale, "yyyy") + verticalAlignment: Text.AlignVCenter + } + visible: d.pageIndex === 1 + onClicked: { + d.pageIndex = 2 + } + } + FluTextButton{ + width: parent.width + anchors.centerIn: parent + contentItem: FluText { + text: "%1-%2".arg(d.yearRing.x).arg(d.yearRing.y) + verticalAlignment: Text.AlignVCenter + textColor: FluTheme.fontTertiaryColor + } + visible: d.pageIndex === 2 + } + } + FluIconButton{ + id:icon_up + iconSource: FluentIcons.CaretUpSolid8 + iconSize: 10 + onClicked: { + d.previousButton() + } + } + FluIconButton{ + id:icon_down + iconSource: FluentIcons.CaretDownSolid8 + iconSize: 10 + Layout.rightMargin: parent.spacing + onClicked: { + d.nextButton() + } + } + } + FluDivider{ + width: parent.width + height: 1 + anchors.bottom: parent.bottom + } } + Item{ + Layout.fillWidth: true + Layout.fillHeight: true + StackView{ + id:stack_view + anchors.fill: parent + initialItem: com_page_one + replaceEnter : Transition{ + OpacityAnimator{ + from: 0 + to: 1 + duration: 88 + } + ScaleAnimator{ + from: 0.5 + to: 1 + duration: 167 + easing.type: Easing.OutCubic + } + } + replaceExit : Transition{ + OpacityAnimator{ + from: 1 + to: 0 + duration: 88 + } + ScaleAnimator{ + from: 1.0 + to: 0.5 + duration: 167 + easing.type: Easing.OutCubic + } + } + } + Connections{ + target: d + function onPageIndexChanged(){ + if(d.pageIndex === 0){ + stack_view.replace(com_page_one) + } + if(d.pageIndex === 1){ + stack_view.replace(com_page_two) + } + if(d.pageIndex === 2){ + stack_view.replace(com_page_three) + } + } + } + Component{ + id:com_page_three + GridView{ + id:grid_view + cellHeight: 75 + cellWidth: 75 + clip: true + boundsBehavior: GridView.StopAtBounds + ScrollBar.vertical: FluScrollBar {} + model: { + var fromYear = calender_model.from.getFullYear() + var toYear = calender_model.to.getFullYear() + return toYear-fromYear+1 + } + snapMode: GridView.SnapOneRow + highlightRangeMode: GridView.StrictlyEnforceRange + onCurrentIndexChanged:{ + var year = currentIndex + calender_model.from.getFullYear() + var start = Math.ceil(year / 10) * 10 + var end = start+10 + d.yearRing = Qt.point(start,end) + } + highlightMoveDuration: 100 + Component.onCompleted: { + grid_view.highlightMoveDuration = 0 + currentIndex = d.displayDate.getFullYear()-calender_model.from.getFullYear() + timer_delay.restart() + } + Connections{ + target: d + function onNextButton(){ + grid_view.currentIndex = Math.min(grid_view.currentIndex+16,grid_view.count-1) + } + function onPreviousButton(){ + grid_view.currentIndex = Math.max(grid_view.currentIndex-16,0) + } + } + Timer{ + id:timer_delay + interval: 100 + onTriggered: { + grid_view.highlightMoveDuration = 100 + } + } + currentIndex: -1 + delegate: Item{ + property int year : calender_model.from.getFullYear()+modelData + property bool toYear: year === d.toDay.getFullYear() + implicitHeight: 75 + implicitWidth: 75 + FluControl{ + id:control_delegate + width: 60 + height: 60 + anchors.centerIn: parent + Rectangle{ + width: 48 + height: 48 + radius: width/2 + color: { + if(toYear){ + if(control_delegate.pressed){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2) + } + if(control_delegate.hovered){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1) + } + return FluTheme.primaryColor + }else{ + if(control_delegate.pressed){ + return FluTheme.itemPressColor + } + if(control_delegate.hovered){ + return FluTheme.itemHoverColor + } + return FluColors.Transparent + } + } + anchors.centerIn: parent + } + + FluText{ + text: year + anchors.centerIn: parent + opacity: { + if(year >= d.yearRing.x && year <= d.yearRing.y){ + return 1 + } + if(control_delegate.hovered){ + return 1 + } + return 0.3 + } + color: { + if(toYear){ + return FluColors.White + } + if(control_delegate.pressed){ + return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100 + } + if(control_delegate.hovered){ + return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 + } + return FluTheme.dark ? FluColors.White : FluColors.Grey220 + } + } + onClicked: { + d.displayDate = new Date(year,0,1) + d.pageIndex = 1 + } + } + } + } + } + Component{ + id:com_page_two + + ListView{ + id:listview + ScrollBar.vertical: FluScrollBar {} + snapMode: ListView.SnapOneItem + highlightRangeMode: ListView.StrictlyEnforceRange + clip: true + boundsBehavior: ListView.StopAtBounds + spacing: 0 + highlightMoveDuration: 100 + model: { + var fromYear = calender_model.from.getFullYear() + var toYear = calender_model.to.getFullYear() + var yearsArray = [] + for (var i = fromYear; i <= toYear; i++) { + yearsArray.push(i) + } + return yearsArray + } + currentIndex: -1 + onCurrentIndexChanged:{ + var year = model[currentIndex] + var month = d.displayDate.getMonth() + d.displayDate = new Date(year,month,1) + } + Connections{ + target: d + function onNextButton(){ + listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1) + } + function onPreviousButton(){ + listview.currentIndex = Math.max(listview.currentIndex-1,0) + } + } + Component.onCompleted: { + listview.highlightMoveDuration = 0 + currentIndex = model.indexOf(d.displayDate.getFullYear()) + timer_delay.restart() + } + Timer{ + id:timer_delay + interval: 100 + onTriggered: { + listview.highlightMoveDuration = 100 + } + } + delegate: Item{ + id:layout_congrol + property int year : modelData + width: listview.width + height: 75*3 + GridView{ + anchors.fill: parent + cellHeight: 75 + cellWidth: 75 + clip: true + interactive: false + boundsBehavior: GridView.StopAtBounds + model: 12 + delegate: Item{ + property int month : modelData + property bool toMonth: layout_congrol.year === d.toDay.getFullYear() && month === d.toDay.getMonth() + implicitHeight: 75 + implicitWidth: 75 + FluControl{ + id:control_delegate + width: 60 + height: 60 + anchors.centerIn: parent + Rectangle{ + width: 48 + height: 48 + radius: width/2 + color: { + if(toMonth){ + if(control_delegate.pressed){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2) + } + if(control_delegate.hovered){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1) + } + return FluTheme.primaryColor + }else{ + if(control_delegate.pressed){ + return FluTheme.itemPressColor + } + if(control_delegate.hovered){ + return FluTheme.itemHoverColor + } + return FluColors.Transparent + } + } + anchors.centerIn: parent + } + FluText{ + text: new Date(layout_congrol.year,month).toLocaleString(FluApp.locale, "MMMM") + anchors.centerIn: parent + opacity: { + if(layout_congrol.year === d.displayDate.getFullYear()){ + return 1 + } + if(control_delegate.hovered){ + return 1 + } + return 0.3 + } + color: { + if(toMonth){ + return FluColors.White + } + if(control_delegate.pressed){ + return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100 + } + if(control_delegate.hovered){ + return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 + } + return FluTheme.dark ? FluColors.White : FluColors.Grey220 + } + } + onClicked: { + d.displayDate = new Date(layout_congrol.year,month) + timer_delay_start.restart() + } + Timer{ + id:timer_delay_start + interval: 100 + onTriggered: { + d.pageIndex = 0 + } + } + } + } + } + } + } + } + Component{ + id:com_page_one + ColumnLayout { + DayOfWeekRow { + id: dayOfWeekRow + locale: FluApp.locale + font.bold: false + delegate: Label { + text: model.shortName + font: dayOfWeekRow.font + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + Layout.column: 1 + Layout.fillWidth: true + } + ListView{ + id:listview + property bool isCompleted: false + snapMode: ListView.SnapOneItem + Layout.fillWidth: true + Layout.fillHeight: true + highlightRangeMode: ListView.StrictlyEnforceRange + clip: true + boundsBehavior: ListView.StopAtBounds + spacing: 0 + highlightMoveDuration: 100 + currentIndex: -1 + ScrollBar.vertical: FluScrollBar {} + onCurrentIndexChanged:{ + if(isCompleted){ + var month = calender_model.monthAt(currentIndex) + var year = calender_model.yearAt(currentIndex) + d.displayDate = new Date(year,month,1) + } + } + Component.onCompleted: { + listview.model = calender_model + listview.highlightMoveDuration = 0 + currentIndex = calender_model.indexOf(d.displayDate) + timer_delay.restart() + isCompleted = true + } + Timer{ + id:timer_delay + interval: 100 + onTriggered: { + listview.highlightMoveDuration = 100 + } + } + Connections{ + target: d + function onNextButton(){ + listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1) + } + function onPreviousButton(){ + listview.currentIndex = Math.max(listview.currentIndex-1,0) + } + } + delegate: MonthGrid { + id: grid + width: listview.width + height: listview.height + month: model.month + year: model.year + spacing: 0 + locale: FluApp.locale + delegate: FluControl { + required property bool today + required property int year + required property int month + required property int day + required property int visibleMonth + id: control_delegate + visibleMonth: grid.month + implicitHeight: 40 + implicitWidth: 40 + Rectangle{ + width: 34 + height: 34 + radius: width/2 + color: { + if(today){ + if(control_delegate.pressed){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2) + } + if(control_delegate.hovered){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1) + } + return FluTheme.primaryColor + }else{ + if(control_delegate.pressed){ + return FluTheme.itemPressColor + } + if(control_delegate.hovered){ + return FluTheme.itemHoverColor + } + return FluColors.Transparent + } + } + anchors.centerIn: parent + } + Rectangle{ + width: 40 + height: 40 + border.width: 1 + anchors.centerIn: parent + radius: width/2 + border.color: FluTheme.primaryColor + color: FluColors.Transparent + visible: { + if(control.current){ + var y = control.current.getFullYear() + var m = control.current.getMonth() + var d = control.current.getDate() + if(y === year && m === month && d === day){ + return true + } + return false + } + return false + } + } + FluText{ + text: day + opacity: { + if(month === grid.month){ + return 1 + } + if(control_delegate.hovered){ + return 1 + } + return 0.3 + } + anchors.centerIn: parent + color: { + if(today){ + return FluColors.White + } + if(control_delegate.pressed){ + return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100 + } + if(control_delegate.hovered){ + return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 + } + return FluTheme.dark ? FluColors.White : FluColors.Grey220 + } + } + onClicked: { + control.current = new Date(year,month,day) + control.accepted() + popup.close() + } + } + background: Item { + x: grid.leftPadding + y: grid.topPadding + width: grid.availableWidth + height: grid.availableHeight + } + } + } + } + } + } + } } } background: Item{ @@ -112,11 +655,6 @@ Rectangle { } } function showPopup() { - if(current){ - container.currentDate = current - container.date = current - container.updateMouth(current) - } var pos = control.mapToItem(null, 0, 0) if(d.window.height>pos.y+control.height+container.height){ popup.y = control.height diff --git a/src/Qt5/imports/FluentUI/Controls/FluCalendarView.qml b/src/Qt5/imports/FluentUI/Controls/FluCalendarView.qml deleted file mode 100644 index 0a3cba0b..00000000 --- a/src/Qt5/imports/FluentUI/Controls/FluCalendarView.qml +++ /dev/null @@ -1,433 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import FluentUI 1.0 - -Item { - property int displayMode: FluCalendarViewType.Month - property var date: new Date() - property var currentDate : new Date() - property var toDay: new Date() - property int radius: 5 - signal dateClicked(var date) - id:control - width: 280 - height: 325 - Component.onCompleted: { - updateMouth(date) - } - Component{ - id:com_week - Item{ - height: 40 - width: 40 - FluText{ - text:name - anchors.centerIn: parent - } - } - } - Component{ - id:com_year - Button{ - id:item_control - property bool isYear: control.toDay.getFullYear() === date.getFullYear() - height: 70 - width: 70 - onClicked:{ - control.date = date - displayMode = FluCalendarViewType.Year - updateYear(date) - } - background: Item{ - Rectangle{ - width: 60 - height: 60 - radius: 4 - anchors.centerIn: parent - color:{ - if(FluTheme.dark){ - if(item_control.hovered){ - return Qt.rgba(1,1,1,0.05) - } - return Qt.rgba(0,0,0,0) - }else{ - if(item_control.hovered){ - return Qt.rgba(0,0,0,0.05) - } - return Qt.rgba(0,0,0,0) - } - } - } - Rectangle{ - id:backgound_selected - anchors.centerIn: parent - width: 50 - height: 50 - radius: 25 - visible: isYear - color: FluTheme.primaryColor - } - FluText{ - text:date.getFullYear() - anchors.centerIn: parent - color: { - if(isYear){ - return "#FFFFFF" - } - if(isDecade){ - return FluTheme.dark ? "#FFFFFF" : "#1A1A1A" - } - return Qt.rgba(150/255,150/255,150/255,1) - } - } - } - contentItem: Item{} - } - } - Component{ - id:com_month - Button{ - id:item_control - property bool isYear: control.date.getFullYear() === date.getFullYear() - property bool isMonth: control.toDay.getFullYear() === date.getFullYear() && control.toDay.getMonth() === date.getMonth() - height: 70 - width: 70 - onClicked:{ - control.date = date - displayMode = FluCalendarViewType.Month - updateMouth(date) - } - background: Item{ - Rectangle{ - width: 60 - height: 60 - radius: 4 - anchors.centerIn: parent - color:{ - if(FluTheme.dark){ - if(item_control.hovered){ - return Qt.rgba(1,1,1,0.05) - } - return Qt.rgba(0,0,0,0) - }else{ - if(item_control.hovered){ - return Qt.rgba(0,0,0,0.05) - } - return Qt.rgba(0,0,0,0) - } - } - } - Rectangle{ - id:backgound_selected - anchors.centerIn: parent - width: 50 - height: 50 - radius: 25 - visible: isMonth - color: FluTheme.primaryColor - } - FluText{ - text:(date.getMonth()+1)+"月" - anchors.centerIn: parent - color: { - if(isMonth){ - return "#FFFFFF" - } - if(isYear){ - return FluTheme.dark ? "#FFFFFF" : "#1A1A1A" - } - return Qt.rgba(150/255,150/255,150/255,1) - } - } - } - contentItem: Item{} - } - } - Component{ - id:com_day - Button{ - id:item_control - property bool isMonth: control.date.getMonth() === date.getMonth() - property bool isDay: control.currentDate.getFullYear() === date.getFullYear() && control.currentDate.getMonth() === date.getMonth() && control.currentDate.getDate() === date.getDate() - property bool isToDay: control.toDay.getFullYear() === date.getFullYear() && control.toDay.getMonth() === date.getMonth() && control.toDay.getDate() === date.getDate() - height: 40 - width: 40 - onClicked: { - currentDate = date - control.dateClicked(date) - } - background: Item{ - Rectangle{ - width: 36 - height: 36 - radius: 4 - anchors.centerIn: parent - color:{ - if(FluTheme.dark){ - if(item_control.hovered){ - return Qt.rgba(1,1,1,0.05) - } - return Qt.rgba(0,0,0,0) - }else{ - if(item_control.hovered){ - return Qt.rgba(0,0,0,0.05) - } - return Qt.rgba(0,0,0,0) - } - } - } - Rectangle{ - id:backgound_today - anchors.centerIn: parent - width: 36 - height: 36 - radius: 18 - color:"#00000000" - visible: isDay - border.color: FluTheme.primaryColor - border.width: 1 - } - Rectangle{ - id:backgound_selected - anchors.centerIn: parent - width: 30 - height: 30 - radius: 15 - visible: isToDay - color: FluTheme.primaryColor - } - FluText{ - text:date.getDate() - anchors.centerIn: parent - color: { - if(isToDay){ - return "#FFFFFF" - } - if(isMonth){ - return FluTheme.dark ? "#FFFFFF" : "#1A1A1A" - } - return Qt.rgba(150/255,150/255,150/255,1) - } - } - } - contentItem: Item{} - } - } - FluArea{ - anchors.fill: parent - radius: control.radius - Rectangle{ - id:layout_divider - height: 1 - width: parent.width - color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1) - anchors{ - top: parent.top - topMargin: 44 - } - } - Item{ - id:layout_top - anchors{ - left: parent.left - right: parent.right - top: parent.top - bottom: layout_divider.top - } - FluTextButton{ - id:title - anchors{ - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: 14 - } - disabled: displayMode === FluCalendarViewType.Decade - onClicked:{ - if(displayMode === FluCalendarViewType.Month){ - displayMode = FluCalendarViewType.Year - updateYear(date) - }else if(displayMode === FluCalendarViewType.Year){ - displayMode = FluCalendarViewType.Decade - updateDecade(date) - } - } - } - FluIconButton{ - id:icon_up - iconSource: FluentIcons.CaretUpSolid8 - iconSize: 10 - anchors{ - verticalCenter: parent.verticalCenter - right: icon_down.left - rightMargin: 14 - } - onClicked: { - var year = date.getFullYear() - var month = date.getMonth() - if(displayMode === FluCalendarViewType.Month){ - var lastMonthYear = year; - var lastMonthMonth = month - 1 - if (month === 0) { - lastMonthYear = year - 1 - lastMonthMonth = 11 - } - date = new Date(lastMonthYear,lastMonthMonth,1) - updateMouth(date) - }else if(displayMode === FluCalendarViewType.Year){ - date = new Date(year-1,month,1) - updateYear(date) - }else if(displayMode === FluCalendarViewType.Decade){ - date = new Date(Math.floor(year / 10) * 10-10,month,1) - updateDecade(date) - } - } - } - FluIconButton{ - id:icon_down - iconSource: FluentIcons.CaretDownSolid8 - iconSize: 10 - anchors{ - verticalCenter: parent.verticalCenter - right: parent.right - rightMargin: 8 - } - onClicked: { - var year = date.getFullYear() - var month = date.getMonth() - if(displayMode === FluCalendarViewType.Month){ - var nextMonthYear = year - var nextMonth = month + 1 - if (month === 11) { - nextMonthYear = year + 1 - nextMonth = 0 - } - date = new Date(nextMonthYear,nextMonth,1) - updateMouth(date) - }else if(displayMode === FluCalendarViewType.Year){ - date = new Date(year+1,month,1) - updateYear(date) - }else if(displayMode === FluCalendarViewType.Decade){ - date = new Date(Math.floor(year / 10) * 10+10,month,1) - updateDecade(date) - } - } - } - } - ListModel { - id:list_model - } - Item{ - id:layout_bottom - anchors{ - left: parent.left - right: parent.right - top: layout_divider.bottom - bottom: parent.bottom - } - GridView{ - model: list_model - anchors.fill: parent - cellHeight: displayMode === FluCalendarViewType.Month ? 40 : 70 - cellWidth: displayMode === FluCalendarViewType.Month ? 40 : 70 - clip: true - boundsBehavior:Flickable.StopAtBounds - delegate: FluLoader{ - property var modelData : model - property var name : model.name - property var date : model.date - property var isDecade: { - return model.isDecade - } - sourceComponent: { - if(model.type === 0){ - return com_week - } - if(model.type === 1){ - return com_day - } - if(model.type === 2){ - return com_month - } - if(model.type === 3){ - return com_year - } - return com_day - } - } - } - } - } - function createItemWeek(name){ - return {type:0,date:new Date(),name:name,isDecade:false} - } - function createItemDay(date){ - return {type:1,date:date,name:"",isDecade:false} - } - function createItemMonth(date){ - return {type:2,date:date,name:"",isDecade:false} - } - function createItemYear(date,isDecade){ - return {type:3,date:date,name:"",isDecade:isDecade} - } - function updateDecade(date){ - list_model.clear() - var year = date.getFullYear() - const decadeStart = Math.floor(year / 10) * 10; - for(var i = decadeStart ; i< decadeStart+10 ; i++){ - list_model.append(createItemYear(new Date(i,0,1),true)); - } - for(var j = decadeStart+10 ; j< decadeStart+16 ; j++){ - list_model.append(createItemYear(new Date(j,0,1),false)); - } - title.text = decadeStart+"-"+(decadeStart+10) - } - function updateYear(date){ - list_model.clear() - var year = date.getFullYear() - for(var i = 0 ; i< 12 ; i++){ - list_model.append(createItemMonth(new Date(year,i))); - } - for(var j = 0 ; j< 4 ; j++){ - list_model.append(createItemMonth(new Date(year+1,j))); - } - title.text = year+"年" - } - function updateMouth(date){ - list_model.clear() - list_model.append([createItemWeek("一"),createItemWeek("二"),createItemWeek("三"),createItemWeek("四"),createItemWeek("五"),createItemWeek("六"),createItemWeek("日")]) - var year = date.getFullYear() - var month = date.getMonth() - var day = date.getDate() - var firstDayOfMonth = new Date(year, month, 1) - var dayOfWeek = firstDayOfMonth.getDay() - var headerSize = (dayOfWeek===0?7:dayOfWeek)-1 - if(headerSize!==0){ - var lastMonthYear = year; - var lastMonthMonth = month - 1 - if (month === 0) { - lastMonthYear = year - 1 - lastMonthMonth = 11 - } - var lastMonthDays = new Date(lastMonthYear, lastMonthMonth+1, 0).getDate() - for (var i = headerSize-1; i >= 0; i--) { - list_model.append(createItemDay(new Date(lastMonthYear, lastMonthMonth,lastMonthDays-i))) - } - } - const lastDayOfMonth = new Date(year, month+1, 0).getDate() - for (let day = 1; day <= lastDayOfMonth; day++) { - list_model.append(createItemDay(new Date(year, month,day))) - } - var footerSize = 49-list_model.count - var nextMonthYear = year - var nextMonth = month + 1 - if (month === 11) { - nextMonthYear = year + 1 - nextMonth = 0 - } - const nextDayOfMonth = new Date(nextMonthYear, nextMonth+1, 0).getDate() - for (let j = 1; j <= footerSize; j++) { - list_model.append(createItemDay(new Date(nextMonthYear, nextMonth,j))) - } - title.text = year+"年"+(month+1)+"月" - } -} diff --git a/src/Qt5/imports/FluentUI/plugins.qmltypes b/src/Qt5/imports/FluentUI/plugins.qmltypes index ca5f7803..7c00c2c9 100644 --- a/src/Qt5/imports/FluentUI/plugins.qmltypes +++ b/src/Qt5/imports/FluentUI/plugins.qmltypes @@ -2313,87 +2313,6 @@ Module { Property { name: "targetRect"; type: "QRectF" } Property { name: "target"; type: "QQuickItem"; isPointer: true } } - Component { - prototype: "QQuickRectangle" - name: "FluentUI/FluAppBar 1.0" - exports: ["FluentUI/FluAppBar 1.0"] - exportMetaObjectRevisions: [0] - isComposite: true - defaultProperty: "data" - Property { name: "title"; type: "string" } - Property { name: "darkText"; type: "string" } - Property { name: "lightText"; type: "string" } - Property { name: "minimizeText"; type: "string" } - Property { name: "restoreText"; type: "string" } - Property { name: "maximizeText"; type: "string" } - Property { name: "closeText"; type: "string" } - Property { name: "stayTopText"; type: "string" } - Property { name: "stayTopCancelText"; type: "string" } - Property { name: "textColor"; type: "QColor" } - Property { name: "minimizeNormalColor"; type: "QColor" } - Property { name: "minimizeHoverColor"; type: "QColor" } - Property { name: "minimizePressColor"; type: "QColor" } - Property { name: "maximizeNormalColor"; type: "QColor" } - Property { name: "maximizeHoverColor"; type: "QColor" } - Property { name: "maximizePressColor"; type: "QColor" } - Property { name: "closeNormalColor"; type: "QColor" } - Property { name: "closeHoverColor"; type: "QColor" } - Property { name: "closePressColor"; type: "QColor" } - Property { name: "showDark"; type: "bool" } - Property { name: "showClose"; type: "bool" } - Property { name: "showMinimize"; type: "bool" } - Property { name: "showMaximize"; type: "bool" } - Property { name: "showStayTop"; type: "bool" } - Property { name: "titleVisible"; type: "bool" } - Property { name: "icon"; type: "QUrl" } - Property { name: "iconSize"; type: "int" } - Property { name: "isMac"; type: "bool" } - Property { name: "borerlessColor"; type: "QColor" } - Property { name: "systemMoveEnable"; type: "bool" } - Property { name: "maxClickListener"; type: "QVariant" } - Property { name: "minClickListener"; type: "QVariant" } - Property { name: "closeClickListener"; type: "QVariant" } - Property { name: "stayTopClickListener"; type: "QVariant" } - Property { name: "darkClickListener"; type: "QVariant" } - Property { name: "systemMenuListener"; type: "QVariant" } - Property { - name: "buttonStayTop" - type: "FluIconButton_QMLTYPE_17" - isReadonly: true - isPointer: true - } - Property { - name: "buttonMinimize" - type: "FluIconButton_QMLTYPE_17" - isReadonly: true - isPointer: true - } - Property { - name: "buttonMaximize" - type: "FluIconButton_QMLTYPE_17" - isReadonly: true - isPointer: true - } - Property { - name: "buttonClose" - type: "FluIconButton_QMLTYPE_17" - isReadonly: true - isPointer: true - } - Property { - name: "buttonDark" - type: "FluIconButton_QMLTYPE_17" - isReadonly: true - isPointer: true - } - Method { name: "_maximizeButtonHover"; type: "QVariant" } - Method { name: "_appBarHover"; type: "QVariant" } - Method { - name: "setHitTestVisible" - type: "QVariant" - Parameter { name: "id"; type: "QVariant" } - } - } Component { prototype: "QQuickRectangle" name: "FluentUI/FluArea 1.0" @@ -2418,22 +2337,11 @@ Module { Property { name: "items"; type: "QVariant" } Property { name: "emptyText"; type: "string" } Property { name: "autoSuggestBoxReplacement"; type: "int" } + Property { name: "filter"; type: "QVariant" } Signal { name: "itemClicked" Parameter { name: "data"; type: "QVariant" } } - Signal { name: "handleClicked" } - Method { - name: "handleClick" - type: "QVariant" - Parameter { name: "modelData"; type: "QVariant" } - } - Method { - name: "updateText" - type: "QVariant" - Parameter { name: "text"; type: "QVariant" } - } - Method { name: "loadData"; type: "QVariant" } Property { name: "disabled"; type: "bool" } Property { name: "iconSource"; type: "int" } Property { name: "normalColor"; type: "QColor" } @@ -2510,59 +2418,6 @@ Module { Property { name: "current"; type: "QVariant" } Signal { name: "accepted" } } - Component { - prototype: "QQuickItem" - name: "FluentUI/FluCalendarView 1.0" - exports: ["FluentUI/FluCalendarView 1.0"] - exportMetaObjectRevisions: [0] - isComposite: true - defaultProperty: "data" - Property { name: "displayMode"; type: "int" } - Property { name: "date"; type: "QVariant" } - Property { name: "currentDate"; type: "QVariant" } - Property { name: "toDay"; type: "QVariant" } - Property { name: "radius"; type: "int" } - Signal { - name: "dateClicked" - Parameter { name: "date"; type: "QVariant" } - } - Method { - name: "createItemWeek" - type: "QVariant" - Parameter { name: "name"; type: "QVariant" } - } - Method { - name: "createItemDay" - type: "QVariant" - Parameter { name: "date"; type: "QVariant" } - } - Method { - name: "createItemMonth" - type: "QVariant" - Parameter { name: "date"; type: "QVariant" } - } - Method { - name: "createItemYear" - type: "QVariant" - Parameter { name: "date"; type: "QVariant" } - Parameter { name: "isDecade"; type: "QVariant" } - } - Method { - name: "updateDecade" - type: "QVariant" - Parameter { name: "date"; type: "QVariant" } - } - Method { - name: "updateYear" - type: "QVariant" - Parameter { name: "date"; type: "QVariant" } - } - Method { - name: "updateMouth" - type: "QVariant" - Parameter { name: "date"; type: "QVariant" } - } - } Component { prototype: "QQuickItem" name: "FluentUI/FluCarousel 1.0" @@ -3053,15 +2908,15 @@ Module { defaultProperty: "data" Property { name: "logo"; type: "QUrl" } Property { name: "title"; type: "string" } - Property { name: "items"; type: "FluObject_QMLTYPE_129"; isPointer: true } - Property { name: "footerItems"; type: "FluObject_QMLTYPE_129"; isPointer: true } + Property { name: "items"; type: "FluObject_QMLTYPE_139"; isPointer: true } + Property { name: "footerItems"; type: "FluObject_QMLTYPE_139"; isPointer: true } Property { name: "displayMode"; type: "int" } Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true } Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true } Property { name: "topPadding"; type: "int" } Property { name: "pageMode"; type: "int" } - Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_31"; isPointer: true } - Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_31"; isPointer: true } + Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_35"; isPointer: true } + Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_35"; isPointer: true } Property { name: "navCompactWidth"; type: "int" } Property { name: "navTopMargin"; type: "int" } Property { name: "cellHeight"; type: "int" } @@ -3869,96 +3724,4 @@ Module { Method { name: "allExpand"; type: "QVariant" } Method { name: "allCollapse"; type: "QVariant" } } - Component { - prototype: "QQuickWindowQmlImpl" - name: "FluentUI/FluWindow 1.0" - exports: ["FluentUI/FluWindow 1.0"] - exportMetaObjectRevisions: [0] - isComposite: true - defaultProperty: "contentData" - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "windowIcon"; type: "string" } - Property { name: "launchMode"; type: "int" } - Property { name: "argument"; type: "QVariant" } - Property { name: "background"; type: "QVariant" } - Property { name: "fixSize"; type: "bool" } - Property { name: "loadingItem"; type: "QQmlComponent"; isPointer: true } - Property { name: "fitsAppBarWindows"; type: "bool" } - Property { name: "appBar"; type: "QQuickItem"; isPointer: true } - Property { name: "backgroundColor"; type: "QColor" } - Property { name: "stayTop"; type: "bool" } - Property { name: "showDark"; type: "bool" } - Property { name: "showClose"; type: "bool" } - Property { name: "showMinimize"; type: "bool" } - Property { name: "showMaximize"; type: "bool" } - Property { name: "showStayTop"; type: "bool" } - Property { name: "autoMaximize"; type: "bool" } - Property { name: "autoVisible"; type: "bool" } - Property { name: "autoCenter"; type: "bool" } - Property { name: "autoDestory"; type: "bool" } - Property { name: "useSystemAppBar"; type: "bool" } - Property { name: "resizeBorderColor"; type: "QColor" } - Property { name: "resizeBorderWidth"; type: "int" } - Property { name: "closeListener"; type: "QVariant" } - Property { name: "_realHeight"; type: "int" } - Property { name: "_realWidth"; type: "int" } - Property { name: "_appBarHeight"; type: "int" } - Property { name: "_windowRegister"; type: "QVariant" } - Property { name: "_route"; type: "string" } - Signal { name: "showSystemMenu" } - Signal { - name: "initArgument" - Parameter { name: "argument"; type: "QVariant" } - } - Signal { name: "firstVisible" } - Method { name: "destoryOnClose"; type: "QVariant" } - Method { - name: "showLoading" - type: "QVariant" - Parameter { name: "text"; type: "QVariant" } - Parameter { name: "cancel"; type: "QVariant" } - } - Method { name: "hideLoading"; type: "QVariant" } - Method { - name: "showSuccess" - type: "QVariant" - Parameter { name: "text"; type: "QVariant" } - Parameter { name: "duration"; type: "QVariant" } - Parameter { name: "moremsg"; type: "QVariant" } - } - Method { - name: "showInfo" - type: "QVariant" - Parameter { name: "text"; type: "QVariant" } - Parameter { name: "duration"; type: "QVariant" } - Parameter { name: "moremsg"; type: "QVariant" } - } - Method { - name: "showWarning" - type: "QVariant" - Parameter { name: "text"; type: "QVariant" } - Parameter { name: "duration"; type: "QVariant" } - Parameter { name: "moremsg"; type: "QVariant" } - } - Method { - name: "showError" - type: "QVariant" - Parameter { name: "text"; type: "QVariant" } - Parameter { name: "duration"; type: "QVariant" } - Parameter { name: "moremsg"; type: "QVariant" } - } - Method { name: "moveWindowToDesktopCenter"; type: "QVariant" } - Method { name: "fixWindowSize"; type: "QVariant" } - Method { - name: "registerForWindowResult" - type: "QVariant" - Parameter { name: "path"; type: "QVariant" } - } - Method { - name: "onResult" - type: "QVariant" - Parameter { name: "data"; type: "QVariant" } - } - Method { name: "showMaximized"; type: "QVariant" } - } } diff --git a/src/Qt5/imports/FluentUI/qmldir b/src/Qt5/imports/FluentUI/qmldir index 0c9327da..7d2bd41d 100644 --- a/src/Qt5/imports/FluentUI/qmldir +++ b/src/Qt5/imports/FluentUI/qmldir @@ -11,7 +11,6 @@ FluBadge 1.0 Controls/FluBadge.qml FluBreadcrumbBar 1.0 Controls/FluBreadcrumbBar.qml FluButton 1.0 Controls/FluButton.qml FluCalendarPicker 1.0 Controls/FluCalendarPicker.qml -FluCalendarView 1.0 Controls/FluCalendarView.qml FluCarousel 1.0 Controls/FluCarousel.qml FluChart 1.0 Controls/FluChart.qml FluCheckBox 1.0 Controls/FluCheckBox.qml diff --git a/src/Qt5/imports/fluentui.qrc b/src/Qt5/imports/fluentui.qrc index 356791ef..21972b2a 100644 --- a/src/Qt5/imports/fluentui.qrc +++ b/src/Qt5/imports/fluentui.qrc @@ -11,7 +11,6 @@ FluentUI/Controls/FluBreadcrumbBar.qml FluentUI/Controls/FluButton.qml FluentUI/Controls/FluCalendarPicker.qml - FluentUI/Controls/FluCalendarView.qml FluentUI/Controls/FluCarousel.qml FluentUI/Controls/FluChart.qml FluentUI/Controls/FluCheckBox.qml diff --git a/src/Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml b/src/Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml index 0a57c66b..3417e0b2 100644 --- a/src/Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml +++ b/src/Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml @@ -8,7 +8,7 @@ Rectangle { property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/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 normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) - property string text: qsTr("Please select a date") + property string text: qsTr("Pick a date") property var current signal accepted() id:control @@ -23,15 +23,6 @@ Rectangle { radius: 4 border.width: 1 border.color: dividerColor - Component.onCompleted: { - if(current){ - const date = current - var year = date.getFullYear() - var month = date.getMonth() - var day = date.getDate() - text_date.text = year+"-"+(month+1)+"-"+day - } - } MouseArea{ id:mouse_area hoverEnabled: true @@ -40,9 +31,25 @@ Rectangle { popup.showPopup() } } + CalendarModel { + id:calender_model + from: new Date(1924, 0, 1) + to: new Date(2124, 11, 31) + } Item{ id:d property var window : Window.window + property date displayDate: { + if(control.current){ + return control.current + } + return new Date() + } + property date toDay : new Date() + property int pageIndex: 0 + signal nextButton + signal previousButton + property point yearRing : Qt.point(0,0) } FluText{ id:text_date @@ -55,7 +62,12 @@ Rectangle { } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - text:control.text + text:{ + if(control.current){ + return control.current.toLocaleDateString(FluApp.locale,"yyyy/M/d") + } + return control.text + } } FluIcon{ iconSource: FluentIcons.Calendar @@ -92,18 +104,548 @@ Rectangle { } contentItem: Item{ clip: true - FluCalendarView{ + FluArea{ id:container - onDateClicked: - (date)=>{ - popup.close() - var year = date.getFullYear() - var month = date.getMonth() - var day = date.getDate() - text_date.text = year+"-"+(month+1)+"-"+day - current= date - control.accepted() + width: 300 + height: 360 + ColumnLayout { + anchors.fill: parent + spacing: 0 + Item{ + Layout.fillWidth: true + Layout.preferredHeight: 50 + RowLayout{ + anchors.fill: parent + spacing: 10 + Item{ + Layout.leftMargin: parent.spacing + Layout.fillWidth: true + Layout.fillHeight: true + FluTextButton{ + width: parent.width + anchors.centerIn: parent + contentItem: FluText { + text: d.displayDate.toLocaleString(FluApp.locale, "MMMM yyyy") + verticalAlignment: Text.AlignVCenter + } + visible: d.pageIndex === 0 + onClicked: { + d.pageIndex = 1 + } + } + FluTextButton{ + width: parent.width + anchors.centerIn: parent + contentItem: FluText { + text: d.displayDate.toLocaleString(FluApp.locale, "yyyy") + verticalAlignment: Text.AlignVCenter + } + visible: d.pageIndex === 1 + onClicked: { + d.pageIndex = 2 + } + } + FluTextButton{ + width: parent.width + anchors.centerIn: parent + contentItem: FluText { + text: "%1-%2".arg(d.yearRing.x).arg(d.yearRing.y) + verticalAlignment: Text.AlignVCenter + textColor: FluTheme.fontTertiaryColor + } + visible: d.pageIndex === 2 + } + } + FluIconButton{ + id:icon_up + iconSource: FluentIcons.CaretUpSolid8 + iconSize: 10 + onClicked: { + d.previousButton() + } + } + FluIconButton{ + id:icon_down + iconSource: FluentIcons.CaretDownSolid8 + iconSize: 10 + Layout.rightMargin: parent.spacing + onClicked: { + d.nextButton() + } + } + } + FluDivider{ + width: parent.width + height: 1 + anchors.bottom: parent.bottom + } } + Item{ + Layout.fillWidth: true + Layout.fillHeight: true + StackView{ + id:stack_view + anchors.fill: parent + initialItem: com_page_one + replaceEnter : Transition{ + OpacityAnimator{ + from: 0 + to: 1 + duration: 88 + } + ScaleAnimator{ + from: 0.5 + to: 1 + duration: 167 + easing.type: Easing.OutCubic + } + } + replaceExit : Transition{ + OpacityAnimator{ + from: 1 + to: 0 + duration: 88 + } + ScaleAnimator{ + from: 1.0 + to: 0.5 + duration: 167 + easing.type: Easing.OutCubic + } + } + } + Connections{ + target: d + function onPageIndexChanged(){ + if(d.pageIndex === 0){ + stack_view.replace(com_page_one) + } + if(d.pageIndex === 1){ + stack_view.replace(com_page_two) + } + if(d.pageIndex === 2){ + stack_view.replace(com_page_three) + } + } + } + Component{ + id:com_page_three + GridView{ + id:grid_view + cellHeight: 75 + cellWidth: 75 + clip: true + boundsBehavior: GridView.StopAtBounds + ScrollBar.vertical: FluScrollBar {} + model: { + var fromYear = calender_model.from.getFullYear() + var toYear = calender_model.to.getFullYear() + return toYear-fromYear+1 + } + snapMode: GridView.SnapOneRow + highlightRangeMode: GridView.StrictlyEnforceRange + onCurrentIndexChanged:{ + var year = currentIndex + calender_model.from.getFullYear() + var start = Math.ceil(year / 10) * 10 + var end = start+10 + d.yearRing = Qt.point(start,end) + } + highlightMoveDuration: 100 + Component.onCompleted: { + grid_view.highlightMoveDuration = 0 + currentIndex = d.displayDate.getFullYear()-calender_model.from.getFullYear() + timer_delay.restart() + } + Connections{ + target: d + function onNextButton(){ + grid_view.currentIndex = Math.min(grid_view.currentIndex+16,grid_view.count-1) + } + function onPreviousButton(){ + grid_view.currentIndex = Math.max(grid_view.currentIndex-16,0) + } + } + Timer{ + id:timer_delay + interval: 100 + onTriggered: { + grid_view.highlightMoveDuration = 100 + } + } + currentIndex: -1 + delegate: Item{ + property int year : calender_model.from.getFullYear()+modelData + property bool toYear: year === d.toDay.getFullYear() + implicitHeight: 75 + implicitWidth: 75 + FluControl{ + id:control_delegate + width: 60 + height: 60 + anchors.centerIn: parent + Rectangle{ + width: 48 + height: 48 + radius: width/2 + color: { + if(toYear){ + if(control_delegate.pressed){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2) + } + if(control_delegate.hovered){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1) + } + return FluTheme.primaryColor + }else{ + if(control_delegate.pressed){ + return FluTheme.itemPressColor + } + if(control_delegate.hovered){ + return FluTheme.itemHoverColor + } + return FluColors.Transparent + } + } + anchors.centerIn: parent + } + + FluText{ + text: year + anchors.centerIn: parent + opacity: { + if(year >= d.yearRing.x && year <= d.yearRing.y){ + return 1 + } + if(control_delegate.hovered){ + return 1 + } + return 0.3 + } + color: { + if(toYear){ + return FluColors.White + } + if(control_delegate.pressed){ + return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100 + } + if(control_delegate.hovered){ + return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 + } + return FluTheme.dark ? FluColors.White : FluColors.Grey220 + } + } + onClicked: { + d.displayDate = new Date(year,0,1) + d.pageIndex = 1 + } + } + } + } + } + Component{ + id:com_page_two + + ListView{ + id:listview + ScrollBar.vertical: FluScrollBar {} + snapMode: ListView.SnapOneItem + highlightRangeMode: ListView.StrictlyEnforceRange + clip: true + boundsBehavior: ListView.StopAtBounds + spacing: 0 + highlightMoveDuration: 100 + model: { + var fromYear = calender_model.from.getFullYear() + var toYear = calender_model.to.getFullYear() + var yearsArray = [] + for (var i = fromYear; i <= toYear; i++) { + yearsArray.push(i) + } + return yearsArray + } + currentIndex: -1 + onCurrentIndexChanged:{ + var year = model[currentIndex] + var month = d.displayDate.getMonth() + d.displayDate = new Date(year,month,1) + } + Connections{ + target: d + function onNextButton(){ + listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1) + } + function onPreviousButton(){ + listview.currentIndex = Math.max(listview.currentIndex-1,0) + } + } + Component.onCompleted: { + listview.highlightMoveDuration = 0 + currentIndex = model.indexOf(d.displayDate.getFullYear()) + timer_delay.restart() + } + Timer{ + id:timer_delay + interval: 100 + onTriggered: { + listview.highlightMoveDuration = 100 + } + } + delegate: Item{ + id:layout_congrol + property int year : modelData + width: listview.width + height: 75*3 + GridView{ + anchors.fill: parent + cellHeight: 75 + cellWidth: 75 + clip: true + interactive: false + boundsBehavior: GridView.StopAtBounds + model: 12 + delegate: Item{ + property int month : modelData + property bool toMonth: layout_congrol.year === d.toDay.getFullYear() && month === d.toDay.getMonth() + implicitHeight: 75 + implicitWidth: 75 + FluControl{ + id:control_delegate + width: 60 + height: 60 + anchors.centerIn: parent + Rectangle{ + width: 48 + height: 48 + radius: width/2 + color: { + if(toMonth){ + if(control_delegate.pressed){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2) + } + if(control_delegate.hovered){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1) + } + return FluTheme.primaryColor + }else{ + if(control_delegate.pressed){ + return FluTheme.itemPressColor + } + if(control_delegate.hovered){ + return FluTheme.itemHoverColor + } + return FluColors.Transparent + } + } + anchors.centerIn: parent + } + FluText{ + text: new Date(layout_congrol.year,month).toLocaleString(FluApp.locale, "MMMM") + anchors.centerIn: parent + opacity: { + if(layout_congrol.year === d.displayDate.getFullYear()){ + return 1 + } + if(control_delegate.hovered){ + return 1 + } + return 0.3 + } + color: { + if(toMonth){ + return FluColors.White + } + if(control_delegate.pressed){ + return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100 + } + if(control_delegate.hovered){ + return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 + } + return FluTheme.dark ? FluColors.White : FluColors.Grey220 + } + } + onClicked: { + d.displayDate = new Date(layout_congrol.year,month) + timer_delay_start.restart() + } + Timer{ + id:timer_delay_start + interval: 100 + onTriggered: { + d.pageIndex = 0 + } + } + } + } + } + } + } + } + Component{ + id:com_page_one + ColumnLayout { + DayOfWeekRow { + id: dayOfWeekRow + locale: FluApp.locale + font.bold: false + delegate: Label { + text: model.shortName + font: dayOfWeekRow.font + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + Layout.column: 1 + Layout.fillWidth: true + } + ListView{ + id:listview + property bool isCompleted: false + snapMode: ListView.SnapOneItem + Layout.fillWidth: true + Layout.fillHeight: true + highlightRangeMode: ListView.StrictlyEnforceRange + clip: true + boundsBehavior: ListView.StopAtBounds + spacing: 0 + highlightMoveDuration: 100 + currentIndex: -1 + ScrollBar.vertical: FluScrollBar {} + onCurrentIndexChanged:{ + if(isCompleted){ + var month = calender_model.monthAt(currentIndex) + var year = calender_model.yearAt(currentIndex) + d.displayDate = new Date(year,month,1) + } + } + Component.onCompleted: { + listview.model = calender_model + listview.highlightMoveDuration = 0 + currentIndex = calender_model.indexOf(d.displayDate) + timer_delay.restart() + isCompleted = true + } + Timer{ + id:timer_delay + interval: 100 + onTriggered: { + listview.highlightMoveDuration = 100 + } + } + Connections{ + target: d + function onNextButton(){ + listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1) + } + function onPreviousButton(){ + listview.currentIndex = Math.max(listview.currentIndex-1,0) + } + } + delegate: MonthGrid { + id: grid + width: listview.width + height: listview.height + month: model.month + year: model.year + spacing: 0 + locale: FluApp.locale + delegate: FluControl { + required property bool today + required property int year + required property int month + required property int day + required property int visibleMonth + id: control_delegate + visibleMonth: grid.month + implicitHeight: 40 + implicitWidth: 40 + Rectangle{ + width: 34 + height: 34 + radius: width/2 + color: { + if(today){ + if(control_delegate.pressed){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2) + } + if(control_delegate.hovered){ + return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1) + } + return FluTheme.primaryColor + }else{ + if(control_delegate.pressed){ + return FluTheme.itemPressColor + } + if(control_delegate.hovered){ + return FluTheme.itemHoverColor + } + return FluColors.Transparent + } + } + anchors.centerIn: parent + } + Rectangle{ + width: 40 + height: 40 + border.width: 1 + anchors.centerIn: parent + radius: width/2 + border.color: FluTheme.primaryColor + color: FluColors.Transparent + visible: { + if(control.current){ + var y = control.current.getFullYear() + var m = control.current.getMonth() + var d = control.current.getDate() + if(y === year && m === month && d === day){ + return true + } + return false + } + return false + } + } + FluText{ + text: day + opacity: { + if(month === grid.month){ + return 1 + } + if(control_delegate.hovered){ + return 1 + } + return 0.3 + } + anchors.centerIn: parent + color: { + if(today){ + return FluColors.White + } + if(control_delegate.pressed){ + return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100 + } + if(control_delegate.hovered){ + return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 + } + return FluTheme.dark ? FluColors.White : FluColors.Grey220 + } + } + onClicked: { + control.current = new Date(year,month,day) + control.accepted() + popup.close() + } + } + background: Item { + x: grid.leftPadding + y: grid.topPadding + width: grid.availableWidth + height: grid.availableHeight + } + } + } + } + } + } + } } } background: Item{ @@ -112,11 +654,6 @@ Rectangle { } } function showPopup() { - if(current){ - container.currentDate = current - container.date = current - container.updateMouth(current) - } var pos = control.mapToItem(null, 0, 0) if(d.window.height>pos.y+control.height+container.height){ popup.y = control.height diff --git a/src/Qt6/imports/FluentUI/Controls/FluCalendarView.qml b/src/Qt6/imports/FluentUI/Controls/FluCalendarView.qml deleted file mode 100644 index 50d293fc..00000000 --- a/src/Qt6/imports/FluentUI/Controls/FluCalendarView.qml +++ /dev/null @@ -1,433 +0,0 @@ -import QtQuick -import QtQuick.Controls -import FluentUI - -Item { - property int displayMode: FluCalendarViewType.Month - property var date: new Date() - property var currentDate : new Date() - property var toDay: new Date() - property int radius: 5 - signal dateClicked(var date) - id:control - width: 280 - height: 325 - Component.onCompleted: { - updateMouth(date) - } - Component{ - id:com_week - Item{ - height: 40 - width: 40 - FluText{ - text:name - anchors.centerIn: parent - } - } - } - Component{ - id:com_year - Button{ - id:item_control - property bool isYear: control.toDay.getFullYear() === date.getFullYear() - height: 70 - width: 70 - onClicked:{ - control.date = date - displayMode = FluCalendarViewType.Year - updateYear(date) - } - background: Item{ - Rectangle{ - width: 60 - height: 60 - radius: 4 - anchors.centerIn: parent - color:{ - if(FluTheme.dark){ - if(item_control.hovered){ - return Qt.rgba(1,1,1,0.05) - } - return Qt.rgba(0,0,0,0) - }else{ - if(item_control.hovered){ - return Qt.rgba(0,0,0,0.05) - } - return Qt.rgba(0,0,0,0) - } - } - } - Rectangle{ - id:backgound_selected - anchors.centerIn: parent - width: 50 - height: 50 - radius: 25 - visible: isYear - color: FluTheme.primaryColor - } - FluText{ - text:date.getFullYear() - anchors.centerIn: parent - color: { - if(isYear){ - return "#FFFFFF" - } - if(isDecade){ - return FluTheme.dark ? "#FFFFFF" : "#1A1A1A" - } - return Qt.rgba(150/255,150/255,150/255,1) - } - } - } - contentItem: Item{} - } - } - Component{ - id:com_month - Button{ - id:item_control - property bool isYear: control.date.getFullYear() === date.getFullYear() - property bool isMonth: control.toDay.getFullYear() === date.getFullYear() && control.toDay.getMonth() === date.getMonth() - height: 70 - width: 70 - onClicked:{ - control.date = date - displayMode = FluCalendarViewType.Month - updateMouth(date) - } - background: Item{ - Rectangle{ - width: 60 - height: 60 - radius: 4 - anchors.centerIn: parent - color:{ - if(FluTheme.dark){ - if(item_control.hovered){ - return Qt.rgba(1,1,1,0.05) - } - return Qt.rgba(0,0,0,0) - }else{ - if(item_control.hovered){ - return Qt.rgba(0,0,0,0.05) - } - return Qt.rgba(0,0,0,0) - } - } - } - Rectangle{ - id:backgound_selected - anchors.centerIn: parent - width: 50 - height: 50 - radius: 25 - visible: isMonth - color: FluTheme.primaryColor - } - FluText{ - text:(date.getMonth()+1)+"月" - anchors.centerIn: parent - color: { - if(isMonth){ - return "#FFFFFF" - } - if(isYear){ - return FluTheme.dark ? "#FFFFFF" : "#1A1A1A" - } - return Qt.rgba(150/255,150/255,150/255,1) - } - } - } - contentItem: Item{} - } - } - Component{ - id:com_day - Button{ - id:item_control - property bool isMonth: control.date.getMonth() === date.getMonth() - property bool isDay: control.currentDate.getFullYear() === date.getFullYear() && control.currentDate.getMonth() === date.getMonth() && control.currentDate.getDate() === date.getDate() - property bool isToDay: control.toDay.getFullYear() === date.getFullYear() && control.toDay.getMonth() === date.getMonth() && control.toDay.getDate() === date.getDate() - height: 40 - width: 40 - onClicked: { - currentDate = date - control.dateClicked(date) - } - background: Item{ - Rectangle{ - width: 36 - height: 36 - radius: 4 - anchors.centerIn: parent - color:{ - if(FluTheme.dark){ - if(item_control.hovered){ - return Qt.rgba(1,1,1,0.05) - } - return Qt.rgba(0,0,0,0) - }else{ - if(item_control.hovered){ - return Qt.rgba(0,0,0,0.05) - } - return Qt.rgba(0,0,0,0) - } - } - } - Rectangle{ - id:backgound_today - anchors.centerIn: parent - width: 36 - height: 36 - radius: 18 - color:"#00000000" - visible: isDay - border.color: FluTheme.primaryColor - border.width: 1 - } - Rectangle{ - id:backgound_selected - anchors.centerIn: parent - width: 30 - height: 30 - radius: 15 - visible: isToDay - color: FluTheme.primaryColor - } - FluText{ - text:date.getDate() - anchors.centerIn: parent - color: { - if(isToDay){ - return "#FFFFFF" - } - if(isMonth){ - return FluTheme.dark ? "#FFFFFF" : "#1A1A1A" - } - return Qt.rgba(150/255,150/255,150/255,1) - } - } - } - contentItem: Item{} - } - } - FluArea{ - anchors.fill: parent - radius: control.radius - Rectangle{ - id:layout_divider - height: 1 - width: parent.width - color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1) - anchors{ - top: parent.top - topMargin: 44 - } - } - Item{ - id:layout_top - anchors{ - left: parent.left - right: parent.right - top: parent.top - bottom: layout_divider.top - } - FluTextButton{ - id:title - anchors{ - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: 14 - } - disabled: displayMode === FluCalendarViewType.Decade - onClicked:{ - if(displayMode === FluCalendarViewType.Month){ - displayMode = FluCalendarViewType.Year - updateYear(date) - }else if(displayMode === FluCalendarViewType.Year){ - displayMode = FluCalendarViewType.Decade - updateDecade(date) - } - } - } - FluIconButton{ - id:icon_up - iconSource: FluentIcons.CaretUpSolid8 - iconSize: 10 - anchors{ - verticalCenter: parent.verticalCenter - right: icon_down.left - rightMargin: 14 - } - onClicked: { - var year = date.getFullYear() - var month = date.getMonth() - if(displayMode === FluCalendarViewType.Month){ - var lastMonthYear = year; - var lastMonthMonth = month - 1 - if (month === 0) { - lastMonthYear = year - 1 - lastMonthMonth = 11 - } - date = new Date(lastMonthYear,lastMonthMonth,1) - updateMouth(date) - }else if(displayMode === FluCalendarViewType.Year){ - date = new Date(year-1,month,1) - updateYear(date) - }else if(displayMode === FluCalendarViewType.Decade){ - date = new Date(Math.floor(year / 10) * 10-10,month,1) - updateDecade(date) - } - } - } - FluIconButton{ - id:icon_down - iconSource: FluentIcons.CaretDownSolid8 - iconSize: 10 - anchors{ - verticalCenter: parent.verticalCenter - right: parent.right - rightMargin: 8 - } - onClicked: { - var year = date.getFullYear() - var month = date.getMonth() - if(displayMode === FluCalendarViewType.Month){ - var nextMonthYear = year - var nextMonth = month + 1 - if (month === 11) { - nextMonthYear = year + 1 - nextMonth = 0 - } - date = new Date(nextMonthYear,nextMonth,1) - updateMouth(date) - }else if(displayMode === FluCalendarViewType.Year){ - date = new Date(year+1,month,1) - updateYear(date) - }else if(displayMode === FluCalendarViewType.Decade){ - date = new Date(Math.floor(year / 10) * 10+10,month,1) - updateDecade(date) - } - } - } - } - ListModel { - id:list_model - } - Item{ - id:layout_bottom - anchors{ - left: parent.left - right: parent.right - top: layout_divider.bottom - bottom: parent.bottom - } - GridView{ - model: list_model - anchors.fill: parent - cellHeight: displayMode === FluCalendarViewType.Month ? 40 : 70 - cellWidth: displayMode === FluCalendarViewType.Month ? 40 : 70 - clip: true - boundsBehavior:Flickable.StopAtBounds - delegate: FluLoader{ - property var modelData : model - property var name : model.name - property var date : model.date - property var isDecade: { - return model.isDecade - } - sourceComponent: { - if(model.type === 0){ - return com_week - } - if(model.type === 1){ - return com_day - } - if(model.type === 2){ - return com_month - } - if(model.type === 3){ - return com_year - } - return com_day - } - } - } - } - } - function createItemWeek(name){ - return {type:0,date:new Date(),name:name,isDecade:false} - } - function createItemDay(date){ - return {type:1,date:date,name:"",isDecade:false} - } - function createItemMonth(date){ - return {type:2,date:date,name:"",isDecade:false} - } - function createItemYear(date,isDecade){ - return {type:3,date:date,name:"",isDecade:isDecade} - } - function updateDecade(date){ - list_model.clear() - var year = date.getFullYear() - const decadeStart = Math.floor(year / 10) * 10; - for(var i = decadeStart ; i< decadeStart+10 ; i++){ - list_model.append(createItemYear(new Date(i,0,1),true)); - } - for(var j = decadeStart+10 ; j< decadeStart+16 ; j++){ - list_model.append(createItemYear(new Date(j,0,1),false)); - } - title.text = decadeStart+"-"+(decadeStart+10) - } - function updateYear(date){ - list_model.clear() - var year = date.getFullYear() - for(var i = 0 ; i< 12 ; i++){ - list_model.append(createItemMonth(new Date(year,i))); - } - for(var j = 0 ; j< 4 ; j++){ - list_model.append(createItemMonth(new Date(year+1,j))); - } - title.text = year+"年" - } - function updateMouth(date){ - list_model.clear() - list_model.append([createItemWeek("一"),createItemWeek("二"),createItemWeek("三"),createItemWeek("四"),createItemWeek("五"),createItemWeek("六"),createItemWeek("日")]) - var year = date.getFullYear() - var month = date.getMonth() - var day = date.getDate() - var firstDayOfMonth = new Date(year, month, 1) - var dayOfWeek = firstDayOfMonth.getDay() - var headerSize = (dayOfWeek===0?7:dayOfWeek)-1 - if(headerSize!==0){ - var lastMonthYear = year; - var lastMonthMonth = month - 1 - if (month === 0) { - lastMonthYear = year - 1 - lastMonthMonth = 11 - } - var lastMonthDays = new Date(lastMonthYear, lastMonthMonth+1, 0).getDate() - for (var i = headerSize-1; i >= 0; i--) { - list_model.append(createItemDay(new Date(lastMonthYear, lastMonthMonth,lastMonthDays-i))) - } - } - const lastDayOfMonth = new Date(year, month+1, 0).getDate() - for (let day = 1; day <= lastDayOfMonth; day++) { - list_model.append(createItemDay(new Date(year, month,day))) - } - var footerSize = 49-list_model.count - var nextMonthYear = year - var nextMonth = month + 1 - if (month === 11) { - nextMonthYear = year + 1 - nextMonth = 0 - } - const nextDayOfMonth = new Date(nextMonthYear, nextMonth+1, 0).getDate() - for (let j = 1; j <= footerSize; j++) { - list_model.append(createItemDay(new Date(nextMonthYear, nextMonth,j))) - } - title.text = year+"年"+(month+1)+"月" - } -} diff --git a/src/fluentuiplugin_en_US.ts b/src/fluentuiplugin_en_US.ts index 3452860e..c35a5e09 100644 --- a/src/fluentuiplugin_en_US.ts +++ b/src/fluentuiplugin_en_US.ts @@ -65,10 +65,14 @@ FluCalendarPicker - Please select a date + + + Pick a date + + FluContentDialog diff --git a/src/fluentuiplugin_zh_CN.ts b/src/fluentuiplugin_zh_CN.ts index de8599be..5cd91207 100644 --- a/src/fluentuiplugin_zh_CN.ts +++ b/src/fluentuiplugin_zh_CN.ts @@ -65,10 +65,14 @@ FluCalendarPicker - Please select a date 请选择日期 + + + Pick a date + 选择日期 + FluContentDialog