-rw-r--r-- | qtcompat/qgridview.cpp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/qtcompat/qgridview.cpp b/qtcompat/qgridview.cpp new file mode 100644 index 0000000..bee3698 --- a/dev/null +++ b/qtcompat/qgridview.cpp | |||
@@ -0,0 +1,362 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Implementation of QGridView class | ||
5 | ** | ||
6 | ** Created: 010523 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2001 Trolltech AS. All rights reserved. | ||
9 | ** | ||
10 | ** This file is part of the widgets module of the Qt GUI Toolkit. | ||
11 | ** | ||
12 | ** This file may be distributed under the terms of the Q Public License | ||
13 | ** as defined by Trolltech AS of Norway and appearing in the file | ||
14 | ** LICENSE.QPL included in the packaging of this file. | ||
15 | ** | ||
16 | ** This file may be distributed and/or modified under the terms of the | ||
17 | ** GNU General Public License version 2 as published by the Free Software | ||
18 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
19 | ** packaging of this file. | ||
20 | ** | ||
21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition | ||
22 | ** licenses may use this file in accordance with the Qt Commercial License | ||
23 | ** Agreement provided with the Software. | ||
24 | ** | ||
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
27 | ** | ||
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | ||
29 | ** information about Qt Commercial License Agreements. | ||
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | ||
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
32 | ** | ||
33 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
34 | ** not clear to you. | ||
35 | ** | ||
36 | **********************************************************************/ | ||
37 | |||
38 | |||
39 | #include "qgridview.h" | ||
40 | |||
41 | #ifndef QT_NO_GRIDVIEW | ||
42 | |||
43 | #include "qpainter.h" | ||
44 | |||
45 | /*! | ||
46 | \class QGridView qgridview.h | ||
47 | \brief The QGridView class provides an abstract base for fixed-size | ||
48 | grids. | ||
49 | |||
50 | \ingroup abstractwidgets | ||
51 | |||
52 | A grid view consists of a number of abstract cells organized in rows | ||
53 | and columns. The cells have a fixed size and are identified with a | ||
54 | row index and a column index. The top-left cell is in row 0, column | ||
55 | 0. The bottom-right cell is in row numRows()-1, column numCols()-1. | ||
56 | |||
57 | You can define \l numRows, \l numCols, \l cellWidth and | ||
58 | \l cellHeight. Reimplement the pure virtual function paintCell() to | ||
59 | draw the content of a cell. | ||
60 | |||
61 | With ensureCellVisible(), you can ensure a certain cell is | ||
62 | visible. With rowAt() and columnAt() you can find a cell based on | ||
63 | the given x- and y-coordinates. | ||
64 | |||
65 | If you need to monitor changes to the grid's dimensions (i.e. when | ||
66 | numRows or numCols is changed), reimplement the dimensionChange() | ||
67 | change handler. | ||
68 | |||
69 | Note: the row, column indices are always given in the order, row | ||
70 | (vertical offset) then column (horizontal offset). This order is the | ||
71 | opposite of all pixel operations, which are given in the order x | ||
72 | (horizontal offset), y (vertical offset). | ||
73 | |||
74 | QGridView is a very simple abstract class based on QScrollView. It | ||
75 | is designed to simplify the task of drawing many cells of the same | ||
76 | size in a potentially scrollable canvas. If you need rows and | ||
77 | columns in different sizes, use a QTable instead. If you need a | ||
78 | simple list of items, use a QListBox. If you need to present | ||
79 | hierachical data use a QListView, and if you need random objects at | ||
80 | random positions, consider using either a QIconView or a QCanvas. | ||
81 | |||
82 | */ | ||
83 | |||
84 | |||
85 | /*! | ||
86 | Constructs a grid view. | ||
87 | |||
88 | The \a parent, \a name and widget flag, \a f, arguments are passed to the | ||
89 | QScrollView constructor. | ||
90 | */ | ||
91 | QGridView::QGridView( QWidget *parent, const char *name, WFlags f ) | ||
92 | :QScrollView( parent, name ,f ),nrows(5),ncols(5),cellw(12),cellh(12) | ||
93 | { | ||
94 | viewport()->setBackgroundMode( PaletteBase ); | ||
95 | setBackgroundMode( PaletteBackground ); | ||
96 | viewport()->setFocusProxy( this ); | ||
97 | } | ||
98 | |||
99 | /*! | ||
100 | Destroys the grid view. | ||
101 | */ | ||
102 | QGridView::~QGridView() | ||
103 | { | ||
104 | } | ||
105 | |||
106 | void QGridView::updateGrid() | ||
107 | { | ||
108 | resizeContents( ncols * cellw, nrows * cellh ); | ||
109 | } | ||
110 | |||
111 | /*! \property QGridView::numRows | ||
112 | \brief The number of rows in the grid | ||
113 | |||
114 | \sa numCols | ||
115 | */ | ||
116 | void QGridView::setNumRows( int numRows ) | ||
117 | { | ||
118 | int oldnrows = nrows; | ||
119 | nrows = numRows; | ||
120 | dimensionChange( oldnrows, ncols ); | ||
121 | updateGrid(); | ||
122 | } | ||
123 | |||
124 | /*! \property QGridView::numCols | ||
125 | \brief The number of columns in the grid | ||
126 | |||
127 | \sa numRows | ||
128 | */ | ||
129 | void QGridView::setNumCols( int numCols ) | ||
130 | { | ||
131 | int oldncols = ncols; | ||
132 | ncols = numCols; | ||
133 | dimensionChange( nrows, oldncols ); | ||
134 | updateGrid(); | ||
135 | } | ||
136 | |||
137 | /*! \property QGridView::cellWidth | ||
138 | \brief The width of a grid column | ||
139 | |||
140 | All columns in a grid view have the same width. | ||
141 | |||
142 | \sa cellHeight | ||
143 | */ | ||
144 | void QGridView::setCellWidth( int cellWidth ) | ||
145 | { | ||
146 | cellw = cellWidth; | ||
147 | updateGrid(); | ||
148 | updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); | ||
149 | } | ||
150 | |||
151 | /*! \property QGridView::cellHeight | ||
152 | \brief The height of a grid row | ||
153 | |||
154 | All rows in a grid view have the same height. | ||
155 | |||
156 | \sa cellWidth | ||
157 | */ | ||
158 | void QGridView::setCellHeight( int cellHeight ) | ||
159 | { | ||
160 | cellh = cellHeight; | ||
161 | updateGrid(); | ||
162 | updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); | ||
163 | } | ||
164 | |||
165 | /*! | ||
166 | Returns the geometry of cell (\a row, \a column) in the content | ||
167 | coordinate system. | ||
168 | |||
169 | \sa cellRect() | ||
170 | */ | ||
171 | QRect QGridView::cellGeometry( int row, int column ) | ||
172 | { | ||
173 | QRect r; | ||
174 | if ( row >= 0 && row < nrows && column >= 0 && column < ncols ) | ||
175 | r.setRect( cellw * column, cellh * row, cellw, cellh ); | ||
176 | return r; | ||
177 | } | ||
178 | |||
179 | /*! Repaints cell (\a row, \a column). | ||
180 | |||
181 | If \a erase is TRUE, Qt erases the area of the cell before the | ||
182 | paintCell() call; otherwise no erasing takes place. | ||
183 | |||
184 | \sa QWidget::repaint() | ||
185 | */ | ||
186 | void QGridView::repaintCell( int row, int column, bool erase ) | ||
187 | { | ||
188 | QScrollView::repaintContents( cellGeometry( row, column ), erase ); | ||
189 | } | ||
190 | |||
191 | /*! Updates cell (\a row, \a column). | ||
192 | |||
193 | \sa QWidget::update() | ||
194 | */ | ||
195 | void QGridView::updateCell( int row, int column ) | ||
196 | { | ||
197 | updateContents( cellGeometry( row, column ) ); | ||
198 | } | ||
199 | |||
200 | /*! | ||
201 | Ensure cell (\a row, \a column) is visible, scrolling the grid view | ||
202 | if necessary. | ||
203 | */ | ||
204 | void QGridView::ensureCellVisible( int row, int column ) | ||
205 | { | ||
206 | QRect r = cellGeometry( row, column ); | ||
207 | ensureVisible( r.x(), r.y(), r.width(), r.height() ); | ||
208 | } | ||
209 | |||
210 | /*! This function fills the \a cw pixels wide and \a ch pixels high | ||
211 | rectangle starting at position (\a cx, \a cy) with the | ||
212 | background color using the painter \a p. | ||
213 | |||
214 | paintEmptyArea() is invoked by drawContents() to erase | ||
215 | or fill unused areas. | ||
216 | */ | ||
217 | |||
218 | void QGridView::paintEmptyArea( QPainter *p, int cx ,int cy, int cw, int ch) | ||
219 | { | ||
220 | if ( gridSize().width() >= contentsWidth() && gridSize().height() >= contentsHeight() ) | ||
221 | return; | ||
222 | // Region of the rect we should draw | ||
223 | contentsToViewport( cx, cy, cx, cy ); | ||
224 | QRegion reg( QRect( cx, cy, cw, ch ) ); | ||
225 | // Subtract the table from it | ||
226 | reg = reg.subtract( QRect( contentsToViewport( QPoint( 0, 0 ) ), gridSize() ) ); | ||
227 | |||
228 | // And draw the rectangles (transformed as needed) | ||
229 | QArray<QRect> r = reg.rects(); | ||
230 | QBrush brush = colorGroup().brush( QColorGroup::Background ); | ||
231 | for ( int i = 0; i < (int)r.count(); ++i) | ||
232 | p->fillRect( r[ i ], brush ); | ||
233 | } | ||
234 | |||
235 | /*!\reimp | ||
236 | */ | ||
237 | void QGridView::drawContents( QPainter *p, int cx, int cy, int cw, int ch ) | ||
238 | { | ||
239 | int colfirst = columnAt( cx ); | ||
240 | int collast = columnAt( cx + cw ); | ||
241 | int rowfirst = rowAt( cy ); | ||
242 | int rowlast = rowAt( cy + ch ); | ||
243 | |||
244 | if ( rowfirst == -1 || colfirst == -1 ) { | ||
245 | paintEmptyArea( p, cx, cy, cw, ch ); | ||
246 | return; | ||
247 | } | ||
248 | |||
249 | if ( collast < 0 || collast >= ncols ) | ||
250 | collast = ncols-1; | ||
251 | if ( rowlast < 0 || rowlast >= nrows ) | ||
252 | rowlast = nrows-1; | ||
253 | |||
254 | // Go through the rows | ||
255 | for ( int r = rowfirst; r <= rowlast; ++r ) { | ||
256 | // get row position and height | ||
257 | int rowp = r * cellh; | ||
258 | |||
259 | // Go through the columns in the row r | ||
260 | // if we know from where to where, go through [colfirst, collast], | ||
261 | // else go through all of them | ||
262 | for ( int c = colfirst; c <= collast; ++c ) { | ||
263 | // get position and width of column c | ||
264 | int colp = c * cellw; | ||
265 | // Translate painter and draw the cell | ||
266 | p->translate( colp, rowp ); | ||
267 | paintCell( p, r, c ); | ||
268 | p->translate( -colp, -rowp ); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | // Paint empty rects | ||
273 | paintEmptyArea( p, cx, cy, cw, ch ); | ||
274 | } | ||
275 | |||
276 | /*! | ||
277 | \reimp | ||
278 | |||
279 | (Implemented to get rid of a compiler warning.) | ||
280 | */ | ||
281 | void QGridView::drawContents( QPainter * ) | ||
282 | { | ||
283 | } | ||
284 | |||
285 | /*! \fn void QGridView::dimensionChange( int oldNumRows, int oldNumCols ) | ||
286 | |||
287 | This change handler is called whenever any of the grid's dimensions | ||
288 | changes. \a oldNumRows and \a oldNumCols contain the old dimensions, | ||
289 | numRows() and numCols() contain the new dimensions. | ||
290 | */ | ||
291 | void QGridView::dimensionChange( int, int ) {} | ||
292 | |||
293 | |||
294 | |||
295 | /*! \fn int QGridView::rowAt( int y ) const | ||
296 | |||
297 | Returns the number of the row at position \a y. \a y must be given in | ||
298 | content coordinates. | ||
299 | |||
300 | \sa columnAt() | ||
301 | */ | ||
302 | |||
303 | /*! \fn int QGridView::columnAt( int x ) const | ||
304 | |||
305 | Returns the number of the column at position \a x. \a x must be | ||
306 | given in content coordinates. | ||
307 | |||
308 | \sa rowAt() | ||
309 | */ | ||
310 | |||
311 | /*! | ||
312 | \fn void QGridView::paintCell( QPainter *p, int row, int col ) | ||
313 | |||
314 | This pure virtual function is called to paint the single cell at | ||
315 | (\a row, \a col) using painter \a p. The painter must be open when | ||
316 | paintCell() is called and must remain open. | ||
317 | |||
318 | The coordinate system is \link QPainter::translate() translated \endlink | ||
319 | so that the origin is at the top-left corner of the cell to be | ||
320 | painted, i.e. \e cell coordinates. Do not scale or shear the coordinate | ||
321 | system (or if you do, restore the transformation matrix before you | ||
322 | return). | ||
323 | |||
324 | The painter is not clipped by default in order to get maximum | ||
325 | efficiency. If you want clipping, use | ||
326 | |||
327 | \code | ||
328 | p->setClipRect( cellRect(), QPainter::CoordPainter ); | ||
329 | //... your drawing code | ||
330 | p->setClipping( FALSE ); | ||
331 | |||
332 | \endcode | ||
333 | |||
334 | */ | ||
335 | |||
336 | /*! \fn QRect QGridView::cellRect() const | ||
337 | |||
338 | Returns the geometry of a cell in a cell's coordinate system. This | ||
339 | is a convenience function useful in paintCell(). It is equivalent to | ||
340 | QRect( 0, 0, cellWidth(), cellHeight() ). | ||
341 | |||
342 | \sa cellGeometry() | ||
343 | |||
344 | */ | ||
345 | |||
346 | /*!\fn QSize QGridView::gridSize() const | ||
347 | |||
348 | Returns the size of the grid in pixels. | ||
349 | |||
350 | */ | ||
351 | |||
352 | /*! | ||
353 | \overload | ||
354 | Repaints the contents. If \a erase is TRUE the | ||
355 | background is cleared using the background color. | ||
356 | */ | ||
357 | void QGridView::repaintContents( bool erase ) | ||
358 | { | ||
359 | QScrollView::repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), erase ); | ||
360 | } | ||
361 | |||
362 | #endif // QT_NO_GRIDVIEW | ||