xref: /AOO41X/main/svtools/source/hatchwindow/ipwin.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
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