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 1260 : 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 33216 : static void ImplCursorInvert( ImplCursorData* pData )
50 : {
51 33216 : Window* pWindow = pData->mpWindow;
52 33216 : bool bMapMode = pWindow->IsMapModeEnabled();
53 33216 : pWindow->EnableMapMode( false );
54 : sal_uInt16 nInvertStyle;
55 33216 : if ( pData->mnStyle & CURSOR_SHADOW )
56 0 : nInvertStyle = INVERT_50;
57 : else
58 33216 : nInvertStyle = 0;
59 :
60 33216 : Rectangle aRect( pData->maPixPos, pData->maPixSize );
61 33216 : 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 33216 : pWindow->Invert( aRect, nInvertStyle );
120 33216 : pWindow->EnableMapMode( bMapMode );
121 33216 : }
122 :
123 : // -----------------------------------------------------------------------
124 :
125 16608 : void Cursor::ImplDraw()
126 : {
127 16608 : if ( mpData && mpData->mpWindow && !mpData->mbCurVisible )
128 : {
129 16608 : Window* pWindow = mpData->mpWindow;
130 16608 : mpData->maPixPos = pWindow->LogicToPixel( maPos );
131 16608 : mpData->maPixSize = pWindow->LogicToPixel( maSize );
132 16608 : mpData->mnPixSlant = pWindow->LogicToPixel( Size( mnSlant, 0 ) ).Width();
133 16608 : mpData->mnOrientation = mnOrientation;
134 16608 : mpData->mnDirection = mnDirection;
135 16608 : long nOffsetY = pWindow->LogicToPixel( Size( 0, mnOffsetY ) ).Height();
136 :
137 : // Position um den Offset korrigieren
138 16608 : mpData->maPixPos.Y() -= nOffsetY;
139 16608 : mpData->maPixRotOff = mpData->maPixPos;
140 16608 : mpData->maPixRotOff.Y() += nOffsetY;
141 :
142 : // Wenn groesse 0 ist, nehmen wir die breite, die in den
143 : // Settings eingestellt ist
144 16608 : if ( !mpData->maPixSize.Width() )
145 16565 : mpData->maPixSize.Width() = pWindow->GetSettings().GetStyleSettings().GetCursorSize();
146 :
147 : // Ausgabeflaeche berechnen und ausgeben
148 16608 : ImplCursorInvert( mpData );
149 16608 : mpData->mbCurVisible = true;
150 : }
151 16608 : }
152 :
153 : // -----------------------------------------------------------------------
154 :
155 16608 : void Cursor::ImplRestore()
156 : {
157 16608 : if ( mpData && mpData->mbCurVisible )
158 : {
159 16608 : ImplCursorInvert( mpData );
160 16608 : mpData->mbCurVisible = false;
161 : }
162 16608 : }
163 :
164 41701 : void Cursor::ImplDoShow( bool bDrawDirect, bool bRestore )
165 : {
166 41701 : if ( mbVisible )
167 : {
168 : Window* pWindow;
169 32332 : 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 32332 : pWindow = Application::GetFocusWindow();
176 32332 : if ( !pWindow || (pWindow->mpWindowImpl->mpCursor != this) || pWindow->mpWindowImpl->mbInPaint
177 16547 : || !pWindow->mpWindowImpl->mpFrameData->mbHasFocus )
178 15786 : pWindow = NULL;
179 : }
180 :
181 32332 : if ( pWindow )
182 : {
183 16546 : if ( !mpData )
184 : {
185 630 : mpData = new ImplCursorData;
186 630 : mpData->mbCurVisible = false;
187 630 : mpData->maTimer.SetTimeoutHdl( LINK( this, Cursor, ImplTimerHdl ) );
188 : }
189 :
190 16546 : mpData->mpWindow = pWindow;
191 16546 : mpData->mnStyle = mnStyle;
192 16546 : if ( bDrawDirect || bRestore )
193 16533 : ImplDraw();
194 :
195 16546 : if ( !mpWindow && ! ( ! bDrawDirect && mpData->maTimer.IsActive()) )
196 : {
197 16546 : mpData->maTimer.SetTimeout( pWindow->GetSettings().GetStyleSettings().GetCursorBlinkTime() );
198 16546 : if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
199 0 : mpData->maTimer.Start();
200 16546 : else if ( !mpData->mbCurVisible )
201 13 : ImplDraw();
202 : }
203 : }
204 : }
205 41701 : }
206 :
207 39561 : bool Cursor::ImplDoHide( bool bSuspend )
208 : {
209 39561 : bool bWasCurVisible = false;
210 39561 : if ( mpData && mpData->mpWindow )
211 : {
212 18104 : bWasCurVisible = mpData->mbCurVisible;
213 18104 : if ( mpData->mbCurVisible )
214 16546 : ImplRestore();
215 :
216 18104 : if ( !bSuspend )
217 : {
218 15550 : mpData->maTimer.Stop();
219 15550 : mpData->mpWindow = NULL;
220 : }
221 : }
222 39561 : return bWasCurVisible;
223 : }
224 :
225 30655 : void Cursor::ImplShow( bool bDrawDirect )
226 : {
227 30655 : ImplDoShow( bDrawDirect, false );
228 30655 : }
229 :
230 28718 : void Cursor::ImplHide( bool i_bStopTimer )
231 : {
232 : assert( i_bStopTimer );
233 28718 : ImplDoHide( !i_bStopTimer );
234 28718 : }
235 :
236 11046 : void Cursor::ImplResume( bool bRestore )
237 : {
238 11046 : ImplDoShow( false, bRestore );
239 11046 : }
240 :
241 10843 : bool Cursor::ImplSuspend()
242 : {
243 10843 : return ImplDoHide( true );
244 : }
245 :
246 46302 : void Cursor::ImplNew()
247 : {
248 46302 : if ( mbVisible && mpData && mpData->mpWindow )
249 : {
250 62 : if ( mpData->mbCurVisible )
251 62 : ImplRestore();
252 :
253 62 : ImplDraw();
254 62 : if ( !mpWindow )
255 : {
256 62 : if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
257 0 : mpData->maTimer.Start();
258 : }
259 : }
260 46302 : }
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 5367 : Cursor::Cursor()
276 : {
277 5367 : mpData = NULL;
278 5367 : mpWindow = NULL;
279 5367 : mnSlant = 0;
280 5367 : mnOffsetY = 0;
281 5367 : mnOrientation = 0;
282 5367 : mnDirection = 0;
283 5367 : mnStyle = 0;
284 5367 : mbVisible = false;
285 5367 : }
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 5362 : Cursor::~Cursor()
305 : {
306 5362 : if ( mpData )
307 : {
308 630 : if ( mpData->mbCurVisible )
309 0 : ImplRestore();
310 :
311 630 : delete mpData;
312 : }
313 5362 : }
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 25028 : void Cursor::Show()
329 : {
330 25028 : if ( !mbVisible )
331 : {
332 24679 : mbVisible = true;
333 24679 : ImplShow();
334 : }
335 25028 : }
336 :
337 : // -----------------------------------------------------------------------
338 :
339 24298 : void Cursor::Hide()
340 : {
341 24298 : if ( mbVisible )
342 : {
343 22727 : mbVisible = false;
344 22727 : ImplHide( true );
345 : }
346 24298 : }
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 21138 : void Cursor::SetPos( const Point& rPoint )
362 : {
363 21138 : if ( maPos != rPoint )
364 : {
365 4933 : maPos = rPoint;
366 4933 : ImplNew();
367 : }
368 21138 : }
369 :
370 : // -----------------------------------------------------------------------
371 :
372 21134 : void Cursor::SetSize( const Size& rSize )
373 : {
374 21134 : if ( maSize != rSize )
375 : {
376 3760 : maSize = rSize;
377 3760 : ImplNew();
378 : }
379 21134 : }
380 :
381 : // -----------------------------------------------------------------------
382 :
383 793 : void Cursor::SetWidth( long nNewWidth )
384 : {
385 793 : if ( maSize.Width() != nNewWidth )
386 : {
387 0 : maSize.Width() = nNewWidth;
388 0 : ImplNew();
389 : }
390 793 : }
391 :
392 : // -----------------------------------------------------------------------
393 :
394 18981 : void Cursor::SetOrientation( short nNewOrientation )
395 : {
396 18981 : if ( mnOrientation != nNewOrientation )
397 : {
398 0 : mnOrientation = nNewOrientation;
399 0 : ImplNew();
400 : }
401 18981 : }
402 :
403 : // -----------------------------------------------------------------------
404 :
405 18981 : void Cursor::SetDirection( unsigned char nNewDirection )
406 : {
407 18981 : if ( mnDirection != nNewDirection )
408 : {
409 0 : mnDirection = nNewDirection;
410 0 : ImplNew();
411 : }
412 18981 : }
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 0 : (mnSlant == rCursor.mnSlant) &&
437 0 : (mnOrientation == rCursor.mnOrientation) &&
438 0 : (mnDirection == rCursor.mnDirection) &&
439 0 : (mbVisible == rCursor.mbVisible))
440 : ;
441 465 : }
442 :
443 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|