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