CalendarStyle.qml 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2016 The Qt Company Ltd.
  4. ** Contact: https://www.qt.io/licensing/
  5. **
  6. ** This file is part of the Qt Quick Controls module of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and The Qt Company. For licensing terms
  14. ** and conditions see https://www.qt.io/terms-conditions. For further
  15. ** information use the contact form at https://www.qt.io/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 3 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL3 included in the
  21. ** packaging of this file. Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 3 requirements
  23. ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
  24. **
  25. ** GNU General Public License Usage
  26. ** Alternatively, this file may be used under the terms of the GNU
  27. ** General Public License version 2.0 or (at your option) the GNU General
  28. ** Public license version 3 or any later version approved by the KDE Free
  29. ** Qt Foundation. The licenses are as published by the Free Software
  30. ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
  31. ** included in the packaging of this file. Please review the following
  32. ** information to ensure the GNU General Public License requirements will
  33. ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
  34. ** https://www.gnu.org/licenses/gpl-3.0.html.
  35. **
  36. ** $QT_END_LICENSE$
  37. **
  38. ****************************************************************************/
  39. import QtQuick 2.2
  40. import QtQuick.Controls 1.2
  41. import QtQuick.Controls.Private 1.0
  42. /*!
  43. \qmltype CalendarStyle
  44. \inqmlmodule QtQuick.Controls.Styles
  45. \since 5.3
  46. \ingroup controlsstyling
  47. \brief Provides custom styling for \l Calendar.
  48. \section2 Component Map
  49. \image calendarstyle-components-week-numbers.png
  50. The calendar has the following styleable components:
  51. \table
  52. \row \li \image square-white.png
  53. \li \l background
  54. \li Fills the entire control.
  55. \row \li \image square-yellow.png
  56. \li \l navigationBar
  57. \li
  58. \row \li \image square-green.png
  59. \li \l dayOfWeekDelegate
  60. \li One instance per day of week.
  61. \row \li \image square-red.png
  62. \li \l weekNumberDelegate
  63. \li One instance per week.
  64. \row \li \image square-blue.png
  65. \li \l dayDelegate
  66. \li One instance per day of month.
  67. \endtable
  68. \section2 Custom Style Example
  69. \qml
  70. Calendar {
  71. anchors.centerIn: parent
  72. style: CalendarStyle {
  73. gridVisible: false
  74. dayDelegate: Rectangle {
  75. gradient: Gradient {
  76. GradientStop {
  77. position: 0.00
  78. color: styleData.selected ? "#111" : (styleData.visibleMonth && styleData.valid ? "#444" : "#666");
  79. }
  80. GradientStop {
  81. position: 1.00
  82. color: styleData.selected ? "#444" : (styleData.visibleMonth && styleData.valid ? "#111" : "#666");
  83. }
  84. GradientStop {
  85. position: 1.00
  86. color: styleData.selected ? "#777" : (styleData.visibleMonth && styleData.valid ? "#111" : "#666");
  87. }
  88. }
  89. Label {
  90. text: styleData.date.getDate()
  91. anchors.centerIn: parent
  92. color: styleData.valid ? "white" : "grey"
  93. }
  94. Rectangle {
  95. width: parent.width
  96. height: 1
  97. color: "#555"
  98. anchors.bottom: parent.bottom
  99. }
  100. Rectangle {
  101. width: 1
  102. height: parent.height
  103. color: "#555"
  104. anchors.right: parent.right
  105. }
  106. }
  107. }
  108. }
  109. \endqml
  110. */
  111. Style {
  112. id: calendarStyle
  113. /*!
  114. The Calendar this style is attached to.
  115. */
  116. readonly property Calendar control: __control
  117. /*!
  118. The color of the grid lines.
  119. */
  120. property color gridColor: "#d3d3d3"
  121. /*!
  122. This property determines the visibility of the grid.
  123. The default value is \c true.
  124. */
  125. property bool gridVisible: true
  126. /*!
  127. \internal
  128. The width of each grid line.
  129. */
  130. property real __gridLineWidth: 1
  131. /*! \internal */
  132. property color __horizontalSeparatorColor: gridColor
  133. /*! \internal */
  134. property color __verticalSeparatorColor: gridColor
  135. function __cellRectAt(index) {
  136. return CalendarUtils.cellRectAt(index, control.__panel.columns, control.__panel.rows,
  137. control.__panel.availableWidth, control.__panel.availableHeight, gridVisible ? __gridLineWidth : 0);
  138. }
  139. function __isValidDate(date) {
  140. return date !== undefined
  141. && date.getTime() >= control.minimumDate.getTime()
  142. && date.getTime() <= control.maximumDate.getTime();
  143. }
  144. /*!
  145. The background of the calendar.
  146. The implicit size of the calendar is calculated based on the implicit size of the background delegate.
  147. */
  148. property Component background: Rectangle {
  149. color: "#fff"
  150. implicitWidth: Math.max(250, Math.round(TextSingleton.implicitHeight * 14))
  151. implicitHeight: Math.max(250, Math.round(TextSingleton.implicitHeight * 14))
  152. }
  153. /*!
  154. The navigation bar of the calendar.
  155. Styles the bar at the top of the calendar that contains the
  156. next month/previous month buttons and the selected date label.
  157. The properties provided to the delegate are:
  158. \table
  159. \row \li readonly property string \b styleData.title
  160. \li The title of the calendar.
  161. \endtable
  162. */
  163. property Component navigationBar: Rectangle {
  164. height: Math.round(TextSingleton.implicitHeight * 2.73)
  165. color: "#f9f9f9"
  166. Rectangle {
  167. color: Qt.rgba(1,1,1,0.6)
  168. height: 1
  169. width: parent.width
  170. }
  171. Rectangle {
  172. anchors.bottom: parent.bottom
  173. height: 1
  174. width: parent.width
  175. color: "#ddd"
  176. }
  177. HoverButton {
  178. id: previousMonth
  179. width: parent.height
  180. height: width
  181. anchors.verticalCenter: parent.verticalCenter
  182. anchors.left: parent.left
  183. source: "images/leftanglearrow.png"
  184. onClicked: control.showPreviousMonth()
  185. }
  186. Label {
  187. id: dateText
  188. text: styleData.title
  189. elide: Text.ElideRight
  190. horizontalAlignment: Text.AlignHCenter
  191. font.pixelSize: TextSingleton.implicitHeight * 1.25
  192. anchors.verticalCenter: parent.verticalCenter
  193. anchors.left: previousMonth.right
  194. anchors.leftMargin: 2
  195. anchors.right: nextMonth.left
  196. anchors.rightMargin: 2
  197. }
  198. HoverButton {
  199. id: nextMonth
  200. width: parent.height
  201. height: width
  202. anchors.verticalCenter: parent.verticalCenter
  203. anchors.right: parent.right
  204. source: "images/rightanglearrow.png"
  205. onClicked: control.showNextMonth()
  206. }
  207. }
  208. /*!
  209. The delegate that styles each date in the calendar.
  210. The properties provided to each delegate are:
  211. \table
  212. \row \li readonly property date \b styleData.date
  213. \li The date this delegate represents.
  214. \row \li readonly property bool \b styleData.selected
  215. \li \c true if this is the selected date.
  216. \row \li readonly property int \b styleData.index
  217. \li The index of this delegate.
  218. \row \li readonly property bool \b styleData.valid
  219. \li \c true if this date is greater than or equal to than \l {Calendar::minimumDate}{minimumDate} and
  220. less than or equal to \l {Calendar::maximumDate}{maximumDate}.
  221. \row \li readonly property bool \b styleData.today
  222. \li \c true if this date is equal to today's date.
  223. \row \li readonly property bool \b styleData.visibleMonth
  224. \li \c true if the month in this date is the visible month.
  225. \row \li readonly property bool \b styleData.hovered
  226. \li \c true if the mouse is over this cell.
  227. \note This property is \c true even when the mouse is hovered over an invalid date.
  228. \row \li readonly property bool \b styleData.pressed
  229. \li \c true if the mouse is pressed on this cell.
  230. \note This property is \c true even when the mouse is pressed on an invalid date.
  231. \endtable
  232. */
  233. property Component dayDelegate: Rectangle {
  234. anchors.fill: parent
  235. anchors.leftMargin: (!addExtraMargin || control.weekNumbersVisible) && styleData.index % CalendarUtils.daysInAWeek === 0 ? 0 : -1
  236. anchors.rightMargin: !addExtraMargin && styleData.index % CalendarUtils.daysInAWeek === CalendarUtils.daysInAWeek - 1 ? 0 : -1
  237. anchors.bottomMargin: !addExtraMargin && styleData.index >= CalendarUtils.daysInAWeek * (CalendarUtils.weeksOnACalendarMonth - 1) ? 0 : -1
  238. anchors.topMargin: styleData.selected ? -1 : 0
  239. color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "transparent"
  240. readonly property bool addExtraMargin: control.frameVisible && styleData.selected
  241. readonly property color sameMonthDateTextColor: "#444"
  242. readonly property color selectedDateColor: Qt.platform.os === "osx" ? "#3778d0" : SystemPaletteSingleton.highlight(control.enabled)
  243. readonly property color selectedDateTextColor: "white"
  244. readonly property color differentMonthDateTextColor: "#bbb"
  245. readonly property color invalidDateColor: "#dddddd"
  246. Label {
  247. id: dayDelegateText
  248. text: styleData.date.getDate()
  249. anchors.centerIn: parent
  250. horizontalAlignment: Text.AlignRight
  251. font.pixelSize: Math.min(parent.height/3, parent.width/3)
  252. color: {
  253. var theColor = invalidDateColor;
  254. if (styleData.valid) {
  255. // Date is within the valid range.
  256. theColor = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor;
  257. if (styleData.selected)
  258. theColor = selectedDateTextColor;
  259. }
  260. theColor;
  261. }
  262. }
  263. }
  264. /*!
  265. The delegate that styles each weekday.
  266. The height of the weekday row is calculated based on the maximum implicit height of the delegates.
  267. The properties provided to each delegate are:
  268. \table
  269. \row \li readonly property int \b styleData.index
  270. \li The index (0-6) of the delegate.
  271. \row \li readonly property int \b styleData.dayOfWeek
  272. \li The day of the week this delegate represents. Possible values:
  273. \list
  274. \li \c Locale.Sunday
  275. \li \c Locale.Monday
  276. \li \c Locale.Tuesday
  277. \li \c Locale.Wednesday
  278. \li \c Locale.Thursday
  279. \li \c Locale.Friday
  280. \li \c Locale.Saturday
  281. \endlist
  282. \endtable
  283. */
  284. property Component dayOfWeekDelegate: Rectangle {
  285. color: gridVisible ? "#fcfcfc" : "transparent"
  286. implicitHeight: Math.round(TextSingleton.implicitHeight * 2.25)
  287. Label {
  288. text: control.locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat)
  289. anchors.centerIn: parent
  290. }
  291. }
  292. /*!
  293. The delegate that styles each week number.
  294. The width of the week number column is calculated based on the maximum implicit width of the delegates.
  295. The properties provided to each delegate are:
  296. \table
  297. \row \li readonly property int \b styleData.index
  298. \li The index (0-5) of the delegate.
  299. \row \li readonly property int \b styleData.weekNumber
  300. \li The number of the week this delegate represents.
  301. \endtable
  302. */
  303. property Component weekNumberDelegate: Rectangle {
  304. implicitWidth: Math.round(TextSingleton.implicitHeight * 2)
  305. Label {
  306. text: styleData.weekNumber
  307. anchors.centerIn: parent
  308. color: "#444"
  309. }
  310. }
  311. /*! \internal */
  312. property Component panel: Item {
  313. id: panelItem
  314. implicitWidth: backgroundLoader.implicitWidth
  315. implicitHeight: backgroundLoader.implicitHeight
  316. property alias navigationBarItem: navigationBarLoader.item
  317. property alias dayOfWeekHeaderRow: dayOfWeekHeaderRow
  318. readonly property int weeksToShow: 6
  319. readonly property int rows: weeksToShow
  320. readonly property int columns: CalendarUtils.daysInAWeek
  321. // The combined available width and height to be shared amongst each cell.
  322. readonly property real availableWidth: viewContainer.width
  323. readonly property real availableHeight: viewContainer.height
  324. property int hoveredCellIndex: -1
  325. property int pressedCellIndex: -1
  326. property int pressCellIndex: -1
  327. property var pressDate: null
  328. Rectangle {
  329. anchors.fill: parent
  330. color: "transparent"
  331. border.color: gridColor
  332. visible: control.frameVisible
  333. }
  334. Item {
  335. id: container
  336. anchors.fill: parent
  337. anchors.margins: control.frameVisible ? 1 : 0
  338. Loader {
  339. id: backgroundLoader
  340. anchors.fill: parent
  341. sourceComponent: background
  342. }
  343. Loader {
  344. id: navigationBarLoader
  345. anchors.left: parent.left
  346. anchors.right: parent.right
  347. anchors.top: parent.top
  348. sourceComponent: navigationBar
  349. active: control.navigationBarVisible
  350. property QtObject styleData: QtObject {
  351. readonly property string title: control.locale.standaloneMonthName(control.visibleMonth)
  352. + new Date(control.visibleYear, control.visibleMonth, 1).toLocaleDateString(control.locale, " yyyy")
  353. }
  354. }
  355. Row {
  356. id: dayOfWeekHeaderRow
  357. anchors.top: navigationBarLoader.bottom
  358. anchors.left: parent.left
  359. anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0)
  360. anchors.right: parent.right
  361. spacing: gridVisible ? __gridLineWidth : 0
  362. property alias __repeater: repeater
  363. Repeater {
  364. id: repeater
  365. model: CalendarHeaderModel {
  366. locale: control.locale
  367. }
  368. Loader {
  369. id: dayOfWeekDelegateLoader
  370. sourceComponent: dayOfWeekDelegate
  371. width: __cellRectAt(index).width
  372. readonly property int __index: index
  373. readonly property var __dayOfWeek: dayOfWeek
  374. property QtObject styleData: QtObject {
  375. readonly property alias index: dayOfWeekDelegateLoader.__index
  376. readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek
  377. }
  378. }
  379. }
  380. }
  381. Rectangle {
  382. id: topGridLine
  383. color: __horizontalSeparatorColor
  384. width: parent.width
  385. height: __gridLineWidth
  386. visible: gridVisible
  387. anchors.top: dayOfWeekHeaderRow.bottom
  388. }
  389. Row {
  390. id: gridRow
  391. width: weekNumbersItem.width + viewContainer.width
  392. height: viewContainer.height
  393. anchors.top: topGridLine.bottom
  394. Column {
  395. id: weekNumbersItem
  396. visible: control.weekNumbersVisible
  397. height: viewContainer.height
  398. spacing: gridVisible ? __gridLineWidth : 0
  399. Repeater {
  400. id: weekNumberRepeater
  401. model: panelItem.weeksToShow
  402. Loader {
  403. id: weekNumberDelegateLoader
  404. height: __cellRectAt(index * panelItem.columns).height
  405. sourceComponent: weekNumberDelegate
  406. readonly property int __index: index
  407. property int __weekNumber: control.__model.weekNumberAt(index)
  408. Connections {
  409. target: control
  410. function onVisibleMonthChanged() {
  411. __weekNumber = control.__model.weekNumberAt(index)
  412. }
  413. function onVisibleYearChanged() {
  414. __weekNumber = control.__model.weekNumberAt(index)
  415. }
  416. }
  417. Connections {
  418. target: control.__model
  419. function onCountChanged() {
  420. __weekNumber = control.__model.weekNumberAt(index)
  421. }
  422. }
  423. property QtObject styleData: QtObject {
  424. readonly property alias index: weekNumberDelegateLoader.__index
  425. readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber
  426. }
  427. }
  428. }
  429. }
  430. Rectangle {
  431. id: separator
  432. anchors.topMargin: - dayOfWeekHeaderRow.height - 1
  433. anchors.top: weekNumbersItem.top
  434. anchors.bottom: weekNumbersItem.bottom
  435. width: __gridLineWidth
  436. color: __verticalSeparatorColor
  437. visible: control.weekNumbersVisible
  438. }
  439. // Contains the grid lines and the grid itself.
  440. Item {
  441. id: viewContainer
  442. width: container.width - (control.weekNumbersVisible ? weekNumbersItem.width + separator.width : 0)
  443. height: container.height - navigationBarLoader.height - dayOfWeekHeaderRow.height - topGridLine.height
  444. Repeater {
  445. id: verticalGridLineRepeater
  446. model: panelItem.columns - 1
  447. delegate: Rectangle {
  448. x: __cellRectAt(index + 1).x - __gridLineWidth
  449. y: 0
  450. width: __gridLineWidth
  451. height: viewContainer.height
  452. color: gridColor
  453. visible: gridVisible
  454. }
  455. }
  456. Repeater {
  457. id: horizontalGridLineRepeater
  458. model: panelItem.rows - 1
  459. delegate: Rectangle {
  460. x: 0
  461. y: __cellRectAt((index + 1) * panelItem.columns).y - __gridLineWidth
  462. width: viewContainer.width
  463. height: __gridLineWidth
  464. color: gridColor
  465. visible: gridVisible
  466. }
  467. }
  468. MouseArea {
  469. id: mouseArea
  470. anchors.fill: parent
  471. hoverEnabled: Settings.hoverEnabled
  472. function cellIndexAt(mouseX, mouseY) {
  473. var viewContainerPos = viewContainer.mapFromItem(mouseArea, mouseX, mouseY);
  474. var child = viewContainer.childAt(viewContainerPos.x, viewContainerPos.y);
  475. // In the tests, the mouseArea sometimes gets picked instead of the cells,
  476. // probably because stuff is still loading. To be safe, we check for that here.
  477. return child && child !== mouseArea ? child.__index : -1;
  478. }
  479. onEntered: {
  480. hoveredCellIndex = cellIndexAt(mouseX, mouseY);
  481. if (hoveredCellIndex === undefined) {
  482. hoveredCellIndex = cellIndexAt(mouseX, mouseY);
  483. }
  484. var date = view.model.dateAt(hoveredCellIndex);
  485. if (__isValidDate(date)) {
  486. control.hovered(date);
  487. }
  488. }
  489. onExited: {
  490. hoveredCellIndex = -1;
  491. }
  492. onPositionChanged: {
  493. var indexOfCell = cellIndexAt(mouse.x, mouse.y);
  494. var previousHoveredCellIndex = hoveredCellIndex;
  495. hoveredCellIndex = indexOfCell;
  496. if (indexOfCell !== -1) {
  497. var date = view.model.dateAt(indexOfCell);
  498. if (__isValidDate(date)) {
  499. if (hoveredCellIndex !== previousHoveredCellIndex)
  500. control.hovered(date);
  501. // The date must be different for the pressed signal to be emitted.
  502. if (pressed && date.getTime() !== control.selectedDate.getTime()) {
  503. control.pressed(date);
  504. // You can't select dates in a different month while dragging.
  505. if (date.getMonth() === control.selectedDate.getMonth()) {
  506. control.selectedDate = date;
  507. pressedCellIndex = indexOfCell;
  508. }
  509. }
  510. }
  511. }
  512. }
  513. onPressed: {
  514. pressCellIndex = cellIndexAt(mouse.x, mouse.y);
  515. pressDate = null;
  516. if (pressCellIndex !== -1) {
  517. var date = view.model.dateAt(pressCellIndex);
  518. pressedCellIndex = pressCellIndex;
  519. pressDate = date;
  520. if (__isValidDate(date)) {
  521. control.selectedDate = date;
  522. control.pressed(date);
  523. }
  524. }
  525. }
  526. onReleased: {
  527. var indexOfCell = cellIndexAt(mouse.x, mouse.y);
  528. if (indexOfCell !== -1) {
  529. // The cell index might be valid, but the date has to be too. We could let the
  530. // selected date validation take care of this, but then the selected date would
  531. // change to the earliest day if a day before the minimum date is clicked, for example.
  532. var date = view.model.dateAt(indexOfCell);
  533. if (__isValidDate(date)) {
  534. control.released(date);
  535. }
  536. }
  537. pressedCellIndex = -1;
  538. }
  539. onClicked: {
  540. var indexOfCell = cellIndexAt(mouse.x, mouse.y);
  541. if (indexOfCell !== -1 && indexOfCell === pressCellIndex) {
  542. if (__isValidDate(pressDate))
  543. control.clicked(pressDate);
  544. }
  545. }
  546. onDoubleClicked: {
  547. var indexOfCell = cellIndexAt(mouse.x, mouse.y);
  548. if (indexOfCell !== -1) {
  549. var date = view.model.dateAt(indexOfCell);
  550. if (__isValidDate(date))
  551. control.doubleClicked(date);
  552. }
  553. }
  554. onPressAndHold: {
  555. var indexOfCell = cellIndexAt(mouse.x, mouse.y);
  556. if (indexOfCell !== -1 && indexOfCell === pressCellIndex) {
  557. var date = view.model.dateAt(indexOfCell);
  558. if (__isValidDate(date))
  559. control.pressAndHold(date);
  560. }
  561. }
  562. }
  563. Connections {
  564. target: control
  565. function onSelectedDateChanged() { view.selectedDateChanged() }
  566. }
  567. Repeater {
  568. id: view
  569. property int currentIndex: -1
  570. model: control.__model
  571. Component.onCompleted: selectedDateChanged()
  572. function selectedDateChanged() {
  573. if (model !== undefined && model.locale !== undefined) {
  574. currentIndex = model.indexAt(control.selectedDate);
  575. }
  576. }
  577. delegate: Loader {
  578. id: delegateLoader
  579. x: __cellRectAt(index).x
  580. y: __cellRectAt(index).y
  581. width: __cellRectAt(index).width
  582. height: __cellRectAt(index).height
  583. sourceComponent: dayDelegate
  584. readonly property int __index: index
  585. readonly property date __date: date
  586. // We rely on the fact that an invalid QDate will be converted to a Date
  587. // whose year is -4713, which is always an invalid date since our
  588. // earliest minimum date is the year 1.
  589. readonly property bool valid: __isValidDate(date)
  590. property QtObject styleData: QtObject {
  591. readonly property alias index: delegateLoader.__index
  592. readonly property bool selected: control.selectedDate.getFullYear() === date.getFullYear() &&
  593. control.selectedDate.getMonth() === date.getMonth() &&
  594. control.selectedDate.getDate() === date.getDate()
  595. readonly property alias date: delegateLoader.__date
  596. readonly property bool valid: delegateLoader.valid
  597. // TODO: this will not be correct if the app is running when a new day begins.
  598. readonly property bool today: date.getTime() === new Date().setHours(0, 0, 0, 0)
  599. readonly property bool visibleMonth: date.getMonth() === control.visibleMonth
  600. readonly property bool hovered: panelItem.hoveredCellIndex == index
  601. readonly property bool pressed: panelItem.pressedCellIndex == index
  602. // todo: pressed property here, clicked and doubleClicked in the control itself
  603. }
  604. }
  605. }
  606. }
  607. }
  608. }
  609. }
  610. }