Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

calibrate.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include <math.h>
00022 
00023 #include "calibrate.h"
00024 
00025 #include <qpe/resource.h>
00026 #include <qpe/qcopenvelope_qws.h>
00027 #include <qapplication.h>
00028 
00029 #include <qpixmap.h>
00030 #include <qimage.h>
00031 #include <qpainter.h>
00032 #include <qtimer.h>
00033 #include <qwindowsystem_qws.h>
00034 #include <qgfx_qws.h>
00035 
00036 
00037 Calibrate::Calibrate( QWidget* parent, const char * name, WFlags wf ) :
00038                 QDialog( parent, name, TRUE, wf | WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop )
00039 {
00040 #ifdef QWS
00041         showCross = TRUE;
00042         const int offset = 30;
00043         QRect desk = qApp->desktop() ->geometry();
00044         setGeometry( 0, 0, desk.width(), desk.height() );
00045         crosshair.convertFromImage( Resource::loadImage("launcher/crosshair") );
00046 
00047         splash.convertFromImage( Resource::loadImage("launcher/firstuse").smoothScale( width(), height() ) );
00048         setBackgroundPixmap( splash );
00049 
00050         cd.screenPoints[ QWSPointerCalibrationData::TopLeft ] = QPoint( offset, offset );
00051         cd.screenPoints[ QWSPointerCalibrationData::BottomLeft ] = QPoint( offset, qt_screen->deviceHeight() - offset );
00052         cd.screenPoints[ QWSPointerCalibrationData::BottomRight ] = QPoint( qt_screen->deviceWidth() - offset, qt_screen->deviceHeight() - offset );
00053         cd.screenPoints[ QWSPointerCalibrationData::TopRight ] = QPoint( qt_screen->deviceWidth() - offset, offset );
00054         cd.screenPoints[ QWSPointerCalibrationData::Center ] = QPoint( qt_screen->deviceWidth() / 2, qt_screen->deviceHeight() / 2 );
00055         goodcd = cd;
00056         reset();
00057 
00058         timer = new QTimer( this );
00059         connect( timer, SIGNAL( timeout() ), this, SLOT( timeout() ) );
00060 #endif
00061 }
00062 
00063 Calibrate::~Calibrate()
00064 {
00065         store();
00066 }
00067 
00068 void Calibrate::show()
00069 {
00070 #ifdef QWS
00071         grabMouse();
00072         QWSServer::mouseHandler() ->getCalibration( &goodcd );
00073         QWSServer::mouseHandler() ->clearCalibration();
00074         QDialog::show();
00075 #endif
00076 }
00077 
00078 void Calibrate::store()
00079 {
00080 #ifdef QWS
00081         QWSServer::mouseHandler() ->calibrate( &goodcd );
00082 #endif
00083 }
00084 
00085 void Calibrate::hide()
00086 {
00087         if ( isVisible()) {
00088                 store();
00089 
00090                 // hack - calibrate is a launcher dialog, but treated like a standalone app
00091                 {
00092                         QCopEnvelope e( "QPE/System", "closing(QString)" );
00093                         e << QString ( "calibrate" );
00094                 }
00095         }
00096         QDialog::hide();
00097 }
00098 
00099 void Calibrate::reset()
00100 {
00101 #ifdef QWS
00102         penPos = QPoint();
00103         location = QWSPointerCalibrationData::TopLeft;
00104         crossPos = fromDevice( cd.screenPoints[ location ] );
00105 #endif
00106 }
00107 
00108 QPoint Calibrate::fromDevice( const QPoint &p )
00109 {
00110 #ifdef QWS
00111         return qt_screen->mapFromDevice ( p, QSize( qt_screen->deviceWidth ( ), qt_screen->deviceHeight() ) );
00112 #else
00113         return QPoint();
00114 #endif
00115 
00116 }
00117 
00118 bool Calibrate::sanityCheck()
00119 {
00120 #ifdef QWS
00121         QPoint tl = cd.devPoints[QWSPointerCalibrationData::TopLeft];
00122         QPoint tr = cd.devPoints[QWSPointerCalibrationData::TopRight];
00123         QPoint bl = cd.devPoints[QWSPointerCalibrationData::BottomLeft];
00124         QPoint br = cd.devPoints[QWSPointerCalibrationData::BottomRight];
00125 
00126         // not needed anywhere .. just calculate it, so it's there
00127         //cd.devPoints[QWSPointerCalibrationData::Center] = QRect( tl, br ).normalize().center();
00128 
00129         int dlx = QABS( bl. x ( ) - tl. x ( ));
00130         int dly = QABS( bl. y ( ) - tl. y ( ));
00131         int drx = QABS( br. x ( ) - tr. x ( ));
00132         int dry = QABS( br. y ( ) - tr. y ( ));
00133         int dtx = QABS( tr. x ( ) - tl. x ( ));
00134         int dty = QABS( tr. y ( ) - tl. y ( ));
00135         int dbx = QABS( br. x ( ) - bl. x ( ));
00136         int dby = QABS( br. y ( ) - bl. y ( ));
00137 
00138         int dl = (int) ::sqrt (( dlx * dlx ) + ( dly * dly )); // calculate vector lengths for all sides
00139         int dr = (int) ::sqrt (( drx * drx ) + ( dry * dry ));
00140         int dt = (int) ::sqrt (( dtx * dtx ) + ( dty * dty ));
00141         int db = (int) ::sqrt (( dbx * dbx ) + ( dby * dby ));
00142 
00143         // Calculate leeway for x/y (we do not care if diff1/diff2 is for x or y here !)
00144         int diff1 = QABS( dl - dr );
00145         int avg1  = ( dl + dr ) / 2;
00146         int diff2 = QABS( dt - db );
00147         int avg2 = ( dt + db ) / 2;
00148 
00149         // Calculate leeway for "real" vector length against "manhattan" vector length
00150         // This is a check, if the rect is rotated (other then 0/90/180/270)
00151         // It needs to be performed only for the triange (bl, tl, tr)
00152         int diff3 = QABS(( dlx + dly + dtx + dty ) - ( dl + dt ));
00153         int avg3 = (( dlx + dly + dtx + dty ) + ( dl + dt )) / 2;
00154 
00155         if (( diff1 > ( avg1 / 20 )) || // 5% leeway
00156             ( diff2 > ( avg2 / 20 )) ||
00157             ( diff3 > ( avg3 / 20 )))
00158                 return false;
00159         else
00160                 return true;
00161 #else
00162 return true;
00163 #endif
00164 }
00165 
00166 void Calibrate::moveCrosshair( QPoint pt )
00167 {
00168         showCross = FALSE;
00169         repaint( crossPos.x() - 14, crossPos.y() - 14, 28, 28 );
00170         showCross = TRUE;
00171         crossPos = pt;
00172         repaint( crossPos.x() - 14, crossPos.y() - 14, 28, 28 );
00173 }
00174 
00175 void Calibrate::paintEvent( QPaintEvent * )
00176 {
00177         QPainter p( this );
00178         int y = height() / 2;
00179 
00180         p.drawText( 0, y + height() / 8, width(), height() - y, AlignHCenter,
00181                     tr( "Touch the crosshairs firmly and\n"
00182                         "accurately to calibrate your screen." ) );
00183 
00184         if ( !showCross ) return;
00185 
00186 #if 0
00187         if ( crosshair.isNull() ) {
00188 #endif
00189                 p.setPen( QColor( 0, 0, 155 ) );
00190                 p.drawEllipse( crossPos.x()-8, crossPos.y()-8, 16, 16 );
00191                 p.setPen( QColor( 250, 220, 220 ) );
00192                 p.drawRoundRect( crossPos.x()-12, crossPos.y()-12, 24, 24, 75, 75 );
00193                 p.setPen( QColor( 0, 0, 120 ) );
00194                 p.drawRect( crossPos.x() - 1, crossPos.y() - 14, 2, 13 );
00195                 p.drawRect( crossPos.x() - 1, crossPos.y() + 1, 2, 13 );
00196                 p.drawRect( crossPos.x() - 14, crossPos.y() - 1, 13, 2 );
00197                 p.drawRect( crossPos.x() + 1, crossPos.y() - 1, 13, 2 );
00198 #if 0
00199         }
00200         else p.drawPixmap( crossPos.x(), crossPos.y(), crosshair );
00201 #endif
00202 }
00203 
00204 void Calibrate::mousePressEvent( QMouseEvent *e )
00205 {
00206 #ifdef QWS
00207         // map to device coordinates
00208         QPoint devPos = qt_screen->mapToDevice( e->pos(), QSize( qt_screen->width(), qt_screen->height() ) );
00209         if ( penPos.isNull() )
00210                 penPos = devPos;
00211         else
00212                 penPos = QPoint( ( penPos.x() + devPos.x() ) / 2,
00213                                  ( penPos.y() + devPos.y() ) / 2 );
00214 #endif
00215 }
00216 
00217 void Calibrate::mouseReleaseEvent( QMouseEvent * )
00218 {
00219 #ifdef QWS
00220         if ( timer->isActive() )
00221                 return ;
00222 
00223         bool doMove = TRUE;
00224 
00225         cd.devPoints[ location ] = penPos;
00226         if ( location < QWSPointerCalibrationData::Center ) {
00227                 location = (QWSPointerCalibrationData::Location) ( int( location ) + 1 );
00228         }
00229         else {
00230                 if ( sanityCheck() ) {
00231                         reset();
00232                         goodcd = cd;
00233                         hide();
00234                         emit accept();
00235                         doMove = FALSE;
00236                 }
00237                 else {
00238                         location = QWSPointerCalibrationData::TopLeft;
00239                 }
00240         }
00241 
00242         if ( doMove ) {
00243                 QPoint target = fromDevice( cd.screenPoints[ location ] );
00244                 dx = ( target.x() - crossPos.x() ) / 10;
00245                 dy = ( target.y() - crossPos.y() ) / 10;
00246                 timer->start( 30 );
00247         }
00248 #endif
00249 }
00250 
00251 void Calibrate::timeout()
00252 {
00253 #ifdef QWS
00254         QPoint target = fromDevice( cd.screenPoints[ location ] );
00255 
00256         bool doneX = FALSE;
00257         bool doneY = FALSE;
00258         QPoint newPos( crossPos.x() + dx, crossPos.y() + dy );
00259 
00260         if ( QABS( crossPos.x() - target.x() ) <= QABS( dx ) ) {
00261                 newPos.setX( target.x() );
00262                 doneX = TRUE;
00263         }
00264 
00265         if ( QABS( crossPos.y() - target.y() ) <= QABS( dy ) ) {
00266                 newPos.setY( target.y() );
00267                 doneY = TRUE;
00268         }
00269 
00270         if ( doneX && doneY ) {
00271                 penPos = QPoint();
00272                 timer->stop();
00273         }
00274 
00275         moveCrosshair( newPos );
00276 #endif
00277 }
00278 
00279 //#endif // _WS_QWS_

Generated on Sat Nov 5 16:15:25 2005 for OPIE by  doxygen 1.4.2