summaryrefslogtreecommitdiff
authorzecke <zecke>2004-08-24 13:38:23 (UTC)
committer zecke <zecke>2004-08-24 13:38:23 (UTC)
commit0a141c4a9719aa273867ad45c4293208545489b1 (patch) (side-by-side diff)
tree4059ae180d00d33cc31dd9083d38a14b946253a2
parent102bb2b65c71da12c4f9f1ce7a5d1b37b6eb50ee (diff)
downloadopie-0a141c4a9719aa273867ad45c4293208545489b1.zip
opie-0a141c4a9719aa273867ad45c4293208545489b1.tar.gz
opie-0a141c4a9719aa273867ad45c4293208545489b1.tar.bz2
Add RightOn Hold Visual Feedback and integrate it
into QPEApplication Icons and Config Option will be comitted by WIMPIE
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/rohfeedback.cpp125
-rw-r--r--library/backend/rohfeedback.h62
-rw-r--r--library/qpeapplication.cpp32
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