/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svtools.hxx" #include #include #include #include /************************************************************************/ /************************************************************************* |* SvResizeHelper::SvResizeHelper() |* |* Beschreibung *************************************************************************/ SvResizeHelper::SvResizeHelper() : aBorder( 5, 5 ) , nGrab( -1 ) , bResizeable( sal_True ) { } /************************************************************************* |* SvResizeHelper::FillHandleRects() |* |* Beschreibung: Die acht Handles zum vergroessern *************************************************************************/ void SvResizeHelper::FillHandleRectsPixel( Rectangle aRects[ 8 ] ) const { // nur wegen EMPTY_RECT Point aBottomRight = aOuter.BottomRight(); // Links Oben aRects[ 0 ] = Rectangle( aOuter.TopLeft(), aBorder ); // Oben Mitte aRects[ 1 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2, aOuter.Top() ), aBorder ); // Oben Rechts aRects[ 2 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, aOuter.Top() ), aBorder ); // Mitte Rechts aRects[ 3 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, aOuter.Center().Y() - aBorder.Height() / 2 ), aBorder ); // Unten Rechts aRects[ 4 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, aBottomRight.Y() - aBorder.Height() +1 ), aBorder ); // Mitte Unten aRects[ 5 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2, aBottomRight.Y() - aBorder.Height() +1), aBorder ); // Links Unten aRects[ 6 ] = Rectangle( Point( aOuter.Left(), aBottomRight.Y() - aBorder.Height() +1), aBorder ); // Mitte Links aRects[ 7 ] = Rectangle( Point( aOuter.Left(), aOuter.Center().Y() - aBorder.Height() / 2 ), aBorder ); } /************************************************************************* |* SvResizeHelper::FillMoveRectsPixel() |* |* Beschreibung: Die vier Kanten werden berechnet *************************************************************************/ void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const { // Oben aRects[ 0 ] = aOuter; aRects[ 0 ].Bottom() = aRects[ 0 ].Top() + aBorder.Height() -1; // Rechts aRects[ 1 ] = aOuter; aRects[ 1 ].Left() = aRects[ 1 ].Right() - aBorder.Width() -1; //Unten aRects[ 2 ] = aOuter; aRects[ 2 ].Top() = aRects[ 2 ].Bottom() - aBorder.Height() -1; //Links aRects[ 3 ] = aOuter; aRects[ 3 ].Right() = aRects[ 3 ].Left() + aBorder.Width() -1; } /************************************************************************* |* SvResizeHelper::Draw() |* |* Beschreibung *************************************************************************/ void SvResizeHelper::Draw( OutputDevice * pDev ) { pDev->Push(); pDev->SetMapMode( MapMode() ); Color aColBlack; Color aFillColor( COL_LIGHTGRAY ); pDev->SetFillColor( aFillColor ); pDev->SetLineColor(); Rectangle aMoveRects[ 4 ]; FillMoveRectsPixel( aMoveRects ); sal_uInt16 i; for( i = 0; i < 4; i++ ) pDev->DrawRect( aMoveRects[ i ] ); if( bResizeable ) { // Handles malen pDev->SetFillColor( aColBlack ); Rectangle aRects[ 8 ]; FillHandleRectsPixel( aRects ); for( i = 0; i < 8; i++ ) pDev->DrawRect( aRects[ i ] ); } pDev->Pop(); } /************************************************************************* |* SvResizeHelper::InvalidateBorder() |* |* Beschreibung *************************************************************************/ void SvResizeHelper::InvalidateBorder( Window * pWin ) { Rectangle aMoveRects[ 4 ]; FillMoveRectsPixel( aMoveRects ); for( sal_uInt16 i = 0; i < 4; i++ ) pWin->Invalidate( aMoveRects[ i ] ); } /************************************************************************* |* SvResizeHelper::SelectBegin() |* |* Beschreibung *************************************************************************/ sal_Bool SvResizeHelper::SelectBegin( Window * pWin, const Point & rPos ) { if( -1 == nGrab ) { nGrab = SelectMove( pWin, rPos ); if( -1 != nGrab ) { aSelPos = rPos; // Start-Position merken pWin->CaptureMouse(); return sal_True; } } return sal_False; } /************************************************************************* |* SvResizeHelper::SelectMove() |* |* Beschreibung *************************************************************************/ short SvResizeHelper::SelectMove( Window * pWin, const Point & rPos ) { if( -1 == nGrab ) { if( bResizeable ) { Rectangle aRects[ 8 ]; FillHandleRectsPixel( aRects ); for( sal_uInt16 i = 0; i < 8; i++ ) if( aRects[ i ].IsInside( rPos ) ) return i; } // Move-Rect ueberlappen Handles Rectangle aMoveRects[ 4 ]; FillMoveRectsPixel( aMoveRects ); for( sal_uInt16 i = 0; i < 4; i++ ) if( aMoveRects[ i ].IsInside( rPos ) ) return 8; } else { Rectangle aRect( GetTrackRectPixel( rPos ) ); aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) ); aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) ); pWin->ShowTracking( aRect ); } return nGrab; } Point SvResizeHelper::GetTrackPosPixel( const Rectangle & rRect ) const { // wie das Rechteck zurueckkommt ist egal, es zaehlt welches Handle // initial angefasst wurde Point aPos; Rectangle aRect( rRect ); aRect.Justify(); // nur wegen EMPTY_RECT Point aBR = aOuter.BottomRight(); Point aTR = aOuter.TopRight(); Point aBL = aOuter.BottomLeft(); switch( nGrab ) { case 0: aPos = aRect.TopLeft() - aOuter.TopLeft(); break; case 1: aPos.Y() = aRect.Top() - aOuter.Top(); break; case 2: aPos = aRect.TopRight() - aTR; break; case 3: aPos.X() = aRect.Right() - aTR.X(); break; case 4: aPos = aRect.BottomRight() - aBR; break; case 5: aPos.Y() = aRect.Bottom() - aBR.Y(); break; case 6: aPos = aRect.BottomLeft() - aBL; break; case 7: aPos.X() = aRect.Left() - aOuter.Left(); break; case 8: aPos = aRect.TopLeft() - aOuter.TopLeft(); break; } return aPos += aSelPos; } /************************************************************************* |* SvResizeHelper::GetTrackRectPixel() |* |* Beschreibung *************************************************************************/ Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const { Rectangle aTrackRect; if( -1 != nGrab ) { Point aDiff = rTrackPos - aSelPos; aTrackRect = aOuter; Point aBR = aOuter.BottomRight(); switch( nGrab ) { case 0: aTrackRect.Top() += aDiff.Y(); aTrackRect.Left() += aDiff.X(); break; case 1: aTrackRect.Top() += aDiff.Y(); break; case 2: aTrackRect.Top() += aDiff.Y(); aTrackRect.Right() = aBR.X() + aDiff.X(); break; case 3: aTrackRect.Right() = aBR.X() + aDiff.X(); break; case 4: aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); aTrackRect.Right() = aBR.X() + aDiff.X(); break; case 5: aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); break; case 6: aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); aTrackRect.Left() += aDiff.X(); break; case 7: aTrackRect.Left() += aDiff.X(); break; case 8: if( Application::GetSettings().GetLayoutRTL() ) aDiff.X() = -aDiff.X(); // workaround for move in RTL mode aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff ); break; /* case 0: aTrackRect = Rectangle( rTrackPos, aOuter.BottomRight() ); break; case 1: aTrackRect = Rectangle( Point( aOuter.Left(), rTrackPos.Y() ), aOuter.BottomRight() ); break; case 2: aTrackRect = Rectangle( rTrackPos, aOuter.BottomLeft() ); break; case 3: aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ), aOuter.BottomLeft() ); break; case 4: aTrackRect = Rectangle( rTrackPos, aOuter.TopLeft() ); break; case 5: aTrackRect = Rectangle( aOuter.TopLeft(), Point( aOuter.Right(), rTrackPos.Y() ) ); break; case 6: aTrackRect = Rectangle( aOuter.TopRight(), rTrackPos ); break; case 7: aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ), aOuter.BottomRight() ); break; case 8: aTrackRect = Rectangle( aOuter.TopLeft() + rTrackPos - aSelPos, aOuter.GetSize() ); break; */ } } return aTrackRect; } void SvResizeHelper::ValidateRect( Rectangle & rValidate ) const { switch( nGrab ) { case 0: if( rValidate.Top() > rValidate.Bottom() ) { rValidate.Top() = rValidate.Bottom(); rValidate.Bottom() = RECT_EMPTY; } if( rValidate.Left() > rValidate.Right() ) { rValidate.Left() = rValidate.Right(); rValidate.Right() = RECT_EMPTY; } break; case 1: if( rValidate.Top() > rValidate.Bottom() ) { rValidate.Top() = rValidate.Bottom(); rValidate.Bottom() = RECT_EMPTY; } break; case 2: if( rValidate.Top() > rValidate.Bottom() ) { rValidate.Top() = rValidate.Bottom(); rValidate.Bottom() = RECT_EMPTY; } if( rValidate.Left() > rValidate.Right() ) rValidate.Right() = RECT_EMPTY; break; case 3: if( rValidate.Left() > rValidate.Right() ) rValidate.Right() = RECT_EMPTY; break; case 4: if( rValidate.Top() > rValidate.Bottom() ) rValidate.Bottom() = RECT_EMPTY; if( rValidate.Left() > rValidate.Right() ) rValidate.Right() = RECT_EMPTY; break; case 5: if( rValidate.Top() > rValidate.Bottom() ) rValidate.Bottom() = RECT_EMPTY; break; case 6: if( rValidate.Top() > rValidate.Bottom() ) rValidate.Bottom() = RECT_EMPTY; if( rValidate.Left() > rValidate.Right() ) { rValidate.Left() = rValidate.Right(); rValidate.Right() = RECT_EMPTY; } break; case 7: if( rValidate.Left() > rValidate.Right() ) { rValidate.Left() = rValidate.Right(); rValidate.Right() = RECT_EMPTY; } break; } if( rValidate.Right() == RECT_EMPTY ) rValidate.Right() = rValidate.Left(); if( rValidate.Bottom() == RECT_EMPTY ) rValidate.Bottom() = rValidate.Top(); // Mindestgr"osse 5 x 5 if( rValidate.Left() + 5 > rValidate.Right() ) rValidate.Right() = rValidate.Left() +5; if( rValidate.Top() + 5 > rValidate.Bottom() ) rValidate.Bottom() = rValidate.Top() +5; } /************************************************************************* |* SvResizeHelper::SelectRelease() |* |* Beschreibung *************************************************************************/ sal_Bool SvResizeHelper::SelectRelease( Window * pWin, const Point & rPos, Rectangle & rOutPosSize ) { if( -1 != nGrab ) { rOutPosSize = GetTrackRectPixel( rPos ); rOutPosSize.Justify(); nGrab = -1; pWin->ReleaseMouse(); pWin->HideTracking(); return sal_True; } return sal_False; } /************************************************************************* |* SvResizeHelper::Release() |* |* Beschreibung *************************************************************************/ void SvResizeHelper::Release( Window * pWin ) { if( nGrab != -1 ) { pWin->ReleaseMouse(); pWin->HideTracking(); nGrab = -1; } } /************************************************************************* |* SvResizeWindow::SvResizeWindow() |* |* Beschreibung *************************************************************************/ SvResizeWindow::SvResizeWindow ( Window * pParent, VCLXHatchWindow* pWrapper ) : Window( pParent, WB_CLIPCHILDREN ) , m_nMoveGrab( -1 ) , m_bActive( sal_False ) , m_pWrapper( pWrapper ) { OSL_ENSURE( pParent != NULL && pWrapper != NULL, "Wrong initialization of hatch window!\n" ); SetBackground(); SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT ); m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) ); } /************************************************************************* |* SvResizeWindow::SetHatchBorderPixel() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::SetHatchBorderPixel( const Size & rSize ) { m_aResizer.SetBorderPixel( rSize ); } /************************************************************************* |* SvResizeWindow::SelectMouse() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::SelectMouse( const Point & rPos ) { short nGrab = m_aResizer.SelectMove( this, rPos ); if( nGrab >= 4 ) nGrab -= 4; if( m_nMoveGrab != nGrab ) { // Pointer hat sich geaendert if( -1 == nGrab ) SetPointer( m_aOldPointer ); else { PointerStyle aStyle = POINTER_MOVE; if( nGrab == 3 ) aStyle = POINTER_ESIZE; else if( nGrab == 2 ) aStyle = POINTER_NESIZE; else if( nGrab == 1 ) aStyle = POINTER_SSIZE; else if( nGrab == 0 ) aStyle = POINTER_SESIZE; if( m_nMoveGrab == -1 ) // das erste mal { m_aOldPointer = GetPointer(); SetPointer( Pointer( aStyle ) ); } else SetPointer( Pointer( aStyle ) ); } m_nMoveGrab = nGrab; } } /************************************************************************* |* SvResizeWindow::MouseButtonDown() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt ) { if( m_aResizer.SelectBegin( this, rEvt.GetPosPixel() ) ) SelectMouse( rEvt.GetPosPixel() ); } /************************************************************************* |* SvResizeWindow::MouseMove() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::MouseMove( const MouseEvent & rEvt ) { if( m_aResizer.GetGrab() == -1 ) SelectMouse( rEvt.GetPosPixel() ); else { Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) ); Point aDiff = GetPosPixel(); aRect.SetPos( aRect.TopLeft() + aDiff ); m_aResizer.ValidateRect( aRect ); m_pWrapper->QueryObjAreaPixel( aRect ); aRect.SetPos( aRect.TopLeft() - aDiff ); Point aPos = m_aResizer.GetTrackPosPixel( aRect ); SelectMouse( aPos ); } } /************************************************************************* |* SvResizeWindow::MouseButtonUp() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::MouseButtonUp( const MouseEvent & rEvt ) { if( m_aResizer.GetGrab() != -1 ) { Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) ); Point aDiff = GetPosPixel(); aRect.SetPos( aRect.TopLeft() + aDiff ); // aRect -= GetAllBorderPixel(); m_aResizer.ValidateRect( aRect ); m_pWrapper->QueryObjAreaPixel( aRect ); Rectangle aOutRect; if( m_aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) ) { m_nMoveGrab = -1; SetPointer( m_aOldPointer ); m_pWrapper->RequestObjAreaPixel( aRect ); } } } /************************************************************************* |* SvResizeWindow::KeyEvent() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::KeyInput( const KeyEvent & rEvt ) { if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE ) { m_aResizer.Release( this ); m_pWrapper->InplaceDeactivate(); } } /************************************************************************* |* SvResizeWindow::Resize() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::Resize() { m_aResizer.InvalidateBorder( this ); // alten Bereich m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) ); m_aResizer.InvalidateBorder( this ); // neuen Bereich } /************************************************************************* |* SvResizeWindow::Paint() |* |* Beschreibung *************************************************************************/ void SvResizeWindow::Paint( const Rectangle & /*rRect*/ ) { m_aResizer.Draw( this ); } long SvResizeWindow::PreNotify( NotifyEvent& rEvt ) { if ( rEvt.GetType() == EVENT_GETFOCUS && !m_bActive ) { m_bActive = sal_True; m_pWrapper->Activated(); } return Window::PreNotify(rEvt); } long SvResizeWindow::Notify( NotifyEvent& rEvt ) { if ( rEvt.GetType() == EVENT_LOSEFOCUS && m_bActive ) { sal_Bool bHasFocus = HasChildPathFocus(sal_True); if ( !bHasFocus ) { m_bActive = sal_False; m_pWrapper->Deactivated(); } } return Window::Notify(rEvt); }