-rw-r--r-- | library/backend/rohfeedback.cpp | 125 | ||||
-rw-r--r-- | library/backend/rohfeedback.h | 62 | ||||
-rw-r--r-- | library/qpeapplication.cpp | 32 |
3 files changed, 216 insertions, 3 deletions
diff --git a/library/backend/rohfeedback.cpp b/library/backend/rohfeedback.cpp new file mode 100644 index 0000000..ff76a36 --- a/dev/null +++ b/library/backend/rohfeedback.cpp @@ -0,0 +1,125 @@ +#include <rohfeedback.h> + + +#include <stdio.h> +#include <qpeapplication.h> +#include <qevent.h> +#include <resource.h> +#include <qpixmap.h> +#include <qbitmap.h> + +#define SPEED 600 +#define DELAY 500 + +namespace Opie { +namespace Internal { +/* + + RightOnHold feedback + +*/ + +QPixmap * RoHFeedback::Imgs[NOOFICONS] = { 0, 0, 0, 0, 0 }; +QBitmap * RoHFeedback::Masks[NOOFICONS]; +int RoHFeedback::IconWidth; +int RoHFeedback::IconHeight; + +RoHFeedback::RoHFeedback() : + QLabel( 0, 0, Qt::WType_Popup ), Timer() { + + Receiver = 0l; + connect( &Timer, SIGNAL( timeout() ), this, SLOT( iconShow() ) ); + + if( Imgs[0] == 0 ) { + QString S; + + + for( int i = 0; i < NOOFICONS ; i ++ ) { + Imgs[i] = new QPixmap( Resource::loadPixmap("RoH/star/"+ + QString::number(i+1) + + ".png" )); + Masks[i] = new QBitmap(); + (*Masks[i]) = Resource::loadPixmap("RoH/star/"+QString::number(i+1) + + ".png" ); + } + } + + IconWidth = Imgs[0]->size().width(); + IconHeight = Imgs[0]->size().height(); + + resize( IconWidth, IconHeight ); +} + +int RoHFeedback::delay( void ) { + return DELAY+SPEED+50; +} + +RoHFeedback::~RoHFeedback() { + for ( int i = 0; i < NOOFICONS; ++i ) { + delete Imgs [i]; + delete Masks[i]; + } +} + +void RoHFeedback::init( const QPoint & P, QWidget* wid ) { + if( ! IconWidth ) + return; + + Receiver = wid; + IconNr = -1; + move( P.x()-IconWidth/2, P.y() - IconHeight/2 ); + // to initialize + Timer.start( DELAY - SPEED/NOOFICONS ); +} + +void RoHFeedback::stop( void ) { + IconNr = -2; // stop + hide(); + Timer.stop(); +} + +bool RoHFeedback::event( QEvent * E ) { + + if( E->type() >= QEvent::MouseButtonPress && + E->type() <= QEvent::MouseMove ) { + // pass the event to the receiver with translated coord + QMouseEvent QME( ((QMouseEvent *)E)->type(), + Receiver->mapFromGlobal( + ((QMouseEvent *)E)->globalPos() ), + ((QMouseEvent *)E)->globalPos(), + ((QMouseEvent *)E)->button(), + ((QMouseEvent *)E)->state() + ); + return QPEApplication::sendEvent( Receiver, &QME ); + } + + // first let the label treat the event + return QLabel::event( E ); +} + +void RoHFeedback::iconShow( void ) { + switch( IconNr ) { + case FeedbackTimerStart: + IconNr = 0; + Timer.start( SPEED/NOOFICONS ); + break; + case FeedbackStopped: + // stopped + IconNr = FeedbackTimerStart; + hide(); + break; + case FeedbackShow: // first + show(); + // FT + default : + // show + + setPixmap( *(Imgs[IconNr]) ); + setMask( *(Masks[IconNr]) ); + IconNr = (IconNr+1)%NOOFICONS; // rotate + break; + } +} + +} +}
\ No newline at end of file diff --git a/library/backend/rohfeedback.h b/library/backend/rohfeedback.h new file mode 100644 index 0000000..f38a095 --- a/dev/null +++ b/library/backend/rohfeedback.h @@ -0,0 +1,62 @@ +#ifndef ROHFEEDBACK_H +#define ROHFEEDBACK_H + +/* + + RightOnHold feedback show + +*/ + +#define NOOFICONS 5 + +#include <qlabel.h> +#include <qtimer.h> + +class QEvent; +class QPixmap; +class QBitmap; +class QMouseEvent; + +namespace Opie { +namespace Internal { + +class RoHFeedback : public QLabel { + + Q_OBJECT + + enum Actions { + FeedbackStopped = -2, + FeedbackTimerStart = -1, + FeedbackShow = 0 + }; +public : + + RoHFeedback(); + ~RoHFeedback(); + + + void init( const QPoint & P, QWidget* wid ); + void stop( void ); + int delay( void ); + +public slots : + + void iconShow( void ); + +protected : + + bool event( QEvent * E ); + + QTimer Timer; + int IconNr; + QWidget * Receiver; + + static int IconWidth; + static int IconHeight; + static QPixmap * Imgs[NOOFICONS]; + static QBitmap * Masks[NOOFICONS]; +}; +} +} + +#endif diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp index 59ca61b..acad81d 100644 --- a/library/qpeapplication.cpp +++ b/library/qpeapplication.cpp @@ -68,93 +68,98 @@ #include <qmotifstyle.h> #include <qmotifplusstyle.h> #include "lightstyle.h" #include <qpe/qlibrary.h> #endif #include "global.h" #include "resource.h" #if QT_VERSION <= 230 && defined(QT_NO_CODECS) #include "qutfcodec.h" #endif #include "config.h" #include "network.h" #ifdef QWS #include "fontmanager.h" #include "fontdatabase.h" #endif #include "alarmserver.h" #include "applnk.h" #include "qpemenubar.h" #include "textcodecinterface.h" #include "imagecodecinterface.h" #include <unistd.h> #include <sys/file.h> #include <sys/ioctl.h> #ifndef QT_NO_SOUND #include <sys/soundcard.h> #endif #include "qt_override_p.h" +#include <qpe/rohfeedback.h> + + static bool useBigPixmaps = 0; + class HackWidget : public QWidget { public: bool needsOk() { return (getWState() & WState_Reserved1 ); } QRect normalGeometry() { return topData()->normalGeometry; }; }; class QPEApplicationData { public: QPEApplicationData ( ) : presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ), notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ), keep_running( true ), qcopQok( false ), fontFamily( "Vera" ), fontSize( 10 ), smallIconSize( 14 ), bigIconSize( 32 ), qpe_main_widget( 0 ) { Config cfg( "qpe" ); cfg.setGroup( "Appearance" ); useBigPixmaps = cfg.readBoolEntry( "useBigPixmaps", false ); fontFamily = cfg.readEntry( "FontFamily", "Vera" ); fontSize = cfg.readNumEntry( "FontSize", 10 ); smallIconSize = cfg.readNumEntry( "SmallIconSize", 14 ); bigIconSize = cfg.readNumEntry( "BigIconSize", 32 ); + RoH = 0; } int presstimer; QWidget* presswidget; QPoint presspos; bool rightpressed : 1; bool kbgrabbed : 1; bool notbusysent : 1; bool preloaded : 1; bool forceshow : 1; bool nomaximize : 1; bool keep_running : 1; bool qcopQok : 1; QCString fontFamily; int fontSize; int smallIconSize; int bigIconSize; QStringList langs; QString appName; struct QCopRec { QCopRec( const QCString &ch, const QCString &msg, const QByteArray &d ) : channel( ch ), message( msg ), data( d ) { } QCString channel; QCString message; QByteArray data; @@ -463,64 +468,66 @@ static void qpe_show_dialog( QDialog* d, bool nomax ) } } } void loadImageCodecs() { QString path = QPEApplication::qpeDir() + "/plugins/imagecodecs"; #ifdef Q_OS_MACX QDir dir( path, "lib*.dylib" ); #else QDir dir( path, "lib*.so" ); #endif QStringList list; if ( dir. exists ( )) list = dir.entryList(); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { ImageCodecInterface *iface = 0; QLibrary *lib = new QLibrary( path + "/" + *it ); if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) { QStringList formats = iface->keys(); for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) { (void)iface->installIOHandler(*i); // ### it exists now; need to remember if we can delete it } } else { lib->unload(); delete lib; } } } + + Opie::Internal::RoHFeedback * RoH; }; class ResourceMimeFactory : public QMimeSourceFactory { public: ResourceMimeFactory() : resImage( 0 ) { setFilePath( Global::helpPath() ); setExtensionType( "html", "text/html;charset=UTF-8" ); } ~ResourceMimeFactory() { delete resImage; } const QMimeSource* data( const QString& abs_name ) const { const QMimeSource * r = QMimeSourceFactory::data( abs_name ); if ( !r ) { int sl = abs_name.length(); do { sl = abs_name.findRev( '/', sl - 1 ); QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name; int dot = name.findRev( '.' ); if ( dot >= 0 ) name = name.left( dot ); QImage img = Resource::loadImage( name ); if ( !img.isNull() ) { delete resImage; resImage = new QImageDrag( img ); r = resImage; } } @@ -1176,65 +1183,65 @@ bool QPEApplication::qwsEventFilter( QWSEvent * e ) // make sure our modal widget is ALWAYS on top QWidget *topm = activeModalWidget(); if ( topm && static_cast<int>( topm->winId() ) != fe->simpleData.window) { topm->raise(); } } if ( fe->simpleData.get_focus && inputMethodDict ) { InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) ); if ( m == AlwaysOff ) Global::hideInputMethod(); if ( m == AlwaysOn ) Global::showInputMethod(); } } return QApplication::qwsEventFilter( e ); } #endif /*! Destroys the QPEApplication. */ QPEApplication::~QPEApplication() { ungrabKeyboard(); #if defined(Q_WS_QWS) && !defined(QT_NO_COP) // Need to delete QCopChannels early, since the display will // be gone by the time we get to ~QObject(). delete sysChannel; delete pidChannel; #endif - + delete d->RoH; delete d; } /*! Returns <tt>$OPIEDIR/</tt>. */ QString QPEApplication::qpeDir() { const char * base = getenv( "OPIEDIR" ); if ( base ) return QString( base ) + "/"; return QString( "../" ); } /*! Returns the user's current Document directory. There is a trailing "/". .. well, it does now,, and there's no trailing '/' */ QString QPEApplication::documentDir() { const char* base = getenv( "HOME"); if ( base ) return QString( base ) + "/Documents"; return QString( "../Documents" ); } static int deforient = -1; /*! \internal @@ -1994,134 +2001,153 @@ QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w ) void QPEApplication::setStylusOperation( QWidget * w, StylusMode mode ) { createDict(); if ( mode == LeftOnly ) { stylusDict->remove ( w ); w->removeEventFilter( qApp ); } else { stylusDict->insert( w, ( void* ) mode ); connect( w, SIGNAL( destroyed() ), qApp, SLOT( removeSenderFromStylusDict() ) ); w->installEventFilter( qApp ); } } /*! \reimp */ bool QPEApplication::eventFilter( QObject *o, QEvent *e ) { if ( !o->isWidgetType() ) return FALSE; if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) { QMouseEvent * me = ( QMouseEvent* ) e; StylusMode mode = (StylusMode)(int)stylusDict->find(o); switch (mode) { case RightOnHold: switch ( me->type() ) { case QEvent::MouseButtonPress: if ( me->button() == LeftButton ) { - if (!d->presstimer ) - d->presstimer = startTimer(500); // #### pref. d->presswidget = (QWidget*)o; d->presspos = me->pos(); d->rightpressed = FALSE; + // just for the time being + static int pref = 500; +#ifdef WITHROHFEEDBACK + if( ! d->RoH ) + d->RoH = new Opie::Internal::RoHFeedback; + + d->RoH->init( me->globalPos(), d->presswidget ); + pref = d->RoH->delay(); +#endif + if (!d->presstimer ) + d->presstimer = startTimer( pref ); // #### pref. + } break; case QEvent::MouseMove: if (d->presstimer && (me->pos() - d->presspos).manhattanLength() > 8) { killTimer(d->presstimer); +#ifdef WITHROHFEEDBACK + if( d->RoH ) + d->RoH->stop( ); +#endif d->presstimer = 0; } break; case QEvent::MouseButtonRelease: if ( me->button() == LeftButton ) { if ( d->presstimer ) { killTimer(d->presstimer); +#ifdef WITHROHFEEDBACK + if( d->RoH ) + d->RoH->stop( ); +#endif d->presstimer = 0; } if ( d->rightpressed && d->presswidget ) { // Right released postEvent( d->presswidget, new QMouseEvent( QEvent::MouseButtonRelease, me->pos(), RightButton, LeftButton + RightButton ) ); // Left released, off-widget postEvent( d->presswidget, new QMouseEvent( QEvent::MouseMove, QPoint( -1, -1), LeftButton, LeftButton ) ); postEvent( d->presswidget, new QMouseEvent( QEvent::MouseButtonRelease, QPoint( -1, -1), LeftButton, LeftButton ) ); d->rightpressed = FALSE; return TRUE; // don't send the real Left release } } break; default: break; } break; default: ; } } else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { QKeyEvent *ke = (QKeyEvent *)e; if ( ke->key() == Key_Enter ) { if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) { postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ', ke->state(), " ", ke->isAutoRepeat(), ke->count() ) ); return TRUE; } } } return FALSE; } /*! \reimp */ void QPEApplication::timerEvent( QTimerEvent *e ) { if ( e->timerId() == d->presstimer && d->presswidget ) { // Right pressed postEvent( d->presswidget, new QMouseEvent( QEvent::MouseButtonPress, d->presspos, RightButton, LeftButton ) ); killTimer( d->presstimer ); d->presstimer = 0; d->rightpressed = TRUE; + d->RoH->stop(); } } void QPEApplication::removeSenderFromStylusDict() { stylusDict->remove ( ( void* ) sender() ); if ( d->presswidget == sender() ) d->presswidget = 0; } /*! \internal */ bool QPEApplication::keyboardGrabbed() const { return d->kbgrabbed; } /*! Reverses the effect of grabKeyboard(). This is called automatically on program exit. */ void QPEApplication::ungrabKeyboard() { ((QPEApplication *) qApp )-> d-> kbgrabbed = false; } /*! Grabs the physical keyboard keys, e.g. the application's launching keys. Instead of launching applications when these keys are pressed |