| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| |
| #include "precompiled_sw.hxx" |
| |
| #include <AnchorOverlayObject.hxx> |
| #include <SidebarWindowsConsts.hxx> |
| |
| #include <swrect.hxx> |
| #include <view.hxx> |
| #include <svx/sdrpaintwindow.hxx> |
| #include <svx/svdview.hxx> |
| #include <svx/sdr/overlay/overlaymanager.hxx> |
| |
| #include <sw_primitivetypes2d.hxx> |
| #include <drawinglayer/primitive2d/primitivetools2d.hxx> |
| #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/shadowprimitive2d.hxx> |
| |
| 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 mfDiscreteLineWidth; |
| |
| // 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 fDiscreteLineWidth, |
| bool bShadow, |
| bool bLineSolid ) |
| : drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D(), |
| maTriangle(rTriangle), |
| maLine(rLine), |
| maLineTop(rLineTop), |
| maAnchorState(aAnchorState), |
| maColor(rColor), |
| mfDiscreteLineWidth(fDiscreteLineWidth), |
| 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 getDiscreteLineWidth() const { return mfDiscreteLineWidth; } |
| 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); |
| } |
| |
| // prepare view-independent LineWidth and color |
| const drawinglayer::attribute::LineAttribute aLineAttribute( |
| getColor(), |
| getDiscreteLineWidth() * getDiscreteUnit()); |
| |
| if ( AS_ALL == maAnchorState || |
| AS_START == maAnchorState ) |
| { |
| // create line start |
| 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::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() |
| && getDiscreteLineWidth() == rCompare.getDiscreteLineWidth() |
| && 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 ) |
| { |
| sdr::overlay::OverlayManager* pOverlayManager = pPaintWindow->GetOverlayManager(); |
| |
| if ( pOverlayManager ) |
| { |
| 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); |
| pOverlayManager->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(); |
| |
| static double aDiscreteLineWidth(1.6); |
| const drawinglayer::primitive2d::Primitive2DReference aReference( |
| new AnchorPrimitive( maTriangle, |
| maLine, |
| maLineTop, |
| GetAnchorState(), |
| getBaseColor().getBColor(), |
| ANCHORLINE_WIDTH * aDiscreteLineWidth, |
| 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 |
| |