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 4945 : struct ImplCursorData
31 : {
32 : AutoTimer maTimer; // Timer
33 : Point maPixPos; // Pixel-Position
34 : Point maPixRotOff; // Pixel-Offset-Position
35 : Size maPixSize; // Pixel-Size
36 : long mnPixSlant; // Pixel-Slant
37 : short mnOrientation; // Pixel-Orientation
38 : CursorDirection mnDirection; // indicates writing direction
39 : sal_uInt16 mnStyle; // Cursor-Style
40 : bool mbCurVisible; // Ist Cursor aktuell sichtbar
41 : VclPtr<vcl::Window> mpWindow; // Zugeordnetes Windows
42 : };
43 :
44 62356 : static void ImplCursorInvert( ImplCursorData* pData )
45 : {
46 62356 : vcl::Window* pWindow = pData->mpWindow;
47 62356 : bool bMapMode = pWindow->IsMapModeEnabled();
48 62356 : pWindow->EnableMapMode( false );
49 : InvertFlags nInvertStyle;
50 62356 : if ( pData->mnStyle & CURSOR_SHADOW )
51 0 : nInvertStyle = InvertFlags::N50;
52 : else
53 62356 : nInvertStyle = InvertFlags::NONE;
54 :
55 62356 : Rectangle aRect( pData->maPixPos, pData->maPixSize );
56 62356 : if ( pData->mnDirection != CursorDirection::NONE || pData->mnOrientation || pData->mnPixSlant )
57 : {
58 18 : Polygon aPoly( aRect );
59 18 : if( aPoly.GetSize() == 5 )
60 : {
61 18 : aPoly[1].X() += 1; // include the right border
62 18 : aPoly[2].X() += 1;
63 18 : if ( pData->mnPixSlant )
64 : {
65 0 : Point aPoint = aPoly.GetPoint( 0 );
66 0 : aPoint.X() += pData->mnPixSlant;
67 0 : aPoly.SetPoint( aPoint, 0 );
68 0 : aPoly.SetPoint( aPoint, 4 );
69 0 : aPoint = aPoly.GetPoint( 1 );
70 0 : aPoint.X() += pData->mnPixSlant;
71 0 : aPoly.SetPoint( aPoint, 1 );
72 : }
73 :
74 : // apply direction flag after slant to use the correct shape
75 18 : if ( pData->mnDirection != CursorDirection::NONE)
76 : {
77 18 : Point pAry[7];
78 18 : int delta = 3*aRect.getWidth()+1;
79 18 : if( pData->mnDirection == CursorDirection::LTR )
80 : {
81 : // left-to-right
82 18 : pAry[0] = aPoly.GetPoint( 0 );
83 18 : pAry[1] = aPoly.GetPoint( 1 );
84 18 : pAry[2] = pAry[1];
85 18 : pAry[2].X() += delta;
86 18 : pAry[3] = pAry[1];
87 18 : pAry[3].Y() += delta;
88 18 : pAry[4] = aPoly.GetPoint( 2 );
89 18 : pAry[5] = aPoly.GetPoint( 3 );
90 18 : pAry[6] = aPoly.GetPoint( 4 );
91 : }
92 0 : else if( pData->mnDirection == CursorDirection::RTL )
93 : {
94 : // right-to-left
95 0 : pAry[0] = aPoly.GetPoint( 0 );
96 0 : pAry[1] = aPoly.GetPoint( 1 );
97 0 : pAry[2] = aPoly.GetPoint( 2 );
98 0 : pAry[3] = aPoly.GetPoint( 3 );
99 0 : pAry[4] = pAry[0];
100 0 : pAry[4].Y() += delta;
101 0 : pAry[5] = pAry[0];
102 0 : pAry[5].X() -= delta;
103 0 : pAry[6] = aPoly.GetPoint( 4 );
104 : }
105 18 : aPoly = Polygon( 7, pAry);
106 : }
107 :
108 18 : if ( pData->mnOrientation )
109 0 : aPoly.Rotate( pData->maPixRotOff, pData->mnOrientation );
110 18 : pWindow->Invert( aPoly, nInvertStyle );
111 18 : }
112 : }
113 : else
114 62338 : pWindow->Invert( aRect, nInvertStyle );
115 62356 : pWindow->EnableMapMode( bMapMode );
116 62356 : }
117 :
118 31178 : void vcl::Cursor::ImplDraw()
119 : {
120 31178 : if ( mpData && mpData->mpWindow && !mpData->mbCurVisible )
121 : {
122 31178 : vcl::Window* pWindow = mpData->mpWindow;
123 31178 : mpData->maPixPos = pWindow->LogicToPixel( maPos );
124 31178 : mpData->maPixSize = pWindow->LogicToPixel( maSize );
125 31178 : mpData->mnPixSlant = pWindow->LogicToPixel( Size( mnSlant, 0 ) ).Width();
126 31178 : mpData->mnOrientation = mnOrientation;
127 31178 : mpData->mnDirection = mnDirection;
128 :
129 : // correct the position with the offset
130 31178 : mpData->maPixRotOff = mpData->maPixPos;
131 :
132 : // use width (as set in Settings) if size is 0,
133 31178 : if ( !mpData->maPixSize.Width() )
134 31109 : mpData->maPixSize.Width() = pWindow->GetSettings().GetStyleSettings().GetCursorSize();
135 :
136 : // calculate output area and display
137 31178 : ImplCursorInvert( mpData );
138 31178 : mpData->mbCurVisible = true;
139 : }
140 31178 : }
141 :
142 31178 : void vcl::Cursor::ImplRestore()
143 : {
144 31178 : if ( mpData && mpData->mbCurVisible )
145 : {
146 31178 : ImplCursorInvert( mpData );
147 31178 : mpData->mbCurVisible = false;
148 : }
149 31178 : }
150 :
151 93592 : void vcl::Cursor::ImplDoShow( bool bDrawDirect, bool bRestore )
152 : {
153 93592 : if ( mbVisible )
154 : {
155 : vcl::Window* pWindow;
156 72560 : if ( mpWindow )
157 0 : pWindow = mpWindow;
158 : else
159 : {
160 : // show the cursor, if there is an active window and the cursor
161 : // has been selected in this window
162 72560 : pWindow = Application::GetFocusWindow();
163 72560 : if ( !pWindow || (pWindow->mpWindowImpl->mpCursor != this) || pWindow->mpWindowImpl->mbInPaint
164 30275 : || !pWindow->mpWindowImpl->mpFrameData->mbHasFocus )
165 42287 : pWindow = NULL;
166 : }
167 :
168 72560 : if ( pWindow )
169 : {
170 30273 : if ( !mpData )
171 : {
172 2473 : mpData = new ImplCursorData;
173 2473 : mpData->mbCurVisible = false;
174 2473 : mpData->maTimer.SetTimeoutHdl( LINK( this, Cursor, ImplTimerHdl ) );
175 : }
176 :
177 30273 : mpData->mpWindow = pWindow;
178 30273 : mpData->mnStyle = mnStyle;
179 30273 : if ( bDrawDirect || bRestore )
180 30273 : ImplDraw();
181 :
182 30273 : if ( !mpWindow && ! ( ! bDrawDirect && mpData->maTimer.IsActive()) )
183 : {
184 30273 : mpData->maTimer.SetTimeout( pWindow->GetSettings().GetStyleSettings().GetCursorBlinkTime() );
185 30273 : if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
186 0 : mpData->maTimer.Start();
187 30273 : else if ( !mpData->mbCurVisible )
188 0 : ImplDraw();
189 : }
190 : }
191 : }
192 93592 : }
193 :
194 89410 : bool vcl::Cursor::ImplDoHide( bool bSuspend )
195 : {
196 89410 : bool bWasCurVisible = false;
197 89410 : if ( mpData && mpData->mpWindow )
198 : {
199 33048 : bWasCurVisible = mpData->mbCurVisible;
200 33048 : if ( mpData->mbCurVisible )
201 30273 : ImplRestore();
202 :
203 33048 : if ( !bSuspend )
204 : {
205 29411 : mpData->maTimer.Stop();
206 29411 : mpData->mpWindow = NULL;
207 : }
208 : }
209 89410 : return bWasCurVisible;
210 : }
211 :
212 80899 : void vcl::Cursor::ImplShow( bool bDrawDirect )
213 : {
214 80899 : ImplDoShow( bDrawDirect, false );
215 80899 : }
216 :
217 76956 : void vcl::Cursor::ImplHide( bool i_bStopTimer )
218 : {
219 : assert( i_bStopTimer );
220 76956 : ImplDoHide( !i_bStopTimer );
221 76956 : }
222 :
223 12693 : void vcl::Cursor::ImplResume( bool bRestore )
224 : {
225 12693 : ImplDoShow( false, bRestore );
226 12693 : }
227 :
228 12454 : bool vcl::Cursor::ImplSuspend()
229 : {
230 12454 : return ImplDoHide( true );
231 : }
232 :
233 106028 : void vcl::Cursor::ImplNew()
234 : {
235 106028 : if ( mbVisible && mpData && mpData->mpWindow )
236 : {
237 905 : if ( mpData->mbCurVisible )
238 905 : ImplRestore();
239 :
240 905 : ImplDraw();
241 905 : if ( !mpWindow )
242 : {
243 905 : if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
244 0 : mpData->maTimer.Start();
245 : }
246 : }
247 106028 : }
248 :
249 0 : IMPL_LINK_NOARG_TYPED(vcl::Cursor, ImplTimerHdl, Timer *, void)
250 : {
251 0 : if ( mpData->mbCurVisible )
252 0 : ImplRestore();
253 : else
254 0 : ImplDraw();
255 0 : }
256 :
257 17052 : vcl::Cursor::Cursor()
258 : {
259 17052 : mpData = NULL;
260 17052 : mpWindow = NULL;
261 17052 : mnSlant = 0;
262 17052 : mnOrientation = 0;
263 17052 : mnDirection = CursorDirection::NONE;
264 17052 : mnStyle = 0;
265 17052 : mbVisible = false;
266 17052 : }
267 :
268 0 : vcl::Cursor::Cursor( const Cursor& rCursor ) :
269 : maSize( rCursor.maSize ),
270 0 : maPos( rCursor.maPos )
271 : {
272 0 : mpData = NULL;
273 0 : mpWindow = NULL;
274 0 : mnSlant = rCursor.mnSlant;
275 0 : mnOrientation = rCursor.mnOrientation;
276 0 : mnDirection = rCursor.mnDirection;
277 0 : mnStyle = 0;
278 0 : mbVisible = rCursor.mbVisible;
279 0 : }
280 :
281 34072 : vcl::Cursor::~Cursor()
282 : {
283 17036 : if ( mpData )
284 : {
285 2472 : if ( mpData->mbCurVisible )
286 0 : ImplRestore();
287 :
288 2472 : delete mpData;
289 : }
290 17036 : }
291 :
292 0 : void vcl::Cursor::SetStyle( sal_uInt16 nStyle )
293 : {
294 0 : if ( mnStyle != nStyle )
295 : {
296 0 : mnStyle = nStyle;
297 0 : ImplNew();
298 : }
299 0 : }
300 :
301 63003 : void vcl::Cursor::Show()
302 : {
303 63003 : if ( !mbVisible )
304 : {
305 61400 : mbVisible = true;
306 61400 : ImplShow();
307 : }
308 63003 : }
309 :
310 60795 : void vcl::Cursor::Hide()
311 : {
312 60795 : if ( mbVisible )
313 : {
314 57552 : mbVisible = false;
315 57552 : ImplHide( true );
316 : }
317 60795 : }
318 :
319 0 : void vcl::Cursor::SetWindow( vcl::Window* pWindow )
320 : {
321 0 : if ( mpWindow.get() != pWindow )
322 : {
323 0 : mpWindow = pWindow;
324 0 : ImplNew();
325 : }
326 0 : }
327 :
328 60710 : void vcl::Cursor::SetPos( const Point& rPoint )
329 : {
330 60710 : if ( maPos != rPoint )
331 : {
332 9805 : maPos = rPoint;
333 9805 : ImplNew();
334 : }
335 60710 : }
336 :
337 60684 : void vcl::Cursor::SetSize( const Size& rSize )
338 : {
339 60684 : if ( maSize != rSize )
340 : {
341 8638 : maSize = rSize;
342 8638 : ImplNew();
343 : }
344 60684 : }
345 :
346 2761 : void vcl::Cursor::SetWidth( long nNewWidth )
347 : {
348 2761 : if ( maSize.Width() != nNewWidth )
349 : {
350 0 : maSize.Width() = nNewWidth;
351 0 : ImplNew();
352 : }
353 2761 : }
354 :
355 55573 : void vcl::Cursor::SetOrientation( short nNewOrientation )
356 : {
357 55573 : if ( mnOrientation != nNewOrientation )
358 : {
359 0 : mnOrientation = nNewOrientation;
360 0 : ImplNew();
361 : }
362 55573 : }
363 :
364 55592 : void vcl::Cursor::SetDirection( CursorDirection nNewDirection )
365 : {
366 55592 : if ( mnDirection != nNewDirection )
367 : {
368 37 : mnDirection = nNewDirection;
369 37 : ImplNew();
370 : }
371 55592 : }
372 :
373 0 : vcl::Cursor& vcl::Cursor::operator=( const vcl::Cursor& rCursor )
374 : {
375 0 : maPos = rCursor.maPos;
376 0 : maSize = rCursor.maSize;
377 0 : mnSlant = rCursor.mnSlant;
378 0 : mnOrientation = rCursor.mnOrientation;
379 0 : mnDirection = rCursor.mnDirection;
380 0 : mbVisible = rCursor.mbVisible;
381 0 : ImplNew();
382 :
383 0 : return *this;
384 : }
385 :
386 0 : bool vcl::Cursor::operator==( const vcl::Cursor& rCursor ) const
387 : {
388 : return
389 0 : ((maPos == rCursor.maPos) &&
390 0 : (maSize == rCursor.maSize) &&
391 0 : (mnSlant == rCursor.mnSlant) &&
392 0 : (mnOrientation == rCursor.mnOrientation) &&
393 0 : (mnDirection == rCursor.mnDirection) &&
394 0 : (mbVisible == rCursor.mbVisible))
395 : ;
396 : }
397 :
398 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|