blob: 4ce5ce5a25f9415cc93ee179842ee5ed901ab0c8 [file] [log] [blame]
/**************************************************************
*
* 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_svx.hxx"
#include <svx/xoutbmp.hxx>
#include <svx/dialogs.hrc>
#include <svx/svxids.hrc>
#include <contdlg.hrc>
#include <contwnd.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdopath.hxx>
#include <svx/xfltrit.hxx>
#include <svx/xfillit.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
// #i75482#
#include "svx/sdrpaintwindow.hxx"
#define TRANSCOL Color( COL_WHITE )
/*************************************************************************
|*
|*
|*
\************************************************************************/
ContourWindow::ContourWindow( Window* pParent, const ResId& rResId ) :
GraphCtrl ( pParent, rResId ),
aWorkRect ( 0, 0, 0, 0 ),
bPipetteMode ( sal_False ),
bWorkplaceMode ( sal_False ),
bClickValid ( sal_False )
{
SetWinStyle( WB_SDRMODE );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
ContourWindow::~ContourWindow()
{
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::SetPolyPolygon( const PolyPolygon& rPolyPoly )
{
SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 );
const sal_uInt16 nPolyCount = rPolyPoly.Count();
// zuerst alle Zeichenobjekte loeschen
aPolyPoly = rPolyPoly;
// #117412#
// To avoid to have destroyed objects which are still selected, it is necessary to deselect
// them first (!)
pView->UnmarkAllObj();
pPage->Clear();
for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
{
basegfx::B2DPolyPolygon aPolyPolygon;
aPolyPolygon.append(aPolyPoly[ i ].getB2DPolygon());
SdrPathObj* pPathObj = new SdrPathObj( OBJ_PATHFILL, aPolyPolygon );
if ( pPathObj )
{
SfxItemSet aSet( pModel->GetItemPool() );
aSet.Put( XFillStyleItem( XFILL_SOLID ) );
aSet.Put( XFillColorItem( String(), TRANSCOL ) );
aSet.Put( XFillTransparenceItem( 50 ) );
//pPathObj->SetItemSetAndBroadcast(aSet);
pPathObj->SetMergedItemSetAndBroadcast(aSet);
pPage->InsertObject( pPathObj );
}
}
if ( nPolyCount )
{
pView->MarkAll();
pView->CombineMarkedObjects( sal_False );
}
pModel->SetChanged( sal_False );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
const PolyPolygon& ContourWindow::GetPolyPolygon()
{
if ( pModel->IsChanged() )
{
SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 );
aPolyPoly = PolyPolygon();
if ( pPage && pPage->GetObjCount() )
{
SdrPathObj* pPathObj = (SdrPathObj*)pPage->GetObj(0L);
// Not sure if subdivision is needed for ContourWindow, but maybe it cannot handle
// curves at all. Keeping subdivision here for security
const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(pPathObj->GetPathPoly()));
aPolyPoly = PolyPolygon(aB2DPolyPolygon);
}
pModel->SetChanged( sal_False );
}
return aPolyPoly;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::InitSdrModel()
{
GraphCtrl::InitSdrModel();
SfxItemSet aSet( pModel->GetItemPool() );
aSet.Put( XFillColorItem( String(), TRANSCOL ) );
aSet.Put( XFillTransparenceItem( 50 ) );
pView->SetAttributes( aSet );
pView->SetFrameDragSingles( sal_True );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::SdrObjCreated( const SdrObject& )
{
pView->MarkAll();
pView->CombineMarkedObjects( sal_False );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool ContourWindow::IsContourChanged() const
{
SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 );
sal_Bool bRet = sal_False;
if ( pPage && pPage->GetObjCount() )
bRet = ( (SdrPathObj*) pPage->GetObj( 0 ) )->GetPathPoly().count() && pModel->IsChanged();
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
if ( bWorkplaceMode )
{
const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
SetPolyPolygon( PolyPolygon() );
aWorkRect = Rectangle( aLogPt, aLogPt );
Paint( Rectangle( Point(), GetGraphicSize() ) );
SetEditMode( sal_True );
}
if ( !bPipetteMode )
GraphCtrl::MouseButtonDown( rMEvt );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::MouseMove( const MouseEvent& rMEvt )
{
bClickValid = sal_False;
if ( bPipetteMode )
{
const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
aPipetteColor = GetPixel( aLogPt );
Control::MouseMove( rMEvt );
if ( aPipetteLink.IsSet() && Rectangle( Point(), GetGraphicSize() ).IsInside( aLogPt ) )
{
SetPointer( POINTER_REFHAND );
aPipetteLink.Call( this );
}
}
else
GraphCtrl::MouseMove( rMEvt );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::MouseButtonUp(const MouseEvent& rMEvt)
{
Point aTmpPoint;
const Rectangle aGraphRect( aTmpPoint, GetGraphicSize() );
const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
bClickValid = aGraphRect.IsInside( aLogPt );
ReleaseMouse();
if ( bPipetteMode )
{
Control::MouseButtonUp( rMEvt );
if ( aPipetteClickLink.IsSet() )
aPipetteClickLink.Call( this );
}
else if ( bWorkplaceMode )
{
GraphCtrl::MouseButtonUp( rMEvt );
aWorkRect.Right() = aLogPt.X();
aWorkRect.Bottom() = aLogPt.Y();
aWorkRect.Intersection( aGraphRect );
aWorkRect.Justify();
if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() )
{
PolyPolygon _aPolyPoly( GetPolyPolygon() );
_aPolyPoly.Clip( aWorkRect );
SetPolyPolygon( _aPolyPoly );
pView->SetWorkArea( aWorkRect );
}
else
pView->SetWorkArea( aGraphRect );
Invalidate( aGraphRect );
if ( aWorkplaceClickLink.IsSet() )
aWorkplaceClickLink.Call( this );
}
else
GraphCtrl::MouseButtonUp( rMEvt );
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void ContourWindow::Paint( const Rectangle& rRect )
{
// #i75482#
// encapsulate the redraw using Begin/End and use the returned
// data to get the target output device (e.g. when pre-rendering)
SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(this);
OutputDevice& rTarget = pPaintWindow->GetTargetOutputDevice();
const Graphic& rGraphic = GetGraphic();
const Color& rOldLineColor = GetLineColor();
const Color& rOldFillColor = GetFillColor();
rTarget.SetLineColor( Color( COL_BLACK ) );
rTarget.SetFillColor( Color( COL_WHITE ) );
rTarget.DrawRect( Rectangle( Point(), GetGraphicSize() ) );
rTarget.SetLineColor( rOldLineColor );
rTarget.SetFillColor( rOldFillColor );
if ( rGraphic.GetType() != GRAPHIC_NONE )
rGraphic.Draw( &rTarget, Point(), GetGraphicSize() );
if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() )
{
PolyPolygon _aPolyPoly( 2, 2 );
const Color aOldFillColor( GetFillColor() );
_aPolyPoly.Insert( Rectangle( Point(), GetGraphicSize() ) );
_aPolyPoly.Insert( aWorkRect );
rTarget.SetFillColor( COL_LIGHTRED );
rTarget.DrawTransparent( _aPolyPoly, 50 );
rTarget.SetFillColor( aOldFillColor );
}
// #i75482#
const Region aRepaintRegion(rRect);
pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion);
pView->EndCompleteRedraw(*pPaintWindow, true);
}
// eof