Bump version to 5.0-14
[LibreOffice.git] / svtools / source / hatchwindow / ipwin.cxx
blob62ea003ff58edca9285ff45f13500f62f86441d7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
25 #include "ipwin.hxx"
26 #include <hatchwindow.hxx>
28 /************************************************************************/
29 /*************************************************************************
30 |* SvResizeHelper::SvResizeHelper()
32 |* Description
33 *************************************************************************/
34 SvResizeHelper::SvResizeHelper()
35 : aBorder( 5, 5 )
36 , nGrab( -1 )
37 , bResizeable( true )
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();
51 // upper left
52 aRects[ 0 ] = Rectangle( aOuter.TopLeft(), aBorder );
53 // upper middle
54 aRects[ 1 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
55 aOuter.Top() ),
56 aBorder );
57 // upper right
58 aRects[ 2 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
59 aOuter.Top() ),
60 aBorder );
61 // middle right
62 aRects[ 3 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
63 aOuter.Center().Y() - aBorder.Height() / 2 ),
64 aBorder );
65 // lower right
66 aRects[ 4 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1,
67 aBottomRight.Y() - aBorder.Height() +1 ),
68 aBorder );
69 // lower middle
70 aRects[ 5 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2,
71 aBottomRight.Y() - aBorder.Height() +1),
72 aBorder );
73 // lower left
74 aRects[ 6 ] = Rectangle( Point( aOuter.Left(),
75 aBottomRight.Y() - aBorder.Height() +1),
76 aBorder );
77 // middle left
78 aRects[ 7 ] = Rectangle( Point( aOuter.Left(),
79 aOuter.Center().Y() - aBorder.Height() / 2 ),
80 aBorder );
83 /*************************************************************************
84 |* SvResizeHelper::FillMoveRectsPixel()
86 |* Description: the four edges are calculated
87 *************************************************************************/
88 void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const
90 // upper
91 aRects[ 0 ] = aOuter;
92 aRects[ 0 ].Bottom() = aRects[ 0 ].Top() + aBorder.Height() -1;
93 // right
94 aRects[ 1 ] = aOuter;
95 aRects[ 1 ].Left() = aRects[ 1 ].Right() - aBorder.Width() -1;
96 // lower
97 aRects[ 2 ] = aOuter;
98 aRects[ 2 ].Top() = aRects[ 2 ].Bottom() - aBorder.Height() -1;
99 // left
100 aRects[ 3 ] = aOuter;
101 aRects[ 3 ].Right() = aRects[ 3 ].Left() + aBorder.Width() -1;
104 /*************************************************************************
105 |* SvResizeHelper::Draw()
107 |* Description
108 *************************************************************************/
109 void SvResizeHelper::Draw(vcl::RenderContext& rRenderContext)
111 rRenderContext.Push();
112 rRenderContext.SetMapMode( MapMode() );
113 Color aColBlack;
114 Color aFillColor( COL_LIGHTGRAY );
116 rRenderContext.SetFillColor( aFillColor );
117 rRenderContext.SetLineColor();
119 Rectangle aMoveRects[ 4 ];
120 FillMoveRectsPixel( aMoveRects );
121 sal_uInt16 i;
122 for (i = 0; i < 4; i++)
123 rRenderContext.DrawRect(aMoveRects[i]);
124 if (bResizeable)
126 // draw handles
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()
139 |* Description
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()
152 |* Description
153 *************************************************************************/
154 bool SvResizeHelper::SelectBegin( vcl::Window * pWin, const Point & rPos )
156 if( -1 == nGrab )
158 nGrab = SelectMove( pWin, rPos );
159 if( -1 != nGrab )
161 aSelPos = rPos; // store start position
162 pWin->CaptureMouse();
163 return true;
166 return false;
169 /*************************************************************************
170 |* SvResizeHelper::SelectMove()
172 |* Description
173 *************************************************************************/
174 short SvResizeHelper::SelectMove( vcl::Window * pWin, const Point & rPos )
176 if( -1 == nGrab )
178 if( bResizeable )
180 Rectangle aRects[ 8 ];
181 FillHandleRectsPixel( aRects );
182 for( sal_uInt16 i = 0; i < 8; i++ )
183 if( aRects[ i ].IsInside( rPos ) )
184 return i;
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 ) )
191 return 8;
193 else
195 Rectangle aRect( GetTrackRectPixel( rPos ) );
196 aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) );
197 aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) );
198 pWin->ShowTracking( aRect );
200 return nGrab;
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
207 Point aPos;
208 Rectangle aRect( rRect );
209 aRect.Justify();
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();
215 switch( nGrab )
217 case 0:
218 // FIXME: disable it for RTL because it's wrong calculations
219 if( bRTL )
220 break;
221 aPos = aRect.TopLeft() - aOuter.TopLeft();
222 break;
223 case 1:
224 aPos.Y() = aRect.Top() - aOuter.Top();
225 break;
226 case 2:
227 // FIXME: disable it for RTL because it's wrong calculations
228 if( bRTL )
229 break;
230 aPos = aRect.TopRight() - aTR;
231 break;
232 case 3:
233 if( bRTL )
234 aPos.X() = aRect.Left() - aTR.X();
235 else
236 aPos.X() = aRect.Right() - aTR.X();
237 break;
238 case 4:
239 // FIXME: disable it for RTL because it's wrong calculations
240 if( bRTL )
241 break;
242 aPos = aRect.BottomRight() - aBR;
243 break;
244 case 5:
245 aPos.Y() = aRect.Bottom() - aBR.Y();
246 break;
247 case 6:
248 // FIXME: disable it for RTL because it's wrong calculations
249 if( bRTL )
250 break;
251 aPos = aRect.BottomLeft() - aBL;
252 break;
253 case 7:
254 if( bRTL )
255 aPos.X() = aRect.Right() + aOuter.Right() - aOuter.TopRight().X();
256 else
257 aPos.X() = aRect.Left() - aOuter.Left();
258 break;
259 case 8:
260 aPos = aRect.TopLeft() - aOuter.TopLeft();
261 break;
263 return aPos += aSelPos;
266 /*************************************************************************
267 |* SvResizeHelper::GetTrackRectPixel()
269 |* Description
270 *************************************************************************/
271 Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const
273 Rectangle aTrackRect;
274 if( -1 != nGrab )
276 Point aDiff = rTrackPos - aSelPos;
277 aTrackRect = aOuter;
278 Point aBR = aOuter.BottomRight();
279 bool bRTL = AllSettings::GetLayoutRTL();
280 switch( nGrab )
282 case 0:
283 aTrackRect.Top() += aDiff.Y();
284 // ugly solution for resizing OLE objects in RTL
285 if( bRTL )
286 aTrackRect.Right() = aBR.X() - aDiff.X();
287 else
288 aTrackRect.Left() += aDiff.X();
289 break;
290 case 1:
291 aTrackRect.Top() += aDiff.Y();
292 break;
293 case 2:
294 aTrackRect.Top() += aDiff.Y();
295 // ugly solution for resizing OLE objects in RTL
296 if( bRTL )
297 aTrackRect.Left() -= aDiff.X();
298 else
299 aTrackRect.Right() = aBR.X() + aDiff.X();
300 break;
301 case 3:
302 // ugly solution for resizing OLE objects in RTL
303 if( bRTL )
304 aTrackRect.Left() -= aDiff.X();
305 else
306 aTrackRect.Right() = aBR.X() + aDiff.X();
307 break;
308 case 4:
309 aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
310 // ugly solution for resizing OLE objects in RTL
311 if( bRTL )
312 aTrackRect.Left() -= aDiff.X();
313 else
314 aTrackRect.Right() = aBR.X() + aDiff.X();
315 break;
316 case 5:
317 aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
318 break;
319 case 6:
320 aTrackRect.Bottom() = aBR.Y() + aDiff.Y();
321 // ugly solution for resizing OLE objects in RTL
322 if( bRTL )
323 aTrackRect.Right() = aBR.X() - aDiff.X();
324 else
325 aTrackRect.Left() += aDiff.X();
326 break;
327 case 7:
328 // ugly solution for resizing OLE objects in RTL
329 if( bRTL )
330 aTrackRect.Right() = aBR.X() - aDiff.X();
331 else
332 aTrackRect.Left() += aDiff.X();
333 break;
334 case 8:
335 if( bRTL )
336 aDiff.X() = -aDiff.X(); // workaround for move in RTL mode
337 aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff );
338 break;
341 return aTrackRect;
344 void SvResizeHelper::ValidateRect( Rectangle & rValidate ) const
346 switch( nGrab )
348 case 0:
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;
359 break;
360 case 1:
361 if( rValidate.Top() > rValidate.Bottom() )
363 rValidate.Top() = rValidate.Bottom();
364 rValidate.Bottom() = RECT_EMPTY;
366 break;
367 case 2:
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;
375 break;
376 case 3:
377 if( rValidate.Left() > rValidate.Right() )
378 rValidate.Right() = RECT_EMPTY;
379 break;
380 case 4:
381 if( rValidate.Top() > rValidate.Bottom() )
382 rValidate.Bottom() = RECT_EMPTY;
383 if( rValidate.Left() > rValidate.Right() )
384 rValidate.Right() = RECT_EMPTY;
385 break;
386 case 5:
387 if( rValidate.Top() > rValidate.Bottom() )
388 rValidate.Bottom() = RECT_EMPTY;
389 break;
390 case 6:
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;
398 break;
399 case 7:
400 if( rValidate.Left() > rValidate.Right() )
402 rValidate.Left() = rValidate.Right();
403 rValidate.Right() = RECT_EMPTY;
405 break;
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()
422 |* Description
423 *************************************************************************/
424 bool SvResizeHelper::SelectRelease( vcl::Window * pWin, const Point & rPos,
425 Rectangle & rOutPosSize )
427 if( -1 != nGrab )
429 rOutPosSize = GetTrackRectPixel( rPos );
430 rOutPosSize.Justify();
431 nGrab = -1;
432 pWin->ReleaseMouse();
433 pWin->HideTracking();
434 return true;
436 return false;
439 /*************************************************************************
440 |* SvResizeHelper::Release()
442 |* Description
443 *************************************************************************/
444 void SvResizeHelper::Release( vcl::Window * pWin )
446 if( nGrab != -1 )
448 pWin->ReleaseMouse();
449 pWin->HideTracking();
450 nGrab = -1;
454 /*************************************************************************
455 |* SvResizeWindow::SvResizeWindow()
457 |* Description
458 *************************************************************************/
459 SvResizeWindow::SvResizeWindow
461 vcl::Window * pParent,
462 VCLXHatchWindow* pWrapper
464 : Window( pParent, WB_CLIPCHILDREN )
465 , m_nMoveGrab( -1 )
466 , m_bActive( false )
467 , m_pWrapper( pWrapper )
469 OSL_ENSURE( pParent != NULL && pWrapper != NULL, "Wrong initialization of hatch window!\n" );
470 SetBackground();
471 SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT );
472 m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) );
475 /*************************************************************************
476 |* SvResizeWindow::SetHatchBorderPixel()
478 |* Description
479 *************************************************************************/
480 void SvResizeWindow::SetHatchBorderPixel( const Size & rSize )
482 m_aResizer.SetBorderPixel( rSize );
485 /*************************************************************************
486 |* SvResizeWindow::SelectMouse()
488 |* Description
489 *************************************************************************/
490 void SvResizeWindow::SelectMouse( const Point & rPos )
492 short nGrab = m_aResizer.SelectMove( this, rPos );
493 if( nGrab >= 4 )
494 nGrab -= 4;
495 if( m_nMoveGrab != nGrab )
496 { // Pointer did change
497 if( -1 == nGrab )
498 SetPointer( m_aOldPointer );
499 else
501 PointerStyle aStyle = PointerStyle::Move;
502 if( nGrab == 3 )
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 ) );
515 else
516 SetPointer( Pointer( aStyle ) );
518 m_nMoveGrab = nGrab;
522 /*************************************************************************
523 |* SvResizeWindow::MouseButtonDown()
525 |* Description
526 *************************************************************************/
527 void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt )
529 if( m_aResizer.SelectBegin( this, rEvt.GetPosPixel() ) )
530 SelectMouse( rEvt.GetPosPixel() );
533 /*************************************************************************
534 |* SvResizeWindow::MouseMove()
536 |* Description
537 *************************************************************************/
538 void SvResizeWindow::MouseMove( const MouseEvent & rEvt )
540 if( m_aResizer.GetGrab() == -1 )
541 SelectMouse( rEvt.GetPosPixel() );
542 else
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 );
553 SelectMouse( aPos );
557 /*************************************************************************
558 |* SvResizeWindow::MouseButtonUp()
560 |* Description
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 );
574 Rectangle aOutRect;
575 if( m_aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) )
577 m_nMoveGrab = -1;
578 SetPointer( m_aOldPointer );
579 m_pWrapper->RequestObjAreaPixel( aRect );
584 /*************************************************************************
585 |* SvResizeWindow::KeyEvent()
587 |* Description
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()
601 |* Description
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()
613 |* Description
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 )
624 m_bActive = true;
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);
636 if ( !bHasFocus )
638 m_bActive = false;
639 m_pWrapper->Deactivated();
643 return Window::Notify(rEvt);
646 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */