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 "contwnd.hxx"
21 #include <svx/svdpage.hxx>
22 #include <svx/svdopath.hxx>
23 #include <svx/xfillit0.hxx>
24 #include <svx/xfltrit.hxx>
25 #include <svx/xflclit.hxx>
26 #include <basegfx/polygon/b2dpolypolygontools.hxx>
27 #include <svx/sdrpaintwindow.hxx>
28 #include <vcl/ptrstyle.hxx>
32 #define TRANSCOL COL_WHITE
34 ContourWindow::ContourWindow(weld::Dialog
* pDialog
)
36 , aWorkRect(0, 0, 0, 0)
38 , bWorkplaceMode(false)
43 void ContourWindow::SetPolyPolygon(const tools::PolyPolygon
& rPolyPoly
)
45 SdrPage
* pPage
= pModel
->GetPage(0);
46 const sal_uInt16 nPolyCount
= rPolyPoly
.Count();
48 // First delete all drawing objects
49 aPolyPoly
= rPolyPoly
;
51 // To avoid to have destroyed objects which are still selected, it is necessary to deselect
53 pView
->UnmarkAllObj();
55 // clear SdrObjects with broadcasting
56 pPage
->ClearSdrObjList();
58 for (sal_uInt16 i
= 0; i
< nPolyCount
; i
++)
60 basegfx::B2DPolyPolygon aPolyPolygon
;
61 aPolyPolygon
.append(aPolyPoly
[ i
].getB2DPolygon());
62 rtl::Reference
<SdrPathObj
> pPathObj
= new SdrPathObj(
65 std::move(aPolyPolygon
));
67 SfxItemSet
aSet(pModel
->GetItemPool());
69 aSet
.Put(XFillStyleItem(drawing::FillStyle_SOLID
));
70 aSet
.Put(XFillColorItem(u
""_ustr
, TRANSCOL
));
71 aSet
.Put(XFillTransparenceItem(50) );
73 pPathObj
->SetMergedItemSetAndBroadcast(aSet
);
75 pPage
->InsertObject( pPathObj
.get() );
81 pView
->CombineMarkedObjects(false);
84 pModel
->SetChanged(false);
87 const tools::PolyPolygon
& ContourWindow::GetPolyPolygon()
89 if ( pModel
->IsChanged() )
91 SdrPage
* pPage
= pModel
->GetPage( 0 );
93 aPolyPoly
= tools::PolyPolygon();
95 if ( pPage
&& pPage
->GetObjCount() )
97 SdrPathObj
* pPathObj
= static_cast<SdrPathObj
*>(pPage
->GetObj(0));
98 // Not sure if subdivision is needed for ContourWindow, but maybe it cannot handle
99 // curves at all. Keeping subdivision here for security
100 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(basegfx::utils::adaptiveSubdivideByAngle(pPathObj
->GetPathPoly()));
101 aPolyPoly
= tools::PolyPolygon(aB2DPolyPolygon
);
104 pModel
->SetChanged( false );
110 void ContourWindow::InitSdrModel()
112 GraphCtrl::InitSdrModel();
114 SfxItemSet
aSet( pModel
->GetItemPool() );
116 aSet
.Put( XFillColorItem( u
""_ustr
, TRANSCOL
) );
117 aSet
.Put( XFillTransparenceItem( 50 ) );
118 pView
->SetAttributes( aSet
);
119 pView
->SetFrameDragSingles();
122 void ContourWindow::SdrObjCreated( const SdrObject
& )
125 pView
->CombineMarkedObjects( false );
128 bool ContourWindow::IsContourChanged() const
130 SdrPage
* pPage
= pModel
->GetPage( 0 );
133 if ( pPage
&& pPage
->GetObjCount() )
134 bRet
= static_cast<SdrPathObj
*>( pPage
->GetObj( 0 ) )->GetPathPoly().count() && pModel
->IsChanged();
139 bool ContourWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
141 if ( bWorkplaceMode
)
143 const Point
aLogPt(GetDrawingArea()->get_ref_device().PixelToLogic(rMEvt
.GetPosPixel()));
145 SetPolyPolygon( tools::PolyPolygon() );
146 aWorkRect
= tools::Rectangle( aLogPt
, aLogPt
);
147 Invalidate(tools::Rectangle(Point(), GetGraphicSize()));
152 return GraphCtrl::MouseButtonDown( rMEvt
);
157 bool ContourWindow::MouseMove( const MouseEvent
& rMEvt
)
163 const Point
aLogPt( GetDrawingArea()->get_ref_device().PixelToLogic( rMEvt
.GetPosPixel() ) );
165 aPipetteColor
= GetDrawingArea()->get_ref_device().GetPixel( aLogPt
);
166 weld::CustomWidgetController::MouseMove( rMEvt
);
168 if ( aPipetteLink
.IsSet() && tools::Rectangle( Point(), GetGraphicSize() ).Contains( aLogPt
) )
170 SetPointer( PointerStyle::RefHand
);
171 aPipetteLink
.Call( *this );
177 return GraphCtrl::MouseMove( rMEvt
);
180 bool ContourWindow::MouseButtonUp(const MouseEvent
& rMEvt
)
182 const tools::Rectangle
aGraphRect( Point(), GetGraphicSize() );
183 const Point
aLogPt( GetDrawingArea()->get_ref_device().PixelToLogic( rMEvt
.GetPosPixel() ) );
185 bClickValid
= aGraphRect
.Contains( aLogPt
);
190 weld::CustomWidgetController::MouseButtonUp( rMEvt
);
192 aPipetteClickLink
.Call( *this );
196 else if ( bWorkplaceMode
)
198 GraphCtrl::MouseButtonUp( rMEvt
);
200 aWorkRect
.SetRight( aLogPt
.X() );
201 aWorkRect
.SetBottom( aLogPt
.Y() );
202 aWorkRect
.Intersection( aGraphRect
);
203 aWorkRect
.Normalize();
205 if ( aWorkRect
.Left() != aWorkRect
.Right() && aWorkRect
.Top() != aWorkRect
.Bottom() )
207 tools::PolyPolygon
_aPolyPoly( GetPolyPolygon() );
209 _aPolyPoly
.Clip( aWorkRect
);
210 SetPolyPolygon( _aPolyPoly
);
211 pView
->SetWorkArea( aWorkRect
);
214 pView
->SetWorkArea( aGraphRect
);
216 Invalidate( aGraphRect
);
218 aWorkplaceClickLink
.Call( *this );
223 return GraphCtrl::MouseButtonUp( rMEvt
);
226 void ContourWindow::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
229 // encapsulate the redraw using Begin/End and use the returned
230 // data to get the target output device (e.g. when pre-rendering)
231 SdrPaintWindow
* pPaintWindow
= pView
->BeginCompleteRedraw(&rRenderContext
);
232 pPaintWindow
->SetOutputToWindow(true);
233 OutputDevice
& rTarget
= pPaintWindow
->GetTargetOutputDevice();
235 const Graphic
& rGraphic
= GetGraphic();
236 rTarget
.Push(vcl::PushFlags::LINECOLOR
|vcl::PushFlags::FILLCOLOR
);
237 rTarget
.SetLineColor(COL_BLACK
);
238 rTarget
.SetFillColor(COL_WHITE
);
239 rTarget
.DrawRect( tools::Rectangle( Point(), GetGraphicSize() ) );
242 if (rGraphic
.GetType() != GraphicType::NONE
)
243 rGraphic
.Draw(rTarget
, Point(), GetGraphicSize());
245 if (aWorkRect
.Left() != aWorkRect
.Right() && aWorkRect
.Top() != aWorkRect
.Bottom())
247 tools::PolyPolygon
_aPolyPoly(2);
248 rTarget
.Push(vcl::PushFlags::FILLCOLOR
);
249 _aPolyPoly
.Insert(tools::Polygon(tools::Rectangle(Point(), GetGraphicSize())));
250 _aPolyPoly
.Insert(tools::Polygon(aWorkRect
));
251 rTarget
.SetFillColor(COL_LIGHTRED
);
252 rTarget
.DrawTransparent(_aPolyPoly
, 50);
257 const vcl::Region
aRepaintRegion(rRect
);
258 pView
->DoCompleteRedraw(*pPaintWindow
, aRepaintRegion
);
259 pView
->EndCompleteRedraw(*pPaintWindow
, true);
262 void ContourWindow::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
264 GraphCtrl::SetDrawingArea(pDrawingArea
);
265 Size
aSize(pDrawingArea
->get_ref_device().LogicToPixel(Size(270, 170), MapMode(MapUnit::MapAppFont
)));
266 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
267 SetOutputSizePixel(aSize
);
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */