kdeui Library API Documentation

kcursor.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 1998 Kurt Granroth (granroth@kde.org)
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016    Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #ifdef KDE_USE_FINAL
00020 #ifdef KeyRelease
00021 #undef KeyRelease
00022 #endif
00023 #endif
00024 
00025 #include <kcursor.h>
00026 
00027 #include <qbitmap.h>
00028 #include <qcursor.h>
00029 #include <qevent.h>
00030 #include <qtimer.h>
00031 #include <qwidget.h>
00032 
00033 #include <kglobal.h>
00034 #include <kconfig.h>
00035 #include <qscrollview.h>
00036 
00037 #include "kcursor_private.h"
00038 
00039 KCursor::KCursor()
00040 {
00041 }
00042 
00043 QCursor KCursor::handCursor()
00044 {
00045         static QCursor *hand_cursor = 0;
00046 
00047         if (hand_cursor == 0)
00048         {
00049                 KConfig *config = KGlobal::config();
00050                 KConfigGroupSaver saver( config, "General" );
00051 
00052                 if ( config->readEntry("handCursorStyle", "Windows") == "Windows" )
00053                 {
00054                         static const unsigned char HAND_BITS[] = {
00055                                 0x80, 0x01, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02,
00056                                 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x1e, 0x00, 0x40,
00057                                 0xf2, 0x00, 0x40, 0x92, 0x01, 0x70, 0x92, 0x02, 0x50, 0x92, 0x04,
00058                                 0x48, 0x80, 0x04, 0x48, 0x00, 0x04, 0x48, 0x00, 0x04, 0x08, 0x00,
00059                                 0x04, 0x08, 0x00, 0x04, 0x10, 0x00, 0x04, 0x10, 0x00, 0x04, 0x20,
00060                                 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x01, 0xc0, 0xff, 0x01};
00061                         static const unsigned char HAND_MASK_BITS[] = {
00062                                 0x80, 0x01, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03,
00063                                 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x1f, 0x00, 0xc0,
00064                                 0xff, 0x00, 0xc0, 0xff, 0x01, 0xf0, 0xff, 0x03, 0xf0, 0xff, 0x07,
00065                                 0xf8, 0xff, 0x07, 0xf8, 0xff, 0x07, 0xf8, 0xff, 0x07, 0xf8, 0xff,
00066                                 0x07, 0xf8, 0xff, 0x07, 0xf0, 0xff, 0x07, 0xf0, 0xff, 0x07, 0xe0,
00067                                 0xff, 0x03, 0xc0, 0xff, 0x03, 0xc0, 0xff, 0x01, 0xc0, 0xff, 0x01};
00068                         QBitmap hand_bitmap(22, 22, HAND_BITS, true);
00069                         QBitmap hand_mask(22, 22, HAND_MASK_BITS, true);
00070                         hand_cursor = new QCursor(hand_bitmap, hand_mask, 7, 0);
00071                         // Hack to force QCursor to call XCreatePixmapCursor() immediately
00072                         // so the bitmaps don't get pushed out of the Xcursor LRU cache.
00073                         hand_cursor->handle();
00074                 }
00075                 else
00076                         hand_cursor = new QCursor(PointingHandCursor);
00077         }
00078 
00079         Q_CHECK_PTR(hand_cursor);
00080         return *hand_cursor;
00081 }
00082 
00083 /* XPM */
00084 static const char * const working_cursor_xpm[]={
00085 "32 32 3 1",
00086 "# c None",
00087 "a c #000000",
00088 ". c #ffffff",
00089 "..##############################",
00090 ".a.##########.aaaa.#############",
00091 ".aa.#########.aaaa.#############",
00092 ".aaa.#######.aaaaaa.############",
00093 ".aaaa.#####.a...a..a..##########",
00094 ".aaaaa.####a....a...aa##########",
00095 ".aaaaaa.###a...aa...aa##########",
00096 ".aaaaaaa.##a..a.....aa##########",
00097 ".aaaaaaaa.#.aa.....a..##########",
00098 ".aaaaa....##.aaaaaa.############",
00099 ".aa.aa.######.aaaa.#############",
00100 ".a.#.aa.#####.aaaa.#############",
00101 "..##.aa.########################",
00102 "#####.aa.#######################",
00103 "#####.aa.#######################",
00104 "######..########################",
00105 "################################",
00106 "################################",
00107 "################################",
00108 "################################",
00109 "################################",
00110 "################################",
00111 "################################",
00112 "################################",
00113 "################################",
00114 "################################",
00115 "################################",
00116 "################################",
00117 "################################",
00118 "################################",
00119 "################################",
00120 "################################"};
00121 
00122 
00123 QCursor KCursor::workingCursor()
00124 {
00125         static QCursor *working_cursor = 0;
00126 
00127         if (working_cursor == 0)
00128         {
00129             QPixmap pm( const_cast< const char** >( working_cursor_xpm ));
00130             working_cursor = new QCursor( pm, 1, 1 );
00131             // Hack to force QCursor to call XCreatePixmapCursor() immediately
00132             // so the bitmaps don't get pushed out of the Xcursor LRU cache.
00133             working_cursor->handle();
00134         }
00135 
00136         Q_CHECK_PTR(working_cursor);
00137         return *working_cursor;
00138 }
00139 
00144 QCursor KCursor::arrowCursor()
00145 {
00146     return Qt::arrowCursor;
00147 }
00148 
00149 
00150 QCursor KCursor::upArrowCursor()
00151 {
00152     return Qt::upArrowCursor;
00153 }
00154 
00155 
00156 QCursor KCursor::crossCursor()
00157 {
00158     return Qt::crossCursor;
00159 }
00160 
00161 
00162 QCursor KCursor::waitCursor()
00163 {
00164     return Qt::waitCursor;
00165 }
00166 
00167 
00168 QCursor KCursor::ibeamCursor()
00169 {
00170     return Qt::ibeamCursor;
00171 }
00172 
00173 
00174 QCursor KCursor::sizeVerCursor()
00175 {
00176     return Qt::sizeVerCursor;
00177 }
00178 
00179 
00180 QCursor KCursor::sizeHorCursor()
00181 {
00182     return Qt::sizeHorCursor;
00183 }
00184 
00185 
00186 QCursor KCursor::sizeBDiagCursor()
00187 {
00188     return Qt::sizeBDiagCursor;
00189 }
00190 
00191 
00192 QCursor KCursor::sizeFDiagCursor()
00193 {
00194     return Qt::sizeFDiagCursor;
00195 }
00196 
00197 
00198 QCursor KCursor::sizeAllCursor()
00199 {
00200     return Qt::sizeAllCursor;
00201 }
00202 
00203 
00204 QCursor KCursor::blankCursor()
00205 {
00206     return Qt::blankCursor;
00207 }
00208 
00209 QCursor KCursor::whatsThisCursor()
00210 {
00211     return Qt::whatsThisCursor;
00212 }
00213 
00214 // auto-hide cursor stuff
00215 
00216 void KCursor::setAutoHideCursor( QWidget *w, bool enable )
00217 {
00218     setAutoHideCursor( w, enable, false );
00219 }
00220 
00221 void KCursor::setAutoHideCursor( QWidget *w, bool enable,
00222                  bool customEventFilter )
00223 {
00224     KCursorPrivate::self()->setAutoHideCursor( w, enable, customEventFilter );
00225 }
00226 
00227 void KCursor::autoHideEventFilter( QObject *o, QEvent *e )
00228 {
00229     KCursorPrivate::self()->eventFilter( o, e );
00230 }
00231 
00232 void KCursor::setHideCursorDelay( int ms )
00233 {
00234     KCursorPrivate::self()->hideCursorDelay = ms;
00235 }
00236 
00237 int KCursor::hideCursorDelay()
00238 {
00239     return KCursorPrivate::self()->hideCursorDelay;
00240 }
00241 
00242 // **************************************************************************
00243 
00244 KCursorPrivateAutoHideEventFilter::KCursorPrivateAutoHideEventFilter( QWidget* widget )
00245     : m_widget( widget )
00246     , m_wasMouseTracking( m_widget->hasMouseTracking() )
00247     , m_isCursorHidden( false )
00248     , m_isOwnCursor( false )
00249 {
00250     m_widget->setMouseTracking( true );
00251     connect( &m_autoHideTimer, SIGNAL( timeout() ),
00252              this, SLOT( hideCursor() ) );
00253 }
00254 
00255 KCursorPrivateAutoHideEventFilter::~KCursorPrivateAutoHideEventFilter()
00256 {
00257     if( m_widget != NULL )
00258         m_widget->setMouseTracking( m_wasMouseTracking );
00259 }
00260 
00261 void KCursorPrivateAutoHideEventFilter::resetWidget()
00262 {
00263     m_widget = NULL;
00264 }
00265 
00266 void KCursorPrivateAutoHideEventFilter::hideCursor()
00267 {
00268     m_autoHideTimer.stop();
00269 
00270     if ( m_isCursorHidden )
00271         return;
00272 
00273     m_isCursorHidden = true;
00274 
00275     QWidget* w = actualWidget();
00276 
00277     m_isOwnCursor = w->ownCursor();
00278     if ( m_isOwnCursor )
00279         m_oldCursor = w->cursor();
00280 
00281     w->setCursor( KCursor::blankCursor() );
00282 }
00283 
00284 void KCursorPrivateAutoHideEventFilter::unhideCursor()
00285 {
00286     m_autoHideTimer.stop();
00287 
00288     if ( !m_isCursorHidden )
00289         return;
00290 
00291     m_isCursorHidden = false;
00292 
00293     QWidget* w = actualWidget();
00294 
00295     if ( m_isOwnCursor )
00296         w->setCursor( m_oldCursor );
00297     else
00298         w->unsetCursor();
00299 }
00300 
00301 QWidget* KCursorPrivateAutoHideEventFilter::actualWidget() const
00302 {
00303     QWidget* w = m_widget;
00304 
00305     // Is w a scrollview ? Call setCursor on the viewport in that case.
00306     QScrollView * sv = dynamic_cast<QScrollView *>( w );
00307     if ( sv )
00308         w = sv->viewport();
00309 
00310     return w;
00311 }
00312 
00313 bool KCursorPrivateAutoHideEventFilter::eventFilter( QObject *o, QEvent *e )
00314 {
00315     Q_ASSERT( o == m_widget );
00316 
00317     switch ( e->type() )
00318     {
00319     case QEvent::Create:
00320         // Qt steals mouseTracking on create()
00321         m_widget->setMouseTracking( true );
00322         break;
00323     case QEvent::Leave:
00324     case QEvent::FocusOut:
00325     case QEvent::WindowDeactivate:
00326         unhideCursor();
00327         break;
00328     case QEvent::KeyPress:
00329     case QEvent::AccelOverride:
00330         hideCursor();
00331         break;
00332     case QEvent::Enter:
00333     case QEvent::FocusIn:
00334     case QEvent::MouseButtonPress:
00335     case QEvent::MouseButtonRelease:
00336     case QEvent::MouseButtonDblClick:
00337     case QEvent::MouseMove:
00338     case QEvent::Show:
00339     case QEvent::Hide:
00340     case QEvent::Wheel:
00341         unhideCursor();
00342         if ( m_widget->hasFocus() )
00343             m_autoHideTimer.start( KCursorPrivate::self()->hideCursorDelay, true );
00344         break;
00345     default:
00346         break;
00347     }
00348 
00349     return false;
00350 }
00351 
00352 KCursorPrivate * KCursorPrivate::s_self = 0L;
00353 
00354 KCursorPrivate * KCursorPrivate::self()
00355 {
00356     if ( !s_self )
00357         s_self = new KCursorPrivate;
00358     // WABA: We never delete KCursorPrivate. Don't change.
00359 
00360     return s_self;
00361 }
00362 
00363 KCursorPrivate::KCursorPrivate()
00364 {
00365     hideCursorDelay = 5000; // 5s default value
00366 
00367     KConfig *kc = KGlobal::config();
00368     KConfigGroupSaver ks( kc, QString::fromLatin1("KDE") );
00369     enabled = kc->readBoolEntry(
00370           QString::fromLatin1("Autohiding cursor enabled"), true );
00371 }
00372 
00373 KCursorPrivate::~KCursorPrivate()
00374 {
00375 }
00376 
00377 void KCursorPrivate::setAutoHideCursor( QWidget *w, bool enable, bool customEventFilter )
00378 {
00379     if ( !w || !enabled )
00380         return;
00381 
00382     if ( enable )
00383     {
00384         if ( m_eventFilters.find( w ) != NULL )
00385             return;
00386         KCursorPrivateAutoHideEventFilter* filter = new KCursorPrivateAutoHideEventFilter( w );
00387         m_eventFilters.insert( w, filter );
00388         if ( !customEventFilter )
00389             w->installEventFilter( filter );
00390         connect( w, SIGNAL( destroyed(QObject*) ),
00391                  this, SLOT( slotWidgetDestroyed(QObject*) ) );
00392     }
00393     else
00394     {
00395         KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( w );
00396         if ( filter == NULL )
00397             return;
00398         w->removeEventFilter( filter );
00399         delete filter;
00400         disconnect( w, SIGNAL( destroyed(QObject*) ),
00401                     this, SLOT( slotWidgetDestroyed(QObject*) ) );
00402     }
00403 }
00404 
00405 bool KCursorPrivate::eventFilter( QObject *o, QEvent *e )
00406 {
00407     if ( !enabled )
00408         return false;
00409 
00410     KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.find( o );
00411 
00412     Q_ASSERT( filter != NULL );
00413     if ( filter == NULL )
00414         return false;
00415 
00416     return filter->eventFilter( o, e );
00417 }
00418 
00419 void KCursorPrivate::slotWidgetDestroyed( QObject* o )
00420 {
00421     KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( o );
00422 
00423     Q_ASSERT( filter != NULL );
00424 
00425     filter->resetWidget(); // so that dtor doesn't access it
00426     delete filter;
00427 }
00428 
00429 #include "kcursor_private.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Feb 18 15:10:17 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003