diff options
author | Mitch Curtis <mitch.curtis@digia.com> | 2014-01-20 19:08:22 +0100 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@digia.com> | 2014-01-21 12:22:29 +0100 |
commit | e97d9c8d3dda6c3b906b45d1cb7e190932496c21 (patch) | |
tree | 9a4610deb426bba5ef38c25af8868e5134e45870 | |
parent | 8a6890ecd41e20e02dd43ae323a3584fdf1f9bd2 (diff) | |
download | qtquickcontrols-e97d9c8d3dda6c3b906b45d1cb7e190932496c21.tar.gz |
Add grid line functionality.
Change-Id: I37fa8ad7f752b4d125c6f8984b76a41e81762dd4
Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
-rw-r--r-- | src/controls/Calendar.qml | 273 | ||||
-rw-r--r-- | src/controls/Styles/Base/CalendarStyle.qml | 53 | ||||
-rw-r--r-- | src/controls/Styles/Desktop/CalendarStyle.qml | 19 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_calendar.qml | 6 |
4 files changed, 191 insertions, 160 deletions
diff --git a/src/controls/Calendar.qml b/src/controls/Calendar.qml index 8127ca11..e78734af 100644 --- a/src/controls/Calendar.qml +++ b/src/controls/Calendar.qml @@ -63,6 +63,10 @@ import QtQuick.Controls.Private 1.0 Localization is supported through the \l locale property. The selected date is displayed according to \l locale, and it can be accessed through the \l selectedDateText property. + + \note Due to the fact that the cell sizes are calculated based on the + available space within the control, gaps can be seen between the bottom and + right edges when assigning certain sizes to the Calendar. */ Control { @@ -121,14 +125,11 @@ Control { } /*! - This property determines the visibility of the navigation bar. - - The navigation bar contains the previous and next month buttons, as well - as the displayed date. + This property determines the visibility of the grid. The default value is \c true. */ - property bool navigationBarVisible: true + property bool gridVisible: true /*! \qmlproperty enum Calendar::dayOfWeekFormat @@ -242,147 +243,189 @@ Control { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - height: __style.__protectedScope.navigationBarHeight sourceComponent: __style.navigationBar } - GridView { - id: view - cellWidth: __style.__protectedScope.cellWidth - cellHeight: __style.__protectedScope.cellHeight - currentIndex: -1 - anchors.left: parent.left - anchors.right: parent.right + + Item { + id: viewContainer anchors.top: navigationBarLoader.bottom - width: cellWidth * DateUtils.daysInAWeek - // TODO: fix the reason behind + 1 stopping the flickableness.. - // might have something to do with the header - height: cellHeight * (__style.__protectedScope.weeksToShow + 1) - model: calendar.__model - - boundsBehavior: Flickable.StopAtBounds - KeyNavigation.tab: panel.navigationBarItem - - Keys.onLeftPressed: { - if (currentIndex != 0) { - // Be lazy and let the view determine which index we're moving - // to, then we can calculate the date from that. - moveCurrentIndexLeft(); - // This will cause the index to be set again (to the same value). - calendar.selectedDate = model.dateAt(currentIndex); - } else { - // We're at the left edge of the calendar on the first row; - // this day is the first of the week and the month, so - // moving left should go to the last day of the previous month, - // rather than do nothing (which is what GridView does when - // keyNavigationWraps is false). - var newDate = new Date(calendar.selectedDate); - newDate.setDate(newDate.getDate() - 1); - calendar.selectedDate = newDate; + width: view.cellWidth * DateUtils.daysInAWeek + height: view.cellHeight * (view.weeksToShow + 1) + + Repeater { + id: verticalGridLineRepeater + model: DateUtils.daysInAWeek + 1 + delegate: Rectangle { + x: view.cellWidth * index + y: 0 + width: __style.gridLineWidth + height: view.cellHeight * (verticalGridLineRepeater.count - 1) + __style.gridLineWidth + color: __style.gridColor + visible: calendar.gridVisible } } - Keys.onUpPressed: { - moveCurrentIndexUp(); - calendar.selectedDate = model.dateAt(currentIndex); + Repeater { + id: horizontalGridLineRepeater + model: view.weeksToShow + 2 + delegate: Rectangle { + x: 0 + y: view.cellHeight * index + width: view.cellWidth * (horizontalGridLineRepeater.count - 1) + __style.gridLineWidth + height: __style.gridLineWidth + color: __style.gridColor + visible: calendar.gridVisible + } } - Keys.onDownPressed: { - moveCurrentIndexDown(); - calendar.selectedDate = model.dateAt(currentIndex); - } + GridView { + id: view + /* + The cells will be as big as possible without causing them to spill over into the next row. + When gridVisible is true, we make the cells bigger to account for the grid lines. + */ + cellWidth: Math.floor((calendar.width - (calendar.gridVisible ? __style.gridLineWidth : 0)) / DateUtils.daysInAWeek) + cellHeight: Math.floor((calendar.height - (calendar.gridVisible ? __style.gridLineWidth : 0) + - navigationBarLoader.height) / (weeksToShow + 1)) + currentIndex: -1 + x: calendar.gridVisible ? __style.gridLineWidth : 0 + y: calendar.gridVisible ? __style.gridLineWidth : 0 + width: parent.width + height: parent.height + + // TODO: fix the reason behind + 1 stopping the flickableness.. + // might have something to do with the header + + model: calendar.__model + + boundsBehavior: Flickable.StopAtBounds + KeyNavigation.tab: panel.navigationBarItem + + readonly property int weeksToShow: 6 + + Keys.onLeftPressed: { + if (currentIndex != 0) { + // Be lazy and let the view determine which index we're moving + // to, then we can calculate the date from that. + moveCurrentIndexLeft(); + // This will cause the index to be set again (to the same value). + calendar.selectedDate = model.dateAt(currentIndex); + } else { + // We're at the left edge of the calendar on the first row; + // this day is the first of the week and the month, so + // moving left should go to the last day of the previous month, + // rather than do nothing (which is what GridView does when + // keyNavigationWraps is false). + var newDate = new Date(calendar.selectedDate); + newDate.setDate(newDate.getDate() - 1); + calendar.selectedDate = newDate; + } + } - Keys.onRightPressed: { - moveCurrentIndexRight(); - calendar.selectedDate = model.dateAt(currentIndex); - } + Keys.onUpPressed: { + moveCurrentIndexUp(); + calendar.selectedDate = model.dateAt(currentIndex); + } - Keys.onEscapePressed: { - calendar.escapePressed(); - } + Keys.onDownPressed: { + moveCurrentIndexDown(); + calendar.selectedDate = model.dateAt(currentIndex); + } - Component.onCompleted: { - dateChanged(); + Keys.onRightPressed: { + moveCurrentIndexRight(); + calendar.selectedDate = model.dateAt(currentIndex); + } - if (visible) { - forceActiveFocus(); + Keys.onEscapePressed: { + calendar.escapePressed(); } - } - Connections { - target: calendar - onSelectedDateChanged: view.dateChanged() - } + Component.onCompleted: { + dateChanged(); - function dateChanged() { - if (model !== undefined && model.locale !== undefined) { - __model.selectedDate = calendar.selectedDate; - currentIndex = __model.indexAt(calendar.selectedDate); + if (visible) { + forceActiveFocus(); + } } - } - delegate: Loader { - id: delegateLoader - width: view.cellWidth - height: view.cellHeight - sourceComponent: __style.dateDelegate - - readonly property int __index: index - readonly property var __model: model + Connections { + target: calendar + onSelectedDateChanged: view.dateChanged() + } - property QtObject styleData: QtObject { - readonly property alias index: delegateLoader.__index - readonly property alias model: delegateLoader.__model - readonly property bool selected: delegateLoader.GridView.isCurrentItem - readonly property date date: model.date + function dateChanged() { + if (model !== undefined && model.locale !== undefined) { + __model.selectedDate = calendar.selectedDate; + currentIndex = __model.indexAt(calendar.selectedDate); + } } - MouseArea { - anchors.fill: parent + delegate: Loader { + id: delegateLoader + width: view.cellWidth - (calendar.gridVisible ? __style.gridLineWidth : 0) + height: view.cellHeight - (calendar.gridVisible ? __style.gridLineWidth : 0) + sourceComponent: __style.dateDelegate - function setDateIfValid(date) { - if (calendar.isValidDate(date)) { - calendar.selectedDate = date; - } - } + readonly property int __index: index + readonly property var __model: model - onClicked: { - setDateIfValid(date) + property QtObject styleData: QtObject { + readonly property alias index: delegateLoader.__index + readonly property alias model: delegateLoader.__model + readonly property bool selected: delegateLoader.GridView.isCurrentItem + readonly property date date: model.date } - onDoubleClicked: { - if (date.getTime() === calendar.selectedDate.getTime()) { - // Only accept double clicks if the first click does not - // change the month displayed. This is because double- - // clicking on a date in the next month will first cause - // a single click which will change the month and the - // the release will be triggered on the same index but a - // different date (the date in the next month). - calendar.doubleClicked(date); + MouseArea { + anchors.fill: parent + + function setDateIfValid(date) { + if (calendar.isValidDate(date)) { + calendar.selectedDate = date; + } + } + + onClicked: { + setDateIfValid(date) + } + + onDoubleClicked: { + if (date.getTime() === calendar.selectedDate.getTime()) { + // Only accept double clicks if the first click does not + // change the month displayed. This is because double- + // clicking on a date in the next month will first cause + // a single click which will change the month and the + // the release will be triggered on the same index but a + // different date (the date in the next month). + calendar.doubleClicked(date); + } } } } - } - header: Loader { - width: view.width - height: view.cellHeight + header: Loader { + width: view.width + height: view.cellHeight - sourceComponent: Row { - Repeater { - id: repeater - model: CalendarHeaderModel { - locale: calendar.locale - } - Loader { - id: dayOfWeekDelegateLoader - sourceComponent: __style.weekdayDelegate - width: view.cellWidth - height: view.cellHeight + sourceComponent: Row { + spacing: (calendar.gridVisible ? __style.gridLineWidth : 0) + Repeater { + id: repeater + model: CalendarHeaderModel { + locale: calendar.locale + } + Loader { + id: dayOfWeekDelegateLoader + sourceComponent: __style.weekdayDelegate + width: view.cellWidth - (calendar.gridVisible ? __style.gridLineWidth : 0) + height: view.cellHeight - (calendar.gridVisible ? __style.gridLineWidth : 0) - readonly property var __dayOfWeek: dayOfWeek + readonly property var __dayOfWeek: dayOfWeek - property QtObject styleData: QtObject { - readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek + property QtObject styleData: QtObject { + readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek + } } } } diff --git a/src/controls/Styles/Base/CalendarStyle.qml b/src/controls/Styles/Base/CalendarStyle.qml index 9a928f5f..95bf48dc 100644 --- a/src/controls/Styles/Base/CalendarStyle.qml +++ b/src/controls/Styles/Base/CalendarStyle.qml @@ -53,6 +53,7 @@ import QtQuick.Controls.Private 1.0 \qml Calendar { anchors.centerIn: parent + gridVisible: false style: CalendarStyle { dateDelegate: Rectangle { @@ -101,26 +102,24 @@ import QtQuick.Controls.Private 1.0 Style { id: calendarStyle - property QtObject __protectedScope: QtObject { - readonly property int weeksToShow: 6 - readonly property real navigationBarHeight: 40 - - readonly property real cellWidth: control.width % 2 == 0 - ? control.width / DateUtils.daysInAWeek - : Math.floor(control.width / DateUtils.daysInAWeek) - - readonly property real cellHeight: {control.height - navigationBarHeight % 2 == 0 - ? (parent.height - navigationBarHeight) / (weeksToShow + 1) - : Math.floor((control.height - navigationBarHeight) / (weeksToShow + 1)) - } - } - /*! The Calendar attached to this style. */ property Calendar control: __control /*! + The color of the grid lines. + */ + property color gridColor: "#f0f0f0" + + /*! + The width of each grid line. + + The default value is \c 1. + */ + property real gridLineWidth: 1 + + /*! The background of the calendar. This component is typically not visible (that is, it is not able to be @@ -138,13 +137,7 @@ Style { next month/previous month buttons and the selected date label. */ property Component navigationBar: Item { - visible: control.navigationBarVisible - anchors.fill: parent - - Rectangle { - anchors.fill: parent - color: "#464646" - } + height: 50 KeyNavigation.tab: previousMonth @@ -162,10 +155,15 @@ Style { Text { id: dateText text: control.selectedDateText - color: "#fff" - - font.pixelSize: 12 - anchors.centerIn: parent + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pointSize: 14 + anchors.verticalCenter: parent.verticalCenter + anchors.left: previousMonth.right + anchors.leftMargin: 2 + anchors.right: nextMonth.left + anchors.rightMargin: 2 } Button { id: nextMonth @@ -193,9 +191,9 @@ Style { */ property Component dateDelegate: Rectangle { id: dayDelegate - color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "white" + color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "white"/*"transparent"*/ readonly property color sameMonthDateTextColor: "black" - readonly property color selectedDateColor: "steelblue" + readonly property color selectedDateColor: __syspal.highlight readonly property color selectedDateTextColor: "white" readonly property color differentMonthDateTextColor: Qt.darker("darkgrey", 1.4); readonly property color invalidDatecolor: "#dddddd" @@ -205,6 +203,7 @@ Style { text: styleData.date.getDate() font.pixelSize: 14 anchors.centerIn: parent + horizontalAlignment: Text.AlignRight color: { var color = invalidDatecolor; if (control.isValidDate(styleData.date)) { diff --git a/src/controls/Styles/Desktop/CalendarStyle.qml b/src/controls/Styles/Desktop/CalendarStyle.qml index 58492706..b6fc68c5 100644 --- a/src/controls/Styles/Desktop/CalendarStyle.qml +++ b/src/controls/Styles/Desktop/CalendarStyle.qml @@ -48,29 +48,18 @@ import QtQuick.Controls.Private 1.0 Style { id: calendarStyle - property QtObject __protectedScope: QtObject { - readonly property int weeksToShow: 6 - readonly property real navigationBarHeight: 40 + property Calendar control: __control - readonly property real cellWidth: control.width % 2 == 0 - ? control.width / DateUtils.daysInAWeek - : Math.floor(control.width / DateUtils.daysInAWeek) + property color gridColor: "#f0f0f0" - readonly property real cellHeight: {control.height - navigationBarHeight % 2 == 0 - ? (parent.height - navigationBarHeight) / (weeksToShow + 1) - : Math.floor((control.height - navigationBarHeight) / (weeksToShow + 1)) - } - } - - property Calendar control: __control + property real gridLineWidth: 1 property Component background: Rectangle { color: __syspal.base } property Component navigationBar: Item { - visible: control.navigationBarVisible - anchors.fill: parent + height: 40 Rectangle { anchors.fill: parent diff --git a/tests/auto/controls/data/tst_calendar.qml b/tests/auto/controls/data/tst_calendar.qml index 55d92e55..7cb01073 100644 --- a/tests/auto/controls/data/tst_calendar.qml +++ b/tests/auto/controls/data/tst_calendar.qml @@ -93,7 +93,7 @@ Item { compare(calendar.minimumDate, new Date(1, 0, 1)); compare(calendar.maximumDate, new Date(4000, 0, 1)); compare(calendar.selectedDate, new Date(new Date().setHours(0, 0, 0, 0))); - compare(calendar.navigationBarVisible, true); + compare(calendar.gridVisible, true); compare(calendar.dayOfWeekFormat, Locale.ShortFormat); compare(calendar.locale, Qt.locale()); compare(calendar.selectedDateText, @@ -105,14 +105,14 @@ Item { calendar.minimumDate = new Date(1900, 0, 1); calendar.maximumDate = new Date(1999, 11, 31); calendar.selectedDate = new Date(1980, 0, 1); - calendar.navigationBarVisible = false; + calendar.gridVisible = false; calendar.dayOfWeekFormat = Locale.NarrowFormat; calendar.locale = Qt.locale("de_DE"); compare(calendar.minimumDate, new Date(1900, 0, 1)); compare(calendar.maximumDate, new Date(1999, 11, 31)); compare(calendar.selectedDate, new Date(1980, 0, 1)); - compare(calendar.navigationBarVisible, false); + compare(calendar.gridVisible, false); compare(calendar.locale, Qt.locale("de_DE")); compare(calendar.selectedDateText, calendar.locale.standaloneMonthName(calendar.selectedDate.getMonth()) |