Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/svapp.hxx>
21 : #include <vcl/timer.hxx>
22 : #include <vcl/settings.hxx>
23 : #include <vcl/window.hxx>
24 : #include <vcl/cursor.hxx>
25 :
26 : #include <window.h>
27 :
28 : #include <tools/poly.hxx>
29 :
30 :
31 : // =======================================================================
32 :
33 181 : struct ImplCursorData
34 : {
35 : AutoTimer maTimer; // Timer
36 : Point maPixPos; // Pixel-Position
37 : Point maPixRotOff; // Pixel-Offset-Position
38 : Size maPixSize; // Pixel-Size
39 : long mnPixSlant; // Pixel-Slant
40 : short mnOrientation; // Pixel-Orientation
41 : unsigned char mnDirection; // indicates writing direction
42 : sal_uInt16 mnStyle; // Cursor-Style
43 : bool mbCurVisible; // Ist Cursor aktuell sichtbar
44 : Window* mpWindow; // Zugeordnetes Windows
45 : };
46 :
47 : // =======================================================================
48 :
49 1132 : static void ImplCursorInvert( ImplCursorData* pData )
50 : {
51 1132 : Window* pWindow = pData->mpWindow;
52 1132 : bool bMapMode = pWindow->IsMapModeEnabled();
53 1132 : pWindow->EnableMapMode( false );
54 : sal_uInt16 nInvertStyle;
55 1132 : if ( pData->mnStyle & CURSOR_SHADOW )
56 0 : nInvertStyle = INVERT_50;
57 : else
58 1132 : nInvertStyle = 0;
59 :
60 1132 : Rectangle aRect( pData->maPixPos, pData->maPixSize );
61 1132 : if ( pData->mnDirection || pData->mnOrientation || pData->mnPixSlant )
62 : {
63 0 : Polygon aPoly( aRect );
64 0 : if( aPoly.GetSize() == 5 )
65 : {
66 0 : aPoly[1].X() += 1; // include the right border
67 0 : aPoly[2].X() += 1;
68 0 : if ( pData->mnPixSlant )
69 : {
70 0 : Point aPoint = aPoly.GetPoint( 0 );
71 0 : aPoint.X() += pData->mnPixSlant;
72 0 : aPoly.SetPoint( aPoint, 0 );
73 0 : aPoly.SetPoint( aPoint, 4 );
74 0 : aPoint = aPoly.GetPoint( 1 );
75 0 : aPoint.X() += pData->mnPixSlant;
76 0 : aPoly.SetPoint( aPoint, 1 );
77 : }
78 :
79 : // apply direction flag after slant to use the correct shape
80 0 : if ( pData->mnDirection )
81 : {
82 0 : Point pAry[7];
83 0 : int delta = 3*aRect.getWidth()+1;
84 0 : if( pData->mnDirection == CURSOR_DIRECTION_LTR )
85 : {
86 : // left-to-right
87 0 : pAry[0] = aPoly.GetPoint( 0 );
88 0 : pAry[1] = aPoly.GetPoint( 1 );
89 0 : pAry[2] = pAry[1];
90 0 : pAry[2].X() += delta;
91 0 : pAry[3] = pAry[1];
92 0 : pAry[3].Y() += delta;
93 0 : pAry[4] = aPoly.GetPoint( 2 );
94 0 : pAry[5] = aPoly.GetPoint( 3 );
95 0 : pAry[6] = aPoly.GetPoint( 4 );
96 : }
97 0 : else if( pData->mnDirection == CURSOR_DIRECTION_RTL )
98 : {
99 : // right-to-left
100 0 : pAry[0] = aPoly.GetPoint( 0 );
101 0 : pAry[1] = aPoly.GetPoint( 1 );
102 0 : pAry[2] = aPoly.GetPoint( 2 );
103 0 : pAry[3] = aPoly.GetPoint( 3 );
104 0 : pAry[4] = pAry[0];
105 0 : pAry[4].Y() += delta;
106 0 : pAry[5] = pAry[0];
107 0 : pAry[5].X() -= delta;
108 0 : pAry[6] = aPoly.GetPoint( 4 );
109 : }
110 0 : aPoly = Polygon( 7, pAry);
111 : }
112 :
113 0 : if ( pData->mnOrientation )
114 0 : aPoly.Rotate( pData->maPixRotOff, pData->mnOrientation );
115 0 : pWindow->Invert( aPoly, nInvertStyle );
116 0 : }
117 : }
118 : else
119 1132 : pWindow->Invert( aRect, nInvertStyle );
120 1132 : pWindow->EnableMapMode( bMapMode );
121 1132 : }
122 :
123 : // -----------------------------------------------------------------------
124 :
125 566 : void Cursor::ImplDraw()
126 : {
127 566 : if ( mpData && mpData->mpWindow && !mpData->mbCurVisible )
128 : {
129 566 : Window* pWindow = mpData->mpWindow;
130 566 : mpData->maPixPos = pWindow->LogicToPixel( maPos );
131 566 : mpData->maPixSize = pWindow->LogicToPixel( maSize );
132 566 : mpData->mnPixSlant = pWindow->LogicToPixel( Size( mnSlant, 0 ) ).Width();
133 566 : mpData->mnOrientation = mnOrientation;
134 566 : mpData->mnDirection = mnDirection;
135 566 : long nOffsetY = pWindow->LogicToPixel( Size( 0, mnOffsetY ) ).Height();
136 :
137 : // Position um den Offset korrigieren
138 566 : mpData->maPixPos.Y() -= nOffsetY;
139 566 : mpData->maPixRotOff = mpData->maPixPos;
140 566 : mpData->maPixRotOff.Y() += nOffsetY;
141 :
142 : // Wenn groesse 0 ist, nehmen wir die breite, die in den
143 : // Settings eingestellt ist
144 566 : if ( !mpData->maPixSize.Width() )
145 566 : mpData->maPixSize.Width() = pWindow->GetSettings().GetStyleSettings().GetCursorSize();
146 :
147 : // Ausgabeflaeche berechnen und ausgeben
148 566 : ImplCursorInvert( mpData );
149 566 : mpData->mbCurVisible = true;
150 : }
151 566 : }
152 :
153 : // -----------------------------------------------------------------------
154 :
155 566 : void Cursor::ImplRestore()
156 : {
157 566 : if ( mpData && mpData->mbCurVisible )
158 : {
159 566 : ImplCursorInvert( mpData );
160 566 : mpData->mbCurVisible = false;
161 : }
162 566 : }
163 :
164 2565 : void Cursor::ImplDoShow( bool bDrawDirect, bool bRestore )
165 : {
166 2565 : if ( mbVisible )
167 : {
168 : Window* pWindow;
169 1989 : if ( mpWindow )
170 0 : pWindow = mpWindow;
171 : else
172 : {
173 : // Gibt es ein aktives Fenster und ist der Cursor in dieses Fenster
174 : // selektiert, dann zeige den Cursor an
175 1989 : pWindow = Application::GetFocusWindow();
176 2636 : if ( !pWindow || (pWindow->mpWindowImpl->mpCursor != this) || pWindow->mpWindowImpl->mbInPaint
177 647 : || !pWindow->mpWindowImpl->mpFrameData->mbHasFocus )
178 1443 : pWindow = NULL;
179 : }
180 :
181 1989 : if ( pWindow )
182 : {
183 546 : if ( !mpData )
184 : {
185 141 : mpData = new ImplCursorData;
186 141 : mpData->mbCurVisible = false;
187 141 : mpData->maTimer.SetTimeoutHdl( LINK( this, Cursor, ImplTimerHdl ) );
188 : }
189 :
190 546 : mpData->mpWindow = pWindow;
191 546 : mpData->mnStyle = mnStyle;
192 546 : if ( bDrawDirect || bRestore )
193 546 : ImplDraw();
194 :
195 546 : if ( !mpWindow && ! ( ! bDrawDirect && mpData->maTimer.IsActive()) )
196 : {
197 546 : mpData->maTimer.SetTimeout( pWindow->GetSettings().GetStyleSettings().GetCursorBlinkTime() );
198 546 : if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
199 0 : mpData->maTimer.Start();
200 546 : else if ( !mpData->mbCurVisible )
201 0 : ImplDraw();
202 : }
203 : }
204 : }
205 2565 : }
206 :
207 2287 : bool Cursor::ImplDoHide( bool bSuspend )
208 : {
209 2287 : bool bWasCurVisible = false;
210 2287 : if ( mpData && mpData->mpWindow )
211 : {
212 546 : bWasCurVisible = mpData->mbCurVisible;
213 546 : if ( mpData->mbCurVisible )
214 546 : ImplRestore();
215 :
216 546 : if ( !bSuspend )
217 : {
218 545 : mpData->maTimer.Stop();
219 545 : mpData->mpWindow = NULL;
220 : }
221 : }
222 2287 : return bWasCurVisible;
223 : }
224 :
225 2275 : void Cursor::ImplShow( bool bDrawDirect )
226 : {
227 2275 : ImplDoShow( bDrawDirect, false );
228 2275 : }
229 :
230 1997 : void Cursor::ImplHide( bool i_bStopTimer )
231 : {
232 : assert( i_bStopTimer );
233 1997 : ImplDoHide( !i_bStopTimer );
234 1997 : }
235 :
236 290 : void Cursor::ImplResume( bool bRestore )
237 : {
238 290 : ImplDoShow( false, bRestore );
239 290 : }
240 :
241 290 : bool Cursor::ImplSuspend()
242 : {
243 290 : return ImplDoHide( true );
244 : }
245 :
246 3668 : void Cursor::ImplNew()
247 : {
248 3668 : if ( mbVisible && mpData && mpData->mpWindow )
249 : {
250 20 : if ( mpData->mbCurVisible )
251 20 : ImplRestore();
252 :
253 20 : ImplDraw();
254 20 : if ( !mpWindow )
255 : {
256 20 : if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
257 0 : mpData->maTimer.Start();
258 : }
259 : }
260 3668 : }
261 :
262 : // -----------------------------------------------------------------------
263 :
264 0 : IMPL_LINK_NOARG(Cursor, ImplTimerHdl)
265 : {
266 0 : if ( mpData->mbCurVisible )
267 0 : ImplRestore();
268 : else
269 0 : ImplDraw();
270 0 : return 0;
271 : }
272 :
273 : // =======================================================================
274 :
275 498 : Cursor::Cursor()
276 : {
277 498 : mpData = NULL;
278 498 : mpWindow = NULL;
279 498 : mnSlant = 0;
280 498 : mnOffsetY = 0;
281 498 : mnOrientation = 0;
282 498 : mnDirection = 0;
283 498 : mnStyle = 0;
284 498 : mbVisible = false;
285 498 : }
286 :
287 : // -----------------------------------------------------------------------
288 :
289 0 : Cursor::Cursor( const Cursor& rCursor ) :
290 : maSize( rCursor.maSize ),
291 0 : maPos( rCursor.maPos )
292 : {
293 0 : mpData = NULL;
294 0 : mpWindow = NULL;
295 0 : mnSlant = rCursor.mnSlant;
296 0 : mnOrientation = rCursor.mnOrientation;
297 0 : mnDirection = rCursor.mnDirection;
298 0 : mnStyle = 0;
299 0 : mbVisible = rCursor.mbVisible;
300 0 : }
301 :
302 : // -----------------------------------------------------------------------
303 :
304 143 : Cursor::~Cursor()
305 : {
306 143 : if ( mpData )
307 : {
308 40 : if ( mpData->mbCurVisible )
309 0 : ImplRestore();
310 :
311 40 : delete mpData;
312 : }
313 143 : }
314 :
315 : // -----------------------------------------------------------------------
316 :
317 0 : void Cursor::SetStyle( sal_uInt16 nStyle )
318 : {
319 0 : if ( mnStyle != nStyle )
320 : {
321 0 : mnStyle = nStyle;
322 0 : ImplNew();
323 : }
324 0 : }
325 :
326 : // -----------------------------------------------------------------------
327 :
328 1659 : void Cursor::Show()
329 : {
330 1659 : if ( !mbVisible )
331 : {
332 1643 : mbVisible = true;
333 1643 : ImplShow();
334 : }
335 1659 : }
336 :
337 : // -----------------------------------------------------------------------
338 :
339 1667 : void Cursor::Hide()
340 : {
341 1667 : if ( mbVisible )
342 : {
343 1621 : mbVisible = false;
344 1621 : ImplHide( true );
345 : }
346 1667 : }
347 :
348 : // -----------------------------------------------------------------------
349 :
350 0 : void Cursor::SetWindow( Window* pWindow )
351 : {
352 0 : if ( mpWindow != pWindow )
353 : {
354 0 : mpWindow = pWindow;
355 0 : ImplNew();
356 : }
357 0 : }
358 :
359 : // -----------------------------------------------------------------------
360 :
361 1677 : void Cursor::SetPos( const Point& rPoint )
362 : {
363 1677 : if ( maPos != rPoint )
364 : {
365 236 : maPos = rPoint;
366 236 : ImplNew();
367 : }
368 1677 : }
369 :
370 : // -----------------------------------------------------------------------
371 :
372 1675 : void Cursor::SetSize( const Size& rSize )
373 : {
374 1675 : if ( maSize != rSize )
375 : {
376 231 : maSize = rSize;
377 231 : ImplNew();
378 : }
379 1675 : }
380 :
381 : // -----------------------------------------------------------------------
382 :
383 236 : void Cursor::SetWidth( long nNewWidth )
384 : {
385 236 : if ( maSize.Width() != nNewWidth )
386 : {
387 0 : maSize.Width() = nNewWidth;
388 0 : ImplNew();
389 : }
390 236 : }
391 :
392 : // -----------------------------------------------------------------------
393 :
394 1663 : void Cursor::SetOrientation( short nNewOrientation )
395 : {
396 1663 : if ( mnOrientation != nNewOrientation )
397 : {
398 0 : mnOrientation = nNewOrientation;
399 0 : ImplNew();
400 : }
401 1663 : }
402 :
403 : // -----------------------------------------------------------------------
404 :
405 1663 : void Cursor::SetDirection( unsigned char nNewDirection )
406 : {
407 1663 : if ( mnDirection != nNewDirection )
408 : {
409 0 : mnDirection = nNewDirection;
410 0 : ImplNew();
411 : }
412 1663 : }
413 :
414 : // -----------------------------------------------------------------------
415 :
416 0 : Cursor& Cursor::operator=( const Cursor& rCursor )
417 : {
418 0 : maPos = rCursor.maPos;
419 0 : maSize = rCursor.maSize;
420 0 : mnSlant = rCursor.mnSlant;
421 0 : mnOrientation = rCursor.mnOrientation;
422 0 : mnDirection = rCursor.mnDirection;
423 0 : mbVisible = rCursor.mbVisible;
424 0 : ImplNew();
425 :
426 0 : return *this;
427 : }
428 :
429 : // -----------------------------------------------------------------------
430 :
431 0 : bool Cursor::operator==( const Cursor& rCursor ) const
432 : {
433 : return
434 0 : ((maPos == rCursor.maPos) &&
435 0 : (maSize == rCursor.maSize) &&
436 : (mnSlant == rCursor.mnSlant) &&
437 : (mnOrientation == rCursor.mnOrientation) &&
438 : (mnDirection == rCursor.mnDirection) &&
439 0 : (mbVisible == rCursor.mbVisible))
440 : ;
441 : }
442 :
443 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|