]> sigrok.org Git - pulseview.git/blob - pv/widgets/wellarray.cpp
QWellArray: Removed QT_NO_MENU functionality
[pulseview.git] / pv / widgets / wellarray.cpp
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 #include <QPainter>
43 #include <QPaintEvent>
44 #include <QStyle>
45 #include <QStyleOptionFrame>
46
47 #include "wellarray.h"
48
49 void QWellArray::paintEvent(QPaintEvent *e)
50 {
51     QRect r = e->rect();
52     int cx = r.x();
53     int cy = r.y();
54     int ch = r.height();
55     int cw = r.width();
56     int colfirst = columnAt(cx);
57     int collast = columnAt(cx + cw);
58     int rowfirst = rowAt(cy);
59     int rowlast = rowAt(cy + ch);
60
61     if (isRightToLeft()) {
62         int t = colfirst;
63         colfirst = collast;
64         collast = t;
65     }
66
67     QPainter painter(this);
68     QPainter *p = &painter;
69     QRect rect(0, 0, cellWidth(), cellHeight());
70
71
72     if (collast < 0 || collast >= ncols)
73         collast = ncols-1;
74     if (rowlast < 0 || rowlast >= nrows)
75         rowlast = nrows-1;
76
77     // Go through the rows
78     for (int r = rowfirst; r <= rowlast; ++r) {
79         // get row position and height
80         int rowp = rowY(r);
81
82         // Go through the columns in the row r
83         // if we know from where to where, go through [colfirst, collast],
84         // else go through all of them
85         for (int c = colfirst; c <= collast; ++c) {
86             // get position and width of column c
87             int colp = columnX(c);
88             // Translate painter and draw the cell
89             rect.translate(colp, rowp);
90             paintCell(p, r, c, rect);
91             rect.translate(-colp, -rowp);
92         }
93     }
94 }
95
96 struct QWellArrayData {
97     QBrush *brush;
98 };
99
100 QWellArray::QWellArray(int rows, int cols, QWidget *parent)
101     : QWidget(parent)
102         ,nrows(rows), ncols(cols)
103 {
104     d = 0;
105     setFocusPolicy(Qt::StrongFocus);
106     cellw = 28;
107     cellh = 24;
108     curCol = 0;
109     curRow = 0;
110     selCol = -1;
111     selRow = -1;
112 }
113
114 QSize QWellArray::sizeHint() const
115 {
116     ensurePolished();
117     return gridSize().boundedTo(QSize(640, 480));
118 }
119
120
121 void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
122 {
123     int b = 3; //margin
124
125     const QPalette & g = palette();
126     QStyleOptionFrame opt;
127     int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
128     opt.lineWidth = dfw;
129     opt.midLineWidth = 1;
130     opt.rect = rect.adjusted(b, b, -b, -b);
131     opt.palette = g;
132     opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
133     style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
134     b += dfw;
135
136     if ((row == curRow) && (col == curCol)) {
137         if (hasFocus()) {
138             QStyleOptionFocusRect opt;
139             opt.palette = g;
140             opt.rect = rect;
141             opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
142             style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
143         }
144     }
145     paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
146 }
147
148 /*!
149   Reimplement this function to change the contents of the well array.
150  */
151 void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
152 {
153     if (d) {
154         p->fillRect(r, d->brush[row*numCols()+col]);
155     } else {
156         p->fillRect(r, Qt::white);
157         p->setPen(Qt::black);
158         p->drawLine(r.topLeft(), r.bottomRight());
159         p->drawLine(r.topRight(), r.bottomLeft());
160     }
161 }
162
163 void QWellArray::mousePressEvent(QMouseEvent *e)
164 {
165     // The current cell marker is set to the cell the mouse is pressed in
166     QPoint pos = e->pos();
167     setCurrent(rowAt(pos.y()), columnAt(pos.x()));
168 }
169
170 void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
171 {
172     // The current cell marker is set to the cell the mouse is clicked in
173     setSelected(curRow, curCol);
174 }
175
176
177 /*
178   Sets the cell currently having the focus. This is not necessarily
179   the same as the currently selected cell.
180 */
181
182 void QWellArray::setCurrent(int row, int col)
183 {
184     if ((curRow == row) && (curCol == col))
185         return;
186
187     if (row < 0 || col < 0)
188         row = col = -1;
189
190     int oldRow = curRow;
191     int oldCol = curCol;
192
193     curRow = row;
194     curCol = col;
195
196     updateCell(oldRow, oldCol);
197     updateCell(curRow, curCol);
198 }
199
200 /*
201   Sets the currently selected cell to \a row, \a column. If \a row or
202   \a column are less than zero, the current cell is unselected.
203
204   Does not set the position of the focus indicator.
205 */
206 void QWellArray::setSelected(int row, int col)
207 {
208     int oldRow = selRow;
209     int oldCol = selCol;
210
211     if (row < 0 || col < 0)
212         row = col = -1;
213
214     selCol = col;
215     selRow = row;
216
217     updateCell(oldRow, oldCol);
218     updateCell(selRow, selCol);
219     if (row >= 0)
220         emit selected(row, col);
221 }
222
223 void QWellArray::focusInEvent(QFocusEvent*)
224 {
225     updateCell(curRow, curCol);
226 }
227
228 void QWellArray::setCellBrush(int row, int col, const QBrush &b)
229 {
230     if (!d) {
231         d = new QWellArrayData;
232         int i = numRows()*numCols();
233         d->brush = new QBrush[i];
234     }
235     if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
236         d->brush[row*numCols()+col] = b;
237 }
238
239 /*
240   Returns the brush set for the cell at \a row, \a column. If no brush is
241   set, Qt::NoBrush is returned.
242 */
243
244 QBrush QWellArray::cellBrush(int row, int col)
245 {
246     if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
247         return d->brush[row*numCols()+col];
248     return Qt::NoBrush;
249 }
250
251
252
253 /*!\reimp
254 */
255
256 void QWellArray::focusOutEvent(QFocusEvent*)
257 {
258     updateCell(curRow, curCol);
259 }
260
261 /*\reimp
262 */
263 void QWellArray::keyPressEvent(QKeyEvent* e)
264 {
265     switch(e->key()) {                        // Look at the key code
266     case Qt::Key_Left:                                // If 'left arrow'-key,
267         if(curCol > 0)                        // and cr't not in leftmost col
268             setCurrent(curRow, curCol - 1);        // set cr't to next left column
269         break;
270     case Qt::Key_Right:                                // Correspondingly...
271         if(curCol < numCols()-1)
272             setCurrent(curRow, curCol + 1);
273         break;
274     case Qt::Key_Up:
275         if(curRow > 0)
276             setCurrent(curRow - 1, curCol);
277         break;
278     case Qt::Key_Down:
279         if(curRow < numRows()-1)
280             setCurrent(curRow + 1, curCol);
281         break;
282     case Qt::Key_Space:
283         setSelected(curRow, curCol);
284         break;
285     default:                                // If not an interesting key,
286         e->ignore();                        // we don't accept the event
287         return;
288     }
289
290 }