PulseView  0.3.0
A Qt-based sigrok GUI
wellarray.cpp
Go to the documentation of this file.
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.hpp"
48 
49 namespace pv {
50 namespace widgets {
51 
52 void WellArray::paintEvent(QPaintEvent *e)
53 {
54  QRect r = e->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);
63 
64  if (isRightToLeft()) {
65  int t = colfirst;
66  colfirst = collast;
67  collast = t;
68  }
69 
70  QPainter painter(this);
71  QPainter *p = &painter;
72  QRect rect(0, 0, cellWidth(), cellHeight());
73 
74 
75  if (collast < 0 || collast >= ncols)
76  collast = ncols-1;
77  if (rowlast < 0 || rowlast >= nrows)
78  rowlast = nrows-1;
79 
80  // Go through the rows
81  for (int r = rowfirst; r <= rowlast; ++r) {
82  // get row position and height
83  int rowp = rowY(r);
84 
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);
95  }
96  }
97 }
98 
99 struct WellArrayData {
100  QBrush *brush;
101 };
102 
103 WellArray::WellArray(int rows, int cols, QWidget *parent)
104  : QWidget(parent)
105  ,nrows(rows), ncols(cols)
106 {
107  d = 0;
108  setFocusPolicy(Qt::StrongFocus);
109  cellw = 28;
110  cellh = 24;
111  curCol = 0;
112  curRow = 0;
113  selCol = -1;
114  selRow = -1;
115 }
116 
117 QSize WellArray::sizeHint() const
118 {
119  ensurePolished();
120  return gridSize().boundedTo(QSize(640, 480));
121 }
122 
123 
124 void WellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
125 {
126  int b = 3; //margin
127 
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;
138 
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);
146  }
147  }
148  paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
149 }
150 
154 void WellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
155 {
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());
163  }
164 }
165 
166 void WellArray::mousePressEvent(QMouseEvent *e)
167 {
168  // The current cell marker is set to the cell the mouse is pressed in
169  QPoint pos = e->pos();
170  setCurrent(rowAt(pos.y()), columnAt(pos.x()));
171 }
172 
173 void WellArray::mouseReleaseEvent(QMouseEvent * /* event */)
174 {
175  // The current cell marker is set to the cell the mouse is clicked in
177 }
178 
179 
180 /*
181  Sets the cell currently having the focus. This is not necessarily
182  the same as the currently selected cell.
183 */
184 
185 void WellArray::setCurrent(int row, int col)
186 {
187  if ((curRow == row) && (curCol == col))
188  return;
189 
190  if (row < 0 || col < 0)
191  row = col = -1;
192 
193  int oldRow = curRow;
194  int oldCol = curCol;
195 
196  curRow = row;
197  curCol = col;
198 
199  updateCell(oldRow, oldCol);
201 }
202 
203 /*
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.
206 
207  Does not set the position of the focus indicator.
208 */
209 void WellArray::setSelected(int row, int col)
210 {
211  int oldRow = selRow;
212  int oldCol = selCol;
213 
214  if (row < 0 || col < 0)
215  row = col = -1;
216 
217  selCol = col;
218  selRow = row;
219 
220  updateCell(oldRow, oldCol);
222  if (row >= 0)
223  Q_EMIT selected(row, col);
224 }
225 
226 void WellArray::focusInEvent(QFocusEvent*)
227 {
229 }
230 
231 void WellArray::setCellBrush(int row, int col, const QBrush &b)
232 {
233  if (!d) {
234  d = new WellArrayData;
235  int i = numRows()*numCols();
236  d->brush = new QBrush[i];
237  }
238  if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
239  d->brush[row*numCols()+col] = b;
240 }
241 
242 /*
243  Returns the brush set for the cell at \a row, \a column. If no brush is
244  set, Qt::NoBrush is returned.
245 */
246 
247 QBrush WellArray::cellBrush(int row, int col)
248 {
249  if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
250  return d->brush[row*numCols()+col];
251  return Qt::NoBrush;
252 }
253 
254 
255 
259 void WellArray::focusOutEvent(QFocusEvent*)
260 {
262 }
263 
264 /*\reimp
265 */
266 void WellArray::keyPressEvent(QKeyEvent* e)
267 {
268  switch(e->key()) { // Look at the key code
269  case Qt::Key_Left: // If 'left arrow'-key,
270  if (curCol > 0) // and cr't not in leftmost col
271  setCurrent(curRow, curCol - 1); // set cr't to next left column
272  break;
273  case Qt::Key_Right: // Correspondingly...
274  if (curCol < numCols()-1)
275  setCurrent(curRow, curCol + 1);
276  break;
277  case Qt::Key_Up:
278  if (curRow > 0)
279  setCurrent(curRow - 1, curCol);
280  break;
281  case Qt::Key_Down:
282  if (curRow < numRows()-1)
283  setCurrent(curRow + 1, curCol);
284  break;
285  case Qt::Key_Space:
287  break;
288  default: // If not an interesting key,
289  e->ignore(); // we don't accept the event
290  return;
291  }
292 
293 }
294 
295 } // namespace wellarray
296 } // namespace pv
WellArrayData * d
Definition: wellarray.hpp:135
void keyPressEvent(QKeyEvent *)
Definition: wellarray.cpp:266
virtual void setSelected(int row, int col)
Definition: wellarray.cpp:209
virtual void paintCellContents(QPainter *, int row, int col, const QRect &)
Definition: wellarray.cpp:154
void paintEvent(QPaintEvent *)
Definition: wellarray.cpp:52
void focusOutEvent(QFocusEvent *)
Definition: wellarray.cpp:259
int numCols() const
Definition: wellarray.hpp:91
int columnAt(int x) const
Definition: wellarray.hpp:79
QBrush cellBrush(int row, int col)
Definition: wellarray.cpp:247
int rowAt(int y) const
Definition: wellarray.hpp:76
void focusInEvent(QFocusEvent *)
Definition: wellarray.cpp:226
virtual void paintCell(QPainter *, int row, int col, const QRect &)
Definition: wellarray.cpp:124
int cellHeight() const
Definition: wellarray.hpp:73
WellArray(int rows, int cols, QWidget *parent=0)
Definition: wellarray.cpp:103
int rowY(int row) const
Definition: wellarray.hpp:82
QSize gridSize() const
Definition: wellarray.hpp:97
void selected(int row, int col)
virtual void setCellBrush(int row, int col, const QBrush &)
Definition: wellarray.cpp:231
void mouseReleaseEvent(QMouseEvent *)
Definition: wellarray.cpp:173
int numRows() const
Definition: wellarray.hpp:88
void mousePressEvent(QMouseEvent *)
Definition: wellarray.cpp:166
QSize sizeHint() const
Definition: wellarray.cpp:117
int cellWidth() const
Definition: wellarray.hpp:70
int columnX(int column) const
Definition: wellarray.hpp:85
virtual void setCurrent(int row, int col)
Definition: wellarray.cpp:185
void updateCell(int row, int column)
Definition: wellarray.hpp:108