Add a comment to clarify what kind of inputs the class handles
[LibreOffice.git] / sw / source / uibase / docvw / AnchorOverlayObject.cxx
blob697e15a3ccb426adafdac4dcb8f03aed3d3c2115
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
23 #include <swrect.hxx>
24 #include <utility>
25 #include <view.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 {
41 namespace {
43 // helper class: Primitive for discrete visualisation
44 class AnchorPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D
46 private:
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;
56 bool mbLineSolid : 1;
58 protected:
59 virtual drawinglayer::primitive2d::Primitive2DReference create2DDecomposition(
60 const drawinglayer::geometry::ViewInformation2D& rViewInformation) const override;
62 public:
63 AnchorPrimitive( basegfx::B2DPolygon aTriangle,
64 basegfx::B2DPolygon aLine,
65 basegfx::B2DPolygon aLineTop,
66 AnchorState aAnchorState,
67 const basegfx::BColor& rColor,
68 double fDiscreteLineWidth,
69 bool bLineSolid )
70 : maTriangle(std::move(aTriangle)),
71 maLine(std::move(aLine)),
72 maLineTop(std::move(aLineTop)),
73 maAnchorState(aAnchorState),
74 maColor(rColor),
75 mfDiscreteLineWidth(fDiscreteLineWidth),
76 mbLineSolid(bLineSolid)
79 // data access
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 )
99 // create triangle
100 const drawinglayer::primitive2d::Primitive2DReference aTriangle(
101 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
102 basegfx::B2DPolyPolygon(maTriangle),
103 getColor()));
105 aContainer.push_back(aTriangle);
108 // prepare view-independent LineWidth and color
109 const drawinglayer::attribute::LineAttribute aLineAttribute(
110 getColor(),
111 mfDiscreteLineWidth * getDiscreteUnit());
113 if ( AnchorState::All == maAnchorState )
115 // create line start
116 if(getLineSolid())
118 const drawinglayer::primitive2d::Primitive2DReference aSolidLine(
119 new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
120 getLine(),
121 aLineAttribute));
123 aContainer.push_back(aSolidLine);
125 else
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(
140 getLine(),
141 aLineAttribute,
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(
155 maLineTop,
156 aLineAttribute));
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());
179 return false;
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);
199 if( pPaintWindow )
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()) ,
213 aColorAnchor));
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)
238 , mbLineSolid(false)
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);
261 if(!maLine.count())
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()
277 maTriangle.clear();
278 maLine.clear();
279 maLineTop.clear();
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,
289 maLine,
290 maLineTop,
291 GetAnchorState(),
292 getBaseColor().getBColor(),
293 ANCHORLINE_WIDTH * aDiscreteLineWidth,
294 getLineSolid()) );
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()) )
314 return;
316 maBasePosition = rPoint1;
317 maSecondPosition = rPoint2;
318 maThirdPosition = rPoint3;
319 maFourthPosition = rPoint4;
320 maFifthPosition = rPoint5;
321 maSixthPosition = rPoint6;
322 maSeventhPosition = rPoint7;
324 implResetGeometry();
325 objectChange();
328 void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint& rNew)
330 if(rNew != maSixthPosition)
332 maSixthPosition = rNew;
333 implResetGeometry();
334 objectChange();
338 void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint& rNew)
340 if(rNew != maSeventhPosition)
342 maSeventhPosition = rNew;
343 implResetGeometry();
344 objectChange();
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;
363 implResetGeometry();
364 objectChange();
368 void AnchorOverlayObject::setLineSolid( const bool bNew )
370 if ( bNew != getLineSolid() )
372 mbLineSolid = bNew;
373 objectChange();
377 void AnchorOverlayObject::SetAnchorState( const AnchorState aState)
379 if ( mAnchorState != aState)
381 mAnchorState = aState;
382 objectChange();
386 } // end of namespace sw::sidebarwindows
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */