1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 #include <svx/xoutbmp.hxx> 27 #include <svx/dialogs.hrc> 28 #include <svx/svxids.hrc> 29 #include <contdlg.hrc> 30 #include <contwnd.hxx> 31 #include <svx/svdpage.hxx> 32 #include <svx/svdopath.hxx> 33 #include <svx/xfltrit.hxx> 34 #include <svx/xfillit.hxx> 35 #include <basegfx/polygon/b2dpolygon.hxx> 36 #include <basegfx/polygon/b2dpolypolygontools.hxx> 37 38 // #i75482# 39 #include "svx/sdrpaintwindow.hxx" 40 41 #define TRANSCOL Color( COL_WHITE ) 42 43 /************************************************************************* 44 |* 45 |* 46 |* 47 \************************************************************************/ 48 49 ContourWindow::ContourWindow( Window* pParent, const ResId& rResId ) : 50 GraphCtrl ( pParent, rResId ), 51 aWorkRect ( 0, 0, 0, 0 ), 52 bPipetteMode ( sal_False ), 53 bWorkplaceMode ( sal_False ), 54 bClickValid ( sal_False ) 55 { 56 SetWinStyle( WB_SDRMODE ); 57 } 58 59 60 /************************************************************************* 61 |* 62 |* 63 |* 64 \************************************************************************/ 65 66 ContourWindow::~ContourWindow() 67 { 68 } 69 70 71 /************************************************************************* 72 |* 73 |* 74 |* 75 \************************************************************************/ 76 77 void ContourWindow::SetPolyPolygon( const PolyPolygon& rPolyPoly ) 78 { 79 SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 ); 80 const sal_uInt16 nPolyCount = rPolyPoly.Count(); 81 82 // zuerst alle Zeichenobjekte loeschen 83 aPolyPoly = rPolyPoly; 84 85 // #117412# 86 // To avoid to have destroyed objects which are still selected, it is necessary to deselect 87 // them first (!) 88 pView->UnmarkAllObj(); 89 90 pPage->Clear(); 91 92 for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 93 { 94 basegfx::B2DPolyPolygon aPolyPolygon; 95 aPolyPolygon.append(aPolyPoly[ i ].getB2DPolygon()); 96 SdrPathObj* pPathObj = new SdrPathObj( OBJ_PATHFILL, aPolyPolygon ); 97 98 if ( pPathObj ) 99 { 100 SfxItemSet aSet( pModel->GetItemPool() ); 101 102 aSet.Put( XFillStyleItem( XFILL_SOLID ) ); 103 aSet.Put( XFillColorItem( String(), TRANSCOL ) ); 104 aSet.Put( XFillTransparenceItem( 50 ) ); 105 106 //pPathObj->SetItemSetAndBroadcast(aSet); 107 pPathObj->SetMergedItemSetAndBroadcast(aSet); 108 109 pPage->InsertObject( pPathObj ); 110 } 111 } 112 113 if ( nPolyCount ) 114 { 115 pView->MarkAll(); 116 pView->CombineMarkedObjects( sal_False ); 117 } 118 119 pModel->SetChanged( sal_False ); 120 } 121 122 123 /************************************************************************* 124 |* 125 |* 126 |* 127 \************************************************************************/ 128 129 const PolyPolygon& ContourWindow::GetPolyPolygon() 130 { 131 if ( pModel->IsChanged() ) 132 { 133 SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 ); 134 135 aPolyPoly = PolyPolygon(); 136 137 if ( pPage && pPage->GetObjCount() ) 138 { 139 SdrPathObj* pPathObj = (SdrPathObj*)pPage->GetObj(0L); 140 // Not sure if subdivision is needed for ContourWindow, but maybe it cannot handle 141 // curves at all. Keeping subdivision here for security 142 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(pPathObj->GetPathPoly())); 143 aPolyPoly = PolyPolygon(aB2DPolyPolygon); 144 } 145 146 pModel->SetChanged( sal_False ); 147 } 148 149 return aPolyPoly; 150 } 151 152 153 /************************************************************************* 154 |* 155 |* 156 |* 157 \************************************************************************/ 158 159 void ContourWindow::InitSdrModel() 160 { 161 GraphCtrl::InitSdrModel(); 162 163 SfxItemSet aSet( pModel->GetItemPool() ); 164 165 aSet.Put( XFillColorItem( String(), TRANSCOL ) ); 166 aSet.Put( XFillTransparenceItem( 50 ) ); 167 pView->SetAttributes( aSet ); 168 pView->SetFrameDragSingles( sal_True ); 169 } 170 171 172 /************************************************************************* 173 |* 174 |* 175 |* 176 \************************************************************************/ 177 178 void ContourWindow::SdrObjCreated( const SdrObject& ) 179 { 180 pView->MarkAll(); 181 pView->CombineMarkedObjects( sal_False ); 182 } 183 184 185 /************************************************************************* 186 |* 187 |* 188 |* 189 \************************************************************************/ 190 191 sal_Bool ContourWindow::IsContourChanged() const 192 { 193 SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 ); 194 sal_Bool bRet = sal_False; 195 196 if ( pPage && pPage->GetObjCount() ) 197 bRet = ( (SdrPathObj*) pPage->GetObj( 0 ) )->GetPathPoly().count() && pModel->IsChanged(); 198 199 return bRet; 200 } 201 202 203 /************************************************************************* 204 |* 205 |* 206 |* 207 \************************************************************************/ 208 209 void ContourWindow::MouseButtonDown( const MouseEvent& rMEvt ) 210 { 211 if ( bWorkplaceMode ) 212 { 213 const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) ); 214 215 SetPolyPolygon( PolyPolygon() ); 216 aWorkRect = Rectangle( aLogPt, aLogPt ); 217 Paint( Rectangle( Point(), GetGraphicSize() ) ); 218 SetEditMode( sal_True ); 219 } 220 221 if ( !bPipetteMode ) 222 GraphCtrl::MouseButtonDown( rMEvt ); 223 } 224 225 226 /************************************************************************* 227 |* 228 |* 229 |* 230 \************************************************************************/ 231 232 void ContourWindow::MouseMove( const MouseEvent& rMEvt ) 233 { 234 bClickValid = sal_False; 235 236 if ( bPipetteMode ) 237 { 238 const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) ); 239 240 aPipetteColor = GetPixel( aLogPt ); 241 Control::MouseMove( rMEvt ); 242 243 if ( aPipetteLink.IsSet() && Rectangle( Point(), GetGraphicSize() ).IsInside( aLogPt ) ) 244 { 245 SetPointer( POINTER_REFHAND ); 246 aPipetteLink.Call( this ); 247 } 248 } 249 else 250 GraphCtrl::MouseMove( rMEvt ); 251 } 252 253 254 /************************************************************************* 255 |* 256 |* 257 |* 258 \************************************************************************/ 259 260 void ContourWindow::MouseButtonUp(const MouseEvent& rMEvt) 261 { 262 Point aTmpPoint; 263 const Rectangle aGraphRect( aTmpPoint, GetGraphicSize() ); 264 const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) ); 265 266 bClickValid = aGraphRect.IsInside( aLogPt ); 267 ReleaseMouse(); 268 269 if ( bPipetteMode ) 270 { 271 Control::MouseButtonUp( rMEvt ); 272 273 if ( aPipetteClickLink.IsSet() ) 274 aPipetteClickLink.Call( this ); 275 } 276 else if ( bWorkplaceMode ) 277 { 278 GraphCtrl::MouseButtonUp( rMEvt ); 279 280 aWorkRect.Right() = aLogPt.X(); 281 aWorkRect.Bottom() = aLogPt.Y(); 282 aWorkRect.Intersection( aGraphRect ); 283 aWorkRect.Justify(); 284 285 if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() ) 286 { 287 PolyPolygon _aPolyPoly( GetPolyPolygon() ); 288 289 _aPolyPoly.Clip( aWorkRect ); 290 SetPolyPolygon( _aPolyPoly ); 291 pView->SetWorkArea( aWorkRect ); 292 } 293 else 294 pView->SetWorkArea( aGraphRect ); 295 296 Invalidate( aGraphRect ); 297 298 if ( aWorkplaceClickLink.IsSet() ) 299 aWorkplaceClickLink.Call( this ); 300 } 301 else 302 GraphCtrl::MouseButtonUp( rMEvt ); 303 } 304 305 306 /************************************************************************* 307 |* 308 |* 309 |* 310 \************************************************************************/ 311 312 void ContourWindow::Paint( const Rectangle& rRect ) 313 { 314 // #i75482# 315 // encapsulate the redraw using Begin/End and use the returned 316 // data to get the target output device (e.g. when pre-rendering) 317 SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(this); 318 OutputDevice& rTarget = pPaintWindow->GetTargetOutputDevice(); 319 320 const Graphic& rGraphic = GetGraphic(); 321 const Color& rOldLineColor = GetLineColor(); 322 const Color& rOldFillColor = GetFillColor(); 323 324 rTarget.SetLineColor( Color( COL_BLACK ) ); 325 rTarget.SetFillColor( Color( COL_WHITE ) ); 326 327 rTarget.DrawRect( Rectangle( Point(), GetGraphicSize() ) ); 328 329 rTarget.SetLineColor( rOldLineColor ); 330 rTarget.SetFillColor( rOldFillColor ); 331 332 if ( rGraphic.GetType() != GRAPHIC_NONE ) 333 rGraphic.Draw( &rTarget, Point(), GetGraphicSize() ); 334 335 if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() ) 336 { 337 PolyPolygon _aPolyPoly( 2, 2 ); 338 const Color aOldFillColor( GetFillColor() ); 339 340 _aPolyPoly.Insert( Rectangle( Point(), GetGraphicSize() ) ); 341 _aPolyPoly.Insert( aWorkRect ); 342 343 rTarget.SetFillColor( COL_LIGHTRED ); 344 rTarget.DrawTransparent( _aPolyPoly, 50 ); 345 rTarget.SetFillColor( aOldFillColor ); 346 } 347 348 // #i75482# 349 const Region aRepaintRegion(rRect); 350 pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion); 351 pView->EndCompleteRedraw(*pPaintWindow, true); 352 } 353 354 // eof 355