diff options
-rw-r--r-- | examples/quick/controls/texteditor/qml/main.qml | 17 | ||||
-rw-r--r-- | src/controls/Private/CalendarUtils.js | 36 | ||||
-rw-r--r-- | src/controls/Private/TabBar.qml | 2 | ||||
-rw-r--r-- | src/controls/Private/qquickwheelarea.cpp | 36 | ||||
-rw-r--r-- | src/controls/Private/qquickwheelarea_p.h | 5 | ||||
-rw-r--r-- | src/controls/Styles/Base/BusyIndicatorStyle.qml | 2 | ||||
-rw-r--r-- | src/controls/Styles/Base/CalendarStyle.qml | 479 | ||||
-rw-r--r-- | src/controls/Styles/Base/TableViewStyle.qml | 2 | ||||
-rw-r--r-- | src/controls/Styles/Base/TextFieldStyle.qml | 9 | ||||
-rw-r--r-- | src/controls/TabView.qml | 19 | ||||
-rw-r--r-- | src/controls/TableView.qml | 4 | ||||
-rw-r--r-- | src/controls/TextArea.qml | 7 | ||||
-rw-r--r-- | src/dialogs/qquickabstractdialog.cpp | 4 | ||||
-rw-r--r-- | src/dialogs/qquickmessagedialog.cpp | 48 | ||||
-rw-r--r-- | src/dialogs/qquickmessagedialog_p.h | 1 | ||||
-rw-r--r-- | src/dialogs/qquickplatformfiledialog.cpp | 2 | ||||
-rw-r--r-- | src/layouts/qquicklinearlayout.cpp | 4 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_calendar.qml | 113 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_tabview.qml | 35 |
19 files changed, 495 insertions, 330 deletions
diff --git a/examples/quick/controls/texteditor/qml/main.qml b/examples/quick/controls/texteditor/qml/main.qml index 1a66afa5..26e22e98 100644 --- a/examples/quick/controls/texteditor/qml/main.qml +++ b/examples/quick/controls/texteditor/qml/main.qml @@ -272,16 +272,19 @@ ApplicationWindow { implicitWidth: 150 model: Qt.fontFamilies() property bool special : false - onCurrentTextChanged: { - if (special == false || currentIndex != 0) - document.fontFamily = currentText + onActivated: { + if (special == false || index != 0) { + document.fontFamily = textAt(index) + } } } SpinBox { id: fontSizeSpinBox + activeFocusOnPress: false implicitWidth: 50 value: 0 - onValueChanged: document.fontSize = value + property bool valueGuard: true + onValueChanged: if (valueGuard) document.fontSize = value } Item { Layout.fillWidth: true } } @@ -307,7 +310,11 @@ ApplicationWindow { selectionStart: textArea.selectionStart selectionEnd: textArea.selectionEnd Component.onCompleted: document.fileUrl = "qrc:/example.html" - onFontSizeChanged: fontSizeSpinBox.value = document.fontSize + onFontSizeChanged: { + fontSizeSpinBox.valueGuard = false + fontSizeSpinBox.value = document.fontSize + fontSizeSpinBox.valueGuard = true + } onFontFamilyChanged: { var index = Qt.fontFamilies().indexOf(document.fontFamily) if (index == -1) { diff --git a/src/controls/Private/CalendarUtils.js b/src/controls/Private/CalendarUtils.js index 75f3b6c1..fce2a677 100644 --- a/src/controls/Private/CalendarUtils.js +++ b/src/controls/Private/CalendarUtils.js @@ -75,14 +75,37 @@ function setMonth(date, month) { return newDate; } -function cellRectAt(index, columns, rows, availableWidth, availableHeight) { +/*! + Returns the cell rectangle for the cell at the given \a index, assuming + that the grid has a number of columns equal to \a columns and rows + equal to \a rows, with an available width of \a availableWidth and height + of \a availableHeight. + + If \a gridLineWidth is greater than \c 0, the cell rectangle will be + calculated under the assumption that there is a grid between the cells: + + 31 | 1 | 2 | 3 | 4 | 5 | 6 + -------------------------------- + 7 | 8 | 9 | 10 | 11 | 12 | 13 + -------------------------------- + 14 | 15 | 16 | 17 | 18 | 19 | 20 + -------------------------------- + 21 | 22 | 23 | 24 | 25 | 26 | 27 + -------------------------------- + 28 | 29 | 30 | 31 | 1 | 2 | 3 + -------------------------------- + 4 | 5 | 6 | 7 | 8 | 9 | 10 +*/ +function cellRectAt(index, columns, rows, availableWidth, availableHeight, gridLineWidth) { var col = Math.floor(index % columns); var row = Math.floor(index / columns); - var remainingHorizontalSpace = Math.floor(availableWidth % columns); - var remainingVerticalSpace = Math.floor(availableHeight % rows); - var baseCellWidth = Math.floor(availableWidth / columns); - var baseCellHeight = Math.floor(availableHeight / rows); + var availableWidthMinusGridLines = availableWidth - ((columns - 1) * gridLineWidth); + var availableHeightMinusGridLines = availableHeight - ((rows - 1) * gridLineWidth); + var remainingHorizontalSpace = Math.floor(availableWidthMinusGridLines % columns); + var remainingVerticalSpace = Math.floor(availableHeightMinusGridLines % rows); + var baseCellWidth = Math.floor(availableWidthMinusGridLines / columns); + var baseCellHeight = Math.floor(availableHeightMinusGridLines / rows); var rect = Qt.rect(0, 0, 0, 0); @@ -108,5 +131,8 @@ function cellRectAt(index, columns, rows, availableWidth, availableHeight) { rect.y += Math.min(remainingVerticalSpace, row); } + rect.x += col * gridLineWidth; + rect.y += row * gridLineWidth; + return rect; } diff --git a/src/controls/Private/TabBar.qml b/src/controls/Private/TabBar.qml index 3262b680..540b994f 100644 --- a/src/controls/Private/TabBar.qml +++ b/src/controls/Private/TabBar.qml @@ -220,7 +220,7 @@ FocusScope { readonly property alias selected: tabitem.selected readonly property alias title: tabitem.title readonly property alias nextSelected: tabitem.nextSelected - readonly property alias previsousSelected: tabitem.previousSelected + readonly property alias previousSelected: tabitem.previousSelected readonly property alias hovered: tabitem.containsMouse readonly property alias enabled: tabitem.enabled readonly property bool activeFocus: tabitem.activeFocus diff --git a/src/controls/Private/qquickwheelarea.cpp b/src/controls/Private/qquickwheelarea.cpp index e276247b..5fb3e4a6 100644 --- a/src/controls/Private/qquickwheelarea.cpp +++ b/src/controls/Private/qquickwheelarea.cpp @@ -77,6 +77,26 @@ QQuickWheelArea::~QQuickWheelArea() } +bool QQuickWheelArea::isAtXEnd() const +{ + return qFuzzyCompare(m_horizontalMaximumValue, m_horizontalValue); +} + +bool QQuickWheelArea::isAtXBeginning() const +{ + return qFuzzyCompare(m_horizontalMinimumValue, m_horizontalValue); +} + +bool QQuickWheelArea::isAtYEnd() const +{ + return qFuzzyCompare(m_verticalMaximumValue, m_verticalValue); +} + +bool QQuickWheelArea::isAtYBeginning() const +{ + return qFuzzyCompare(m_verticalMinimumValue, m_verticalValue); +} + void QQuickWheelArea::wheelEvent(QWheelEvent *we) { if (we->phase() == Qt::ScrollBegin) @@ -95,7 +115,21 @@ void QQuickWheelArea::wheelEvent(QWheelEvent *we) setVerticalDelta(numDegrees.y() / 15.0 * m_scrollSpeed); } - we->accept(); + // This allows other parent WheelArea's to handle scrolling + // For example this allows for ScrollView inside of another ScrollView to work correctly + // Once this scrollbar can't scroll anymore, ie it reaches the limits, + // it will ignore the scroll event so the parent WheelArea can start scrolling + if ((numPixels.x() != 0 || numDegrees.x() != 0) && + m_horizontalMinimumValue <= m_horizontalMaximumValue && + (isAtXBeginning() || isAtXEnd())) { + we->ignore(); + } else if ((numPixels.y() != 0 || numDegrees.y() != 0) && + m_verticalMinimumValue <= m_verticalMaximumValue && + (isAtYBeginning() || isAtYEnd())) { + we->ignore(); + } else { + we->accept(); + } } void QQuickWheelArea::setHorizontalMinimumValue(qreal value) diff --git a/src/controls/Private/qquickwheelarea_p.h b/src/controls/Private/qquickwheelarea_p.h index ebaa1453..7f9f2b7e 100644 --- a/src/controls/Private/qquickwheelarea_p.h +++ b/src/controls/Private/qquickwheelarea_p.h @@ -97,6 +97,11 @@ public: void wheelEvent(QWheelEvent *event); + bool isAtXEnd() const; + bool isAtXBeginning() const; + bool isAtYEnd() const; + bool isAtYBeginning() const; + Q_SIGNALS: void verticalValueChanged(); void horizontalValueChanged(); diff --git a/src/controls/Styles/Base/BusyIndicatorStyle.qml b/src/controls/Styles/Base/BusyIndicatorStyle.qml index 03c3812e..ce8550db 100644 --- a/src/controls/Styles/Base/BusyIndicatorStyle.qml +++ b/src/controls/Styles/Base/BusyIndicatorStyle.qml @@ -58,7 +58,7 @@ import QtQuick.Controls.Private 1.0 indicator: Image { visible: control.running source: "spinner.png" - NumberAnimation on rotation { + RotationAnimator on rotation { running: control.running loops: Animation.Infinite duration: 2000 diff --git a/src/controls/Styles/Base/CalendarStyle.qml b/src/controls/Styles/Base/CalendarStyle.qml index 34f6eb05..5f391b37 100644 --- a/src/controls/Styles/Base/CalendarStyle.qml +++ b/src/controls/Styles/Base/CalendarStyle.qml @@ -150,7 +150,7 @@ Style { function __cellRectAt(index) { return CalendarUtils.cellRectAt(index, control.__panel.columns, control.__panel.rows, - control.__panel.availableWidth, control.__panel.availableHeight); + control.__panel.availableWidth, control.__panel.availableHeight, gridVisible ? __gridLineWidth : 0); } function __isValidDate(date) { @@ -248,8 +248,13 @@ Style { */ property Component dayDelegate: Rectangle { anchors.fill: parent - anchors.margins: styleData.selected ? -1 : 0 + anchors.leftMargin: (!addExtraMargin || control.weekNumbersVisible) && styleData.index % CalendarUtils.daysInAWeek === 0 ? 0 : -1 + anchors.rightMargin: !addExtraMargin && styleData.index % CalendarUtils.daysInAWeek === CalendarUtils.daysInAWeek - 1 ? 0 : -1 + anchors.bottomMargin: !addExtraMargin && styleData.index >= CalendarUtils.daysInAWeek * (CalendarUtils.weeksOnACalendarMonth - 1) ? 0 : -1 + anchors.topMargin: styleData.selected ? -1 : 0 color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "transparent" + + readonly property bool addExtraMargin: control.frameVisible && styleData.selected readonly property color sameMonthDateTextColor: "#444" readonly property color selectedDateColor: Qt.platform.os === "osx" ? "#3778d0" : __syspal.highlight readonly property color selectedDateTextColor: "white" @@ -312,306 +317,318 @@ Style { readonly property int columns: CalendarUtils.daysInAWeek // The combined available width and height to be shared amongst each cell. - readonly property real availableWidth: (viewContainer.width - (control.frameVisible ? 2 * __gridLineWidth : 0)) - readonly property real availableHeight: (viewContainer.height - (control.frameVisible ? 2 * __gridLineWidth : 0)) + readonly property real availableWidth: viewContainer.width + readonly property real availableHeight: viewContainer.height property int hoveredCellIndex: -1 property int pressedCellIndex: -1 - Loader { - id: backgroundLoader + Rectangle { anchors.fill: parent - sourceComponent: background + color: "transparent" + border.color: gridColor + visible: control.frameVisible } - Loader { - id: navigationBarLoader - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top + Item { + id: container + anchors.fill: parent anchors.margins: control.frameVisible ? 1 : 0 - sourceComponent: navigationBar - property QtObject styleData: QtObject { - readonly property string title: control.__locale.standaloneMonthName(control.visibleMonth) - + new Date(control.visibleYear, control.visibleMonth, 1).toLocaleDateString(control.__locale, " yyyy") + Loader { + id: backgroundLoader + anchors.fill: parent + sourceComponent: background } - } - Row { - id: dayOfWeekHeaderRow - anchors.top: navigationBarLoader.bottom - anchors.left: parent.left - anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0) - anchors.right: parent.right - height: dayOfWeekHeaderRowHeight + Loader { + id: navigationBarLoader + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + sourceComponent: navigationBar - Repeater { - id: repeater - model: CalendarHeaderModel { - locale: control.__locale - } - Loader { - id: dayOfWeekDelegateLoader - sourceComponent: dayOfWeekDelegate - width: __cellRectAt(index).width - height: dayOfWeekHeaderRow.height - - readonly property var __dayOfWeek: dayOfWeek - - property QtObject styleData: QtObject { - readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek - } + property QtObject styleData: QtObject { + readonly property string title: control.__locale.standaloneMonthName(control.visibleMonth) + + new Date(control.visibleYear, control.visibleMonth, 1).toLocaleDateString(control.__locale, " yyyy") } } - } - Row { - id: gridRow - width: weekNumbersItem.width + viewContainer.width - height: viewContainer.height - anchors.top: dayOfWeekHeaderRow.bottom + Row { + id: dayOfWeekHeaderRow + anchors.top: navigationBarLoader.bottom + anchors.left: parent.left + anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0) + anchors.right: parent.right + height: dayOfWeekHeaderRowHeight - Item { - id: weekNumbersItem - visible: control.weekNumbersVisible - width: 30 - height: viewContainer.height Repeater { - id: weekNumberRepeater - model: panelItem.weeksToShow - + id: repeater + model: CalendarHeaderModel { + locale: control.__locale + } Loader { - id: weekNumberDelegateLoader - y: __cellRectAt(index * panelItem.columns).y + (gridVisible ? __gridLineWidth : 0) - width: weekNumbersItem.width - height: __cellRectAt(index * panelItem.columns).height - (control.frameVisible ? __gridLineWidth : 0) - sourceComponent: weekNumberDelegate - - readonly property int __index: index - property int __weekNumber: control.__model.weekNumberAt(index) - - Connections { - target: control - onVisibleMonthChanged: __weekNumber = control.__model.weekNumberAt(index) - onVisibleYearChanged: __weekNumber = control.__model.weekNumberAt(index) - } + id: dayOfWeekDelegateLoader + sourceComponent: dayOfWeekDelegate + width: __cellRectAt(index).width + height: dayOfWeekHeaderRow.height - Connections { - target: control.__model - onCountChanged: __weekNumber = control.__model.weekNumberAt(index) - } + readonly property var __dayOfWeek: dayOfWeek property QtObject styleData: QtObject { - readonly property alias index: weekNumberDelegateLoader.__index - readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber + readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek } } } - Rectangle { - anchors.topMargin: - navigationBarLoader.height - anchors.top: parent.top - anchors.bottom: parent.bottom - - width: 1 - anchors.rightMargin: -1 - anchors.right: parent.right - color: gridColor - } + } + Rectangle { + id: topGridLine + color: gridColor + width: parent.width + height: __gridLineWidth + visible: gridVisible + anchors.top: dayOfWeekHeaderRow.bottom } - // Contains the grid lines and the grid itself. - Item { - id: viewContainer - width: panelItem.width - (control.weekNumbersVisible ? weekNumbersItem.width : 0) - height: panelItem.height - navigationBarLoader.height - dayOfWeekHeaderRow.height + Row { + id: gridRow + width: weekNumbersItem.width + viewContainer.width + height: viewContainer.height + anchors.top: topGridLine.bottom + + Item { + id: weekNumbersItem + visible: control.weekNumbersVisible + width: 30 + height: viewContainer.height + Repeater { + id: weekNumberRepeater + model: panelItem.weeksToShow + + Loader { + id: weekNumberDelegateLoader + y: __cellRectAt(index * panelItem.columns).y + width: weekNumbersItem.width + height: __cellRectAt(index * panelItem.columns).height + sourceComponent: weekNumberDelegate + + readonly property int __index: index + property int __weekNumber: control.__model.weekNumberAt(index) + + Connections { + target: control + onVisibleMonthChanged: __weekNumber = control.__model.weekNumberAt(index) + onVisibleYearChanged: __weekNumber = control.__model.weekNumberAt(index) + } + + Connections { + target: control.__model + onCountChanged: __weekNumber = control.__model.weekNumberAt(index) + } + + property QtObject styleData: QtObject { + readonly property alias index: weekNumberDelegateLoader.__index + readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber + } + } + } + Rectangle { + anchors.topMargin: - navigationBarLoader.height + anchors.top: parent.top + anchors.bottom: parent.bottom - Repeater { - id: verticalGridLineRepeater - model: panelItem.columns - 1 - delegate: Rectangle { - // The last line will be an invalid index, so we must handle it - x: index < panelItem.columns - ? __cellRectAt(index + 1).x - : __cellRectAt(panelItem.columns).x + __cellRectAt(panelItem.columns).width - y: 0 width: __gridLineWidth - height: viewContainer.height + anchors.rightMargin: -__gridLineWidth + anchors.right: parent.right color: gridColor - visible: gridVisible } + } - Repeater { - id: horizontalGridLineRepeater - model: panelItem.rows - delegate: Rectangle { - x: 0 - // The last line will be an invalid index, so we must handle it - y: index < panelItem.columns - 1 - ? __cellRectAt(index * panelItem.columns).y - : __cellRectAt((panelItem.rows - 1) * panelItem.columns).y + __cellRectAt((panelItem.rows - 1) * panelItem.columns).height - width: viewContainer.width - height: __gridLineWidth - color: gridColor - visible: gridVisible + // Contains the grid lines and the grid itself. + Item { + id: viewContainer + width: container.width - (control.weekNumbersVisible ? weekNumbersItem.width : 0) + height: container.height - navigationBarLoader.height - dayOfWeekHeaderRow.height - topGridLine.height + + Repeater { + id: verticalGridLineRepeater + model: panelItem.columns - 1 + delegate: Rectangle { + x: __cellRectAt(index + 1).x - __gridLineWidth + y: 0 + width: __gridLineWidth + height: viewContainer.height + color: gridColor + visible: gridVisible + } } - } - MouseArea { - id: mouseArea - anchors.fill: parent + Repeater { + id: horizontalGridLineRepeater + model: panelItem.rows - 1 + delegate: Rectangle { + x: 0 + y: __cellRectAt((index + 1) * panelItem.columns).y - __gridLineWidth + width: viewContainer.width + height: __gridLineWidth + color: gridColor + visible: gridVisible + } + } - hoverEnabled: true + MouseArea { + id: mouseArea + anchors.fill: parent - function cellIndexAt(mouseX, mouseY) { - var viewContainerPos = viewContainer.mapFromItem(mouseArea, mouseX, mouseY); - var child = viewContainer.childAt(viewContainerPos.x, viewContainerPos.y); - // In the tests, the mouseArea sometimes gets picked instead of the cells, - // probably because stuff is still loading. To be safe, we check for that here. - return child && child !== mouseArea ? child.__index : -1; - } + hoverEnabled: true - onEntered: { - hoveredCellIndex = cellIndexAt(mouseX, mouseY); - if (hoveredCellIndex === undefined) { - hoveredCellIndex = cellIndexAt(mouseX, mouseY); + function cellIndexAt(mouseX, mouseY) { + var viewContainerPos = viewContainer.mapFromItem(mouseArea, mouseX, mouseY); + var child = viewContainer.childAt(viewContainerPos.x, viewContainerPos.y); + // In the tests, the mouseArea sometimes gets picked instead of the cells, + // probably because stuff is still loading. To be safe, we check for that here. + return child && child !== mouseArea ? child.__index : -1; } - var date = view.model.dateAt(hoveredCellIndex); - if (__isValidDate(date)) { - control.hovered(date); + onEntered: { + hoveredCellIndex = cellIndexAt(mouseX, mouseY); + if (hoveredCellIndex === undefined) { + hoveredCellIndex = cellIndexAt(mouseX, mouseY); + } + + var date = view.model.dateAt(hoveredCellIndex); + if (__isValidDate(date)) { + control.hovered(date); + } } - } - onExited: { - hoveredCellIndex = -1; - } + onExited: { + hoveredCellIndex = -1; + } - onPositionChanged: { - var indexOfCell = cellIndexAt(mouse.x, mouse.y); - var previousHoveredCellIndex = hoveredCellIndex; - hoveredCellIndex = indexOfCell; - if (indexOfCell !== -1) { - var date = view.model.dateAt(indexOfCell); - if (__isValidDate(date)) { - if (hoveredCellIndex !== previousHoveredCellIndex) - control.hovered(date); + onPositionChanged: { + var indexOfCell = cellIndexAt(mouse.x, mouse.y); + var previousHoveredCellIndex = hoveredCellIndex; + hoveredCellIndex = indexOfCell; + if (indexOfCell !== -1) { + var date = view.model.dateAt(indexOfCell); + if (__isValidDate(date)) { + if (hoveredCellIndex !== previousHoveredCellIndex) + control.hovered(date); + + // The date must be different for the pressed signal to be emitted. + if (pressed && date.getTime() !== control.selectedDate.getTime()) { + control.pressed(date); + + // You can't select dates in a different month while dragging. + if (date.getMonth() === control.selectedDate.getMonth()) { + control.selectedDate = date; + pressedCellIndex = indexOfCell; + } + } + } + } + } - if (pressed && date.getTime() !== control.selectedDate.getTime()) { + onPressed: { + var indexOfCell = cellIndexAt(mouse.x, mouse.y); + if (indexOfCell !== -1) { + var date = view.model.dateAt(indexOfCell); + pressedCellIndex = indexOfCell; + if (__isValidDate(date)) { control.selectedDate = date; - pressedCellIndex = indexOfCell; control.pressed(date); } } } - } - onPressed: { - var indexOfCell = cellIndexAt(mouse.x, mouse.y); - if (indexOfCell !== -1) { - var date = view.model.dateAt(indexOfCell); - pressedCellIndex = indexOfCell; - if (__isValidDate(date)) { - control.selectedDate = date; - control.pressed(date); + onReleased: { + var indexOfCell = cellIndexAt(mouse.x, mouse.y); + if (indexOfCell !== -1) { + // The cell index might be valid, but the date has to be too. We could let the + // selected date validation take care of this, but then the selected date would + // change to the earliest day if a day before the minimum date is clicked, for example. + var date = view.model.dateAt(indexOfCell); + if (__isValidDate(date)) { + control.released(date); + } } + pressedCellIndex = -1; } - } - onReleased: { - var indexOfCell = cellIndexAt(mouse.x, mouse.y); - if (indexOfCell !== -1) { - // The cell index might be valid, but the date has to be too. We could let the - // selected date validation take care of this, but then the selected date would - // change to the earliest day if a day before the minimum date is clicked, for example. - var date = view.model.dateAt(indexOfCell); - if (__isValidDate(date)) { - control.released(date); + onClicked: { + var indexOfCell = cellIndexAt(mouse.x, mouse.y); + if (indexOfCell !== -1) { + var date = view.model.dateAt(indexOfCell); + if (__isValidDate(date)) + control.clicked(date); } } - pressedCellIndex = -1; - } - onClicked: { - var indexOfCell = cellIndexAt(mouse.x, mouse.y); - if (indexOfCell !== -1) { - var date = view.model.dateAt(indexOfCell); - if (__isValidDate(date)) - control.clicked(date); + onDoubleClicked: { + var indexOfCell = cellIndexAt(mouse.x, mouse.y); + if (indexOfCell !== -1) { + var date = view.model.dateAt(indexOfCell); + if (__isValidDate(date)) + control.doubleClicked(date); + } } } - onDoubleClicked: { - var indexOfCell = cellIndexAt(mouse.x, mouse.y); - if (indexOfCell !== -1) { - var date = view.model.dateAt(indexOfCell); - if (__isValidDate(date)) - control.doubleClicked(date); - } + Connections { + target: control + onSelectedDateChanged: view.selectedDateChanged() } - } - Connections { - target: control - onSelectedDateChanged: view.selectedDateChanged() - } + Repeater { + id: view - Repeater { - id: view + property int currentIndex: -1 - property int currentIndex: -1 + model: control.__model - model: control.__model + Component.onCompleted: selectedDateChanged() - Component.onCompleted: selectedDateChanged() - - function selectedDateChanged() { - if (model !== undefined && model.locale !== undefined) { - currentIndex = model.indexAt(control.selectedDate); + function selectedDateChanged() { + if (model !== undefined && model.locale !== undefined) { + currentIndex = model.indexAt(control.selectedDate); + } } - } - - delegate: Loader { - id: delegateLoader - - x: __cellRectAt(index).x + (gridVisible ? __gridLineWidth : 0) - y: __cellRectAt(index).y + (gridVisible ? __gridLineWidth : 0) - width: __cellRectAt(index).width - (gridVisible ? __gridLineWidth : 0) - height: __cellRectAt(index).height - (gridVisible ? __gridLineWidth : 0) - z: styleData.selected ? 1 : 0 - sourceComponent: dayDelegate - readonly property int __index: index - readonly property date __date: date - // We rely on the fact that an invalid QDate will be converted to a Date - // whose year is -4713, which is always an invalid date since our - // earliest minimum date is the year 1. - readonly property bool valid: __isValidDate(date) - - property QtObject styleData: QtObject { - readonly property alias index: delegateLoader.__index - readonly property bool selected: control.selectedDate.getTime() === date.getTime() - readonly property alias date: delegateLoader.__date - readonly property bool valid: delegateLoader.valid - // TODO: this will not be correct if the app is running when a new day begins. - readonly property bool today: date.getTime() === new Date().setHours(0, 0, 0, 0) - readonly property bool visibleMonth: date.getMonth() === control.visibleMonth - readonly property bool hovered: panelItem.hoveredCellIndex == index - readonly property bool pressed: panelItem.pressedCellIndex == index - // todo: pressed property here, clicked and doubleClicked in the control itself + delegate: Loader { + id: delegateLoader + + x: __cellRectAt(index).x + y: __cellRectAt(index).y + width: __cellRectAt(index).width + height: __cellRectAt(index).height + sourceComponent: dayDelegate + + readonly property int __index: index + readonly property date __date: date + // We rely on the fact that an invalid QDate will be converted to a Date + // whose year is -4713, which is always an invalid date since our + // earliest minimum date is the year 1. + readonly property bool valid: __isValidDate(date) + + property QtObject styleData: QtObject { + readonly property alias index: delegateLoader.__index + readonly property bool selected: control.selectedDate.getTime() === date.getTime() + readonly property alias date: delegateLoader.__date + readonly property bool valid: delegateLoader.valid + // TODO: this will not be correct if the app is running when a new day begins. + readonly property bool today: date.getTime() === new Date().setHours(0, 0, 0, 0) + readonly property bool visibleMonth: date.getMonth() === control.visibleMonth + readonly property bool hovered: panelItem.hoveredCellIndex == index + readonly property bool pressed: panelItem.pressedCellIndex == index + // todo: pressed property here, clicked and doubleClicked in the control itself + } } } } } } - Rectangle { - anchors.fill: parent - color: "transparent" - border.color: gridColor - visible: control.frameVisible - } - } } diff --git a/src/controls/Styles/Base/TableViewStyle.qml b/src/controls/Styles/Base/TableViewStyle.qml index 667841bb..5dca6631 100644 --- a/src/controls/Styles/Base/TableViewStyle.qml +++ b/src/controls/Styles/Base/TableViewStyle.qml @@ -106,7 +106,7 @@ ScrollViewStyle { } /*! \qmlproperty Component TableViewStyle::rowDelegate - Delegate for header. This delegate is described in \l {TableView::rowDelegate} + Delegate for row. This delegate is described in \l {TableView::rowDelegate} */ property Component rowDelegate: Rectangle { height: Math.round(TextSingleton.implicitHeight * 1.2) diff --git a/src/controls/Styles/Base/TextFieldStyle.qml b/src/controls/Styles/Base/TextFieldStyle.qml index 80fa9c8e..d999551c 100644 --- a/src/controls/Styles/Base/TextFieldStyle.qml +++ b/src/controls/Styles/Base/TextFieldStyle.qml @@ -114,9 +114,6 @@ Style { /*! The background of the text field. */ property Component background: Item { - implicitWidth: Math.round(control.__contentHeight * 8) - implicitHeight: Math.max(25, Math.round(control.__contentHeight * 1.2)) - baselineOffset: control.__baselineOffset Rectangle { anchors.fill: parent anchors.bottomMargin: -1 @@ -149,9 +146,9 @@ Style { property color selectionColor: style.selectionColor property color selectedTextColor: style.selectedTextColor - implicitWidth: backgroundLoader.implicitWidth ? backgroundLoader.implicitWidth : 100 - implicitHeight: backgroundLoader.implicitHeight ? backgroundLoader.implicitHeight : 20 - baselineOffset: backgroundLoader.item ? padding.top + backgroundLoader.item.baselineOffset : 0 + implicitWidth: backgroundLoader.implicitWidth || Math.round(control.__contentHeight * 8) + implicitHeight: backgroundLoader.implicitHeight || Math.max(25, Math.round(control.__contentHeight * 1.2)) + baselineOffset: padding.top + control.__baselineOffset property color placeholderTextColor: style.placeholderTextColor property font font: style.font diff --git a/src/controls/TabView.qml b/src/controls/TabView.qml index 5be224ce..440606e0 100644 --- a/src/controls/TabView.qml +++ b/src/controls/TabView.qml @@ -103,6 +103,7 @@ FocusScope { __tabs.insert(index, {tab: tab}) tab.__inserted = true tab.parent = stack + __didInsertIndex(index) __setOpacities() return tab } @@ -110,10 +111,9 @@ FocusScope { /*! Removes and destroys a tab at the given \a index. */ function removeTab(index) { var tab = __tabs.get(index).tab + __willRemoveIndex(index) __tabs.remove(index, 1) tab.destroy() - if (currentIndex > 0) - currentIndex-- __setOpacities() } @@ -153,6 +153,19 @@ FocusScope { onCurrentIndexChanged: __setOpacities() /*! \internal */ + function __willRemoveIndex(index) { + // Make sure currentIndex will points to the same tab after the removal. + // Also activate the next index if the current index is being removed, + // except when it's both the current and last index. + if (count > 1 && (currentIndex > index || currentIndex == count -1)) + --currentIndex + } + function __didInsertIndex(index) { + // Make sure currentIndex points to the same tab as before the insertion. + if (count > 1 && currentIndex >= index) + currentIndex++ + } + function __setOpacities() { for (var i = 0; i < __tabs.count; ++i) { var child = __tabs.get(i).tab @@ -229,6 +242,7 @@ FocusScope { if (completed) tab.Component.onDestruction.connect(stack.onDynamicTabDestroyed.bind(tab)) __tabs.append({tab: tab}) + __didInsertIndex(__tabs.count - 1) tabAdded = true } } @@ -239,6 +253,7 @@ FocusScope { function onDynamicTabDestroyed() { for (var i = 0; i < __tabs.count; ++i) { if (__tabs.get(i).tab === this) { + __willRemoveIndex(i) __tabs.remove(i, 1) __setOpacities() break diff --git a/src/controls/TableView.qml b/src/controls/TableView.qml index 75e1b4e1..c04ba971 100644 --- a/src/controls/TableView.qml +++ b/src/controls/TableView.qml @@ -708,7 +708,7 @@ ScrollView { property int rowHeight: rowSizeItem.implicitHeight property int paddedRowCount: height/rowHeight - y: listView.contentHeight + y: listView.contentHeight - listView.contentY + listView.originY width: parent.width visible: alternatingRowColors height: viewport.height - listView.contentHeight @@ -918,8 +918,6 @@ ScrollView { } } - Text{ id:text } - Item { id: tableHeader clip: true diff --git a/src/controls/TextArea.qml b/src/controls/TextArea.qml index 4b22dded..8cf02857 100644 --- a/src/controls/TextArea.qml +++ b/src/controls/TextArea.qml @@ -710,7 +710,12 @@ ScrollView { onWrapModeChanged: edit.doLayout() renderType: __style ? __style.renderType : Text.NativeRendering - font: __style ? __style.font : font + Binding { + target: edit + property: 'font' + value: __style.font + when: __style + } color: __style ? __style.textColor : "darkgray" selectionColor: __style ? __style.selectionColor : "darkred" selectedTextColor: __style ? __style.selectedTextColor : "white" diff --git a/src/dialogs/qquickabstractdialog.cpp b/src/dialogs/qquickabstractdialog.cpp index 005d1015..847fb697 100644 --- a/src/dialogs/qquickabstractdialog.cpp +++ b/src/dialogs/qquickabstractdialog.cpp @@ -295,7 +295,7 @@ int QQuickAbstractDialog::height() const void QQuickAbstractDialog::setX(int arg) { m_hasAspiredPosition = true; - m_sizeAspiration.setX(arg); + m_sizeAspiration.moveLeft(arg); if (helper()) { // TODO } else if (m_dialogWindow) { @@ -310,7 +310,7 @@ void QQuickAbstractDialog::setX(int arg) void QQuickAbstractDialog::setY(int arg) { m_hasAspiredPosition = true; - m_sizeAspiration.setY(arg); + m_sizeAspiration.moveTop(arg); if (helper()) { // TODO } else if (m_dialogWindow) { diff --git a/src/dialogs/qquickmessagedialog.cpp b/src/dialogs/qquickmessagedialog.cpp index f5ff79af..4732a706 100644 --- a/src/dialogs/qquickmessagedialog.cpp +++ b/src/dialogs/qquickmessagedialog.cpp @@ -97,7 +97,6 @@ QT_BEGIN_NAMESPACE QQuickMessageDialog::QQuickMessageDialog(QObject *parent) : QQuickAbstractMessageDialog(parent) { - connect(this, SIGNAL(buttonClicked()), this, SLOT(clicked())); } @@ -121,53 +120,6 @@ QQuickMessageDialog::~QQuickMessageDialog() \l Window or an \l Item. */ - -void QQuickMessageDialog::clicked() { - switch (m_clickedButton) { - // This mapping from buttons to roles is the same as - // documented for enum QMessageBox::StandardButton - case Ok: - case Open: - case Save: - case SaveAll: - case Retry: - case Ignore: - accept(); - break; - case Cancel: - case Close: - case Abort: - reject(); - break; - case Discard: - emit discard(); - close(); - break; - case Help: - emit help(); - break; - case Yes: - case YesToAll: - emit yes(); - close(); - break; - case No: - case NoToAll: - emit no(); - close(); - break; - case Apply: - emit apply(); - break; - case Reset: - case RestoreDefaults: - emit reset(); - break; - default: - qWarning("StandardButton %d has no role", m_clickedButton); - } -} - void QQuickMessageDialog::accept() { // enter key is treated like OK if (m_clickedButton == NoButton) diff --git a/src/dialogs/qquickmessagedialog_p.h b/src/dialogs/qquickmessagedialog_p.h index 80a0b04d..a20b8677 100644 --- a/src/dialogs/qquickmessagedialog_p.h +++ b/src/dialogs/qquickmessagedialog_p.h @@ -73,7 +73,6 @@ protected: protected Q_SLOTS: virtual void accept(); virtual void reject(); - void clicked(); private: Q_DISABLE_COPY(QQuickMessageDialog) diff --git a/src/dialogs/qquickplatformfiledialog.cpp b/src/dialogs/qquickplatformfiledialog.cpp index 5a969adb..c4a39060 100644 --- a/src/dialogs/qquickplatformfiledialog.cpp +++ b/src/dialogs/qquickplatformfiledialog.cpp @@ -264,7 +264,7 @@ QPlatformFileDialogHelper *QQuickPlatformFileDialog::helper() The value of this property is also updated after the dialog is closed. - By default, this property is false. + By default, the url is empty. */ /*! diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index 4af3a76f..ea772225 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -219,14 +219,14 @@ QSizeF QQuickGridLayoutBase::sizeHint(Qt::SizeHint whichSizeHint) const \since QtQuick.Layouts 1.1 This property holds the layout direction of the grid layout - it controls whether items are - laid out from left ro right or right to left. If \c Qt.RightToLeft is specified, + laid out from left to right or right to left. If \c Qt.RightToLeft is specified, left-aligned items will be right-aligned and right-aligned items will be left-aligned. Possible values: \list \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left + \li Qt.RightToLeft - Items are laid out from right to left. \endlist \sa RowLayout::layoutDirection, ColumnLayout::layoutDirection diff --git a/tests/auto/controls/data/tst_calendar.qml b/tests/auto/controls/data/tst_calendar.qml index 843aed15..f2002844 100644 --- a/tests/auto/controls/data/tst_calendar.qml +++ b/tests/auto/controls/data/tst_calendar.qml @@ -642,13 +642,27 @@ Item { dragTo(x, Math.floor(index / CalendarUtils.daysInAWeek), index, new Date(2014, 1, 24 + x)); } - // Dragging into the next month should work. - var firstDateInNextMonth = new Date(2014, 2, 1); - dragTo(5, 4, 33, firstDateInNextMonth); + // Dragging into the next month shouldn't work, as it can lead to + // unwanted month changes if moving within a bunch of "next month" cells. + // We still emit the signals as usual, though. + var oldDate = calendar.selectedDate; + mouseMove(calendar, toPixelsX(5), toPixelsY(4), Qt.LeftButton); + compare(calendar.selectedDate, oldDate); + compare(calendar.__panel.pressedCellIndex, 32); + compare(calendar.__panel.hoveredCellIndex, 33); + compare(hoveredSignalSpy.count, 1); + compare(pressedSignalSpy.count, 1); + compare(releasedSignalSpy.count, 0); + compare(clickedSignalSpy.count, 0); + + hoveredSignalSpy.clear(); + pressedSignalSpy.clear(); + releasedSignalSpy.clear(); + clickedSignalSpy.clear(); - // Finish the drag. - mouseRelease(calendar, toPixelsX(5), toPixelsY(0), Qt.LeftButton); - compare(calendar.selectedDate, firstDateInNextMonth); + // Finish the drag over the day in the next month. + mouseRelease(calendar, toPixelsX(5), toPixelsY(4), Qt.LeftButton); + compare(calendar.selectedDate, oldDate); compare(calendar.__panel.pressedCellIndex, -1); compare(hoveredSignalSpy.count, 0); compare(pressedSignalSpy.count, 0); @@ -691,49 +705,68 @@ Item { } } - function test_cellRectCalculation() { + function ensureGapsBetweenCells(columns, rows, availableWidth, availableHeight, gridLineWidth) { + for (var row = 1; row < rows; ++row) { + for (var col = 1; col < columns; ++col) { + var lastHorizontalRect = CalendarUtils.cellRectAt((row - 1) * columns + col - 1, columns, rows, availableWidth, availableHeight); + var thisHorizontalRect = CalendarUtils.cellRectAt((row - 1) * columns + col, columns, rows, availableWidth, availableHeight); + compare (lastHorizontalRect.x + lastHorizontalRect.width + gridLineWidth, thisHorizontalRect.x, + "No gap for grid line between column " + (col - 1) + " and " + col + " in a grid of " + columns + " columns and " + rows + " rows, " + + "with an availableWidth of " + availableWidth + " and availableHeight of " + availableHeight); + + var lastVerticalRect = CalendarUtils.cellRectAt((row - 1) * columns + col - 1, columns, rows, availableWidth, availableHeight); + var thisVerticalRect = CalendarUtils.cellRectAt(row * columns + col - 1, columns, rows, availableWidth, availableHeight); + compare (lastVerticalRect.y + lastVerticalRect.height + gridLineWidth, thisVerticalRect.y, + "No gap for grid line between row " + (row - 1) + " and " + row + " in a grid of " + columns + " columns and " + rows + " rows, " + + "with an availableWidth of " + availableWidth + " and availableHeight of " + availableHeight); + } + } + } + + function test_gridlessCellRectCalculation() { var columns = CalendarUtils.daysInAWeek; var rows = CalendarUtils.weeksOnACalendarMonth; + var gridLineWidth = 0; // No extra space available. var availableWidth = 10 * columns; var availableHeight = 10 * rows; - var rect = CalendarUtils.cellRectAt(0, columns, rows, availableWidth, availableHeight); + var rect = CalendarUtils.cellRectAt(0, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, 0); compare(rect.y, 0); compare(rect.width, 10); compare(rect.height, 10); - rect = CalendarUtils.cellRectAt(columns - 1, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(columns - 1, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, (columns - 1) * 10); compare(rect.y, 0); compare(rect.width, 10); compare(rect.height, 10); - rect = CalendarUtils.cellRectAt(rows * columns - 1, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(rows * columns - 1, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, (columns - 1) * 10); compare(rect.y, (rows - 1) * 10); compare(rect.width, 10); compare(rect.height, 10); - ensureNoGapsBetweenCells(columns, rows, availableWidth, availableHeight); + ensureNoGapsBetweenCells(columns, rows, availableWidth, availableHeight, gridLineWidth); // 1 extra pixel of space in both width and height. availableWidth = 10 * columns + 1; availableHeight = 10 * rows + 1; - rect = CalendarUtils.cellRectAt(0, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(0, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, 0); compare(rect.y, 0); compare(rect.width, 10 + 1); compare(rect.height, 10 + 1); - rect = CalendarUtils.cellRectAt(columns - 1, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(columns - 1, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, (columns - 1) * 10 + 1); compare(rect.y, 0); compare(rect.width, 10); compare(rect.height, 10 + 1); - rect = CalendarUtils.cellRectAt(rows * columns - 1, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(rows * columns - 1, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, (columns - 1) * 10 + 1); compare(rect.y, (rows - 1) * 10 + 1); compare(rect.width, 10); @@ -744,19 +777,19 @@ Item { // 6 extra pixels in width, 5 in height. availableWidth = 10 * columns + 6; availableHeight = 10 * rows + 5; - rect = CalendarUtils.cellRectAt(0, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(0, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, 0); compare(rect.y, 0); compare(rect.width, 10 + 1); compare(rect.height, 10 + 1); - rect = CalendarUtils.cellRectAt(columns - 1, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(columns - 1, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, (columns - 1) * 10 + 6); compare(rect.y, 0); compare(rect.width, 10); compare(rect.height, 10 + 1); - rect = CalendarUtils.cellRectAt(rows * columns - 1, columns, rows, availableWidth, availableHeight); + rect = CalendarUtils.cellRectAt(rows * columns - 1, columns, rows, availableWidth, availableHeight, gridLineWidth); compare(rect.x, (columns - 1) * 10 + 6); compare(rect.y, (rows - 1) * 10 + 5); compare(rect.width, 10); @@ -770,12 +803,54 @@ Item { for (var i = 0; i < columns; ++i) { ++availableWidth; - ensureNoGapsBetweenCells(columns, rows, availableWidth, availableHeight); + ensureNoGapsBetweenCells(columns, rows, availableWidth, availableHeight, gridLineWidth); } for (i = 0; i < columns; ++i) { ++availableHeight; - ensureNoGapsBetweenCells(columns, rows, availableWidth, availableHeight); + ensureNoGapsBetweenCells(columns, rows, availableWidth, availableHeight, gridLineWidth); + } + } + + function test_gridCellRectCalculation() { + var columns = CalendarUtils.daysInAWeek; + var rows = CalendarUtils.weeksOnACalendarMonth; + var gridLineWidth = 1; + + var availableWidth = 10 * columns; + var availableHeight = 10 * rows; + var expectedXs = [0, 11, 21, 31, 41, 51, 61]; + var expectedWidths = [10, 9, 9, 9, 9, 9, 9]; + // Expected y positions and heights actually are the same as the x positions and widths in this case. + // The code below assumes that columns >= rows; if this becomes false, arrays for the expected + // y positions and heights must be created to avoid out of bounds accesses. + for (var row = 0; row < rows; ++row) { + for (var col = 0; col < columns; ++col) { + var index = row * columns + col; + var rect = CalendarUtils.cellRectAt(index, columns, rows, availableWidth, availableHeight, gridLineWidth); + compare(rect.x, expectedXs[col]); + compare(rect.y, expectedXs[row]); + compare(rect.width, expectedWidths[col]); + compare(rect.height, expectedWidths[row]); + } + } + + // The available width and height of a 250x250 calendar (its implicit size). + availableWidth = 250; + availableHeight = 168; + expectedXs = [0, 36, 72, 108, 144, 180, 216]; + var expectedYs = [0, 29, 57, 85, 113, 141]; + expectedWidths = [35, 35, 35, 35, 35, 35, 34]; + var expectedHeights = [28, 27, 27, 27, 27, 27]; + for (row = 0; row < rows; ++row) { + for (col = 0; col < columns; ++col) { + index = row * columns + col; + rect = CalendarUtils.cellRectAt(index, columns, rows, availableWidth, availableHeight, gridLineWidth); + compare(rect.x, expectedXs[col]); + compare(rect.y, expectedYs[row]); + compare(rect.width, expectedWidths[col]); + compare(rect.height, expectedHeights[row]); + } } } } diff --git a/tests/auto/controls/data/tst_tabview.qml b/tests/auto/controls/data/tst_tabview.qml index b7de67ba..9e556dd1 100644 --- a/tests/auto/controls/data/tst_tabview.qml +++ b/tests/auto/controls/data/tst_tabview.qml @@ -84,22 +84,53 @@ TestCase { function test_addRemoveTab() { var tabView = Qt.createQmlObject('import QtQuick 2.2; import QtQuick.Controls 1.2; TabView { }', testCase, ''); + + function verifyCurrentIndexCountDiff() { + verify(!tabView.currentIndex || tabView.count > tabView.currentIndex) + } + tabView.currentIndexChanged.connect(verifyCurrentIndexCountDiff) + tabView.countChanged.connect(verifyCurrentIndexCountDiff) + compare(tabView.count, 0) + compare(tabView.currentIndex, 0) tabView.addTab("title 1", newTab) compare(tabView.count, 1) + compare(tabView.currentIndex, 0) tabView.addTab("title 2", newTab) compare(tabView.count, 2) + compare(tabView.currentIndex, 0) compare(tabView.getTab(0).title, "title 1") compare(tabView.getTab(1).title, "title 2") + tabView.currentIndex = 1 + tabView.insertTab(1, "title 3") compare(tabView.count, 3) + compare(tabView.currentIndex, 2) compare(tabView.getTab(0).title, "title 1") compare(tabView.getTab(1).title, "title 3") compare(tabView.getTab(2).title, "title 2") tabView.insertTab(0, "title 4") compare(tabView.count, 4) + compare(tabView.currentIndex, 3) + compare(tabView.getTab(0).title, "title 4") + compare(tabView.getTab(1).title, "title 1") + compare(tabView.getTab(2).title, "title 3") + compare(tabView.getTab(3).title, "title 2") + + tabView.insertTab(tabView.count, "title 5") + compare(tabView.count, 5) + compare(tabView.currentIndex, 3) + compare(tabView.getTab(0).title, "title 4") + compare(tabView.getTab(1).title, "title 1") + compare(tabView.getTab(2).title, "title 3") + compare(tabView.getTab(3).title, "title 2") + compare(tabView.getTab(4).title, "title 5") + + tabView.removeTab(tabView.count - 1) + compare(tabView.count, 4) + compare(tabView.currentIndex, 3) compare(tabView.getTab(0).title, "title 4") compare(tabView.getTab(1).title, "title 1") compare(tabView.getTab(2).title, "title 3") @@ -107,21 +138,25 @@ TestCase { tabView.removeTab(0) compare(tabView.count, 3) + compare(tabView.currentIndex, 2) compare(tabView.getTab(0).title, "title 1") compare(tabView.getTab(1).title, "title 3") compare(tabView.getTab(2).title, "title 2") tabView.removeTab(1) compare(tabView.count, 2) + compare(tabView.currentIndex, 1) compare(tabView.getTab(0).title, "title 1") compare(tabView.getTab(1).title, "title 2") tabView.removeTab(1) compare(tabView.count, 1) + compare(tabView.currentIndex, 0) compare(tabView.getTab(0).title, "title 1") tabView.removeTab(0) compare(tabView.count, 0) + compare(tabView.currentIndex, 0) tabView.destroy() } |