]> sigrok.org Git - pulseview.git/blame - pv/widgets/wellarray.cpp
Added missing includes and defintions
[pulseview.git] / pv / widgets / wellarray.cpp
CommitLineData
0c0e1888
JH
1/****************************************************************************
2**
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtGui 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 Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#define QT_NO_MENU
43
44#include <QPainter>
45#include <QPaintEvent>
46#include <QStyle>
47#include <QStyleOptionFrame>
48
49#include "wellarray.h"
50
51void QWellArray::paintEvent(QPaintEvent *e)
52{
53 QRect r = e->rect();
54 int cx = r.x();
55 int cy = r.y();
56 int ch = r.height();
57 int cw = r.width();
58 int colfirst = columnAt(cx);
59 int collast = columnAt(cx + cw);
60 int rowfirst = rowAt(cy);
61 int rowlast = rowAt(cy + ch);
62
63 if (isRightToLeft()) {
64 int t = colfirst;
65 colfirst = collast;
66 collast = t;
67 }
68
69 QPainter painter(this);
70 QPainter *p = &painter;
71 QRect rect(0, 0, cellWidth(), cellHeight());
72
73
74 if (collast < 0 || collast >= ncols)
75 collast = ncols-1;
76 if (rowlast < 0 || rowlast >= nrows)
77 rowlast = nrows-1;
78
79 // Go through the rows
80 for (int r = rowfirst; r <= rowlast; ++r) {
81 // get row position and height
82 int rowp = rowY(r);
83
84 // Go through the columns in the row r
85 // if we know from where to where, go through [colfirst, collast],
86 // else go through all of them
87 for (int c = colfirst; c <= collast; ++c) {
88 // get position and width of column c
89 int colp = columnX(c);
90 // Translate painter and draw the cell
91 rect.translate(colp, rowp);
92 paintCell(p, r, c, rect);
93 rect.translate(-colp, -rowp);
94 }
95 }
96}
97
98struct QWellArrayData {
99 QBrush *brush;
100};
101
102QWellArray::QWellArray(int rows, int cols, QWidget *parent)
103 : QWidget(parent)
104 ,nrows(rows), ncols(cols)
105{
106 d = 0;
107 setFocusPolicy(Qt::StrongFocus);
108 cellw = 28;
109 cellh = 24;
110 curCol = 0;
111 curRow = 0;
112 selCol = -1;
113 selRow = -1;
114}
115
116QSize QWellArray::sizeHint() const
117{
118 ensurePolished();
119 return gridSize().boundedTo(QSize(640, 480));
120}
121
122
123void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
124{
125 int b = 3; //margin
126
127 const QPalette & g = palette();
128 QStyleOptionFrame opt;
129 int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
130 opt.lineWidth = dfw;
131 opt.midLineWidth = 1;
132 opt.rect = rect.adjusted(b, b, -b, -b);
133 opt.palette = g;
134 opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
135 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
136 b += dfw;
137
138 if ((row == curRow) && (col == curCol)) {
139 if (hasFocus()) {
140 QStyleOptionFocusRect opt;
141 opt.palette = g;
142 opt.rect = rect;
143 opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
144 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
145 }
146 }
147 paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
148}
149
150/*!
151 Reimplement this function to change the contents of the well array.
152 */
153void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
154{
155 if (d) {
156 p->fillRect(r, d->brush[row*numCols()+col]);
157 } else {
158 p->fillRect(r, Qt::white);
159 p->setPen(Qt::black);
160 p->drawLine(r.topLeft(), r.bottomRight());
161 p->drawLine(r.topRight(), r.bottomLeft());
162 }
163}
164
165void QWellArray::mousePressEvent(QMouseEvent *e)
166{
167 // The current cell marker is set to the cell the mouse is pressed in
168 QPoint pos = e->pos();
169 setCurrent(rowAt(pos.y()), columnAt(pos.x()));
170}
171
172void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
173{
174 // The current cell marker is set to the cell the mouse is clicked in
175 setSelected(curRow, curCol);
176}
177
178
179/*
180 Sets the cell currently having the focus. This is not necessarily
181 the same as the currently selected cell.
182*/
183
184void QWellArray::setCurrent(int row, int col)
185{
186 if ((curRow == row) && (curCol == col))
187 return;
188
189 if (row < 0 || col < 0)
190 row = col = -1;
191
192 int oldRow = curRow;
193 int oldCol = curCol;
194
195 curRow = row;
196 curCol = col;
197
198 updateCell(oldRow, oldCol);
199 updateCell(curRow, curCol);
200}
201
202/*
203 Sets the currently selected cell to \a row, \a column. If \a row or
204 \a column are less than zero, the current cell is unselected.
205
206 Does not set the position of the focus indicator.
207*/
208void QWellArray::setSelected(int row, int col)
209{
210 int oldRow = selRow;
211 int oldCol = selCol;
212
213 if (row < 0 || col < 0)
214 row = col = -1;
215
216 selCol = col;
217 selRow = row;
218
219 updateCell(oldRow, oldCol);
220 updateCell(selRow, selCol);
221 if (row >= 0)
222 emit selected(row, col);
223
224#ifndef QT_NO_MENU
225 if (isVisible() && qobject_cast<QMenu*>(parentWidget()))
226 parentWidget()->close();
227#endif
228}
229
230void QWellArray::focusInEvent(QFocusEvent*)
231{
232 updateCell(curRow, curCol);
233}
234
235void QWellArray::setCellBrush(int row, int col, const QBrush &b)
236{
237 if (!d) {
238 d = new QWellArrayData;
239 int i = numRows()*numCols();
240 d->brush = new QBrush[i];
241 }
242 if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
243 d->brush[row*numCols()+col] = b;
244}
245
246/*
247 Returns the brush set for the cell at \a row, \a column. If no brush is
248 set, Qt::NoBrush is returned.
249*/
250
251QBrush QWellArray::cellBrush(int row, int col)
252{
253 if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
254 return d->brush[row*numCols()+col];
255 return Qt::NoBrush;
256}
257
258
259
260/*!\reimp
261*/
262
263void QWellArray::focusOutEvent(QFocusEvent*)
264{
265 updateCell(curRow, curCol);
266}
267
268/*\reimp
269*/
270void QWellArray::keyPressEvent(QKeyEvent* e)
271{
272 switch(e->key()) { // Look at the key code
273 case Qt::Key_Left: // If 'left arrow'-key,
274 if(curCol > 0) // and cr't not in leftmost col
275 setCurrent(curRow, curCol - 1); // set cr't to next left column
276 break;
277 case Qt::Key_Right: // Correspondingly...
278 if(curCol < numCols()-1)
279 setCurrent(curRow, curCol + 1);
280 break;
281 case Qt::Key_Up:
282 if(curRow > 0)
283 setCurrent(curRow - 1, curCol);
284 break;
285 case Qt::Key_Down:
286 if(curRow < numRows()-1)
287 setCurrent(curRow + 1, curCol);
288 break;
289#if 0
290 // bad idea that shouldn't have been implemented; very counterintuitive
291 case Qt::Key_Return:
292 case Qt::Key_Enter:
293 /*
294 ignore the key, so that the dialog get it, but still select
295 the current row/col
296 */
297 e->ignore();
298 // fallthrough intended
299#endif
300 case Qt::Key_Space:
301 setSelected(curRow, curCol);
302 break;
303 default: // If not an interesting key,
304 e->ignore(); // we don't accept the event
305 return;
306 }
307
308}