DecodeSignal: Support unitsize > 1 for logic output
[pulseview.git] / pv / widgets / wellarray.cpp
blob655ad87ef5639d8f9d11b14686b73eacbe0587f7
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.
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.
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.
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.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #include <QPaintEvent>
43 #include <QPainter>
44 #include <QStyle>
45 #include <QStyleOptionFrame>
47 #include "wellarray.hpp"
49 namespace pv {
50 namespace widgets {
52 void WellArray::paintEvent(QPaintEvent *event)
54 QRect r = event->rect();
55 int cx = r.x();
56 int cy = r.y();
57 int ch = r.height();
58 int cw = r.width();
59 int colfirst = columnAt(cx);
60 int collast = columnAt(cx + cw);
61 int rowfirst = rowAt(cy);
62 int rowlast = rowAt(cy + ch);
64 if (isRightToLeft()) {
65 int t = colfirst;
66 colfirst = collast;
67 collast = t;
70 QPainter painter(this);
71 QPainter *p = &painter;
72 QRect rect(0, 0, cellWidth(), cellHeight());
75 if (collast < 0 || collast >= ncols)
76 collast = ncols-1;
77 if (rowlast < 0 || rowlast >= nrows)
78 rowlast = nrows-1;
80 // Go through the rows
81 for (int r = rowfirst; r <= rowlast; ++r) {
82 // get row position and height
83 int rowp = rowY(r);
85 // Go through the columns in the row r
86 // if we know from where to where, go through [colfirst, collast],
87 // else go through all of them
88 for (int c = colfirst; c <= collast; ++c) {
89 // get position and width of column c
90 int colp = columnX(c);
91 // Translate painter and draw the cell
92 rect.translate(colp, rowp);
93 paintCell(p, r, c, rect);
94 rect.translate(-colp, -rowp);
99 struct WellArrayData {
100 QBrush *brush;
103 WellArray::WellArray(int rows, int cols, QWidget *parent)
104 : QWidget(parent)
105 ,nrows(rows), ncols(cols)
107 d = nullptr;
108 setFocusPolicy(Qt::StrongFocus);
109 cellw = 28;
110 cellh = 24;
111 curCol = 0;
112 curRow = 0;
113 selCol = -1;
114 selRow = -1;
117 QSize WellArray::sizeHint() const
119 ensurePolished();
120 return gridSize().boundedTo(QSize(640, 480));
124 void WellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
126 int b = 3; //margin
128 const QPalette& g = palette();
129 QStyleOptionFrame opt;
130 int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
131 opt.lineWidth = dfw;
132 opt.midLineWidth = 1;
133 opt.rect = rect.adjusted(b, b, -b, -b);
134 opt.palette = g;
135 opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
136 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
137 b += dfw;
139 if ((row == curRow) && (col == curCol)) {
140 if (hasFocus()) {
141 QStyleOptionFocusRect opt;
142 opt.palette = g;
143 opt.rect = rect;
144 opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
145 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
148 paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
152 Reimplement this function to change the contents of the well array.
154 void WellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
156 if (d) {
157 p->fillRect(r, d->brush[row*numCols()+col]);
158 } else {
159 p->fillRect(r, Qt::white);
160 p->setPen(Qt::black);
161 p->drawLine(r.topLeft(), r.bottomRight());
162 p->drawLine(r.topRight(), r.bottomLeft());
166 void WellArray::mousePressEvent(QMouseEvent *event)
168 // The current cell marker is set to the cell the mouse is pressed in
169 QPoint pos = event->pos();
170 setCurrent(rowAt(pos.y()), columnAt(pos.x()));
173 void WellArray::mouseReleaseEvent(QMouseEvent * /* event */)
175 // The current cell marker is set to the cell the mouse is clicked in
176 setSelected(curRow, curCol);
181 Sets the cell currently having the focus. This is not necessarily
182 the same as the currently selected cell.
185 void WellArray::setCurrent(int row, int col)
187 if ((curRow == row) && (curCol == col))
188 return;
190 if (row < 0 || col < 0)
191 row = col = -1;
193 int oldRow = curRow;
194 int oldCol = curCol;
196 curRow = row;
197 curCol = col;
199 updateCell(oldRow, oldCol);
200 updateCell(curRow, curCol);
204 Sets the currently selected cell to \a row, \a column. If \a row or
205 \a column are less than zero, the current cell is unselected.
207 Does not set the position of the focus indicator.
209 void WellArray::setSelected(int row, int col)
211 int oldRow = selRow;
212 int oldCol = selCol;
214 if (row < 0 || col < 0)
215 row = col = -1;
217 selCol = col;
218 selRow = row;
220 updateCell(oldRow, oldCol);
221 updateCell(selRow, selCol);
222 if (row >= 0)
223 selected(row, col);
226 void WellArray::focusInEvent(QFocusEvent*)
228 updateCell(curRow, curCol);
231 void WellArray::setCellBrush(int row, int col, const QBrush &b)
233 if (!d) {
234 d = new WellArrayData;
235 int i = numRows()*numCols();
236 d->brush = new QBrush[i];
238 if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
239 d->brush[row*numCols()+col] = b;
243 Returns the brush set for the cell at \a row, \a column. If no brush is
244 set, Qt::NoBrush is returned.
247 QBrush WellArray::cellBrush(int row, int col)
249 if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
250 return d->brush[row*numCols()+col];
251 return Qt::NoBrush;
255 /*!\reimp
258 void WellArray::focusOutEvent(QFocusEvent*)
260 updateCell(curRow, curCol);
263 /*\reimp
265 void WellArray::keyPressEvent(QKeyEvent* event)
267 switch (event->key()) { // Look at the key code
268 case Qt::Key_Left: // If 'left arrow'-key,
269 if (curCol > 0) // and cr't not in leftmost col
270 setCurrent(curRow, curCol - 1); // set cr't to next left column
271 break;
272 case Qt::Key_Right: // Correspondingly...
273 if (curCol < numCols()-1)
274 setCurrent(curRow, curCol + 1);
275 break;
276 case Qt::Key_Up:
277 if (curRow > 0)
278 setCurrent(curRow - 1, curCol);
279 break;
280 case Qt::Key_Down:
281 if (curRow < numRows()-1)
282 setCurrent(curRow + 1, curCol);
283 break;
284 case Qt::Key_Space:
285 setSelected(curRow, curCol);
286 break;
287 default: // If not an interesting key,
288 event->ignore(); // we don't accept the event
289 return;
294 } // namespace widgets
295 } // namespace pv