/src/libreoffice/sw/source/uibase/docvw/AnchorOverlayObject.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #include "AnchorOverlayObject.hxx" |
21 | | #include <SidebarWindowsConsts.hxx> |
22 | | |
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> |
30 | | |
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> |
38 | | |
39 | | namespace sw::sidebarwindows { |
40 | | |
41 | | namespace { |
42 | | |
43 | | // helper class: Primitive for discrete visualisation |
44 | | class AnchorPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D |
45 | | { |
46 | | private: |
47 | | basegfx::B2DPolygon maTriangle; |
48 | | basegfx::B2DPolygon maLine; |
49 | | basegfx::B2DPolygon maLineTop; |
50 | | const AnchorState maAnchorState; |
51 | | basegfx::BColor maColor; |
52 | | |
53 | | // discrete line width |
54 | | double mfDiscreteLineWidth; |
55 | | |
56 | | bool mbLineSolid : 1; |
57 | | |
58 | | protected: |
59 | | virtual drawinglayer::primitive2d::Primitive2DReference create2DDecomposition( |
60 | | const drawinglayer::geometry::ViewInformation2D& rViewInformation) const override; |
61 | | |
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 | 0 | : maTriangle(std::move(aTriangle)), |
71 | 0 | maLine(std::move(aLine)), |
72 | 0 | maLineTop(std::move(aLineTop)), |
73 | 0 | maAnchorState(aAnchorState), |
74 | 0 | maColor(rColor), |
75 | 0 | mfDiscreteLineWidth(fDiscreteLineWidth), |
76 | 0 | mbLineSolid(bLineSolid) |
77 | 0 | {} |
78 | | |
79 | | // data access |
80 | 0 | const basegfx::B2DPolygon& getLine() const { return maLine; } |
81 | 0 | const basegfx::BColor& getColor() const { return maColor; } |
82 | 0 | bool getLineSolid() const { return mbLineSolid; } |
83 | | |
84 | | virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const override; |
85 | | |
86 | | virtual sal_uInt32 getPrimitive2DID() const override; |
87 | | }; |
88 | | |
89 | | } |
90 | | |
91 | | drawinglayer::primitive2d::Primitive2DReference AnchorPrimitive::create2DDecomposition( |
92 | | const drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/) const |
93 | 0 | { |
94 | 0 | drawinglayer::primitive2d::Primitive2DContainer aContainer; |
95 | |
|
96 | 0 | if ( AnchorState::Tri == maAnchorState || |
97 | 0 | AnchorState::All == maAnchorState ) |
98 | 0 | { |
99 | | // create triangle |
100 | 0 | const drawinglayer::primitive2d::Primitive2DReference aTriangle( |
101 | 0 | new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( |
102 | 0 | basegfx::B2DPolyPolygon(maTriangle), |
103 | 0 | getColor())); |
104 | |
|
105 | 0 | aContainer.push_back(aTriangle); |
106 | 0 | } |
107 | | |
108 | | // prepare view-independent LineWidth and color |
109 | 0 | const drawinglayer::attribute::LineAttribute aLineAttribute( |
110 | 0 | getColor(), |
111 | 0 | mfDiscreteLineWidth * getDiscreteUnit()); |
112 | |
|
113 | 0 | if ( AnchorState::All == maAnchorState ) |
114 | 0 | { |
115 | | // create line start |
116 | 0 | if(getLineSolid()) |
117 | 0 | { |
118 | 0 | const drawinglayer::primitive2d::Primitive2DReference aSolidLine( |
119 | 0 | new drawinglayer::primitive2d::PolygonStrokePrimitive2D( |
120 | 0 | getLine(), |
121 | 0 | aLineAttribute)); |
122 | |
|
123 | 0 | aContainer.push_back(aSolidLine); |
124 | 0 | } |
125 | 0 | else |
126 | 0 | { |
127 | 0 | std::vector< double > aDotDashArray; |
128 | 0 | const double fDistance(3.0 * 15.0); |
129 | 0 | const double fDashLen(5.0 * 15.0); |
130 | |
|
131 | 0 | aDotDashArray.push_back(fDashLen); |
132 | 0 | aDotDashArray.push_back(fDistance); |
133 | |
|
134 | 0 | drawinglayer::attribute::StrokeAttribute aStrokeAttribute( |
135 | 0 | std::move(aDotDashArray), |
136 | 0 | fDistance + fDashLen); |
137 | |
|
138 | 0 | const drawinglayer::primitive2d::Primitive2DReference aStrokedLine( |
139 | 0 | new drawinglayer::primitive2d::PolygonStrokePrimitive2D( |
140 | 0 | getLine(), |
141 | 0 | aLineAttribute, |
142 | 0 | std::move(aStrokeAttribute))); |
143 | |
|
144 | 0 | aContainer.push_back(aStrokedLine); |
145 | 0 | } |
146 | 0 | } |
147 | |
|
148 | 0 | if ( AnchorState::All == maAnchorState || |
149 | 0 | AnchorState::End == maAnchorState ) |
150 | 0 | { |
151 | | // LineTop has to be created, too, but uses no shadow, so add after |
152 | | // the other parts are created |
153 | 0 | const drawinglayer::primitive2d::Primitive2DReference aLineTop( |
154 | 0 | new drawinglayer::primitive2d::PolygonStrokePrimitive2D( |
155 | 0 | maLineTop, |
156 | 0 | aLineAttribute)); |
157 | |
|
158 | 0 | aContainer.push_back(aLineTop); |
159 | 0 | } |
160 | |
|
161 | 0 | return new drawinglayer::primitive2d::GroupPrimitive2D(std::move(aContainer)); |
162 | 0 | } |
163 | | |
164 | | bool AnchorPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const |
165 | 0 | { |
166 | 0 | if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) |
167 | 0 | { |
168 | 0 | const AnchorPrimitive& rCompare = static_cast< const AnchorPrimitive& >(rPrimitive); |
169 | |
|
170 | 0 | return (maTriangle == rCompare.maTriangle |
171 | 0 | && getLine() == rCompare.getLine() |
172 | 0 | && maLineTop == rCompare.maLineTop |
173 | 0 | && maAnchorState == rCompare.maAnchorState |
174 | 0 | && getColor() == rCompare.getColor() |
175 | 0 | && mfDiscreteLineWidth == rCompare.mfDiscreteLineWidth |
176 | 0 | && getLineSolid() == rCompare.getLineSolid()); |
177 | 0 | } |
178 | | |
179 | 0 | return false; |
180 | 0 | } |
181 | | |
182 | | sal_uInt32 AnchorPrimitive::getPrimitive2DID() const |
183 | 0 | { |
184 | 0 | return PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE; |
185 | 0 | } |
186 | | |
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 ) |
194 | 0 | { |
195 | 0 | std::unique_ptr<AnchorOverlayObject> pAnchorOverlayObject; |
196 | 0 | if ( rDocView.GetDrawView() ) |
197 | 0 | { |
198 | 0 | SdrPaintWindow* pPaintWindow = rDocView.GetDrawView()->GetPaintWindow(0); |
199 | 0 | if( pPaintWindow ) |
200 | 0 | { |
201 | 0 | const rtl::Reference< sdr::overlay::OverlayManager >& xOverlayManager = pPaintWindow->GetOverlayManager(); |
202 | |
|
203 | 0 | if ( xOverlayManager.is() ) |
204 | 0 | { |
205 | 0 | pAnchorOverlayObject.reset(new AnchorOverlayObject( |
206 | 0 | basegfx::B2DPoint( aAnchorRect.Left() , aAnchorRect.Bottom()-5*15), |
207 | 0 | basegfx::B2DPoint( aAnchorRect.Left()-5*15 , aAnchorRect.Bottom()+5*15), |
208 | 0 | basegfx::B2DPoint( aAnchorRect.Left()+5*15 , aAnchorRect.Bottom()+5*15), |
209 | 0 | basegfx::B2DPoint( aAnchorRect.Left(), aAnchorRect.Bottom()+2*15), |
210 | 0 | basegfx::B2DPoint( aPageBorder ,aAnchorRect.Bottom()+2*15), |
211 | 0 | basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()), |
212 | 0 | basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()) , |
213 | 0 | aColorAnchor)); |
214 | 0 | xOverlayManager->add(*pAnchorOverlayObject); |
215 | 0 | } |
216 | 0 | } |
217 | 0 | } |
218 | |
|
219 | 0 | return pAnchorOverlayObject; |
220 | 0 | } |
221 | | |
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 | 0 | : OverlayObjectWithBasePosition(rBasePos, rBaseColor) |
231 | 0 | , maSecondPosition(rSecondPos) |
232 | 0 | , maThirdPosition(rThirdPos) |
233 | 0 | , maFourthPosition(rFourthPos) |
234 | 0 | , maFifthPosition(rFifthPos) |
235 | 0 | , maSixthPosition(rSixthPos) |
236 | 0 | , maSeventhPosition(rSeventhPos) |
237 | 0 | , mAnchorState(AnchorState::All) |
238 | 0 | , mbLineSolid(false) |
239 | 0 | { |
240 | 0 | } |
241 | | |
242 | | AnchorOverlayObject::~AnchorOverlayObject() |
243 | 0 | { |
244 | 0 | if ( getOverlayManager() ) |
245 | 0 | { |
246 | | // remove this object from the chain |
247 | 0 | getOverlayManager()->remove(*this); |
248 | 0 | } |
249 | 0 | } |
250 | | |
251 | | void AnchorOverlayObject::implEnsureGeometry() |
252 | 0 | { |
253 | 0 | if(!maTriangle.count()) |
254 | 0 | { |
255 | 0 | maTriangle.append(getBasePosition()); |
256 | 0 | maTriangle.append(GetSecondPosition()); |
257 | 0 | maTriangle.append(GetThirdPosition()); |
258 | 0 | maTriangle.setClosed(true); |
259 | 0 | } |
260 | |
|
261 | 0 | if(!maLine.count()) |
262 | 0 | { |
263 | 0 | maLine.append(GetFourthPosition()); |
264 | 0 | maLine.append(GetFifthPosition()); |
265 | 0 | maLine.append(GetSixthPosition()); |
266 | 0 | } |
267 | |
|
268 | 0 | if(!maLineTop.count()) |
269 | 0 | { |
270 | 0 | maLineTop.append(GetSixthPosition()); |
271 | 0 | maLineTop.append(GetSeventhPosition()); |
272 | 0 | } |
273 | 0 | } |
274 | | |
275 | | void AnchorOverlayObject::implResetGeometry() |
276 | 0 | { |
277 | 0 | maTriangle.clear(); |
278 | 0 | maLine.clear(); |
279 | 0 | maLineTop.clear(); |
280 | 0 | } |
281 | | |
282 | | drawinglayer::primitive2d::Primitive2DContainer AnchorOverlayObject::createOverlayObjectPrimitive2DSequence() |
283 | 0 | { |
284 | 0 | implEnsureGeometry(); |
285 | |
|
286 | 0 | static const double aDiscreteLineWidth(1.6); |
287 | 0 | const drawinglayer::primitive2d::Primitive2DReference aReference( |
288 | 0 | new AnchorPrimitive( maTriangle, |
289 | 0 | maLine, |
290 | 0 | maLineTop, |
291 | 0 | GetAnchorState(), |
292 | 0 | getBaseColor().getBColor(), |
293 | 0 | ANCHORLINE_WIDTH * aDiscreteLineWidth, |
294 | 0 | getLineSolid()) ); |
295 | |
|
296 | 0 | return drawinglayer::primitive2d::Primitive2DContainer { aReference }; |
297 | 0 | } |
298 | | |
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) |
306 | 0 | { |
307 | 0 | if ( !(rPoint1 != getBasePosition() || |
308 | 0 | rPoint2 != GetSecondPosition() || |
309 | 0 | rPoint3 != GetThirdPosition() || |
310 | 0 | rPoint4 != GetFourthPosition() || |
311 | 0 | rPoint5 != GetFifthPosition() || |
312 | 0 | rPoint6 != GetSixthPosition() || |
313 | 0 | rPoint7 != GetSeventhPosition()) ) |
314 | 0 | return; |
315 | | |
316 | 0 | maBasePosition = rPoint1; |
317 | 0 | maSecondPosition = rPoint2; |
318 | 0 | maThirdPosition = rPoint3; |
319 | 0 | maFourthPosition = rPoint4; |
320 | 0 | maFifthPosition = rPoint5; |
321 | 0 | maSixthPosition = rPoint6; |
322 | 0 | maSeventhPosition = rPoint7; |
323 | |
|
324 | 0 | implResetGeometry(); |
325 | 0 | objectChange(); |
326 | 0 | } |
327 | | |
328 | | void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint& rNew) |
329 | 0 | { |
330 | 0 | if(rNew != maSixthPosition) |
331 | 0 | { |
332 | 0 | maSixthPosition = rNew; |
333 | 0 | implResetGeometry(); |
334 | 0 | objectChange(); |
335 | 0 | } |
336 | 0 | } |
337 | | |
338 | | void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint& rNew) |
339 | 0 | { |
340 | 0 | if(rNew != maSeventhPosition) |
341 | 0 | { |
342 | 0 | maSeventhPosition = rNew; |
343 | 0 | implResetGeometry(); |
344 | 0 | objectChange(); |
345 | 0 | } |
346 | 0 | } |
347 | | |
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) |
350 | 0 | { |
351 | 0 | if(rPoint1 != getBasePosition() |
352 | 0 | || rPoint2 != GetSecondPosition() |
353 | 0 | || rPoint3 != GetThirdPosition() |
354 | 0 | || rPoint4 != GetFourthPosition() |
355 | 0 | || rPoint5 != GetFifthPosition()) |
356 | 0 | { |
357 | 0 | maBasePosition = rPoint1; |
358 | 0 | maSecondPosition = rPoint2; |
359 | 0 | maThirdPosition = rPoint3; |
360 | 0 | maFourthPosition = rPoint4; |
361 | 0 | maFifthPosition = rPoint5; |
362 | |
|
363 | 0 | implResetGeometry(); |
364 | 0 | objectChange(); |
365 | 0 | } |
366 | 0 | } |
367 | | |
368 | | void AnchorOverlayObject::setLineSolid( const bool bNew ) |
369 | 0 | { |
370 | 0 | if ( bNew != getLineSolid() ) |
371 | 0 | { |
372 | 0 | mbLineSolid = bNew; |
373 | 0 | objectChange(); |
374 | 0 | } |
375 | 0 | } |
376 | | |
377 | | void AnchorOverlayObject::SetAnchorState( const AnchorState aState) |
378 | 0 | { |
379 | 0 | if ( mAnchorState != aState) |
380 | 0 | { |
381 | 0 | mAnchorState = aState; |
382 | 0 | objectChange(); |
383 | 0 | } |
384 | 0 | } |
385 | | |
386 | | } // end of namespace sw::sidebarwindows |
387 | | |
388 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |