This commit is contained in:
pika 2025-06-10 17:44:06 +02:00
parent 797c39441f
commit 80e0e90e1d

View file

@ -13,6 +13,38 @@ Column {
property bool isCurrentMonth: true property bool isCurrentMonth: true
property string currentTime: Qt.formatDateTime(new Date(), "HH:mm:ss") property string currentTime: Qt.formatDateTime(new Date(), "HH:mm:ss")
property int currentYear: new Date().getFullYear() property int currentYear: new Date().getFullYear()
property date selectedStartDate: new Date()
property date selectedEndDate: new Date()
property bool isSelectingRange: false
property string dateCalculation: ""
property bool hasSelection: false
function calculateDays() {
if (root.selectedStartDate && root.selectedEndDate) {
const diffTime = Math.abs(root.selectedEndDate - root.selectedStartDate)
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
root.dateCalculation = diffDays + " days"
} else if (root.selectedStartDate) {
const today = new Date()
const diffTime = Math.abs(root.selectedStartDate - today)
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
root.dateCalculation = diffDays + " days"
}
}
function calculateDaysFromReference(referenceDate, targetDate) {
const diffTime = Math.abs(targetDate - referenceDate)
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
root.dateCalculation = diffDays + " days"
}
function resetSelection() {
root.selectedStartDate = new Date()
root.selectedEndDate = new Date()
root.isSelectingRange = false
root.dateCalculation = ""
root.hasSelection = false
}
// Update time every second // Update time every second
Timer { Timer {
@ -24,6 +56,29 @@ Column {
} }
} }
// Date calculation display
Row {
visible: root.hasSelection
anchors.horizontalCenter: parent.horizontalCenter
spacing: Appearance.spacing.small
StyledText {
text: root.dateCalculation
font.pointSize: Appearance.font.size.small
font.family: Appearance.font.family.mono
color: Colours.palette.m3onSurfaceVariant
}
MaterialIcon {
text: "close"
color: Colours.palette.m3onSurfaceVariant
MouseArea {
anchors.fill: parent
onClicked: root.resetSelection()
}
}
}
// Time and Date header // Time and Date header
Column { Column {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@ -131,6 +186,30 @@ Column {
highlightResizeDuration: Appearance.anim.durations.normal highlightResizeDuration: Appearance.anim.durations.normal
highlightResizeVelocity: -1 highlightResizeVelocity: -1
// Add mouse wheel scrolling
MouseArea {
anchors.fill: parent
onWheel: {
if (wheel.angleDelta.y > 0) {
// Going to previous month
if (monthView.currentIndex === 0) {
root.currentYear--
monthView.currentIndex = 11
} else {
monthView.decrementCurrentIndex()
}
} else {
// Going to next month
if (monthView.currentIndex === 11) {
root.currentYear++
monthView.currentIndex = 0
} else {
monthView.incrementCurrentIndex()
}
}
}
}
model: 12 // Show all months model: 12 // Show all months
currentIndex: new Date().getMonth() currentIndex: new Date().getMonth()
@ -166,14 +245,17 @@ Column {
// Add previous month's days // Add previous month's days
const prevMonthLastDay = new Date(root.currentYear, monthView.currentIndex, 0).getDate(); const prevMonthLastDay = new Date(root.currentYear, monthView.currentIndex, 0).getDate();
for (let i = firstDayOfWeek - 1; i > 0; i--) { for (let i = firstDayOfWeek - 1; i > 0; i--) {
const date = new Date(root.currentYear, monthView.currentIndex - 1, prevMonthLastDay - i + 1);
days.push({ days.push({
day: prevMonthLastDay - i + 1, day: prevMonthLastDay - i + 1,
isCurrentMonth: false, isCurrentMonth: false,
isNextMonth: false isNextMonth: false,
date: date
}); });
} }
// Add days of the current month // Add days of the current month
for (let i = 1; i <= daysInMonth; i++) { for (let i = 1; i <= daysInMonth; i++) {
const date = new Date(root.currentYear, monthView.currentIndex, i);
const isToday = i === today.getDate() && const isToday = i === today.getDate() &&
monthView.currentIndex === today.getMonth() && monthView.currentIndex === today.getMonth() &&
root.currentYear === today.getFullYear(); root.currentYear === today.getFullYear();
@ -181,16 +263,19 @@ Column {
day: i, day: i,
isCurrentMonth: true, isCurrentMonth: true,
isToday: isToday, isToday: isToday,
isNextMonth: false isNextMonth: false,
date: date
}); });
} }
// Add next month's days // Add next month's days
const remainingCells = Math.ceil((firstDayOfWeek - 1 + daysInMonth) / 7) * 7 - days.length; const remainingCells = Math.ceil((firstDayOfWeek - 1 + daysInMonth) / 7) * 7 - days.length;
for (let i = 1; i <= remainingCells; i++) { for (let i = 1; i <= remainingCells; i++) {
const date = new Date(root.currentYear, monthView.currentIndex + 1, i);
days.push({ days.push({
day: i, day: i,
isCurrentMonth: false, isCurrentMonth: false,
isNextMonth: true isNextMonth: true,
date: date
}); });
} }
return days; return days;
@ -200,20 +285,58 @@ Column {
width: 30 width: 30
height: 30 height: 30
radius: Appearance.rounding.full radius: Appearance.rounding.full
color: modelData.isToday ? Colours.palette.m3primary : "transparent" color: {
if (modelData.date.getTime() === root.selectedStartDate.getTime()) {
return Colours.palette.m3primary
} else if (modelData.date.getTime() === root.selectedEndDate.getTime()) {
return Colours.palette.m3secondary
} else if (modelData.isToday) {
return Colours.palette.m3tertiary
}
return "transparent"
}
border.width: modelData.isToday ? 2 : 0
border.color: Colours.palette.m3outline
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: function(mouse) {
if (mouse.button === Qt.RightButton) {
root.selectedStartDate = modelData.date
root.hasSelection = true
root.calculateDays()
} else if (mouse.button === Qt.LeftButton) {
if (root.selectedStartDate) {
root.selectedEndDate = modelData.date
root.hasSelection = true
root.calculateDaysFromReference(root.selectedStartDate, modelData.date)
}
}
}
}
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: modelData.day text: modelData.day
font.pointSize: Appearance.font.size.small font.pointSize: Appearance.font.size.small
font.family: Appearance.font.family.mono font.family: Appearance.font.family.mono
color: modelData.isToday ? color: {
Colours.palette.m3onPrimary : if (modelData.date.getTime() === root.selectedStartDate.getTime() ||
modelData.isCurrentMonth ? modelData.date.getTime() === root.selectedEndDate.getTime()) {
Colours.palette.m3onSurface : return Colours.palette.m3onPrimary
modelData.isNextMonth ? } else if (modelData.isToday) {
"#404040" : return Colours.palette.m3onTertiary
"#505050" } else if (modelData.isCurrentMonth) {
return Colours.palette.m3onSurface
} else if (modelData.isNextMonth) {
return "#404040"
} else {
return "#505050"
}
}
} }
} }
} }
@ -226,6 +349,31 @@ Column {
} }
} }
// Usage instructions
Column {
width: 280
anchors.horizontalCenter: parent.horizontalCenter
spacing: Appearance.spacing.small
StyledText {
text: " Usage:"
font.pointSize: Appearance.font.size.smaller
color: "#505050"
}
StyledText {
text: " • Scroll to navigate"
font.pointSize: Appearance.font.size.smaller
color: "#505050"
}
StyledText {
text: " • Right-click = days from/till today"
font.pointSize: Appearance.font.size.smaller
color: "#505050"
}
}
// Reset to current month when popout closes // Reset to current month when popout closes
Connections { Connections {
target: root.parent target: root.parent
@ -235,6 +383,7 @@ Column {
root.currentYear = new Date().getFullYear() root.currentYear = new Date().getFullYear()
root.currentDate = new Date() root.currentDate = new Date()
root.isCurrentMonth = true root.isCurrentMonth = true
root.resetSelection()
} }
} }
} }