update FluCalendarPicker

This commit is contained in:
朱子楚\zhuzi 2024-03-15 00:04:15 +08:00
parent 874e861c64
commit 479e21097c
14 changed files with 1145 additions and 1200 deletions

View File

@ -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())
}

View File

@ -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())
}

View File

@ -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)) {

View File

@ -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:

View File

@ -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");

View File

@ -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

View File

@ -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)+"月"
}
}

View File

@ -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" }
}
}

View File

@ -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

View File

@ -11,7 +11,6 @@
<file>FluentUI/Controls/FluBreadcrumbBar.qml</file>
<file>FluentUI/Controls/FluButton.qml</file>
<file>FluentUI/Controls/FluCalendarPicker.qml</file>
<file>FluentUI/Controls/FluCalendarView.qml</file>
<file>FluentUI/Controls/FluCarousel.qml</file>
<file>FluentUI/Controls/FluChart.qml</file>
<file>FluentUI/Controls/FluCheckBox.qml</file>

View File

@ -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

View File

@ -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)+"月"
}
}

View File

@ -65,10 +65,14 @@
<name>FluCalendarPicker</name>
<message>
<location filename="Qt5/imports/FluentUI/Controls/FluCalendarPicker.qml" line="11"/>
<location filename="Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml" line="11"/>
<source>Please select a date</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml" line="11"/>
<source>Pick a date</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FluContentDialog</name>

View File

@ -65,10 +65,14 @@
<name>FluCalendarPicker</name>
<message>
<location filename="Qt5/imports/FluentUI/Controls/FluCalendarPicker.qml" line="11"/>
<location filename="Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml" line="11"/>
<source>Please select a date</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="Qt6/imports/FluentUI/Controls/FluCalendarPicker.qml" line="11"/>
<source>Pick a date</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FluContentDialog</name>