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