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_chart2.hxx"
26 #include "DragMethod_RotateDiagram.hxx"
27
28 #include "SelectionHelper.hxx"
29 #include "CommonConverters.hxx"
30 #include "ChartModelHelper.hxx"
31 #include "macros.hxx"
32 #include "DiagramHelper.hxx"
33 #include "ChartTypeHelper.hxx"
34 #include "ThreeDHelper.hxx"
35 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
36 #include <svx/sdr/overlay/overlaymanager.hxx>
37
38 // header for class E3dScene
39 #include <svx/scene3d.hxx>
40 #include <basegfx/matrix/b3dhommatrix.hxx>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <basegfx/polygon/b2dpolypolygontools.hxx>
43 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
44 #include <drawinglayer/geometry/viewinformation3d.hxx>
45
46 #define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0)
47
48 //.............................................................................
49 namespace chart
50 {
51 //.............................................................................
52
53 using namespace ::com::sun::star;
54 using ::com::sun::star::uno::Reference;
55
DragMethod_RotateDiagram(DrawViewWrapper & rDrawViewWrapper,const rtl::OUString & rObjectCID,const Reference<frame::XModel> & xChartModel,RotationDirection eRotationDirection)56 DragMethod_RotateDiagram::DragMethod_RotateDiagram( DrawViewWrapper& rDrawViewWrapper
57 , const rtl::OUString& rObjectCID
58 , const Reference< frame::XModel >& xChartModel
59 , RotationDirection eRotationDirection )
60 : DragMethod_Base( rDrawViewWrapper, rObjectCID, xChartModel, ActionDescriptionProvider::ROTATE )
61 , m_pScene(0)
62 , m_aReferenceRect(100,100,100,100)
63 , m_aStartPos(0,0)
64 , m_aWireframePolyPolygon()
65 , m_fInitialXAngleRad(0.0)
66 , m_fInitialYAngleRad(0.0)
67 , m_fInitialZAngleRad(0.0)
68 , m_fAdditionalXAngleRad(0.0)
69 , m_fAdditionalYAngleRad(0.0)
70 , m_fAdditionalZAngleRad(0.0)
71 , m_nInitialHorizontalAngleDegree(0)
72 , m_nInitialVerticalAngleDegree(0)
73 , m_nAdditionalHorizontalAngleDegree(0)
74 , m_nAdditionalVerticalAngleDegree(0)
75 , m_eRotationDirection(eRotationDirection)
76 , m_bRightAngledAxes(sal_False)
77 {
78 m_pScene = SelectionHelper::getSceneToRotate( rDrawViewWrapper.getNamedSdrObject( rObjectCID ) );
79 SdrObject* pObj = rDrawViewWrapper.getSelectedObject();
80 if(pObj && m_pScene)
81 {
82 m_aReferenceRect = pObj->GetLogicRect();
83 Rectangle aTemp = m_pScene->GetLogicRect();
84
85 m_aWireframePolyPolygon = m_pScene->CreateWireframe();
86
87 uno::Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram(this->getChartModel()) );
88 uno::Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY );
89 if( xDiagramProperties.is() )
90 {
91 ThreeDHelper::getRotationFromDiagram( xDiagramProperties
92 , m_nInitialHorizontalAngleDegree, m_nInitialVerticalAngleDegree );
93
94 ThreeDHelper::getRotationAngleFromDiagram( xDiagramProperties
95 , m_fInitialXAngleRad, m_fInitialYAngleRad, m_fInitialZAngleRad );
96
97 if( ChartTypeHelper::isSupportingRightAngledAxes(
98 DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
99 xDiagramProperties->getPropertyValue(C2U( "RightAngledAxes" )) >>= m_bRightAngledAxes;
100 if(m_bRightAngledAxes)
101 {
102 if( m_eRotationDirection==ROTATIONDIRECTION_Z )
103 m_eRotationDirection=ROTATIONDIRECTION_FREE;
104 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fInitialXAngleRad, m_fInitialYAngleRad );
105 }
106 }
107 }
108 }
~DragMethod_RotateDiagram()109 DragMethod_RotateDiagram::~DragMethod_RotateDiagram()
110 {
111 }
TakeSdrDragComment(String &) const112 void DragMethod_RotateDiagram::TakeSdrDragComment(String& /*rStr*/) const
113 {
114 }
BeginSdrDrag()115 bool DragMethod_RotateDiagram::BeginSdrDrag()
116 {
117 m_aStartPos = DragStat().GetStart();
118 Show();
119 return true;
120 }
MoveSdrDrag(const Point & rPnt)121 void DragMethod_RotateDiagram::MoveSdrDrag(const Point& rPnt)
122 {
123 if( DragStat().CheckMinMoved(rPnt) )
124 {
125 Hide();
126
127 //calculate new angle
128 double fX = F_PI / 2.0 * (double)(rPnt.Y() - m_aStartPos.Y())
129 / (double)m_aReferenceRect.GetHeight();
130 double fY = F_PI * (double)(rPnt.X() - m_aStartPos.X())
131 / (double)m_aReferenceRect.GetWidth();
132
133 if( m_eRotationDirection != ROTATIONDIRECTION_Y )
134 m_fAdditionalYAngleRad = fY;
135 else
136 m_fAdditionalYAngleRad = 0.0;
137 if( m_eRotationDirection != ROTATIONDIRECTION_X )
138 m_fAdditionalXAngleRad = fX;
139 else
140 m_fAdditionalXAngleRad = 0.0;
141 m_fAdditionalZAngleRad = 0.0;
142
143 if( m_eRotationDirection == ROTATIONDIRECTION_Z )
144 {
145 m_fAdditionalXAngleRad = 0.0;
146 m_fAdditionalYAngleRad = 0.0;
147
148 double fCx = m_aReferenceRect.Center().X();
149 double fCy = m_aReferenceRect.Center().Y();
150
151 m_fAdditionalZAngleRad = atan((double)(fCx - m_aStartPos.X())/(m_aStartPos.Y()-fCy))
152 + atan((double)(fCx - rPnt.X())/(fCy-rPnt.Y()));
153 }
154
155 m_nAdditionalHorizontalAngleDegree = static_cast<sal_Int32>(m_fAdditionalXAngleRad*180.0/F_PI);
156 m_nAdditionalVerticalAngleDegree = -static_cast<sal_Int32>(m_fAdditionalYAngleRad*180.0/F_PI);
157
158 DragStat().NextMove(rPnt);
159 Show();
160 }
161 }
EndSdrDrag(bool)162 bool DragMethod_RotateDiagram::EndSdrDrag(bool /*bCopy*/)
163 {
164 Hide();
165
166 if( m_bRightAngledAxes || m_eRotationDirection==ROTATIONDIRECTION_Z )
167 {
168 double fResultX = m_fInitialXAngleRad + m_fAdditionalXAngleRad;
169 double fResultY = m_fInitialYAngleRad + m_fAdditionalYAngleRad;
170 double fResultZ = m_fInitialZAngleRad + m_fAdditionalZAngleRad;
171
172 if(m_bRightAngledAxes)
173 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fResultX, fResultY );
174
175 ThreeDHelper::setRotationAngleToDiagram( uno::Reference< beans::XPropertySet >( ChartModelHelper::findDiagram( this->getChartModel() ), uno::UNO_QUERY )
176 , fResultX, fResultY, fResultZ );
177 }
178 else
179 {
180 ThreeDHelper::setRotationToDiagram( ( uno::Reference< beans::XPropertySet >( ChartModelHelper::findDiagram( this->getChartModel() ), uno::UNO_QUERY ) )
181 , m_nInitialHorizontalAngleDegree+m_nAdditionalHorizontalAngleDegree, m_nInitialVerticalAngleDegree+m_nAdditionalVerticalAngleDegree );
182 }
183
184 return true;
185 }
CreateOverlayGeometry(sdr::overlay::OverlayManager & rOverlayManager)186 void DragMethod_RotateDiagram::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
187 {
188 ::basegfx::B3DHomMatrix aCurrentTransform;
189 aCurrentTransform.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
190 -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
191 -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
192
193 double fResultX = m_fInitialXAngleRad + m_fAdditionalXAngleRad;
194 double fResultY = m_fInitialYAngleRad + m_fAdditionalYAngleRad;
195 double fResultZ = m_fInitialZAngleRad + m_fAdditionalZAngleRad;
196
197 if(!m_bRightAngledAxes)
198 {
199 if( m_eRotationDirection!=ROTATIONDIRECTION_Z )
200 {
201 ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
202 m_nInitialHorizontalAngleDegree+m_nAdditionalHorizontalAngleDegree, -(m_nInitialVerticalAngleDegree+m_nAdditionalVerticalAngleDegree)
203 , fResultX, fResultY, fResultZ );
204 }
205 aCurrentTransform.rotate( fResultX, fResultY, fResultZ );
206 }
207 else
208 {
209 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fResultX, fResultY );
210 aCurrentTransform.shearXY(fResultY,-(fResultX));
211 }
212
213 if(m_aWireframePolyPolygon.count() && m_pScene)
214 {
215 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(m_pScene->GetViewContact());
216 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
217 const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation());
218 const basegfx::B3DHomMatrix aTransform(aWorldToView * aCurrentTransform);
219
220 // transform to relative scene coordinates
221 basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(m_aWireframePolyPolygon, aTransform));
222
223 // transform to 2D view coordinates
224 aPolyPolygon.transform(rVCScene.getObjectTransformation());
225
226 sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled(
227 aPolyPolygon);
228 rOverlayManager.add(*pNew);
229 addToOverlayObjectList(*pNew);
230 }
231 }
232 //.............................................................................
233 } //namespace chart
234 //.............................................................................
235