2
* This file is part of Checkbox.
4
* Copyright 2015 Canonical Ltd.
6
* Maciej Kisielewski <maciej.kisielewski@canonical.com>
8
* Checkbox is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 3,
10
* as published by the Free Software Foundation.
12
* Checkbox is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
21
import Ubuntu.Components 1.1
22
import QtQuick.Window 2.0
24
/*! \brief Generic Screen Test.
27
This widget is a page drawing fields that user should click in order to
28
satisfy test requiremets. Fields that have to be clicked appear in the same
29
order as they were added using add* methods. The first field will appear
30
once the runTest method is called.
39
Gets triggered when the last of queued targets receives fieldClicked.
44
Gets triggered when user clicks or taps the screen three times in a
45
quick succession (maximum of 400ms between taps/clicks).
46
This signal might be used to display a menu of advanced test options.
51
Gets triggered when any of the fields (visible or not) are
52
tapped/clicked/dragged onto.
53
By default this signal is used by internal logic of the whole test.
54
Connect to this signala if you need fine control over the test.
56
signal fieldClicked(var row, var col);
59
resolution sets the number of rows that the grid of fields should have.
60
Number of columns is set automatically to produce fields of the shape
61
as close to square as possible.
63
property var resolution: 20
66
call addTarget to add a new target to the queue of to-be-clicked
67
fields. The argument should contain `x` and `y` members that represent
68
coordinates in the grid.
69
Negative values mean index from the back. E.g. -1, -3 on a 10x10 grid
70
means indecies of: 9,7.
72
function addTarget(target) {
73
if (target.x < 0) target.x += _grid.cols;
74
if (target.y < 0) target.y += _grid.rows;
75
_targets.push(target);
79
addRandomTargets adds `count` of targets with random coordinates
81
function addRandomTargets(count) {
82
for (var i = 0; i < count; i++) {
84
"x": Math.floor(Math.random() * _grid.cols),
85
"y": Math.floor(Math.random() * _grid.rows)}
86
addTarget(randomField);
91
Call addEdge to add set of targets that consitute the edge of the
92
screen. `edgeName` is the string specifying which edge should be added.
93
This might be one of the following: 'top', 'bottom', 'right', 'left'.
95
function addEdge(edgeName) {
98
for(var i = 0; i < _grid.cols; i++)
99
addTarget({"x": i, "y": 0});
102
for(var i = _grid.cols - 1; i >= 0; i--)
103
addTarget({"x": i, "y": _grid.rows-1});
106
for(var i = _grid.rows - 1; i >= 0; i--)
107
addTarget({"x": 0, "y": i});
110
for(var i = 0; i < _grid.rows; i++)
111
addTarget({"x": _grid.cols-1, "y": i});
117
Call runTest() to start processing test fields.
118
Testing procedure normally ends with `onAllTargetsHit` signal being
122
var currentTarget = _targets.shift();
123
var col = currentTarget.x;
124
var row = currentTarget.y;
127
var fieldComponentName = "touchField-" + row.toString() +
128
"x" + col.toString();
129
var currentField = Qt.createQmlObject(
130
_touchFieldDefinition, screenTest, fieldComponentName);
131
currentField.width = _grid.fieldWidth;
132
currentField.height = _grid.fieldHeight;
133
currentField.x = _grid.fieldWidth*col;
134
currentField.y = _grid.fieldHeight*row;
135
currentField.color = UbuntuColors.green;
136
_grid[row][col].component = currentField
138
fieldClicked.connect(function(row, col) {
139
if(row === currentTarget.y && col === currentTarget.x) {
140
// disconnect self, so we don't activate ALL next fields while
141
// touching the current one
142
fieldClicked.disconnect(arguments.callee);
143
_grid[row][col].component.color = "grey";
144
if(_targets.length === 0) {
153
MultiPointTouchArea {
157
id: tripleClickTimeout
160
property var clickCount: 0
168
// signalling touchUpdated makes clicking with mouse without moving
169
// the cursor work as expected
170
touchUpdated(touchPoints)
171
tripleClickTimeout.restart();
172
if (++tripleClickTimeout.clickCount > 2) {
174
tripleClickTimeout.stop();
175
tripleClickTimeout.clickCount = 0;
180
for (var i in touchPoints) {
181
_grid.click(touchPoints[i].x, touchPoints[i].y);
186
Component.onCompleted: {
187
_grid = _createGrid(resolution);
190
function _createGrid(resolution) {
191
// initiate the grid of fields
192
// NOTE: components creation is deferred until they are needed
194
_grid.cols = Math.round(resolution*(width/height));
195
_grid.rows = resolution;
196
_grid.fieldWidth = width/_grid.cols;
197
_grid.fieldHeight = height/_grid.rows;
198
for (var row = 0; row<_grid.rows; row++) {
200
for (var col = 0; col<_grid.cols; col++) {
201
_grid[row][col] = {};
202
_grid[row][col].label = row.toString() + "x" + col.toString();
203
_grid[row][col].multi = row*col;
206
_grid.click = function(x, y) {
207
//compute indecies of the field from page coords
208
var col = Math.floor(x / _grid.fieldWidth);
209
var row = Math.floor(y / _grid.fieldHeight);
210
fieldClicked(row, col)
216
property var _targets: [];
217
// string used for dynamic creation of fields
218
property var _touchFieldDefinition: "