| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_vcl.hxx" |
| |
| #include <vcl/svapp.hxx> |
| #include <vcl/timer.hxx> |
| #include <vcl/settings.hxx> |
| #include <vcl/window.hxx> |
| #include <vcl/cursor.hxx> |
| |
| #include <window.h> |
| |
| #include <tools/poly.hxx> |
| |
| |
| // ======================================================================= |
| |
| struct ImplCursorData |
| { |
| AutoTimer maTimer; // Timer |
| Point maPixPos; // Pixel-Position |
| Point maPixRotOff; // Pixel-Offset-Position |
| Size maPixSize; // Pixel-Size |
| long mnPixSlant; // Pixel-Slant |
| short mnOrientation; // Pixel-Orientation |
| unsigned char mnDirection; // indicates writing direction |
| sal_uInt16 mnStyle; // Cursor-Style |
| sal_Bool mbCurVisible; // Ist Cursor aktuell sichtbar |
| Window* mpWindow; // Zugeordnetes Windows |
| }; |
| |
| // ======================================================================= |
| |
| static void ImplCursorInvert( ImplCursorData* pData ) |
| { |
| Window* pWindow = pData->mpWindow; |
| sal_Bool bMapMode = pWindow->IsMapModeEnabled(); |
| pWindow->EnableMapMode( sal_False ); |
| sal_uInt16 nInvertStyle; |
| if ( pData->mnStyle & CURSOR_SHADOW ) |
| nInvertStyle = INVERT_50; |
| else |
| nInvertStyle = 0; |
| |
| Rectangle aRect( pData->maPixPos, pData->maPixSize ); |
| if ( pData->mnDirection || pData->mnOrientation || pData->mnPixSlant ) |
| { |
| Polygon aPoly( aRect ); |
| if( aPoly.GetSize() == 5 ) |
| { |
| aPoly[1].X() += 1; // include the right border |
| aPoly[2].X() += 1; |
| if ( pData->mnPixSlant ) |
| { |
| Point aPoint = aPoly.GetPoint( 0 ); |
| aPoint.X() += pData->mnPixSlant; |
| aPoly.SetPoint( aPoint, 0 ); |
| aPoly.SetPoint( aPoint, 4 ); |
| aPoint = aPoly.GetPoint( 1 ); |
| aPoint.X() += pData->mnPixSlant; |
| aPoly.SetPoint( aPoint, 1 ); |
| } |
| |
| // apply direction flag after slant to use the correct shape |
| if ( pData->mnDirection ) |
| { |
| Point pAry[7]; |
| int delta = 3*aRect.getWidth()+1; |
| if( pData->mnDirection == CURSOR_DIRECTION_LTR ) |
| { |
| // left-to-right |
| pAry[0] = aPoly.GetPoint( 0 ); |
| pAry[1] = aPoly.GetPoint( 1 ); |
| pAry[2] = pAry[1]; |
| pAry[2].X() += delta; |
| pAry[3] = pAry[1]; |
| pAry[3].Y() += delta; |
| pAry[4] = aPoly.GetPoint( 2 ); |
| pAry[5] = aPoly.GetPoint( 3 ); |
| pAry[6] = aPoly.GetPoint( 4 ); |
| } |
| else if( pData->mnDirection == CURSOR_DIRECTION_RTL ) |
| { |
| // right-to-left |
| pAry[0] = aPoly.GetPoint( 0 ); |
| pAry[1] = aPoly.GetPoint( 1 ); |
| pAry[2] = aPoly.GetPoint( 2 ); |
| pAry[3] = aPoly.GetPoint( 3 ); |
| pAry[4] = pAry[0]; |
| pAry[4].Y() += delta; |
| pAry[5] = pAry[0]; |
| pAry[5].X() -= delta; |
| pAry[6] = aPoly.GetPoint( 4 ); |
| } |
| aPoly = Polygon( 7, pAry); |
| } |
| |
| if ( pData->mnOrientation ) |
| aPoly.Rotate( pData->maPixRotOff, pData->mnOrientation ); |
| pWindow->Invert( aPoly, nInvertStyle ); |
| } |
| } |
| else |
| pWindow->Invert( aRect, nInvertStyle ); |
| pWindow->EnableMapMode( bMapMode ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::ImplDraw() |
| { |
| if ( mpData && mpData->mpWindow && !mpData->mbCurVisible ) |
| { |
| Window* pWindow = mpData->mpWindow; |
| mpData->maPixPos = pWindow->LogicToPixel( maPos ); |
| mpData->maPixSize = pWindow->LogicToPixel( maSize ); |
| mpData->mnPixSlant = pWindow->LogicToPixel( Size( mnSlant, 0 ) ).Width(); |
| mpData->mnOrientation = mnOrientation; |
| mpData->mnDirection = mnDirection; |
| long nOffsetY = pWindow->LogicToPixel( Size( 0, mnOffsetY ) ).Height(); |
| |
| // Position um den Offset korrigieren |
| mpData->maPixPos.Y() -= nOffsetY; |
| mpData->maPixRotOff = mpData->maPixPos; |
| mpData->maPixRotOff.Y() += nOffsetY; |
| |
| // Wenn groesse 0 ist, nehmen wir die breite, die in den |
| // Settings eingestellt ist |
| if ( !mpData->maPixSize.Width() ) |
| mpData->maPixSize.Width() = pWindow->GetSettings().GetStyleSettings().GetCursorSize(); |
| |
| // Ausgabeflaeche berechnen und ausgeben |
| ImplCursorInvert( mpData ); |
| mpData->mbCurVisible = sal_True; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::ImplRestore() |
| { |
| if ( mpData && mpData->mbCurVisible ) |
| { |
| ImplCursorInvert( mpData ); |
| mpData->mbCurVisible = sal_False; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::ImplShow( bool bDrawDirect, bool bRestore ) |
| { |
| if ( mbVisible ) |
| { |
| Window* pWindow; |
| if ( mpWindow ) |
| pWindow = mpWindow; |
| else |
| { |
| // Gibt es ein aktives Fenster und ist der Cursor in dieses Fenster |
| // selektiert, dann zeige den Cursor an |
| pWindow = Application::GetFocusWindow(); |
| if ( !pWindow || (pWindow->mpWindowImpl->mpCursor != this) || pWindow->mpWindowImpl->mbInPaint |
| || !pWindow->mpWindowImpl->mpFrameData->mbHasFocus ) |
| pWindow = NULL; |
| } |
| |
| if ( pWindow ) |
| { |
| if ( !mpData ) |
| { |
| mpData = new ImplCursorData; |
| mpData->mbCurVisible = sal_False; |
| mpData->maTimer.SetTimeoutHdl( LINK( this, Cursor, ImplTimerHdl ) ); |
| } |
| |
| mpData->mpWindow = pWindow; |
| mpData->mnStyle = mnStyle; |
| if ( bDrawDirect || bRestore ) |
| ImplDraw(); |
| |
| if ( !mpWindow && ! ( ! bDrawDirect && mpData->maTimer.IsActive()) ) |
| { |
| mpData->maTimer.SetTimeout( pWindow->GetSettings().GetStyleSettings().GetCursorBlinkTime() ); |
| if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME ) |
| mpData->maTimer.Start(); |
| else if ( !mpData->mbCurVisible ) |
| ImplDraw(); |
| } |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| bool Cursor::ImplHide( bool i_bStopTimer ) |
| { |
| bool bWasCurVisible = false; |
| if ( mpData && mpData->mpWindow ) |
| { |
| bWasCurVisible = mpData->mbCurVisible; |
| if ( mpData->mbCurVisible ) |
| ImplRestore(); |
| } |
| |
| if( mpData && i_bStopTimer ) |
| { |
| mpData->maTimer.Stop(); |
| mpData->mpWindow = NULL; |
| } |
| |
| return bWasCurVisible; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::ImplNew() |
| { |
| if ( mbVisible && mpData && mpData->mpWindow ) |
| { |
| if ( mpData->mbCurVisible ) |
| ImplRestore(); |
| |
| ImplDraw(); |
| if ( !mpWindow ) |
| { |
| if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME ) |
| mpData->maTimer.Start(); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( Cursor, ImplTimerHdl, AutoTimer*, EMPTYARG ) |
| { |
| if ( mpData->mbCurVisible ) |
| ImplRestore(); |
| else |
| ImplDraw(); |
| return 0; |
| } |
| |
| // ======================================================================= |
| |
| Cursor::Cursor() |
| { |
| mpData = NULL; |
| mpWindow = NULL; |
| mnSlant = 0; |
| mnOffsetY = 0; |
| mnOrientation = 0; |
| mnDirection = 0; |
| mnStyle = 0; |
| mbVisible = sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Cursor::Cursor( const Cursor& rCursor ) : |
| maSize( rCursor.maSize ), |
| maPos( rCursor.maPos ) |
| { |
| mpData = NULL; |
| mpWindow = NULL; |
| mnSlant = rCursor.mnSlant; |
| mnOrientation = rCursor.mnOrientation; |
| mnDirection = rCursor.mnDirection; |
| mnStyle = 0; |
| mbVisible = rCursor.mbVisible; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Cursor::~Cursor() |
| { |
| if ( mpData ) |
| { |
| if ( mpData->mbCurVisible ) |
| ImplRestore(); |
| |
| delete mpData; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetStyle( sal_uInt16 nStyle ) |
| { |
| if ( mnStyle != nStyle ) |
| { |
| mnStyle = nStyle; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::Show() |
| { |
| if ( !mbVisible ) |
| { |
| mbVisible = sal_True; |
| ImplShow(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::Hide() |
| { |
| if ( mbVisible ) |
| { |
| mbVisible = sal_False; |
| ImplHide( true ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetWindow( Window* pWindow ) |
| { |
| if ( mpWindow != pWindow ) |
| { |
| mpWindow = pWindow; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetPos( const Point& rPoint ) |
| { |
| if ( maPos != rPoint ) |
| { |
| maPos = rPoint; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetOffsetY( long nNewOffsetY ) |
| { |
| if ( mnOffsetY != nNewOffsetY ) |
| { |
| mnOffsetY = nNewOffsetY; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetSize( const Size& rSize ) |
| { |
| if ( maSize != rSize ) |
| { |
| maSize = rSize; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetWidth( long nNewWidth ) |
| { |
| if ( maSize.Width() != nNewWidth ) |
| { |
| maSize.Width() = nNewWidth; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetHeight( long nNewHeight ) |
| { |
| if ( maSize.Height() != nNewHeight ) |
| { |
| maSize.Height() = nNewHeight; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetSlant( long nNewSlant ) |
| { |
| if ( mnSlant != nNewSlant ) |
| { |
| mnSlant = nNewSlant; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetOrientation( short nNewOrientation ) |
| { |
| if ( mnOrientation != nNewOrientation ) |
| { |
| mnOrientation = nNewOrientation; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void Cursor::SetDirection( unsigned char nNewDirection ) |
| { |
| if ( mnDirection != nNewDirection ) |
| { |
| mnDirection = nNewDirection; |
| ImplNew(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Cursor& Cursor::operator=( const Cursor& rCursor ) |
| { |
| maPos = rCursor.maPos; |
| maSize = rCursor.maSize; |
| mnSlant = rCursor.mnSlant; |
| mnOrientation = rCursor.mnOrientation; |
| mnDirection = rCursor.mnDirection; |
| mbVisible = rCursor.mbVisible; |
| ImplNew(); |
| |
| return *this; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool Cursor::operator==( const Cursor& rCursor ) const |
| { |
| if ( (maPos == rCursor.maPos) && |
| (maSize == rCursor.maSize) && |
| (mnSlant == rCursor.mnSlant) && |
| (mnOrientation == rCursor.mnOrientation) && |
| (mnDirection == rCursor.mnDirection) && |
| (mbVisible == rCursor.mbVisible) ) |
| return sal_True; |
| else |
| return sal_False; |
| } |