Line data Source code
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 <svx/xoutbmp.hxx>
21 : #include <svx/dialogs.hrc>
22 : #include <svx/svxids.hrc>
23 : #include <contwnd.hxx>
24 : #include <svx/svdpage.hxx>
25 : #include <svx/svdopath.hxx>
26 : #include <svx/xfltrit.hxx>
27 : #include <svx/xfillit.hxx>
28 : #include <basegfx/polygon/b2dpolygon.hxx>
29 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
30 : #include "svx/sdrpaintwindow.hxx"
31 :
32 : using namespace css;
33 :
34 : #define TRANSCOL Color(COL_WHITE)
35 :
36 0 : ContourWindow::ContourWindow(vcl::Window* pParent, WinBits nBits)
37 : : GraphCtrl (pParent, nBits)
38 : , aWorkRect(0, 0, 0, 0)
39 : , bPipetteMode(false)
40 : , bWorkplaceMode(false)
41 0 : , bClickValid(false)
42 : {
43 0 : SetWinStyle(WB_SDRMODE);
44 0 : }
45 :
46 0 : void ContourWindow::SetPolyPolygon(const tools::PolyPolygon& rPolyPoly)
47 : {
48 0 : SdrPage* pPage = pModel->GetPage(0);
49 0 : const sal_uInt16 nPolyCount = rPolyPoly.Count();
50 :
51 : // First delete all drawing objects
52 0 : aPolyPoly = rPolyPoly;
53 :
54 : // To avoid to have destroyed objects which are still selected, it is necessary to deselect
55 : // them first (!)
56 0 : pView->UnmarkAllObj();
57 :
58 0 : pPage->Clear();
59 :
60 0 : for (sal_uInt16 i = 0; i < nPolyCount; i++)
61 : {
62 0 : basegfx::B2DPolyPolygon aPolyPolygon;
63 0 : aPolyPolygon.append(aPolyPoly[ i ].getB2DPolygon());
64 0 : SdrPathObj* pPathObj = new SdrPathObj( OBJ_PATHFILL, aPolyPolygon );
65 :
66 0 : SfxItemSet aSet(pModel->GetItemPool());
67 :
68 0 : aSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
69 0 : aSet.Put(XFillColorItem("", TRANSCOL));
70 0 : aSet.Put(XFillTransparenceItem(50) );
71 :
72 0 : pPathObj->SetMergedItemSetAndBroadcast(aSet);
73 :
74 0 : pPage->InsertObject( pPathObj );
75 0 : }
76 :
77 0 : if (nPolyCount)
78 : {
79 0 : pView->MarkAll();
80 0 : pView->CombineMarkedObjects(false);
81 : }
82 :
83 0 : pModel->SetChanged(false);
84 0 : }
85 :
86 0 : const tools::PolyPolygon& ContourWindow::GetPolyPolygon()
87 : {
88 0 : if ( pModel->IsChanged() )
89 : {
90 0 : SdrPage* pPage = pModel->GetPage( 0 );
91 :
92 0 : aPolyPoly = tools::PolyPolygon();
93 :
94 0 : if ( pPage && pPage->GetObjCount() )
95 : {
96 0 : SdrPathObj* pPathObj = static_cast<SdrPathObj*>(pPage->GetObj(0));
97 : // Not sure if subdivision is needed for ContourWindow, but maybe it cannot handle
98 : // curves at all. Keeping subdivision here for security
99 0 : const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(pPathObj->GetPathPoly()));
100 0 : aPolyPoly = tools::PolyPolygon(aB2DPolyPolygon);
101 : }
102 :
103 0 : pModel->SetChanged( false );
104 : }
105 :
106 0 : return aPolyPoly;
107 : }
108 :
109 0 : void ContourWindow::InitSdrModel()
110 : {
111 0 : GraphCtrl::InitSdrModel();
112 :
113 0 : SfxItemSet aSet( pModel->GetItemPool() );
114 :
115 0 : aSet.Put( XFillColorItem( "", TRANSCOL ) );
116 0 : aSet.Put( XFillTransparenceItem( 50 ) );
117 0 : pView->SetAttributes( aSet );
118 0 : pView->SetFrameDragSingles( true );
119 0 : }
120 :
121 0 : void ContourWindow::SdrObjCreated( const SdrObject& )
122 : {
123 0 : pView->MarkAll();
124 0 : pView->CombineMarkedObjects( false );
125 0 : }
126 :
127 0 : bool ContourWindow::IsContourChanged() const
128 : {
129 0 : SdrPage* pPage = pModel->GetPage( 0 );
130 0 : bool bRet = false;
131 :
132 0 : if ( pPage && pPage->GetObjCount() )
133 0 : bRet = static_cast<SdrPathObj*>( pPage->GetObj( 0 ) )->GetPathPoly().count() && pModel->IsChanged();
134 :
135 0 : return bRet;
136 : }
137 :
138 0 : void ContourWindow::MouseButtonDown( const MouseEvent& rMEvt )
139 : {
140 0 : if ( bWorkplaceMode )
141 : {
142 0 : const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
143 :
144 0 : SetPolyPolygon( tools::PolyPolygon() );
145 0 : aWorkRect = Rectangle( aLogPt, aLogPt );
146 0 : Invalidate(Rectangle(Point(), GetGraphicSize()));
147 0 : SetEditMode( true );
148 : }
149 :
150 0 : if ( !bPipetteMode )
151 0 : GraphCtrl::MouseButtonDown( rMEvt );
152 0 : }
153 :
154 0 : void ContourWindow::MouseMove( const MouseEvent& rMEvt )
155 : {
156 0 : bClickValid = false;
157 :
158 0 : if ( bPipetteMode )
159 : {
160 0 : const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
161 :
162 0 : aPipetteColor = GetPixel( aLogPt );
163 0 : Control::MouseMove( rMEvt );
164 :
165 0 : if ( aPipetteLink.IsSet() && Rectangle( Point(), GetGraphicSize() ).IsInside( aLogPt ) )
166 : {
167 0 : SetPointer( PointerStyle::RefHand );
168 0 : aPipetteLink.Call( this );
169 : }
170 : }
171 : else
172 0 : GraphCtrl::MouseMove( rMEvt );
173 0 : }
174 :
175 0 : void ContourWindow::MouseButtonUp(const MouseEvent& rMEvt)
176 : {
177 0 : Point aTmpPoint;
178 0 : const Rectangle aGraphRect( aTmpPoint, GetGraphicSize() );
179 0 : const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
180 :
181 0 : bClickValid = aGraphRect.IsInside( aLogPt );
182 0 : ReleaseMouse();
183 :
184 0 : if ( bPipetteMode )
185 : {
186 0 : Control::MouseButtonUp( rMEvt );
187 :
188 0 : if ( aPipetteClickLink.IsSet() )
189 0 : aPipetteClickLink.Call( this );
190 : }
191 0 : else if ( bWorkplaceMode )
192 : {
193 0 : GraphCtrl::MouseButtonUp( rMEvt );
194 :
195 0 : aWorkRect.Right() = aLogPt.X();
196 0 : aWorkRect.Bottom() = aLogPt.Y();
197 0 : aWorkRect.Intersection( aGraphRect );
198 0 : aWorkRect.Justify();
199 :
200 0 : if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() )
201 : {
202 0 : tools::PolyPolygon _aPolyPoly( GetPolyPolygon() );
203 :
204 0 : _aPolyPoly.Clip( aWorkRect );
205 0 : SetPolyPolygon( _aPolyPoly );
206 0 : pView->SetWorkArea( aWorkRect );
207 : }
208 : else
209 0 : pView->SetWorkArea( aGraphRect );
210 :
211 0 : Invalidate( aGraphRect );
212 :
213 0 : if ( aWorkplaceClickLink.IsSet() )
214 0 : aWorkplaceClickLink.Call( this );
215 : }
216 : else
217 0 : GraphCtrl::MouseButtonUp( rMEvt );
218 0 : }
219 :
220 0 : void ContourWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
221 : {
222 : // #i75482#
223 : // encapsulate the redraw using Begin/End and use the returned
224 : // data to get the target output device (e.g. when pre-rendering)
225 0 : SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(&rRenderContext);
226 0 : OutputDevice& rTarget = pPaintWindow->GetTargetOutputDevice();
227 :
228 0 : const Graphic& rGraphic = GetGraphic();
229 0 : rTarget.Push(PushFlags::LINECOLOR |PushFlags::FILLCOLOR);
230 0 : rTarget.SetLineColor(Color(COL_BLACK));
231 0 : rTarget.SetFillColor(Color(COL_WHITE));
232 0 : rTarget.DrawRect( Rectangle( Point(), GetGraphicSize() ) );
233 0 : rTarget.Pop();
234 :
235 0 : if (rGraphic.GetType() != GRAPHIC_NONE)
236 0 : rGraphic.Draw(&rTarget, Point(), GetGraphicSize());
237 :
238 0 : if (aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom())
239 : {
240 0 : tools::PolyPolygon _aPolyPoly(2, 2);
241 0 : rTarget.Push(PushFlags::FILLCOLOR);
242 0 : _aPolyPoly.Insert(Rectangle(Point(), GetGraphicSize()));
243 0 : _aPolyPoly.Insert(aWorkRect);
244 0 : rTarget.SetFillColor(COL_LIGHTRED);
245 0 : rTarget.DrawTransparent(_aPolyPoly, 50);
246 0 : rTarget.Pop();
247 : }
248 :
249 : // #i75482#
250 0 : const vcl::Region aRepaintRegion(rRect);
251 0 : pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion);
252 0 : pView->EndCompleteRedraw(*pPaintWindow, true);
253 0 : }
254 :
255 0 : Size ContourWindow::GetOptimalSize() const
256 : {
257 0 : return LogicToPixel(Size(270, 170), MAP_APPFONT);
258 390 : }
259 :
260 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|