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