1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/accessibility/AccessibleRole.hpp>
22 #include <vcl/svapp.hxx>
23 #include <vcl/settings.hxx>
26 #include <hatchwindow.hxx>
28 /************************************************************************/
29 /*************************************************************************
30 |* SvResizeHelper::SvResizeHelper()
33 *************************************************************************/
34 SvResizeHelper::SvResizeHelper()
41 /*************************************************************************
42 |* SvResizeHelper::FillHandleRects()
44 |* Description: the eight handles to magnify
45 *************************************************************************/
46 void SvResizeHelper::FillHandleRectsPixel( Rectangle aRects
[ 8 ] ) const
48 // only because of EMPTY_RECT
49 Point aBottomRight
= aOuter
.BottomRight();
52 aRects
[ 0 ] = Rectangle( aOuter
.TopLeft(), aBorder
);
54 aRects
[ 1 ] = Rectangle( Point( aOuter
.Center().X() - aBorder
.Width() / 2,
58 aRects
[ 2 ] = Rectangle( Point( aBottomRight
.X() - aBorder
.Width() +1,
62 aRects
[ 3 ] = Rectangle( Point( aBottomRight
.X() - aBorder
.Width() +1,
63 aOuter
.Center().Y() - aBorder
.Height() / 2 ),
66 aRects
[ 4 ] = Rectangle( Point( aBottomRight
.X() - aBorder
.Width() +1,
67 aBottomRight
.Y() - aBorder
.Height() +1 ),
70 aRects
[ 5 ] = Rectangle( Point( aOuter
.Center().X() - aBorder
.Width() / 2,
71 aBottomRight
.Y() - aBorder
.Height() +1),
74 aRects
[ 6 ] = Rectangle( Point( aOuter
.Left(),
75 aBottomRight
.Y() - aBorder
.Height() +1),
78 aRects
[ 7 ] = Rectangle( Point( aOuter
.Left(),
79 aOuter
.Center().Y() - aBorder
.Height() / 2 ),
83 /*************************************************************************
84 |* SvResizeHelper::FillMoveRectsPixel()
86 |* Description: the four edges are calculated
87 *************************************************************************/
88 void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects
[ 4 ] ) const
92 aRects
[ 0 ].Bottom() = aRects
[ 0 ].Top() + aBorder
.Height() -1;
95 aRects
[ 1 ].Left() = aRects
[ 1 ].Right() - aBorder
.Width() -1;
98 aRects
[ 2 ].Top() = aRects
[ 2 ].Bottom() - aBorder
.Height() -1;
100 aRects
[ 3 ] = aOuter
;
101 aRects
[ 3 ].Right() = aRects
[ 3 ].Left() + aBorder
.Width() -1;
104 /*************************************************************************
105 |* SvResizeHelper::Draw()
108 *************************************************************************/
109 void SvResizeHelper::Draw(vcl::RenderContext
& rRenderContext
)
111 rRenderContext
.Push();
112 rRenderContext
.SetMapMode( MapMode() );
114 Color
aFillColor( COL_LIGHTGRAY
);
116 rRenderContext
.SetFillColor( aFillColor
);
117 rRenderContext
.SetLineColor();
119 Rectangle aMoveRects
[ 4 ];
120 FillMoveRectsPixel( aMoveRects
);
122 for (i
= 0; i
< 4; i
++)
123 rRenderContext
.DrawRect(aMoveRects
[i
]);
127 rRenderContext
.SetFillColor(aColBlack
);
128 Rectangle aRects
[ 8 ];
129 FillHandleRectsPixel(aRects
);
130 for (i
= 0; i
< 8; i
++)
131 rRenderContext
.DrawRect( aRects
[ i
] );
133 rRenderContext
.Pop();
136 /*************************************************************************
137 |* SvResizeHelper::InvalidateBorder()
140 *************************************************************************/
141 void SvResizeHelper::InvalidateBorder( vcl::Window
* pWin
)
143 Rectangle aMoveRects
[ 4 ];
144 FillMoveRectsPixel( aMoveRects
);
145 for( sal_uInt16 i
= 0; i
< 4; i
++ )
146 pWin
->Invalidate( aMoveRects
[ i
] );
149 /*************************************************************************
150 |* SvResizeHelper::SelectBegin()
153 *************************************************************************/
154 bool SvResizeHelper::SelectBegin( vcl::Window
* pWin
, const Point
& rPos
)
158 nGrab
= SelectMove( pWin
, rPos
);
161 aSelPos
= rPos
; // store start position
162 pWin
->CaptureMouse();
169 /*************************************************************************
170 |* SvResizeHelper::SelectMove()
173 *************************************************************************/
174 short SvResizeHelper::SelectMove( vcl::Window
* pWin
, const Point
& rPos
)
180 Rectangle aRects
[ 8 ];
181 FillHandleRectsPixel( aRects
);
182 for( sal_uInt16 i
= 0; i
< 8; i
++ )
183 if( aRects
[ i
].IsInside( rPos
) )
186 // Move-Rect overlaps Handles
187 Rectangle aMoveRects
[ 4 ];
188 FillMoveRectsPixel( aMoveRects
);
189 for( sal_uInt16 i
= 0; i
< 4; i
++ )
190 if( aMoveRects
[ i
].IsInside( rPos
) )
195 Rectangle
aRect( GetTrackRectPixel( rPos
) );
196 aRect
.SetSize( pWin
->PixelToLogic( aRect
.GetSize() ) );
197 aRect
.SetPos( pWin
->PixelToLogic( aRect
.TopLeft() ) );
198 pWin
->ShowTracking( aRect
);
203 Point
SvResizeHelper::GetTrackPosPixel( const Rectangle
& rRect
) const
205 // not important how the rectangle is returned, it is important
206 // which handle has been touched
208 Rectangle
aRect( rRect
);
210 // only because of EMPTY_RECT
211 Point aBR
= aOuter
.BottomRight();
212 Point aTR
= aOuter
.TopRight();
213 Point aBL
= aOuter
.BottomLeft();
214 bool bRTL
= AllSettings::GetLayoutRTL();
218 // FIXME: disable it for RTL because it's wrong calculations
221 aPos
= aRect
.TopLeft() - aOuter
.TopLeft();
224 aPos
.Y() = aRect
.Top() - aOuter
.Top();
227 // FIXME: disable it for RTL because it's wrong calculations
230 aPos
= aRect
.TopRight() - aTR
;
234 aPos
.X() = aRect
.Left() - aTR
.X();
236 aPos
.X() = aRect
.Right() - aTR
.X();
239 // FIXME: disable it for RTL because it's wrong calculations
242 aPos
= aRect
.BottomRight() - aBR
;
245 aPos
.Y() = aRect
.Bottom() - aBR
.Y();
248 // FIXME: disable it for RTL because it's wrong calculations
251 aPos
= aRect
.BottomLeft() - aBL
;
255 aPos
.X() = aRect
.Right() + aOuter
.Right() - aOuter
.TopRight().X();
257 aPos
.X() = aRect
.Left() - aOuter
.Left();
260 aPos
= aRect
.TopLeft() - aOuter
.TopLeft();
263 return aPos
+= aSelPos
;
266 /*************************************************************************
267 |* SvResizeHelper::GetTrackRectPixel()
270 *************************************************************************/
271 Rectangle
SvResizeHelper::GetTrackRectPixel( const Point
& rTrackPos
) const
273 Rectangle aTrackRect
;
276 Point aDiff
= rTrackPos
- aSelPos
;
278 Point aBR
= aOuter
.BottomRight();
279 bool bRTL
= AllSettings::GetLayoutRTL();
283 aTrackRect
.Top() += aDiff
.Y();
284 // ugly solution for resizing OLE objects in RTL
286 aTrackRect
.Right() = aBR
.X() - aDiff
.X();
288 aTrackRect
.Left() += aDiff
.X();
291 aTrackRect
.Top() += aDiff
.Y();
294 aTrackRect
.Top() += aDiff
.Y();
295 // ugly solution for resizing OLE objects in RTL
297 aTrackRect
.Left() -= aDiff
.X();
299 aTrackRect
.Right() = aBR
.X() + aDiff
.X();
302 // ugly solution for resizing OLE objects in RTL
304 aTrackRect
.Left() -= aDiff
.X();
306 aTrackRect
.Right() = aBR
.X() + aDiff
.X();
309 aTrackRect
.Bottom() = aBR
.Y() + aDiff
.Y();
310 // ugly solution for resizing OLE objects in RTL
312 aTrackRect
.Left() -= aDiff
.X();
314 aTrackRect
.Right() = aBR
.X() + aDiff
.X();
317 aTrackRect
.Bottom() = aBR
.Y() + aDiff
.Y();
320 aTrackRect
.Bottom() = aBR
.Y() + aDiff
.Y();
321 // ugly solution for resizing OLE objects in RTL
323 aTrackRect
.Right() = aBR
.X() - aDiff
.X();
325 aTrackRect
.Left() += aDiff
.X();
328 // ugly solution for resizing OLE objects in RTL
330 aTrackRect
.Right() = aBR
.X() - aDiff
.X();
332 aTrackRect
.Left() += aDiff
.X();
336 aDiff
.X() = -aDiff
.X(); // workaround for move in RTL mode
337 aTrackRect
.SetPos( aTrackRect
.TopLeft() + aDiff
);
344 void SvResizeHelper::ValidateRect( Rectangle
& rValidate
) const
349 if( rValidate
.Top() > rValidate
.Bottom() )
351 rValidate
.Top() = rValidate
.Bottom();
352 rValidate
.Bottom() = RECT_EMPTY
;
354 if( rValidate
.Left() > rValidate
.Right() )
356 rValidate
.Left() = rValidate
.Right();
357 rValidate
.Right() = RECT_EMPTY
;
361 if( rValidate
.Top() > rValidate
.Bottom() )
363 rValidate
.Top() = rValidate
.Bottom();
364 rValidate
.Bottom() = RECT_EMPTY
;
368 if( rValidate
.Top() > rValidate
.Bottom() )
370 rValidate
.Top() = rValidate
.Bottom();
371 rValidate
.Bottom() = RECT_EMPTY
;
373 if( rValidate
.Left() > rValidate
.Right() )
374 rValidate
.Right() = RECT_EMPTY
;
377 if( rValidate
.Left() > rValidate
.Right() )
378 rValidate
.Right() = RECT_EMPTY
;
381 if( rValidate
.Top() > rValidate
.Bottom() )
382 rValidate
.Bottom() = RECT_EMPTY
;
383 if( rValidate
.Left() > rValidate
.Right() )
384 rValidate
.Right() = RECT_EMPTY
;
387 if( rValidate
.Top() > rValidate
.Bottom() )
388 rValidate
.Bottom() = RECT_EMPTY
;
391 if( rValidate
.Top() > rValidate
.Bottom() )
392 rValidate
.Bottom() = RECT_EMPTY
;
393 if( rValidate
.Left() > rValidate
.Right() )
395 rValidate
.Left() = rValidate
.Right();
396 rValidate
.Right() = RECT_EMPTY
;
400 if( rValidate
.Left() > rValidate
.Right() )
402 rValidate
.Left() = rValidate
.Right();
403 rValidate
.Right() = RECT_EMPTY
;
407 if( rValidate
.Right() == RECT_EMPTY
)
408 rValidate
.Right() = rValidate
.Left();
409 if( rValidate
.Bottom() == RECT_EMPTY
)
410 rValidate
.Bottom() = rValidate
.Top();
412 // Mindestgr"osse 5 x 5
413 if( rValidate
.Left() + 5 > rValidate
.Right() )
414 rValidate
.Right() = rValidate
.Left() +5;
415 if( rValidate
.Top() + 5 > rValidate
.Bottom() )
416 rValidate
.Bottom() = rValidate
.Top() +5;
419 /*************************************************************************
420 |* SvResizeHelper::SelectRelease()
423 *************************************************************************/
424 bool SvResizeHelper::SelectRelease( vcl::Window
* pWin
, const Point
& rPos
,
425 Rectangle
& rOutPosSize
)
429 rOutPosSize
= GetTrackRectPixel( rPos
);
430 rOutPosSize
.Justify();
432 pWin
->ReleaseMouse();
433 pWin
->HideTracking();
439 /*************************************************************************
440 |* SvResizeHelper::Release()
443 *************************************************************************/
444 void SvResizeHelper::Release( vcl::Window
* pWin
)
448 pWin
->ReleaseMouse();
449 pWin
->HideTracking();
454 /*************************************************************************
455 |* SvResizeWindow::SvResizeWindow()
458 *************************************************************************/
459 SvResizeWindow::SvResizeWindow
461 vcl::Window
* pParent
,
462 VCLXHatchWindow
* pWrapper
464 : Window( pParent
, WB_CLIPCHILDREN
)
467 , m_pWrapper( pWrapper
)
469 OSL_ENSURE( pParent
!= NULL
&& pWrapper
!= NULL
, "Wrong initialization of hatch window!\n" );
471 SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT
);
472 m_aResizer
.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
475 /*************************************************************************
476 |* SvResizeWindow::SetHatchBorderPixel()
479 *************************************************************************/
480 void SvResizeWindow::SetHatchBorderPixel( const Size
& rSize
)
482 m_aResizer
.SetBorderPixel( rSize
);
485 /*************************************************************************
486 |* SvResizeWindow::SelectMouse()
489 *************************************************************************/
490 void SvResizeWindow::SelectMouse( const Point
& rPos
)
492 short nGrab
= m_aResizer
.SelectMove( this, rPos
);
495 if( m_nMoveGrab
!= nGrab
)
496 { // Pointer did change
498 SetPointer( m_aOldPointer
);
501 PointerStyle aStyle
= PointerStyle::Move
;
503 aStyle
= PointerStyle::ESize
;
504 else if( nGrab
== 2 )
505 aStyle
= PointerStyle::NESize
;
506 else if( nGrab
== 1 )
507 aStyle
= PointerStyle::SSize
;
508 else if( nGrab
== 0 )
509 aStyle
= PointerStyle::SESize
;
510 if( m_nMoveGrab
== -1 ) // the first time
512 m_aOldPointer
= GetPointer();
513 SetPointer( Pointer( aStyle
) );
516 SetPointer( Pointer( aStyle
) );
522 /*************************************************************************
523 |* SvResizeWindow::MouseButtonDown()
526 *************************************************************************/
527 void SvResizeWindow::MouseButtonDown( const MouseEvent
& rEvt
)
529 if( m_aResizer
.SelectBegin( this, rEvt
.GetPosPixel() ) )
530 SelectMouse( rEvt
.GetPosPixel() );
533 /*************************************************************************
534 |* SvResizeWindow::MouseMove()
537 *************************************************************************/
538 void SvResizeWindow::MouseMove( const MouseEvent
& rEvt
)
540 if( m_aResizer
.GetGrab() == -1 )
541 SelectMouse( rEvt
.GetPosPixel() );
544 Rectangle
aRect( m_aResizer
.GetTrackRectPixel( rEvt
.GetPosPixel() ) );
545 Point aDiff
= GetPosPixel();
546 aRect
.SetPos( aRect
.TopLeft() + aDiff
);
547 m_aResizer
.ValidateRect( aRect
);
549 m_pWrapper
->QueryObjAreaPixel( aRect
);
550 aRect
.SetPos( aRect
.TopLeft() - aDiff
);
551 Point aPos
= m_aResizer
.GetTrackPosPixel( aRect
);
557 /*************************************************************************
558 |* SvResizeWindow::MouseButtonUp()
561 *************************************************************************/
562 void SvResizeWindow::MouseButtonUp( const MouseEvent
& rEvt
)
564 if( m_aResizer
.GetGrab() != -1 )
566 Rectangle
aRect( m_aResizer
.GetTrackRectPixel( rEvt
.GetPosPixel() ) );
567 Point aDiff
= GetPosPixel();
568 aRect
.SetPos( aRect
.TopLeft() + aDiff
);
569 // aRect -= GetAllBorderPixel();
570 m_aResizer
.ValidateRect( aRect
);
572 m_pWrapper
->QueryObjAreaPixel( aRect
);
575 if( m_aResizer
.SelectRelease( this, rEvt
.GetPosPixel(), aOutRect
) )
578 SetPointer( m_aOldPointer
);
579 m_pWrapper
->RequestObjAreaPixel( aRect
);
584 /*************************************************************************
585 |* SvResizeWindow::KeyEvent()
588 *************************************************************************/
589 void SvResizeWindow::KeyInput( const KeyEvent
& rEvt
)
591 if( rEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
)
593 m_aResizer
.Release( this );
594 m_pWrapper
->InplaceDeactivate();
598 /*************************************************************************
599 |* SvResizeWindow::Resize()
602 *************************************************************************/
603 void SvResizeWindow::Resize()
605 m_aResizer
.InvalidateBorder( this ); // old area
606 m_aResizer
.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
607 m_aResizer
.InvalidateBorder( this ); // new area
610 /*************************************************************************
611 |* SvResizeWindow::Paint()
614 *************************************************************************/
615 void SvResizeWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& /*rRect*/ )
617 m_aResizer
.Draw(rRenderContext
);
620 bool SvResizeWindow::PreNotify( NotifyEvent
& rEvt
)
622 if ( rEvt
.GetType() == MouseNotifyEvent::GETFOCUS
&& !m_bActive
)
625 m_pWrapper
->Activated();
628 return Window::PreNotify(rEvt
);
631 bool SvResizeWindow::Notify( NotifyEvent
& rEvt
)
633 if ( rEvt
.GetType() == MouseNotifyEvent::LOSEFOCUS
&& m_bActive
)
635 bool bHasFocus
= HasChildPathFocus(true);
639 m_pWrapper
->Deactivated();
643 return Window::Notify(rEvt
);
646 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */