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_svtools.hxx"
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27
28 #include <vcl/svapp.hxx>
29
30 #include <ipwin.hxx>
31 #include <hatchwindow.hxx>
32
33 /************************************************************************/
34 /*************************************************************************
35 |* SvResizeHelper::SvResizeHelper()
36 |*
37 |* Beschreibung
38 *************************************************************************/
SvResizeHelper()39 SvResizeHelper::SvResizeHelper()
40 : aBorder( 5, 5 )
41 , nGrab( -1 )
42 , bResizeable( sal_True )
43 {
44 }
45
46 /*************************************************************************
47 |* SvResizeHelper::FillHandleRects()
48 |*
49 |* Beschreibung: Die acht Handles zum vergroessern
50 *************************************************************************/
FillHandleRectsPixel(Rectangle aRects[8]) const51 void SvResizeHelper::FillHandleRectsPixel( Rectangle aRects[ 8 ] ) const
52 {
53 // nur wegen EMPTY_RECT
54 Point aBottomRight = aOuter.BottomRight();
55
56 // Links Oben
57 aRects[ 0 ] = Rectangle( aOuter.TopLeft(), aBorder );
58 // Oben Mitte
59 aRects[ 1 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
60 aOuter.Top() ),
61 aBorder );
62 // Oben Rechts
63 aRects[ 2 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
64 aOuter.Top() ),
65 aBorder );
66 // Mitte Rechts
67 aRects[ 3 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
68 aOuter.Center().Y() - aBorder.Height() / 2 ),
69 aBorder );
70 // Unten Rechts
71 aRects[ 4 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
72 aBottomRight.Y() - aBorder.Height() +1 ),
73 aBorder );
74 // Mitte Unten
75 aRects[ 5 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
76 aBottomRight.Y() - aBorder.Height() +1),
77 aBorder );
78 // Links Unten
79 aRects[ 6 ] = Rectangle( Point( aOuter.Left(),
80 aBottomRight.Y() - aBorder.Height() +1),
81 aBorder );
82 // Mitte Links
83 aRects[ 7 ] = Rectangle( Point( aOuter.Left(),
84 aOuter.Center().Y() - aBorder.Height() / 2 ),
85 aBorder );
86 }
87
88 /*************************************************************************
89 |* SvResizeHelper::FillMoveRectsPixel()
90 |*
91 |* Beschreibung: Die vier Kanten werden berechnet
92 *************************************************************************/
FillMoveRectsPixel(Rectangle aRects[4]) const93 void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const
94 {
95 // Oben
96 aRects[ 0 ] = aOuter;
97 aRects[ 0 ].Bottom() = aRects[ 0 ].Top() + aBorder.Height() -1;
98 // Rechts
99 aRects[ 1 ] = aOuter;
100 aRects[ 1 ].Left() = aRects[ 1 ].Right() - aBorder.Width() -1;
101 //Unten
102 aRects[ 2 ] = aOuter;
103 aRects[ 2 ].Top() = aRects[ 2 ].Bottom() - aBorder.Height() -1;
104 //Links
105 aRects[ 3 ] = aOuter;
106 aRects[ 3 ].Right() = aRects[ 3 ].Left() + aBorder.Width() -1;
107 }
108
109 /*************************************************************************
110 |* SvResizeHelper::Draw()
111 |*
112 |* Beschreibung
113 *************************************************************************/
Draw(OutputDevice * pDev)114 void SvResizeHelper::Draw( OutputDevice * pDev )
115 {
116 pDev->Push();
117 pDev->SetMapMode( MapMode() );
118 Color aColBlack;
119 Color aFillColor( COL_LIGHTGRAY );
120
121 pDev->SetFillColor( aFillColor );
122 pDev->SetLineColor();
123
124 Rectangle aMoveRects[ 4 ];
125 FillMoveRectsPixel( aMoveRects );
126 sal_uInt16 i;
127 for( i = 0; i < 4; i++ )
128 pDev->DrawRect( aMoveRects[ i ] );
129 if( bResizeable )
130 {
131 // Handles malen
132 pDev->SetFillColor( aColBlack );
133 Rectangle aRects[ 8 ];
134 FillHandleRectsPixel( aRects );
135 for( i = 0; i < 8; i++ )
136 pDev->DrawRect( aRects[ i ] );
137 }
138 pDev->Pop();
139 }
140
141 /*************************************************************************
142 |* SvResizeHelper::InvalidateBorder()
143 |*
144 |* Beschreibung
145 *************************************************************************/
InvalidateBorder(Window * pWin)146 void SvResizeHelper::InvalidateBorder( Window * pWin )
147 {
148 Rectangle aMoveRects[ 4 ];
149 FillMoveRectsPixel( aMoveRects );
150 for( sal_uInt16 i = 0; i < 4; i++ )
151 pWin->Invalidate( aMoveRects[ i ] );
152 }
153
154 /*************************************************************************
155 |* SvResizeHelper::SelectBegin()
156 |*
157 |* Beschreibung
158 *************************************************************************/
SelectBegin(Window * pWin,const Point & rPos)159 sal_Bool SvResizeHelper::SelectBegin( Window * pWin, const Point & rPos )
160 {
161 if( -1 == nGrab )
162 {
163 nGrab = SelectMove( pWin, rPos );
164 if( -1 != nGrab )
165 {
166 aSelPos = rPos; // Start-Position merken
167 pWin->CaptureMouse();
168 return sal_True;
169 }
170 }
171 return sal_False;
172 }
173
174 /*************************************************************************
175 |* SvResizeHelper::SelectMove()
176 |*
177 |* Beschreibung
178 *************************************************************************/
SelectMove(Window * pWin,const Point & rPos)179 short SvResizeHelper::SelectMove( Window * pWin, const Point & rPos )
180 {
181 if( -1 == nGrab )
182 {
183 if( bResizeable )
184 {
185 Rectangle aRects[ 8 ];
186 FillHandleRectsPixel( aRects );
187 for( sal_uInt16 i = 0; i < 8; i++ )
188 if( aRects[ i ].IsInside( rPos ) )
189 return i;
190 }
191 // Move-Rect ueberlappen Handles
192 Rectangle aMoveRects[ 4 ];
193 FillMoveRectsPixel( aMoveRects );
194 for( sal_uInt16 i = 0; i < 4; i++ )
195 if( aMoveRects[ i ].IsInside( rPos ) )
196 return 8;
197 }
198 else
199 {
200 Rectangle aRect( GetTrackRectPixel( rPos ) );
201 aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) );
202 aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) );
203 pWin->ShowTracking( aRect );
204 }
205 return nGrab;
206 }
207
GetTrackPosPixel(const Rectangle & rRect) const208 Point SvResizeHelper::GetTrackPosPixel( const Rectangle & rRect ) const
209 {
210 // wie das Rechteck zurueckkommt ist egal, es zaehlt welches Handle
211 // initial angefasst wurde
212 Point aPos;
213 Rectangle aRect( rRect );
214 aRect.Justify();
215 // nur wegen EMPTY_RECT
216 Point aBR = aOuter.BottomRight();
217 Point aTR = aOuter.TopRight();
218 Point aBL = aOuter.BottomLeft();
219 switch( nGrab )
220 {
221 case 0:
222 aPos = aRect.TopLeft() - aOuter.TopLeft();
223 break;
224 case 1:
225 aPos.Y() = aRect.Top() - aOuter.Top();
226 break;
227 case 2:
228 aPos = aRect.TopRight() - aTR;
229 break;
230 case 3:
231 aPos.X() = aRect.Right() - aTR.X();
232 break;
233 case 4:
234 aPos = aRect.BottomRight() - aBR;
235 break;
236 case 5:
237 aPos.Y() = aRect.Bottom() - aBR.Y();
238 break;
239 case 6:
240 aPos = aRect.BottomLeft() - aBL;
241 break;
242 case 7:
243 aPos.X() = aRect.Left() - aOuter.Left();
244 break;
245 case 8:
246 aPos = aRect.TopLeft() - aOuter.TopLeft();
247 break;
248 }
249 return aPos += aSelPos;
250 }
251
252 /*************************************************************************
253 |* SvResizeHelper::GetTrackRectPixel()
254 |*
255 |* Beschreibung
256 *************************************************************************/
GetTrackRectPixel(const Point & rTrackPos) const257 Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const
258 {
259 Rectangle aTrackRect;
260 if( -1 != nGrab )
261 {
262 Point aDiff = rTrackPos - aSelPos;
263 aTrackRect = aOuter;
264 Point aBR = aOuter.BottomRight();
265 switch( nGrab )
266 {
267 case 0:
268 aTrackRect.Top() += aDiff.Y();
269 aTrackRect.Left() += aDiff.X();
270 break;
271 case 1:
272 aTrackRect.Top() += aDiff.Y();
273 break;
274 case 2:
275 aTrackRect.Top() += aDiff.Y();
276 aTrackRect.Right() = aBR.X() + aDiff.X();
277 break;
278 case 3:
279 aTrackRect.Right() = aBR.X() + aDiff.X();
280 break;
281 case 4:
282 aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
283 aTrackRect.Right() = aBR.X() + aDiff.X();
284 break;
285 case 5:
286 aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
287 break;
288 case 6:
289 aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
290 aTrackRect.Left() += aDiff.X();
291 break;
292 case 7:
293 aTrackRect.Left() += aDiff.X();
294 break;
295 case 8:
296 if( Application::GetSettings().GetLayoutRTL() )
297 aDiff.X() = -aDiff.X(); // workaround for move in RTL mode
298 aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff );
299 break;
300 /*
301 case 0:
302 aTrackRect = Rectangle( rTrackPos, aOuter.BottomRight() );
303 break;
304 case 1:
305 aTrackRect = Rectangle( Point( aOuter.Left(), rTrackPos.Y() ),
306 aOuter.BottomRight() );
307 break;
308 case 2:
309 aTrackRect = Rectangle( rTrackPos, aOuter.BottomLeft() );
310 break;
311 case 3:
312 aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ),
313 aOuter.BottomLeft() );
314 break;
315 case 4:
316 aTrackRect = Rectangle( rTrackPos, aOuter.TopLeft() );
317 break;
318 case 5:
319 aTrackRect = Rectangle( aOuter.TopLeft(),
320 Point( aOuter.Right(), rTrackPos.Y() ) );
321 break;
322 case 6:
323 aTrackRect = Rectangle( aOuter.TopRight(), rTrackPos );
324 break;
325 case 7:
326 aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ),
327 aOuter.BottomRight() );
328 break;
329 case 8:
330 aTrackRect = Rectangle( aOuter.TopLeft() + rTrackPos - aSelPos,
331 aOuter.GetSize() );
332 break;
333 */
334 }
335 }
336 return aTrackRect;
337 }
338
ValidateRect(Rectangle & rValidate) const339 void SvResizeHelper::ValidateRect( Rectangle & rValidate ) const
340 {
341 switch( nGrab )
342 {
343 case 0:
344 if( rValidate.Top() > rValidate.Bottom() )
345 {
346 rValidate.Top() = rValidate.Bottom();
347 rValidate.Bottom() = RECT_EMPTY;
348 }
349 if( rValidate.Left() > rValidate.Right() )
350 {
351 rValidate.Left() = rValidate.Right();
352 rValidate.Right() = RECT_EMPTY;
353 }
354 break;
355 case 1:
356 if( rValidate.Top() > rValidate.Bottom() )
357 {
358 rValidate.Top() = rValidate.Bottom();
359 rValidate.Bottom() = RECT_EMPTY;
360 }
361 break;
362 case 2:
363 if( rValidate.Top() > rValidate.Bottom() )
364 {
365 rValidate.Top() = rValidate.Bottom();
366 rValidate.Bottom() = RECT_EMPTY;
367 }
368 if( rValidate.Left() > rValidate.Right() )
369 rValidate.Right() = RECT_EMPTY;
370 break;
371 case 3:
372 if( rValidate.Left() > rValidate.Right() )
373 rValidate.Right() = RECT_EMPTY;
374 break;
375 case 4:
376 if( rValidate.Top() > rValidate.Bottom() )
377 rValidate.Bottom() = RECT_EMPTY;
378 if( rValidate.Left() > rValidate.Right() )
379 rValidate.Right() = RECT_EMPTY;
380 break;
381 case 5:
382 if( rValidate.Top() > rValidate.Bottom() )
383 rValidate.Bottom() = RECT_EMPTY;
384 break;
385 case 6:
386 if( rValidate.Top() > rValidate.Bottom() )
387 rValidate.Bottom() = RECT_EMPTY;
388 if( rValidate.Left() > rValidate.Right() )
389 {
390 rValidate.Left() = rValidate.Right();
391 rValidate.Right() = RECT_EMPTY;
392 }
393 break;
394 case 7:
395 if( rValidate.Left() > rValidate.Right() )
396 {
397 rValidate.Left() = rValidate.Right();
398 rValidate.Right() = RECT_EMPTY;
399 }
400 break;
401 }
402 if( rValidate.Right() == RECT_EMPTY )
403 rValidate.Right() = rValidate.Left();
404 if( rValidate.Bottom() == RECT_EMPTY )
405 rValidate.Bottom() = rValidate.Top();
406
407 // Mindestgr"osse 5 x 5
408 if( rValidate.Left() + 5 > rValidate.Right() )
409 rValidate.Right() = rValidate.Left() +5;
410 if( rValidate.Top() + 5 > rValidate.Bottom() )
411 rValidate.Bottom() = rValidate.Top() +5;
412 }
413
414 /*************************************************************************
415 |* SvResizeHelper::SelectRelease()
416 |*
417 |* Beschreibung
418 *************************************************************************/
SelectRelease(Window * pWin,const Point & rPos,Rectangle & rOutPosSize)419 sal_Bool SvResizeHelper::SelectRelease( Window * pWin, const Point & rPos,
420 Rectangle & rOutPosSize )
421 {
422 if( -1 != nGrab )
423 {
424 rOutPosSize = GetTrackRectPixel( rPos );
425 rOutPosSize.Justify();
426 nGrab = -1;
427 pWin->ReleaseMouse();
428 pWin->HideTracking();
429 return sal_True;
430 }
431 return sal_False;
432 }
433
434 /*************************************************************************
435 |* SvResizeHelper::Release()
436 |*
437 |* Beschreibung
438 *************************************************************************/
Release(Window * pWin)439 void SvResizeHelper::Release( Window * pWin )
440 {
441 if( nGrab != -1 )
442 {
443 pWin->ReleaseMouse();
444 pWin->HideTracking();
445 nGrab = -1;
446 }
447 }
448
449 /*************************************************************************
450 |* SvResizeWindow::SvResizeWindow()
451 |*
452 |* Beschreibung
453 *************************************************************************/
SvResizeWindow(Window * pParent,VCLXHatchWindow * pWrapper)454 SvResizeWindow::SvResizeWindow
455 (
456 Window * pParent,
457 VCLXHatchWindow* pWrapper
458 )
459 : Window( pParent, WB_CLIPCHILDREN )
460 , m_nMoveGrab( -1 )
461 , m_bActive( sal_False )
462 , m_pWrapper( pWrapper )
463 {
464 OSL_ENSURE( pParent != NULL && pWrapper != NULL, "Wrong initialization of hatch window!\n" );
465 SetBackground();
466 SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT );
467 m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
468 }
469
470 /*************************************************************************
471 |* SvResizeWindow::SetHatchBorderPixel()
472 |*
473 |* Beschreibung
474 *************************************************************************/
SetHatchBorderPixel(const Size & rSize)475 void SvResizeWindow::SetHatchBorderPixel( const Size & rSize )
476 {
477 m_aResizer.SetBorderPixel( rSize );
478 }
479
480 /*************************************************************************
481 |* SvResizeWindow::SelectMouse()
482 |*
483 |* Beschreibung
484 *************************************************************************/
SelectMouse(const Point & rPos)485 void SvResizeWindow::SelectMouse( const Point & rPos )
486 {
487 short nGrab = m_aResizer.SelectMove( this, rPos );
488 if( nGrab >= 4 )
489 nGrab -= 4;
490 if( m_nMoveGrab != nGrab )
491 { // Pointer hat sich geaendert
492 if( -1 == nGrab )
493 SetPointer( m_aOldPointer );
494 else
495 {
496 PointerStyle aStyle = POINTER_MOVE;
497 if( nGrab == 3 )
498 aStyle = POINTER_ESIZE;
499 else if( nGrab == 2 )
500 aStyle = POINTER_NESIZE;
501 else if( nGrab == 1 )
502 aStyle = POINTER_SSIZE;
503 else if( nGrab == 0 )
504 aStyle = POINTER_SESIZE;
505 if( m_nMoveGrab == -1 ) // das erste mal
506 {
507 m_aOldPointer = GetPointer();
508 SetPointer( Pointer( aStyle ) );
509 }
510 else
511 SetPointer( Pointer( aStyle ) );
512 }
513 m_nMoveGrab = nGrab;
514 }
515 }
516
517 /*************************************************************************
518 |* SvResizeWindow::MouseButtonDown()
519 |*
520 |* Beschreibung
521 *************************************************************************/
MouseButtonDown(const MouseEvent & rEvt)522 void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt )
523 {
524 if( m_aResizer.SelectBegin( this, rEvt.GetPosPixel() ) )
525 SelectMouse( rEvt.GetPosPixel() );
526 }
527
528 /*************************************************************************
529 |* SvResizeWindow::MouseMove()
530 |*
531 |* Beschreibung
532 *************************************************************************/
MouseMove(const MouseEvent & rEvt)533 void SvResizeWindow::MouseMove( const MouseEvent & rEvt )
534 {
535 if( m_aResizer.GetGrab() == -1 )
536 SelectMouse( rEvt.GetPosPixel() );
537 else
538 {
539 Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) );
540 Point aDiff = GetPosPixel();
541 aRect.SetPos( aRect.TopLeft() + aDiff );
542 m_aResizer.ValidateRect( aRect );
543
544 m_pWrapper->QueryObjAreaPixel( aRect );
545 aRect.SetPos( aRect.TopLeft() - aDiff );
546 Point aPos = m_aResizer.GetTrackPosPixel( aRect );
547
548 SelectMouse( aPos );
549 }
550 }
551
552 /*************************************************************************
553 |* SvResizeWindow::MouseButtonUp()
554 |*
555 |* Beschreibung
556 *************************************************************************/
MouseButtonUp(const MouseEvent & rEvt)557 void SvResizeWindow::MouseButtonUp( const MouseEvent & rEvt )
558 {
559 if( m_aResizer.GetGrab() != -1 )
560 {
561 Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) );
562 Point aDiff = GetPosPixel();
563 aRect.SetPos( aRect.TopLeft() + aDiff );
564 // aRect -= GetAllBorderPixel();
565 m_aResizer.ValidateRect( aRect );
566
567 m_pWrapper->QueryObjAreaPixel( aRect );
568
569 Rectangle aOutRect;
570 if( m_aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) )
571 {
572 m_nMoveGrab = -1;
573 SetPointer( m_aOldPointer );
574 m_pWrapper->RequestObjAreaPixel( aRect );
575 }
576 }
577 }
578
579 /*************************************************************************
580 |* SvResizeWindow::KeyEvent()
581 |*
582 |* Beschreibung
583 *************************************************************************/
KeyInput(const KeyEvent & rEvt)584 void SvResizeWindow::KeyInput( const KeyEvent & rEvt )
585 {
586 if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE )
587 {
588 m_aResizer.Release( this );
589 m_pWrapper->InplaceDeactivate();
590 }
591 }
592
593 /*************************************************************************
594 |* SvResizeWindow::Resize()
595 |*
596 |* Beschreibung
597 *************************************************************************/
Resize()598 void SvResizeWindow::Resize()
599 {
600 m_aResizer.InvalidateBorder( this ); // alten Bereich
601 m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
602 m_aResizer.InvalidateBorder( this ); // neuen Bereich
603 }
604
605 /*************************************************************************
606 |* SvResizeWindow::Paint()
607 |*
608 |* Beschreibung
609 *************************************************************************/
Paint(const Rectangle &)610 void SvResizeWindow::Paint( const Rectangle & /*rRect*/ )
611 {
612 m_aResizer.Draw( this );
613 }
614
PreNotify(NotifyEvent & rEvt)615 long SvResizeWindow::PreNotify( NotifyEvent& rEvt )
616 {
617 if ( rEvt.GetType() == EVENT_GETFOCUS && !m_bActive )
618 {
619 m_bActive = sal_True;
620 m_pWrapper->Activated();
621 }
622
623 return Window::PreNotify(rEvt);
624 }
625
Notify(NotifyEvent & rEvt)626 long SvResizeWindow::Notify( NotifyEvent& rEvt )
627 {
628 if ( rEvt.GetType() == EVENT_LOSEFOCUS && m_bActive )
629 {
630 sal_Bool bHasFocus = HasChildPathFocus(sal_True);
631 if ( !bHasFocus )
632 {
633 m_bActive = sal_False;
634 m_pWrapper->Deactivated();
635 }
636 }
637
638 return Window::Notify(rEvt);
639 }
640
641