summaryrefslogtreecommitdiff
path: root/vcl/source/window/cursor.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/window/cursor.cxx')
-rw-r--r--vcl/source/window/cursor.cxx465
1 files changed, 465 insertions, 0 deletions
diff --git a/vcl/source/window/cursor.cxx b/vcl/source/window/cursor.cxx
new file mode 100644
index 000000000000..53450647f0c6
--- /dev/null
+++ b/vcl/source/window/cursor.cxx
@@ -0,0 +1,465 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cursor.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 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/window.h>
+#include <tools/poly.hxx>
+#include <vcl/cursor.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
+ USHORT mnStyle; // Cursor-Style
+ BOOL mbCurVisible; // Ist Cursor aktuell sichtbar
+ Window* mpWindow; // Zugeordnetes Windows
+};
+
+// =======================================================================
+
+static void ImplCursorInvert( ImplCursorData* pData )
+{
+ Window* pWindow = pData->mpWindow;
+ BOOL bMapMode = pWindow->IsMapModeEnabled();
+ pWindow->EnableMapMode( FALSE );
+ USHORT 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 = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplRestore()
+{
+ if ( mpData && mpData->mbCurVisible )
+ {
+ ImplCursorInvert( mpData );
+ mpData->mbCurVisible = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplShow( BOOL bDrawDirect )
+{
+ 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 = FALSE;
+ mpData->maTimer.SetTimeoutHdl( LINK( this, Cursor, ImplTimerHdl ) );
+ }
+
+ mpData->mpWindow = pWindow;
+ mpData->mnStyle = mnStyle;
+ if ( bDrawDirect )
+ ImplDraw();
+
+ if ( !mpWindow )
+ {
+ mpData->maTimer.SetTimeout( pWindow->GetSettings().GetStyleSettings().GetCursorBlinkTime() );
+ if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
+ mpData->maTimer.Start();
+ else if ( !mpData->mbCurVisible )
+ ImplDraw();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplHide()
+{
+ if ( mpData && mpData->mpWindow )
+ {
+ if ( mpData->mbCurVisible )
+ ImplRestore();
+
+ mpData->maTimer.Stop();
+ mpData->mpWindow = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+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 = 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( USHORT nStyle )
+{
+ if ( mnStyle != nStyle )
+ {
+ mnStyle = nStyle;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::Show()
+{
+ if ( !mbVisible )
+ {
+ mbVisible = TRUE;
+ ImplShow();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::Hide()
+{
+ if ( mbVisible )
+ {
+ mbVisible = FALSE;
+ ImplHide();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+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;
+}
+
+// -----------------------------------------------------------------------
+
+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 TRUE;
+ else
+ return FALSE;
+}