/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include namespace sw { namespace sidebarwindows { ////////////////////////////////////////////////////////////////////////////// // helper class: Primitive for discrete visualisation class AnchorPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D { private: basegfx::B2DPolygon maTriangle; basegfx::B2DPolygon maLine; basegfx::B2DPolygon maLineTop; const AnchorState maAnchorState; basegfx::BColor maColor; // discrete line width double mfLogicLineWidth; // bitfield bool mbShadow : 1; bool mbLineSolid : 1; protected: virtual drawinglayer::primitive2d::Primitive2DSequence create2DDecomposition( const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; public: AnchorPrimitive( const basegfx::B2DPolygon& rTriangle, const basegfx::B2DPolygon& rLine, const basegfx::B2DPolygon& rLineTop, AnchorState aAnchorState, const basegfx::BColor& rColor, double fLogicLineWidth, bool bShadow, bool bLineSolid ) : drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D(), maTriangle(rTriangle), maLine(rLine), maLineTop(rLineTop), maAnchorState(aAnchorState), maColor(rColor), mfLogicLineWidth(fLogicLineWidth), mbShadow(bShadow), mbLineSolid(bLineSolid) {} // data access const basegfx::B2DPolygon& getTriangle() const { return maTriangle; } const basegfx::B2DPolygon& getLine() const { return maLine; } const basegfx::B2DPolygon& getLineTop() const { return maLineTop; } AnchorState getAnchorState() const { return maAnchorState; } const basegfx::BColor& getColor() const { return maColor; } double getLogicLineWidth() const { return mfLogicLineWidth; } bool getShadow() const { return mbShadow; } bool getLineSolid() const { return mbLineSolid; } virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const; DeclPrimitrive2DIDBlock() }; drawinglayer::primitive2d::Primitive2DSequence AnchorPrimitive::create2DDecomposition( const drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/) const { drawinglayer::primitive2d::Primitive2DSequence aRetval; if ( AS_TRI == maAnchorState || AS_ALL == maAnchorState || AS_START == maAnchorState ) { // create triangle const drawinglayer::primitive2d::Primitive2DReference aTriangle( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( basegfx::B2DPolyPolygon(getTriangle()), getColor())); drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aTriangle); } if ( AS_ALL == maAnchorState || AS_START == maAnchorState ) { // create line start const drawinglayer::attribute::LineAttribute aLineAttribute( getColor(), getLogicLineWidth() / (basegfx::fTools::equalZero(getDiscreteUnit()) ? 1.0 : getDiscreteUnit())); if(getLineSolid()) { const drawinglayer::primitive2d::Primitive2DReference aSolidLine( new drawinglayer::primitive2d::PolygonStrokePrimitive2D( getLine(), aLineAttribute)); drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aSolidLine); } else { ::std::vector< double > aDotDashArray; const double fDistance(3.0 * 15.0); const double fDashLen(5.0 * 15.0); aDotDashArray.push_back(fDashLen); aDotDashArray.push_back(fDistance); const drawinglayer::attribute::StrokeAttribute aStrokeAttribute( aDotDashArray, fDistance + fDashLen); const drawinglayer::primitive2d::Primitive2DReference aStrokedLine( new drawinglayer::primitive2d::PolygonStrokePrimitive2D( getLine(), aLineAttribute, aStrokeAttribute)); drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aStrokedLine); } } if(aRetval.hasElements() && getShadow()) { // shadow is only for triangle and line start, and in upper left // and lower right direction, in different colors const double fColorChange(20.0 / 255.0); const basegfx::B3DTuple aColorChange(fColorChange, fColorChange, fColorChange); basegfx::BColor aLighterColor(getColor() + aColorChange); basegfx::BColor aDarkerColor(getColor() - aColorChange); aLighterColor.clamp(); aDarkerColor.clamp(); // create shadow sequence drawinglayer::primitive2d::Primitive2DSequence aShadows(2); basegfx::B2DHomMatrix aTransform; aTransform.set(0, 2, -getDiscreteUnit()); aTransform.set(1, 2, -getDiscreteUnit()); aShadows[0] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::ShadowPrimitive2D( aTransform, aLighterColor, aRetval)); aTransform.set(0, 2, getDiscreteUnit()); aTransform.set(1, 2, getDiscreteUnit()); aShadows[1] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::ShadowPrimitive2D( aTransform, aDarkerColor, aRetval)); // add shadow before geometry to make it be proccessed first const drawinglayer::primitive2d::Primitive2DSequence aTemporary(aRetval); aRetval = aShadows; drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aTemporary); } if ( AS_ALL == maAnchorState || AS_END == maAnchorState ) { // LineTop has to be created, too, but uses no shadow, so add after // the other parts are created const drawinglayer::attribute::LineAttribute aLineAttribute( getColor(), getLogicLineWidth() / (basegfx::fTools::equalZero(getDiscreteUnit()) ? 1.0 : getDiscreteUnit())); const drawinglayer::primitive2d::Primitive2DReference aLineTop( new drawinglayer::primitive2d::PolygonStrokePrimitive2D( getLineTop(), aLineAttribute)); drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aLineTop); } return aRetval; } bool AnchorPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const { if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) { const AnchorPrimitive& rCompare = static_cast< const AnchorPrimitive& >(rPrimitive); return (getTriangle() == rCompare.getTriangle() && getLine() == rCompare.getLine() && getLineTop() == rCompare.getLineTop() && getAnchorState() == rCompare.getAnchorState() && getColor() == rCompare.getColor() && getLogicLineWidth() == rCompare.getLogicLineWidth() && getShadow() == rCompare.getShadow() && getLineSolid() == rCompare.getLineSolid()); } return false; } ImplPrimitrive2DIDBlock(AnchorPrimitive, PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE) /****** AnchorOverlayObject ***********************************************************/ /*static*/ AnchorOverlayObject* AnchorOverlayObject::CreateAnchorOverlayObject( SwView& rDocView, const SwRect& aAnchorRect, const long& aPageBorder, const Point& aLineStart, const Point& aLineEnd, const Color& aColorAnchor ) { AnchorOverlayObject* pAnchorOverlayObject( 0 ); if ( rDocView.GetDrawView() ) { SdrPaintWindow* pPaintWindow = rDocView.GetDrawView()->GetPaintWindow(0); if( pPaintWindow ) { rtl::Reference< ::sdr::overlay::OverlayManager > xOverlayManager = pPaintWindow->GetOverlayManager(); if ( xOverlayManager.is() ) { pAnchorOverlayObject = new AnchorOverlayObject( basegfx::B2DPoint( aAnchorRect.Left() , aAnchorRect.Bottom()-5*15), basegfx::B2DPoint( aAnchorRect.Left()-5*15 , aAnchorRect.Bottom()+5*15), basegfx::B2DPoint( aAnchorRect.Left()+5*15 , aAnchorRect.Bottom()+5*15), basegfx::B2DPoint( aAnchorRect.Left(), aAnchorRect.Bottom()+2*15), basegfx::B2DPoint( aPageBorder ,aAnchorRect.Bottom()+2*15), basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()), basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()) , aColorAnchor, false, false); xOverlayManager->add(*pAnchorOverlayObject); } } } return pAnchorOverlayObject; } /*static*/ void AnchorOverlayObject::DestroyAnchorOverlayObject( AnchorOverlayObject* pAnchor ) { if ( pAnchor ) { if ( pAnchor->getOverlayManager() ) { // remove this object from the chain pAnchor->getOverlayManager()->remove(*pAnchor); } delete pAnchor; } } AnchorOverlayObject::AnchorOverlayObject( const basegfx::B2DPoint& rBasePos, const basegfx::B2DPoint& rSecondPos, const basegfx::B2DPoint& rThirdPos, const basegfx::B2DPoint& rFourthPos, const basegfx::B2DPoint& rFifthPos, const basegfx::B2DPoint& rSixthPos, const basegfx::B2DPoint& rSeventhPos, const Color aBaseColor, const bool bShadowedEffect, const bool bLineSolid) : OverlayObjectWithBasePosition( rBasePos, aBaseColor ) , maSecondPosition(rSecondPos) , maThirdPosition(rThirdPos) , maFourthPosition(rFourthPos) , maFifthPosition(rFifthPos) , maSixthPosition(rSixthPos) , maSeventhPosition(rSeventhPos) , maTriangle() , maLine() , maLineTop() , mHeight(0) , mAnchorState(AS_ALL) , mbShadowedEffect(bShadowedEffect) , mbLineSolid(bLineSolid) { } AnchorOverlayObject::~AnchorOverlayObject() { } void AnchorOverlayObject::implEnsureGeometry() { if(!maTriangle.count()) { maTriangle.append(getBasePosition()); maTriangle.append(GetSecondPosition()); maTriangle.append(GetThirdPosition()); maTriangle.setClosed(true); } if(!maLine.count()) { maLine.append(GetFourthPosition()); maLine.append(GetFifthPosition()); maLine.append(GetSixthPosition()); } if(!maLineTop.count()) { maLineTop.append(GetSixthPosition()); maLineTop.append(GetSeventhPosition()); } } void AnchorOverlayObject::implResetGeometry() { maTriangle.clear(); maLine.clear(); maLineTop.clear(); } drawinglayer::primitive2d::Primitive2DSequence AnchorOverlayObject::createOverlayObjectPrimitive2DSequence() { implEnsureGeometry(); const drawinglayer::primitive2d::Primitive2DReference aReference( new AnchorPrimitive( maTriangle, maLine, maLineTop, GetAnchorState(), getBaseColor().getBColor(), ANCHORLINE_WIDTH * 15.0, getShadowedEffect(), getLineSolid()) ); return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); } void AnchorOverlayObject::SetAllPosition( const basegfx::B2DPoint& rPoint1, const basegfx::B2DPoint& rPoint2, const basegfx::B2DPoint& rPoint3, const basegfx::B2DPoint& rPoint4, const basegfx::B2DPoint& rPoint5, const basegfx::B2DPoint& rPoint6, const basegfx::B2DPoint& rPoint7) { if ( rPoint1 != getBasePosition() || rPoint2 != GetSecondPosition() || rPoint3 != GetThirdPosition() || rPoint4 != GetFourthPosition() || rPoint5 != GetFifthPosition() || rPoint6 != GetSixthPosition() || rPoint7 != GetSeventhPosition() ) { maBasePosition = rPoint1; maSecondPosition = rPoint2; maThirdPosition = rPoint3; maFourthPosition = rPoint4; maFifthPosition = rPoint5; maSixthPosition = rPoint6; maSeventhPosition = rPoint7; implResetGeometry(); objectChange(); } } void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint& rNew) { if(rNew != maSixthPosition) { maSixthPosition = rNew; implResetGeometry(); objectChange(); } } void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint& rNew) { if(rNew != maSeventhPosition) { maSeventhPosition = rNew; implResetGeometry(); objectChange(); } } void AnchorOverlayObject::SetTriPosition(const basegfx::B2DPoint& rPoint1,const basegfx::B2DPoint& rPoint2,const basegfx::B2DPoint& rPoint3, const basegfx::B2DPoint& rPoint4,const basegfx::B2DPoint& rPoint5) { if(rPoint1 != getBasePosition() || rPoint2 != GetSecondPosition() || rPoint3 != GetThirdPosition() || rPoint4 != GetFourthPosition() || rPoint5 != GetFifthPosition()) { maBasePosition = rPoint1; maSecondPosition = rPoint2; maThirdPosition = rPoint3; maFourthPosition = rPoint4; maFifthPosition = rPoint5; implResetGeometry(); objectChange(); } } void AnchorOverlayObject::setLineSolid( const bool bNew ) { if ( bNew != getLineSolid() ) { mbLineSolid = bNew; objectChange(); } } void AnchorOverlayObject::SetAnchorState( const AnchorState aState) { if ( mAnchorState != aState) { mAnchorState = aState; objectChange(); } } } } // end of namespace sw::annotation /* vim:set shiftwidth=4 softtabstop=4 expandtab: */