home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / qt3_emx.zip / examples / qmag / qmag.cpp < prev    next >
C/C++ Source or Header  |  2001-10-11  |  10KB  |  391 lines

  1. /****************************************************************************
  2. ** $Id:  qt/qmag.cpp   3.0.0   edited Jun 22 13:24 $
  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.  
  24. class MagWidget : public QWidget
  25. {
  26.     Q_OBJECT
  27. public:
  28.     MagWidget( QWidget *parent=0, const char *name=0 );
  29.  
  30. public slots:
  31.     void    setZoom( int );
  32.     void    setRefresh( int );
  33.     void    save();
  34.     void    multiSave();
  35.  
  36. protected:
  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.  
  45. private:
  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
  68. static const char *zoomfactors[] = {
  69.     "100%", "200%", "300%", "400%", "500%",
  70.     "600%", "700%", "800%", "1600%", 0 };
  71.  
  72. static 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.  
  78. static const int timer[] = {
  79.     0, 20, 250, 333, 500, 1000, 2000, 3000, 5000, 10000 };
  80.  
  81.  
  82. MagWidget::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.  
  170. void MagWidget::setZoom( int index )
  171. {
  172.     if (index == 8)
  173.     z = 16;
  174.     else
  175.     z = index+1;
  176.     grab();
  177. }
  178.  
  179.  
  180. void MagWidget::setRefresh( int index )
  181. {
  182.     r = index;
  183.     killTimers();
  184.     if (index && !grabbing)
  185.     startTimer( timer[r] );
  186. }
  187.  
  188.  
  189. void 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.  
  201. void 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.  
  216. void 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.  
  253. void 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.  
  263. void 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.  
  279. void MagWidget::mouseReleaseEvent( QMouseEvent * e )
  280. {
  281.     if ( grabbing && grabx >= 0 && graby >= 0 ) {
  282.     grabbing = FALSE;
  283.     grabAround(e->pos());
  284.     releaseMouse();
  285.     }
  286. }
  287.  
  288. void 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.  
  323. void 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.  
  349. void MagWidget::focusOutEvent( QFocusEvent * )
  350. {
  351.     rgb->setText( "" );
  352. }
  353.  
  354.  
  355. void 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.  
  373. void 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.  
  383. int 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. }
  391.