/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** BSD License Usage ** Alternatively, you may use this file under the terms of the BSD license ** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ import QtTest 1.0 import QtQuick 2.2 import QtQuick.Controls.Styles 1.4 import "TestUtils.js" as TestUtils TestCase { id: testcase name: "Tests_Gauge" visible: true when: windowShown width: 200 height: 200 property var gauge Rectangle { anchors.fill: parent color: "black" } property Component zeroTickmarkWidthGaugeStyle: GaugeStyle { tickmark: Item { implicitWidth: 0 implicitHeight: 1 } } property Component largeGaugeStyle: GaugeStyle { tickmark: Item { implicitWidth: 8 implicitHeight: 4 } } function init() { gauge = Qt.createQmlObject("import QtQuick.Extras 1.4; Gauge { }", testcase, ""); verify(gauge, "Gauge: failed to create an instance"); verify(gauge.__style); } function cleanup() { if (gauge) gauge.destroy(); } function test_assignStyle() { gauge.style = zeroTickmarkWidthGaugeStyle; compare(gauge.__panel.tickmarkLabelBoundsWidth, gauge.__hiddenText.width); compare(gauge.__panel.tickmarkLength, 0); compare(gauge.__panel.tickmarkWidth, 1); // Ensure that our internals are correct after changing to smaller tickmarks. gauge.style = largeGaugeStyle; compare(gauge.__panel.tickmarkLabelBoundsWidth, gauge.__hiddenText.width + 8); compare(gauge.__panel.tickmarkLength, 8); compare(gauge.__panel.tickmarkWidth, 4); gauge.style = zeroTickmarkWidthGaugeStyle; compare(gauge.__panel.tickmarkLabelBoundsWidth, gauge.__hiddenText.width); compare(gauge.__panel.tickmarkLength, 0); compare(gauge.__panel.tickmarkWidth, 1); } property Component centeredTickmarkStyle: GaugeStyle { tickmark: Item { implicitWidth: 10 implicitHeight: 4 Rectangle { // We must use this as the actual tickmark, because the parent is just spacing. objectName: "tickmark" + styleData.index x: control.tickmarkAlignment === Qt.AlignLeft || control.tickmarkAlignment === Qt.AlignTop ? parent.implicitWidth : -28 width: 28 height: parent.height } } valueBar: Rectangle { objectName: "valueBar" implicitWidth: 28 Text { text: parent.width } } } function test_valueBarPosition_data() { return [ { tag: "AlignLeft", orientation: Qt.Vertical, tickmarkAlignment: Qt.AlignLeft }, { tag: "AlignRight", orientation: Qt.Vertical, tickmarkAlignment: Qt.AlignRight }, // TODO: these combinations work, but the tests need to account for them (perhaps due to rotation) // { tag: "AlignTop", orientation: Qt.Horizontal, tickmarkAlignment: Qt.AlignTop }, // { tag: "AlignBottom", orientation: Qt.Horizontal, tickmarkAlignment: Qt.AlignBottom }, ]; } function test_valueBarPosition(data) { gauge.orientation = data.orientation; gauge.tickmarkAlignment = data.tickmarkAlignment; gauge.value = 1.8; gauge.maximumValue = 4; gauge.tickmarkStepSize = 1; gauge.minorTickmarkCount = 1; gauge.width = 50; gauge.style = centeredTickmarkStyle; var valueBar = TestUtils.findChild(gauge, "valueBar"); var firstTickmark = TestUtils.findChild(gauge, "tickmark0"); compare(testcase.mapFromItem(valueBar, 0, 0).x, testcase.mapFromItem(firstTickmark, 0, 0).x); } property Component tickmarkValueStyle: GaugeStyle { tickmark: Rectangle { implicitWidth: 10 implicitHeight: 4 objectName: "tickmark" + styleData.index readonly property real value: styleData.value readonly property real valuePosition: styleData.valuePosition } minorTickmark: Rectangle { implicitWidth: 5 implicitHeight: 2 objectName: "minorTickmark" + styleData.index readonly property real value: styleData.value readonly property real valuePosition: styleData.valuePosition } } function test_gaugeTickmarkValues_data() { var data = [ { tickmarkStepSize: 1, minorTickmarkCount: 4, minimumValue: 0, maximumValue: 5, expectedTickmarkValues: [0, 1, 2, 3, 4, 5], expectedMinorTickmarkValues: [0.2, 0.4, 0.6, 0.8, 1.2, 1.4, 1.6, 1.8, 2.2, 2.4, 2.6, 2.8, 3.2, 3.4, 3.6, 3.8, 4.2, 4.4, 4.6, 4.8], expectedTickmarkValuePositions: [0, 19, 38, 58, 77, 96], expectedMinorTickmarkValuePositions: [6, 9, 12, 15, 25, 28, 31, 34, 44, 47, 51, 54, 64, 67, 70, 73, 83, 86, 89, 92] }, { tickmarkStepSize: 1, minorTickmarkCount: 1, minimumValue: 0, maximumValue: 5, expectedTickmarkValues: [0, 1, 2, 3, 4, 5], expectedMinorTickmarkValues: [0.5, 1.5, 2.5, 3.5, 4.5], expectedTickmarkValuePositions: [0, 19, 38, 58, 77, 96], expectedMinorTickmarkValuePositions: [11, 30, 49, 68, 87] }, { tickmarkStepSize: 1, minorTickmarkCount: 1, minimumValue: -1, maximumValue: 1, expectedTickmarkValues: [-1, 0, 1], expectedMinorTickmarkValues: [-0.5, 0.5], expectedTickmarkValuePositions: [0, 48, 96], expectedMinorTickmarkValuePositions: [25, 73] }, { tickmarkStepSize: 1, minorTickmarkCount: 1, minimumValue: -2, maximumValue: -1, expectedTickmarkValues: [-2, -1], expectedMinorTickmarkValues: [-1.5], expectedTickmarkValuePositions: [0, 96], expectedMinorTickmarkValuePositions: [49] }, { tickmarkStepSize: 0.5, minorTickmarkCount: 1, minimumValue: 1, maximumValue: 2, expectedTickmarkValues: [1, 1.5, 2], expectedMinorTickmarkValues: [1.25, 1.75], expectedTickmarkValuePositions: [0, 48, 96], expectedMinorTickmarkValuePositions: [25, 73] }, { tickmarkStepSize: 0.5, minorTickmarkCount: 1, minimumValue: -0.5, maximumValue: 0.5, expectedTickmarkValues: [-0.5, 0, 0.5], expectedMinorTickmarkValues: [-0.25, 0.25], expectedTickmarkValuePositions: [0, 48, 96], expectedMinorTickmarkValuePositions: [25, 73] } ]; for (var i = 0; i < data.length; ++i) { data[i].tag = "tickmarkStepSize=" + data[i].tickmarkStepSize + " minorTickmarkCount=" + data[i].minorTickmarkCount + " minimumValue=" + data[i].minimumValue + " maximumValue=" + data[i].maximumValue; } return data; } function gaugeHeightFor100PixelHighValueBar(gauge) { return 100 + gauge.__panel.tickmarkOffset * 2 - 2; } function test_gaugeTickmarkValues(data) { gauge.minimumValue = data.minimumValue; gauge.maximumValue = data.maximumValue; gauge.minorTickmarkCount = data.minorTickmarkCount; gauge.tickmarkStepSize = data.tickmarkStepSize; gauge.style = tickmarkValueStyle; // To make it easier on us, we expect the max length of the value bar to be 100. gauge.height = gaugeHeightFor100PixelHighValueBar(gauge); compare(gauge.__panel.barLength, 100); // Give stuff time to re-layout after the new control height, etc., // otherwise we'll be comparing against incorrect pixel positions. wait(0); for (var tickmarkIndex = 0; tickmarkIndex < data.expectedTickmarkValues.length; ++tickmarkIndex) { var tickmark = TestUtils.findChild(gauge, "tickmark" + tickmarkIndex); compare(tickmark.value, data.expectedTickmarkValues[tickmarkIndex], "Value of tickmark at index " + tickmarkIndex + " is " + data.expectedTickmarkValues[tickmarkIndex]); var expectedValuePos = data.expectedTickmarkValuePositions[tickmarkIndex]; compare(tickmark.valuePosition, expectedValuePos, "Value position of tickmark at index " + tickmarkIndex + " is " + expectedValuePos); } for (var minorTickmarkIndex = 0; minorTickmarkIndex < data.expectedMinorTickmarkValues.length; ++minorTickmarkIndex) { var minorTickmark = TestUtils.findChild(gauge, "minorTickmark" + minorTickmarkIndex); compare(minorTickmark.value, data.expectedMinorTickmarkValues[minorTickmarkIndex], "Value of minor tickmark at index " + minorTickmarkIndex + " is " + data.expectedMinorTickmarkValues[minorTickmarkIndex]); expectedValuePos = data.expectedMinorTickmarkValuePositions[minorTickmarkIndex]; compare(minorTickmark.valuePosition, expectedValuePos, "Value position of minor tickmark at index " + minorTickmarkIndex + " is " + expectedValuePos); } } function test_formatValue() { var formatValueCalled = false; gauge.formatValue = function(value) { formatValueCalled = true; return value; } verify(formatValueCalled); } function test_valuePosition() { gauge.minimumValue = 0; gauge.maximumValue = 100; gauge.tickmarkStepSize = 10; // To make it easier on us, we expect the max length of the value bar to be 100. gauge.height = gaugeHeightFor100PixelHighValueBar(gauge); compare(gauge.__panel.barLength, 100); for (var i = gauge.minimumValue; i < gauge.maximumValue; ++i) { compare(gauge.__style.valuePosition, 0); } } }