1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "AnchorOverlayObject.hxx"
21 #include <SidebarWindowsConsts.hxx>
26 #include <svx/sdrpaintwindow.hxx>
27 #include <svx/svdview.hxx>
28 #include <svx/sdr/overlay/overlaymanager.hxx>
29 #include <tools/long.hxx>
31 #include <sw_primitivetypes2d.hxx>
32 #include <drawinglayer/attribute/lineattribute.hxx>
33 #include <drawinglayer/attribute/strokeattribute.hxx>
34 #include <drawinglayer/primitive2d/primitivetools2d.hxx>
35 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
36 #include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
37 #include <drawinglayer/primitive2d/groupprimitive2d.hxx>
39 namespace sw::sidebarwindows
{
43 // helper class: Primitive for discrete visualisation
44 class AnchorPrimitive
: public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D
47 basegfx::B2DPolygon maTriangle
;
48 basegfx::B2DPolygon maLine
;
49 basegfx::B2DPolygon maLineTop
;
50 const AnchorState maAnchorState
;
51 basegfx::BColor maColor
;
53 // discrete line width
54 double mfDiscreteLineWidth
;
59 virtual drawinglayer::primitive2d::Primitive2DReference
create2DDecomposition(
60 const drawinglayer::geometry::ViewInformation2D
& rViewInformation
) const override
;
63 AnchorPrimitive( basegfx::B2DPolygon aTriangle
,
64 basegfx::B2DPolygon aLine
,
65 basegfx::B2DPolygon aLineTop
,
66 AnchorState aAnchorState
,
67 const basegfx::BColor
& rColor
,
68 double fDiscreteLineWidth
,
70 : maTriangle(std::move(aTriangle
)),
71 maLine(std::move(aLine
)),
72 maLineTop(std::move(aLineTop
)),
73 maAnchorState(aAnchorState
),
75 mfDiscreteLineWidth(fDiscreteLineWidth
),
76 mbLineSolid(bLineSolid
)
80 const basegfx::B2DPolygon
& getLine() const { return maLine
; }
81 const basegfx::BColor
& getColor() const { return maColor
; }
82 bool getLineSolid() const { return mbLineSolid
; }
84 virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D
& rPrimitive
) const override
;
86 virtual sal_uInt32
getPrimitive2DID() const override
;
91 drawinglayer::primitive2d::Primitive2DReference
AnchorPrimitive::create2DDecomposition(
92 const drawinglayer::geometry::ViewInformation2D
& /*rViewInformation*/) const
94 drawinglayer::primitive2d::Primitive2DContainer aContainer
;
96 if ( AnchorState::Tri
== maAnchorState
||
97 AnchorState::All
== maAnchorState
)
100 const drawinglayer::primitive2d::Primitive2DReference
aTriangle(
101 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
102 basegfx::B2DPolyPolygon(maTriangle
),
105 aContainer
.push_back(aTriangle
);
108 // prepare view-independent LineWidth and color
109 const drawinglayer::attribute::LineAttribute
aLineAttribute(
111 mfDiscreteLineWidth
* getDiscreteUnit());
113 if ( AnchorState::All
== maAnchorState
)
118 const drawinglayer::primitive2d::Primitive2DReference
aSolidLine(
119 new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
123 aContainer
.push_back(aSolidLine
);
127 std::vector
< double > aDotDashArray
;
128 const double fDistance(3.0 * 15.0);
129 const double fDashLen(5.0 * 15.0);
131 aDotDashArray
.push_back(fDashLen
);
132 aDotDashArray
.push_back(fDistance
);
134 drawinglayer::attribute::StrokeAttribute
aStrokeAttribute(
135 std::move(aDotDashArray
),
136 fDistance
+ fDashLen
);
138 const drawinglayer::primitive2d::Primitive2DReference
aStrokedLine(
139 new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
142 std::move(aStrokeAttribute
)));
144 aContainer
.push_back(aStrokedLine
);
148 if ( AnchorState::All
== maAnchorState
||
149 AnchorState::End
== maAnchorState
)
151 // LineTop has to be created, too, but uses no shadow, so add after
152 // the other parts are created
153 const drawinglayer::primitive2d::Primitive2DReference
aLineTop(
154 new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
158 aContainer
.push_back(aLineTop
);
161 return new drawinglayer::primitive2d::GroupPrimitive2D(std::move(aContainer
));
164 bool AnchorPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D
& rPrimitive
) const
166 if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive
))
168 const AnchorPrimitive
& rCompare
= static_cast< const AnchorPrimitive
& >(rPrimitive
);
170 return (maTriangle
== rCompare
.maTriangle
171 && getLine() == rCompare
.getLine()
172 && maLineTop
== rCompare
.maLineTop
173 && maAnchorState
== rCompare
.maAnchorState
174 && getColor() == rCompare
.getColor()
175 && mfDiscreteLineWidth
== rCompare
.mfDiscreteLineWidth
176 && getLineSolid() == rCompare
.getLineSolid());
182 sal_uInt32
AnchorPrimitive::getPrimitive2DID() const
184 return PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE
;
187 /*static*/ std::unique_ptr
<AnchorOverlayObject
> AnchorOverlayObject::CreateAnchorOverlayObject(
188 SwView
const & rDocView
,
189 const SwRect
& aAnchorRect
,
190 tools::Long aPageBorder
,
191 const Point
& aLineStart
,
192 const Point
& aLineEnd
,
193 const Color
& aColorAnchor
)
195 std::unique_ptr
<AnchorOverlayObject
> pAnchorOverlayObject
;
196 if ( rDocView
.GetDrawView() )
198 SdrPaintWindow
* pPaintWindow
= rDocView
.GetDrawView()->GetPaintWindow(0);
201 const rtl::Reference
< sdr::overlay::OverlayManager
>& xOverlayManager
= pPaintWindow
->GetOverlayManager();
203 if ( xOverlayManager
.is() )
205 pAnchorOverlayObject
.reset(new AnchorOverlayObject(
206 basegfx::B2DPoint( aAnchorRect
.Left() , aAnchorRect
.Bottom()-5*15),
207 basegfx::B2DPoint( aAnchorRect
.Left()-5*15 , aAnchorRect
.Bottom()+5*15),
208 basegfx::B2DPoint( aAnchorRect
.Left()+5*15 , aAnchorRect
.Bottom()+5*15),
209 basegfx::B2DPoint( aAnchorRect
.Left(), aAnchorRect
.Bottom()+2*15),
210 basegfx::B2DPoint( aPageBorder
,aAnchorRect
.Bottom()+2*15),
211 basegfx::B2DPoint( aLineStart
.X(),aLineStart
.Y()),
212 basegfx::B2DPoint( aLineEnd
.X(),aLineEnd
.Y()) ,
214 xOverlayManager
->add(*pAnchorOverlayObject
);
219 return pAnchorOverlayObject
;
222 AnchorOverlayObject::AnchorOverlayObject( const basegfx::B2DPoint
& rBasePos
,
223 const basegfx::B2DPoint
& rSecondPos
,
224 const basegfx::B2DPoint
& rThirdPos
,
225 const basegfx::B2DPoint
& rFourthPos
,
226 const basegfx::B2DPoint
& rFifthPos
,
227 const basegfx::B2DPoint
& rSixthPos
,
228 const basegfx::B2DPoint
& rSeventhPos
,
229 const Color
& rBaseColor
)
230 : OverlayObjectWithBasePosition(rBasePos
, rBaseColor
)
231 , maSecondPosition(rSecondPos
)
232 , maThirdPosition(rThirdPos
)
233 , maFourthPosition(rFourthPos
)
234 , maFifthPosition(rFifthPos
)
235 , maSixthPosition(rSixthPos
)
236 , maSeventhPosition(rSeventhPos
)
237 , mAnchorState(AnchorState::All
)
242 AnchorOverlayObject::~AnchorOverlayObject()
244 if ( getOverlayManager() )
246 // remove this object from the chain
247 getOverlayManager()->remove(*this);
251 void AnchorOverlayObject::implEnsureGeometry()
253 if(!maTriangle
.count())
255 maTriangle
.append(getBasePosition());
256 maTriangle
.append(GetSecondPosition());
257 maTriangle
.append(GetThirdPosition());
258 maTriangle
.setClosed(true);
263 maLine
.append(GetFourthPosition());
264 maLine
.append(GetFifthPosition());
265 maLine
.append(GetSixthPosition());
268 if(!maLineTop
.count())
270 maLineTop
.append(GetSixthPosition());
271 maLineTop
.append(GetSeventhPosition());
275 void AnchorOverlayObject::implResetGeometry()
282 drawinglayer::primitive2d::Primitive2DContainer
AnchorOverlayObject::createOverlayObjectPrimitive2DSequence()
284 implEnsureGeometry();
286 static const double aDiscreteLineWidth(1.6);
287 const drawinglayer::primitive2d::Primitive2DReference
aReference(
288 new AnchorPrimitive( maTriangle
,
292 getBaseColor().getBColor(),
293 ANCHORLINE_WIDTH
* aDiscreteLineWidth
,
296 return drawinglayer::primitive2d::Primitive2DContainer
{ aReference
};
299 void AnchorOverlayObject::SetAllPosition( const basegfx::B2DPoint
& rPoint1
,
300 const basegfx::B2DPoint
& rPoint2
,
301 const basegfx::B2DPoint
& rPoint3
,
302 const basegfx::B2DPoint
& rPoint4
,
303 const basegfx::B2DPoint
& rPoint5
,
304 const basegfx::B2DPoint
& rPoint6
,
305 const basegfx::B2DPoint
& rPoint7
)
307 if ( !(rPoint1
!= getBasePosition() ||
308 rPoint2
!= GetSecondPosition() ||
309 rPoint3
!= GetThirdPosition() ||
310 rPoint4
!= GetFourthPosition() ||
311 rPoint5
!= GetFifthPosition() ||
312 rPoint6
!= GetSixthPosition() ||
313 rPoint7
!= GetSeventhPosition()) )
316 maBasePosition
= rPoint1
;
317 maSecondPosition
= rPoint2
;
318 maThirdPosition
= rPoint3
;
319 maFourthPosition
= rPoint4
;
320 maFifthPosition
= rPoint5
;
321 maSixthPosition
= rPoint6
;
322 maSeventhPosition
= rPoint7
;
328 void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint
& rNew
)
330 if(rNew
!= maSixthPosition
)
332 maSixthPosition
= rNew
;
338 void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint
& rNew
)
340 if(rNew
!= maSeventhPosition
)
342 maSeventhPosition
= rNew
;
348 void AnchorOverlayObject::SetTriPosition(const basegfx::B2DPoint
& rPoint1
,const basegfx::B2DPoint
& rPoint2
,const basegfx::B2DPoint
& rPoint3
,
349 const basegfx::B2DPoint
& rPoint4
,const basegfx::B2DPoint
& rPoint5
)
351 if(rPoint1
!= getBasePosition()
352 || rPoint2
!= GetSecondPosition()
353 || rPoint3
!= GetThirdPosition()
354 || rPoint4
!= GetFourthPosition()
355 || rPoint5
!= GetFifthPosition())
357 maBasePosition
= rPoint1
;
358 maSecondPosition
= rPoint2
;
359 maThirdPosition
= rPoint3
;
360 maFourthPosition
= rPoint4
;
361 maFifthPosition
= rPoint5
;
368 void AnchorOverlayObject::setLineSolid( const bool bNew
)
370 if ( bNew
!= getLineSolid() )
377 void AnchorOverlayObject::SetAnchorState( const AnchorState aState
)
379 if ( mAnchorState
!= aState
)
381 mAnchorState
= aState
;
386 } // end of namespace sw::sidebarwindows
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */