source: trunk/examples/qmag/qmag.cpp@ 20

Last change on this file since 20 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 9.7 KB
Line 
1/****************************************************************************
2** $Id: qmag.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
5**
6** This file is part of an example program for Qt. This example
7** program may be used, distributed and modified without limitation.
8**
9*****************************************************************************/
10
11#include <qcombobox.h>
12#include <qpushbutton.h>
13#include <qpixmap.h>
14#include <qimage.h>
15#include <qlabel.h>
16#include <qfiledialog.h>
17#include <qregexp.h>
18
19#include <qapplication.h>
20#include <qpainter.h>
21#include <qwmatrix.h>
22
23
24class MagWidget : public QWidget
25{
26 Q_OBJECT
27public:
28 MagWidget( QWidget *parent=0, const char *name=0 );
29
30public slots:
31 void setZoom( int );
32 void setRefresh( int );
33 void save();
34 void multiSave();
35
36protected:
37 void paintEvent( QPaintEvent * );
38 void mousePressEvent( QMouseEvent * );
39 void mouseReleaseEvent( QMouseEvent * );
40 void mouseMoveEvent( QMouseEvent * );
41 void focusOutEvent( QFocusEvent * );
42 void timerEvent( QTimerEvent * );
43 void resizeEvent( QResizeEvent * );
44
45private:
46 void grabAround(QPoint pos);
47 void grab();
48
49 QComboBox *zoom;
50 QComboBox *refresh;
51 QPushButton *saveButton;
52 QPushButton *multiSaveButton;
53 QPushButton *quitButton;
54 QPixmap pm; // pixmap, magnified
55 QPixmap p; // pixmap
56 QImage image; // image of pixmap (for RGB)
57 QLabel *rgb;
58 int yoffset; // pixels in addition to the actual picture
59 int z; // magnification factor
60 int r; // autorefresh rate (index into refreshrates)
61 bool grabbing; // TRUE if qmag is currently grabbing
62 int grabx, graby;
63 QString multifn; // filename for multisave
64};
65
66
67#ifdef COMPLEX_GUI
68static const char *zoomfactors[] = {
69 "100%", "200%", "300%", "400%", "500%",
70 "600%", "700%", "800%", "1600%", 0 };
71
72static const char *refreshrates[] = {
73 "No autorefresh", "50 per second", "4 per second", "3 per second", "2 per second",
74 "Every second", "Every two seconds", "Every three seconds",
75 "Every five seconds", "Every ten seconds", 0 };
76#endif
77
78static const int timer[] = {
79 0, 20, 250, 333, 500, 1000, 2000, 3000, 5000, 10000 };
80
81
82MagWidget::MagWidget( QWidget *parent, const char *name )
83 : QWidget( parent, name)
84{
85 z = 1; // default zoom (100%)
86 r = 0; // default refresh (none)
87
88#ifdef COMPLEX_GUI
89 int w=0, x=0, n;
90
91 zoom = new QComboBox( FALSE, this );
92 Q_CHECK_PTR(zoom);
93 zoom->insertStrList( zoomfactors, 9 );
94 connect( zoom, SIGNAL(activated(int)), SLOT(setZoom(int)) );
95
96 refresh = new QComboBox( FALSE, this );
97 Q_CHECK_PTR(refresh);
98 refresh->insertStrList( refreshrates, 9 );
99 connect( refresh, SIGNAL(activated(int)), SLOT(setRefresh(int)) );
100
101 for( n=0; n<9; n++) {
102 int w2 = zoom->fontMetrics().width( zoomfactors[n] );
103 w = QMAX(w2, w);
104 }
105 zoom->setGeometry( 2, 2, w+30, 20 );
106
107 x = w+34;
108 w = 0;
109 for( n=0; n<9; n++) {
110 int w2 = refresh->fontMetrics().width( refreshrates[n] );
111 w = QMAX(w2, w);
112 }
113 refresh->setGeometry( x, 2, w+30, 20 );
114
115 saveButton = new QPushButton( this );
116 Q_CHECK_PTR(saveButton);
117 connect( saveButton, SIGNAL(clicked()), this, SLOT(save()) );
118 saveButton->setText( "Save" );
119 saveButton->setGeometry( x+w+30+2, 2,
120 10+saveButton->fontMetrics().width("Save"), 20 );
121
122 multiSaveButton = new QPushButton( this );
123 multiSaveButton->setToggleButton(TRUE);
124 Q_CHECK_PTR(multiSaveButton);
125 connect( multiSaveButton, SIGNAL(clicked()), this, SLOT(multiSave()) );
126 multiSaveButton->setText( "MultiSave" );
127 multiSaveButton->setGeometry( saveButton->geometry().right() + 2, 2,
128 10+multiSaveButton->fontMetrics().width("MultiSave"), 20 );
129
130 quitButton = new QPushButton( this );
131 Q_CHECK_PTR(quitButton);
132 connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );
133 quitButton->setText( "Quit" );
134 quitButton->setGeometry( multiSaveButton->geometry().right() + 2, 2,
135 10+quitButton->fontMetrics().width("Quit"), 20 );
136#else
137 zoom = 0;
138 multiSaveButton = 0;
139#endif
140
141 setRefresh(1);
142 setZoom(5);
143
144 rgb = new QLabel( this );
145 Q_CHECK_PTR( rgb );
146 rgb->setText( "" );
147 rgb->setAlignment( AlignVCenter );
148 rgb->resize( width(), rgb->fontMetrics().height() + 4 );
149
150#ifdef COMPLEX_GUI
151 yoffset = zoom->height() // top buttons
152 + 4 // space around top buttons
153 + rgb->height(); // color-value text height
154 setMinimumSize( quitButton->pos().x(), yoffset+20 );
155 resize( quitButton->geometry().topRight().x() + 2, yoffset+60 );
156#else
157 yoffset = 0;
158 resize(350,350);
159#endif
160
161 grabx = graby = -1;
162 grabbing = FALSE;
163
164 setMouseTracking( TRUE ); // and do let me know what pixel I'm at, eh?
165
166 grabAround( QPoint(grabx=qApp->desktop()->width()/2, graby=qApp->desktop()->height()/2) );
167}
168
169
170void MagWidget::setZoom( int index )
171{
172 if (index == 8)
173 z = 16;
174 else
175 z = index+1;
176 grab();
177}
178
179
180void MagWidget::setRefresh( int index )
181{
182 r = index;
183 killTimers();
184 if (index && !grabbing)
185 startTimer( timer[r] );
186}
187
188
189void MagWidget::save()
190{
191 if ( !p.isNull() ) {
192 killTimers();
193 QString fn = QFileDialog::getSaveFileName();
194 if ( !fn.isEmpty() )
195 p.save( fn, "BMP" );
196 if ( r )
197 startTimer( timer[r] );
198 }
199}
200
201void MagWidget::multiSave()
202{
203 if ( !p.isNull() ) {
204 multifn = ""; // stops saving
205 multifn = QFileDialog::getSaveFileName();
206 if ( multifn.isEmpty() )
207 multiSaveButton->setOn(FALSE);
208 if ( !r )
209 p.save( multifn, "BMP" );
210 } else {
211 multiSaveButton->setOn(FALSE);
212 }
213}
214
215
216void MagWidget::grab()
217{
218 if ( !isVisible() )
219 return; // don't eat resources when iconified
220
221 if ( grabx < 0 || graby < 0 )
222 return; // don't grab until the user has said to
223
224 int x,y, w,h;
225
226 w = (width()+z-1)/z;
227 h = (height()+z-1-yoffset)/z;
228 if ( w<1 || h<1 )
229 return; // don't ask too much from the window system :)
230
231 x = grabx-w/2; // find a suitable position to grab from
232 y = graby-h/2;
233 if ( x + w > QApplication::desktop()->width() )
234 x = QApplication::desktop()->width()-w;
235 else if ( x < 0 )
236 x = 0;
237 if ( y + h > QApplication::desktop()->height() )
238 y = QApplication::desktop()->height()-h;
239 else if ( y < 0 )
240 y = 0;
241
242 p = QPixmap::grabWindow( QApplication::desktop()->winId(), x, y, w, h );
243 image = p.convertToImage();
244 QWMatrix m; // after getting it, scale it
245 m.scale( (double)z, (double)z );
246 pm = p.xForm( m );
247
248 if ( !multiSaveButton || !multiSaveButton->isOn() )
249 repaint( FALSE ); // and finally repaint, flicker-free
250}
251
252
253void MagWidget::paintEvent( QPaintEvent * )
254{
255 if ( !pm.isNull() ) {
256 QPainter paint( this );
257 paint.drawPixmap( 0, zoom ? zoom->height()+4 : 0, pm,
258 0,0, width(), height()-yoffset );
259 }
260}
261
262
263void MagWidget::mousePressEvent( QMouseEvent *e )
264{
265 if ( !grabbing ) { // prepare to grab...
266 grabbing = TRUE;
267 killTimers();
268 grabMouse( crossCursor );
269 grabx = -1;
270 graby = -1;
271 } else { // REALLY prepare to grab
272 grabx = mapToGlobal(e->pos()).x();
273 graby = mapToGlobal(e->pos()).y();
274 }
275}
276
277
278
279void MagWidget::mouseReleaseEvent( QMouseEvent * e )
280{
281 if ( grabbing && grabx >= 0 && graby >= 0 ) {
282 grabbing = FALSE;
283 grabAround(e->pos());
284 releaseMouse();
285 }
286}
287
288void MagWidget::grabAround(QPoint pos)
289{
290 int rx, ry;
291 rx = mapToGlobal(pos).x();
292 ry = mapToGlobal(pos).y();
293 int w = QABS(rx-grabx);
294 int h = QABS(ry-graby);
295 if ( w > 10 && h > 10 ) {
296 int pz;
297 pz = 1;
298 while ( w*pz*h*pz < width()*(height()-yoffset) &&
299 w*pz < QApplication::desktop()->width() &&
300 h*pz < QApplication::desktop()->height() )
301 pz++;
302 if ( (w*pz*h*pz - width()*(height()-yoffset)) >
303 (width()*(height()-yoffset) - w*(pz-1)*h*(pz-1)) )
304 pz--;
305 if ( pz < 1 )
306 pz = 1;
307 if ( pz > 8 )
308 pz = 8;
309 if ( zoom )
310 zoom->setCurrentItem( pz-1 );
311
312 z = pz;
313 grabx = QMIN(rx, grabx) + w/2;
314 graby = QMIN(ry, graby) + h/2;
315 resize( w*z, h*z+yoffset );
316 }
317 grab();
318 if ( r )
319 startTimer( timer[r] );
320}
321
322
323void MagWidget::mouseMoveEvent( QMouseEvent *e )
324{
325 if ( grabbing || pm.isNull() ||
326 e->pos().y() > height() - (zoom ? zoom->fontMetrics().height() - 4 : 0) ||
327 e->pos().y() < (zoom ? zoom->height()+4 : 4) ) {
328 rgb->setText( "" );
329 } else {
330 int x,y;
331 x = e->pos().x() / z;
332 y = (e->pos().y() - ( zoom ? zoom->height() : 0 ) - 4) / z;
333 QString pixelinfo;
334 if ( image.valid(x,y) )
335 {
336 QRgb px = image.pixel(x,y);
337 pixelinfo.sprintf(" %3d,%3d,%3d #%02x%02x%02x",
338 qRed(px), qGreen(px), qBlue(px),
339 qRed(px), qGreen(px), qBlue(px));
340 }
341 QString label;
342 label.sprintf( "x=%d, y=%d %s",
343 x+grabx, y+graby, (const char*)pixelinfo );
344 rgb->setText( label );
345 }
346}
347
348
349void MagWidget::focusOutEvent( QFocusEvent * )
350{
351 rgb->setText( "" );
352}
353
354
355void MagWidget::timerEvent( QTimerEvent * )
356{
357 grab();
358/*
359 if ( multiSaveButton->isOn() && !multifn.isEmpty() ) {
360 QRegExp num("[0-9][0-9]*");
361 int start;
362 int len;
363 if ((start=num.match(multifn,0,&len))>=0)
364 multifn.replace(num,
365 QString().setNum(multifn.mid(start,len).toInt()+1)
366 );
367 p.save( multifn, "BMP" );
368 }
369*/
370}
371
372
373void MagWidget::resizeEvent( QResizeEvent * )
374{
375 rgb->setGeometry( 0, height() - rgb->height(), width(), rgb->height() );
376 grab();
377}
378
379
380#include "qmag.moc"
381
382
383int main( int argc, char **argv )
384{
385 QApplication a( argc, argv );
386 MagWidget m;
387 a.setMainWidget( &m );
388 m.show();
389 return a.exec();
390}
Note: See TracBrowser for help on using the repository browser.