1 /************************************************************************* * 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2008 by Sun Microsystems, Inc. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * $RCSfile: postit.cxx,v $ 10 * $Revision: 1.8.42.11 $ 11 * 12 * This file is part of OpenOffice.org. 13 * 14 * OpenOffice.org is free software: you can redistribute it and/or modify 15 * it under the terms of the GNU Lesser General Public License version 3 16 * only, as published by the Free Software Foundation. 17 * 18 * OpenOffice.org is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU Lesser General Public License version 3 for more details 22 * (a copy is included in the LICENSE file that accompanied this code). 23 * 24 * You should have received a copy of the GNU Lesser General Public License 25 * version 3 along with OpenOffice.org. If not, see 26 * <http://www.openoffice.org/license.html> 27 * for a copy of the LGPLv3 License. 28 * 29 ************************************************************************/ 30 31 32 #include "precompiled_sw.hxx" 33 34 #include <AnchorOverlayObject.hxx> 35 #include <SidebarWindowsConsts.hxx> 36 37 #include <swrect.hxx> 38 #include <view.hxx> 39 #include <svx/sdrpaintwindow.hxx> 40 #include <svx/svdview.hxx> 41 #include <svx/sdr/overlay/overlaymanager.hxx> 42 43 #include <sw_primitivetypes2d.hxx> 44 #include <drawinglayer/primitive2d/primitivetools2d.hxx> 45 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 46 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 47 #include <drawinglayer/primitive2d/shadowprimitive2d.hxx> 48 49 namespace sw { namespace sidebarwindows { 50 51 ////////////////////////////////////////////////////////////////////////////// 52 // helper class: Primitive for discrete visualisation 53 54 class AnchorPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D 55 { 56 private: 57 basegfx::B2DPolygon maTriangle; 58 basegfx::B2DPolygon maLine; 59 basegfx::B2DPolygon maLineTop; 60 const AnchorState maAnchorState; 61 basegfx::BColor maColor; 62 63 // discrete line width 64 double mfLogicLineWidth; 65 66 // bitfield 67 bool mbShadow : 1; 68 bool mbLineSolid : 1; 69 70 protected: 71 virtual drawinglayer::primitive2d::Primitive2DSequence create2DDecomposition( 72 const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; 73 74 public: 75 AnchorPrimitive( const basegfx::B2DPolygon& rTriangle, 76 const basegfx::B2DPolygon& rLine, 77 const basegfx::B2DPolygon& rLineTop, 78 AnchorState aAnchorState, 79 const basegfx::BColor& rColor, 80 double fLogicLineWidth, 81 bool bShadow, 82 bool bLineSolid ) 83 : drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D(), 84 maTriangle(rTriangle), 85 maLine(rLine), 86 maLineTop(rLineTop), 87 maAnchorState(aAnchorState), 88 maColor(rColor), 89 mfLogicLineWidth(fLogicLineWidth), 90 mbShadow(bShadow), 91 mbLineSolid(bLineSolid) 92 {} 93 94 // data access 95 const basegfx::B2DPolygon& getTriangle() const { return maTriangle; } 96 const basegfx::B2DPolygon& getLine() const { return maLine; } 97 const basegfx::B2DPolygon& getLineTop() const { return maLineTop; } 98 AnchorState getAnchorState() const { return maAnchorState; } 99 const basegfx::BColor& getColor() const { return maColor; } 100 double getLogicLineWidth() const { return mfLogicLineWidth; } 101 bool getShadow() const { return mbShadow; } 102 bool getLineSolid() const { return mbLineSolid; } 103 104 virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const; 105 106 DeclPrimitrive2DIDBlock() 107 }; 108 109 drawinglayer::primitive2d::Primitive2DSequence AnchorPrimitive::create2DDecomposition( 110 const drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/) const 111 { 112 drawinglayer::primitive2d::Primitive2DSequence aRetval; 113 114 if ( AS_TRI == maAnchorState || 115 AS_ALL == maAnchorState || 116 AS_START == maAnchorState ) 117 { 118 // create triangle 119 const drawinglayer::primitive2d::Primitive2DReference aTriangle( 120 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( 121 basegfx::B2DPolyPolygon(getTriangle()), 122 getColor())); 123 124 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aTriangle); 125 } 126 127 if ( AS_ALL == maAnchorState || 128 AS_START == maAnchorState ) 129 { 130 // create line start 131 const drawinglayer::attribute::LineAttribute aLineAttribute( 132 getColor(), 133 getLogicLineWidth() / (basegfx::fTools::equalZero(getDiscreteUnit()) ? 1.0 : getDiscreteUnit())); 134 135 if(getLineSolid()) 136 { 137 const drawinglayer::primitive2d::Primitive2DReference aSolidLine( 138 new drawinglayer::primitive2d::PolygonStrokePrimitive2D( 139 getLine(), 140 aLineAttribute)); 141 142 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aSolidLine); 143 } 144 else 145 { 146 ::std::vector< double > aDotDashArray; 147 const double fDistance(3.0 * 15.0); 148 const double fDashLen(5.0 * 15.0); 149 150 aDotDashArray.push_back(fDashLen); 151 aDotDashArray.push_back(fDistance); 152 153 const drawinglayer::attribute::StrokeAttribute aStrokeAttribute( 154 aDotDashArray, 155 fDistance + fDashLen); 156 157 const drawinglayer::primitive2d::Primitive2DReference aStrokedLine( 158 new drawinglayer::primitive2d::PolygonStrokePrimitive2D( 159 getLine(), 160 aLineAttribute, 161 aStrokeAttribute)); 162 163 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aStrokedLine); 164 } 165 } 166 167 if(aRetval.hasElements() && getShadow()) 168 { 169 // shadow is only for triangle and line start, and in upper left 170 // and lower right direction, in different colors 171 const double fColorChange(20.0 / 255.0); 172 const basegfx::B3DTuple aColorChange(fColorChange, fColorChange, fColorChange); 173 basegfx::BColor aLighterColor(getColor() + aColorChange); 174 basegfx::BColor aDarkerColor(getColor() - aColorChange); 175 176 aLighterColor.clamp(); 177 aDarkerColor.clamp(); 178 179 // create shadow sequence 180 drawinglayer::primitive2d::Primitive2DSequence aShadows(2); 181 basegfx::B2DHomMatrix aTransform; 182 183 aTransform.set(0, 2, -getDiscreteUnit()); 184 aTransform.set(1, 2, -getDiscreteUnit()); 185 186 aShadows[0] = drawinglayer::primitive2d::Primitive2DReference( 187 new drawinglayer::primitive2d::ShadowPrimitive2D( 188 aTransform, 189 aLighterColor, 190 aRetval)); 191 192 aTransform.set(0, 2, getDiscreteUnit()); 193 aTransform.set(1, 2, getDiscreteUnit()); 194 195 aShadows[1] = drawinglayer::primitive2d::Primitive2DReference( 196 new drawinglayer::primitive2d::ShadowPrimitive2D( 197 aTransform, 198 aDarkerColor, 199 aRetval)); 200 201 // add shadow before geometry to make it be proccessed first 202 const drawinglayer::primitive2d::Primitive2DSequence aTemporary(aRetval); 203 204 aRetval = aShadows; 205 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aTemporary); 206 } 207 208 if ( AS_ALL == maAnchorState || 209 AS_END == maAnchorState ) 210 { 211 // LineTop has to be created, too, but uses no shadow, so add after 212 // the other parts are created 213 const drawinglayer::attribute::LineAttribute aLineAttribute( 214 getColor(), 215 getLogicLineWidth() / (basegfx::fTools::equalZero(getDiscreteUnit()) ? 1.0 : getDiscreteUnit())); 216 217 const drawinglayer::primitive2d::Primitive2DReference aLineTop( 218 new drawinglayer::primitive2d::PolygonStrokePrimitive2D( 219 getLineTop(), 220 aLineAttribute)); 221 222 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aLineTop); 223 } 224 225 return aRetval; 226 } 227 228 bool AnchorPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const 229 { 230 if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) 231 { 232 const AnchorPrimitive& rCompare = static_cast< const AnchorPrimitive& >(rPrimitive); 233 234 return (getTriangle() == rCompare.getTriangle() 235 && getLine() == rCompare.getLine() 236 && getLineTop() == rCompare.getLineTop() 237 && getAnchorState() == rCompare.getAnchorState() 238 && getColor() == rCompare.getColor() 239 && getLogicLineWidth() == rCompare.getLogicLineWidth() 240 && getShadow() == rCompare.getShadow() 241 && getLineSolid() == rCompare.getLineSolid()); 242 } 243 244 return false; 245 } 246 247 ImplPrimitrive2DIDBlock(AnchorPrimitive, PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE) 248 249 /****** AnchorOverlayObject ***********************************************************/ 250 /*static*/ AnchorOverlayObject* AnchorOverlayObject::CreateAnchorOverlayObject( 251 SwView& rDocView, 252 const SwRect& aAnchorRect, 253 const long& aPageBorder, 254 const Point& aLineStart, 255 const Point& aLineEnd, 256 const Color& aColorAnchor ) 257 { 258 AnchorOverlayObject* pAnchorOverlayObject( 0 ); 259 if ( rDocView.GetDrawView() ) 260 { 261 SdrPaintWindow* pPaintWindow = rDocView.GetDrawView()->GetPaintWindow(0); 262 if( pPaintWindow ) 263 { 264 sdr::overlay::OverlayManager* pOverlayManager = pPaintWindow->GetOverlayManager(); 265 266 if ( pOverlayManager ) 267 { 268 pAnchorOverlayObject = new AnchorOverlayObject( 269 basegfx::B2DPoint( aAnchorRect.Left() , aAnchorRect.Bottom()-5*15), 270 basegfx::B2DPoint( aAnchorRect.Left()-5*15 , aAnchorRect.Bottom()+5*15), 271 basegfx::B2DPoint( aAnchorRect.Left()+5*15 , aAnchorRect.Bottom()+5*15), 272 basegfx::B2DPoint( aAnchorRect.Left(), aAnchorRect.Bottom()+2*15), 273 basegfx::B2DPoint( aPageBorder ,aAnchorRect.Bottom()+2*15), 274 basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()), 275 basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()) , 276 aColorAnchor, 277 false, 278 false); 279 pOverlayManager->add(*pAnchorOverlayObject); 280 } 281 } 282 } 283 284 return pAnchorOverlayObject; 285 } 286 287 /*static*/ void AnchorOverlayObject::DestroyAnchorOverlayObject( AnchorOverlayObject* pAnchor ) 288 { 289 if ( pAnchor ) 290 { 291 if ( pAnchor->getOverlayManager() ) 292 { 293 // remove this object from the chain 294 pAnchor->getOverlayManager()->remove(*pAnchor); 295 } 296 delete pAnchor; 297 } 298 } 299 300 AnchorOverlayObject::AnchorOverlayObject( const basegfx::B2DPoint& rBasePos, 301 const basegfx::B2DPoint& rSecondPos, 302 const basegfx::B2DPoint& rThirdPos, 303 const basegfx::B2DPoint& rFourthPos, 304 const basegfx::B2DPoint& rFifthPos, 305 const basegfx::B2DPoint& rSixthPos, 306 const basegfx::B2DPoint& rSeventhPos, 307 const Color aBaseColor, 308 const bool bShadowedEffect, 309 const bool bLineSolid) 310 : OverlayObjectWithBasePosition( rBasePos, aBaseColor ) 311 , maSecondPosition(rSecondPos) 312 , maThirdPosition(rThirdPos) 313 , maFourthPosition(rFourthPos) 314 , maFifthPosition(rFifthPos) 315 , maSixthPosition(rSixthPos) 316 , maSeventhPosition(rSeventhPos) 317 , maTriangle() 318 , maLine() 319 , maLineTop() 320 , mHeight(0) 321 , mAnchorState(AS_ALL) 322 , mbShadowedEffect(bShadowedEffect) 323 , mbLineSolid(bLineSolid) 324 { 325 } 326 327 AnchorOverlayObject::~AnchorOverlayObject() 328 { 329 } 330 331 void AnchorOverlayObject::implEnsureGeometry() 332 { 333 if(!maTriangle.count()) 334 { 335 maTriangle.append(getBasePosition()); 336 maTriangle.append(GetSecondPosition()); 337 maTriangle.append(GetThirdPosition()); 338 maTriangle.setClosed(true); 339 } 340 341 if(!maLine.count()) 342 { 343 maLine.append(GetFourthPosition()); 344 maLine.append(GetFifthPosition()); 345 maLine.append(GetSixthPosition()); 346 } 347 348 if(!maLineTop.count()) 349 { 350 maLineTop.append(GetSixthPosition()); 351 maLineTop.append(GetSeventhPosition()); 352 } 353 } 354 355 void AnchorOverlayObject::implResetGeometry() 356 { 357 maTriangle.clear(); 358 maLine.clear(); 359 maLineTop.clear(); 360 } 361 362 drawinglayer::primitive2d::Primitive2DSequence AnchorOverlayObject::createOverlayObjectPrimitive2DSequence() 363 { 364 implEnsureGeometry(); 365 366 const drawinglayer::primitive2d::Primitive2DReference aReference( 367 new AnchorPrimitive( maTriangle, 368 maLine, 369 maLineTop, 370 GetAnchorState(), 371 getBaseColor().getBColor(), 372 ANCHORLINE_WIDTH * 15.0, 373 getShadowedEffect(), 374 getLineSolid()) ); 375 376 return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); 377 } 378 379 void AnchorOverlayObject::SetAllPosition( const basegfx::B2DPoint& rPoint1, 380 const basegfx::B2DPoint& rPoint2, 381 const basegfx::B2DPoint& rPoint3, 382 const basegfx::B2DPoint& rPoint4, 383 const basegfx::B2DPoint& rPoint5, 384 const basegfx::B2DPoint& rPoint6, 385 const basegfx::B2DPoint& rPoint7) 386 { 387 if ( rPoint1 != getBasePosition() || 388 rPoint2 != GetSecondPosition() || 389 rPoint3 != GetThirdPosition() || 390 rPoint4 != GetFourthPosition() || 391 rPoint5 != GetFifthPosition() || 392 rPoint6 != GetSixthPosition() || 393 rPoint7 != GetSeventhPosition() ) 394 { 395 maBasePosition = rPoint1; 396 maSecondPosition = rPoint2; 397 maThirdPosition = rPoint3; 398 maFourthPosition = rPoint4; 399 maFifthPosition = rPoint5; 400 maSixthPosition = rPoint6; 401 maSeventhPosition = rPoint7; 402 403 implResetGeometry(); 404 objectChange(); 405 } 406 } 407 408 void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint& rNew) 409 { 410 if(rNew != maSixthPosition) 411 { 412 maSixthPosition = rNew; 413 implResetGeometry(); 414 objectChange(); 415 } 416 } 417 418 void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint& rNew) 419 { 420 if(rNew != maSeventhPosition) 421 { 422 maSeventhPosition = rNew; 423 implResetGeometry(); 424 objectChange(); 425 } 426 } 427 428 void AnchorOverlayObject::SetTriPosition(const basegfx::B2DPoint& rPoint1,const basegfx::B2DPoint& rPoint2,const basegfx::B2DPoint& rPoint3, 429 const basegfx::B2DPoint& rPoint4,const basegfx::B2DPoint& rPoint5) 430 { 431 if(rPoint1 != getBasePosition() 432 || rPoint2 != GetSecondPosition() 433 || rPoint3 != GetThirdPosition() 434 || rPoint4 != GetFourthPosition() 435 || rPoint5 != GetFifthPosition()) 436 { 437 maBasePosition = rPoint1; 438 maSecondPosition = rPoint2; 439 maThirdPosition = rPoint3; 440 maFourthPosition = rPoint4; 441 maFifthPosition = rPoint5; 442 443 implResetGeometry(); 444 objectChange(); 445 } 446 } 447 448 void AnchorOverlayObject::setLineSolid( const bool bNew ) 449 { 450 if ( bNew != getLineSolid() ) 451 { 452 mbLineSolid = bNew; 453 objectChange(); 454 } 455 } 456 457 void AnchorOverlayObject::SetAnchorState( const AnchorState aState) 458 { 459 if ( mAnchorState != aState) 460 { 461 mAnchorState = aState; 462 objectChange(); 463 } 464 } 465 466 } } // end of namespace sw::annotation 467 468