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