1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "DragMethod_RotateDiagram.hxx"
31 #include "SelectionHelper.hxx"
32 #include "CommonConverters.hxx"
33 #include "ChartModelHelper.hxx"
35 #include "DiagramHelper.hxx"
36 #include "ChartTypeHelper.hxx"
37 #include "ThreeDHelper.hxx"
38 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
39 #include <svx/sdr/overlay/overlaymanager.hxx>
41 // header for class E3dScene
42 #include <svx/scene3d.hxx>
43 #include <basegfx/matrix/b3dhommatrix.hxx>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <basegfx/polygon/b2dpolypolygontools.hxx>
46 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
47 #include <drawinglayer/geometry/viewinformation3d.hxx>
49 #define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0)
51 //.............................................................................
54 //.............................................................................
56 using namespace ::com::sun::star
;
57 using ::com::sun::star::uno::Reference
;
59 DragMethod_RotateDiagram::DragMethod_RotateDiagram( DrawViewWrapper
& rDrawViewWrapper
60 , const rtl::OUString
& rObjectCID
61 , const Reference
< frame::XModel
>& xChartModel
62 , RotationDirection eRotationDirection
)
63 : DragMethod_Base( rDrawViewWrapper
, rObjectCID
, xChartModel
, ActionDescriptionProvider::ROTATE
)
65 , m_aReferenceRect(100,100,100,100)
67 , m_aWireframePolyPolygon()
68 , m_fInitialXAngleRad(0.0)
69 , m_fInitialYAngleRad(0.0)
70 , m_fInitialZAngleRad(0.0)
71 , m_fAdditionalXAngleRad(0.0)
72 , m_fAdditionalYAngleRad(0.0)
73 , m_fAdditionalZAngleRad(0.0)
74 , m_nInitialHorizontalAngleDegree(0)
75 , m_nInitialVerticalAngleDegree(0)
76 , m_nAdditionalHorizontalAngleDegree(0)
77 , m_nAdditionalVerticalAngleDegree(0)
78 , m_eRotationDirection(eRotationDirection
)
79 , m_bRightAngledAxes(sal_False
)
81 m_pScene
= SelectionHelper::getSceneToRotate( rDrawViewWrapper
.getNamedSdrObject( rObjectCID
) );
82 SdrObject
* pObj
= rDrawViewWrapper
.getSelectedObject();
85 m_aReferenceRect
= pObj
->GetLogicRect();
87 m_aWireframePolyPolygon
= m_pScene
->CreateWireframe();
89 uno::Reference
< chart2::XDiagram
> xDiagram( ChartModelHelper::findDiagram(this->getChartModel()) );
90 uno::Reference
< beans::XPropertySet
> xDiagramProperties( xDiagram
, uno::UNO_QUERY
);
91 if( xDiagramProperties
.is() )
93 ThreeDHelper::getRotationFromDiagram( xDiagramProperties
94 , m_nInitialHorizontalAngleDegree
, m_nInitialVerticalAngleDegree
);
96 ThreeDHelper::getRotationAngleFromDiagram( xDiagramProperties
97 , m_fInitialXAngleRad
, m_fInitialYAngleRad
, m_fInitialZAngleRad
);
99 if( ChartTypeHelper::isSupportingRightAngledAxes(
100 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
101 xDiagramProperties
->getPropertyValue(C2U( "RightAngledAxes" )) >>= m_bRightAngledAxes
;
102 if(m_bRightAngledAxes
)
104 if( m_eRotationDirection
==ROTATIONDIRECTION_Z
)
105 m_eRotationDirection
=ROTATIONDIRECTION_FREE
;
106 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fInitialXAngleRad
, m_fInitialYAngleRad
);
111 DragMethod_RotateDiagram::~DragMethod_RotateDiagram()
114 void DragMethod_RotateDiagram::TakeSdrDragComment(String
& /*rStr*/) const
117 bool DragMethod_RotateDiagram::BeginSdrDrag()
119 m_aStartPos
= DragStat().GetStart();
123 void DragMethod_RotateDiagram::MoveSdrDrag(const Point
& rPnt
)
125 if( DragStat().CheckMinMoved(rPnt
) )
129 //calculate new angle
130 double fX
= F_PI
/ 2.0 * (double)(rPnt
.Y() - m_aStartPos
.Y())
131 / (double)m_aReferenceRect
.GetHeight();
132 double fY
= F_PI
* (double)(rPnt
.X() - m_aStartPos
.X())
133 / (double)m_aReferenceRect
.GetWidth();
135 if( m_eRotationDirection
!= ROTATIONDIRECTION_Y
)
136 m_fAdditionalYAngleRad
= fY
;
138 m_fAdditionalYAngleRad
= 0.0;
139 if( m_eRotationDirection
!= ROTATIONDIRECTION_X
)
140 m_fAdditionalXAngleRad
= fX
;
142 m_fAdditionalXAngleRad
= 0.0;
143 m_fAdditionalZAngleRad
= 0.0;
145 if( m_eRotationDirection
== ROTATIONDIRECTION_Z
)
147 m_fAdditionalXAngleRad
= 0.0;
148 m_fAdditionalYAngleRad
= 0.0;
150 double fCx
= m_aReferenceRect
.Center().X();
151 double fCy
= m_aReferenceRect
.Center().Y();
153 m_fAdditionalZAngleRad
= atan((double)(fCx
- m_aStartPos
.X())/(m_aStartPos
.Y()-fCy
))
154 + atan((double)(fCx
- rPnt
.X())/(fCy
-rPnt
.Y()));
157 m_nAdditionalHorizontalAngleDegree
= static_cast<sal_Int32
>(m_fAdditionalXAngleRad
*180.0/F_PI
);
158 m_nAdditionalVerticalAngleDegree
= -static_cast<sal_Int32
>(m_fAdditionalYAngleRad
*180.0/F_PI
);
160 DragStat().NextMove(rPnt
);
164 bool DragMethod_RotateDiagram::EndSdrDrag(bool /*bCopy*/)
168 if( m_bRightAngledAxes
|| m_eRotationDirection
==ROTATIONDIRECTION_Z
)
170 double fResultX
= m_fInitialXAngleRad
+ m_fAdditionalXAngleRad
;
171 double fResultY
= m_fInitialYAngleRad
+ m_fAdditionalYAngleRad
;
172 double fResultZ
= m_fInitialZAngleRad
+ m_fAdditionalZAngleRad
;
174 if(m_bRightAngledAxes
)
175 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fResultX
, fResultY
);
177 ThreeDHelper::setRotationAngleToDiagram( uno::Reference
< beans::XPropertySet
>( ChartModelHelper::findDiagram( this->getChartModel() ), uno::UNO_QUERY
)
178 , fResultX
, fResultY
, fResultZ
);
182 ThreeDHelper::setRotationToDiagram( ( uno::Reference
< beans::XPropertySet
>( ChartModelHelper::findDiagram( this->getChartModel() ), uno::UNO_QUERY
) )
183 , m_nInitialHorizontalAngleDegree
+m_nAdditionalHorizontalAngleDegree
, m_nInitialVerticalAngleDegree
+m_nAdditionalVerticalAngleDegree
);
188 void DragMethod_RotateDiagram::CreateOverlayGeometry(sdr::overlay::OverlayManager
& rOverlayManager
)
190 ::basegfx::B3DHomMatrix aCurrentTransform
;
191 aCurrentTransform
.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
192 -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
193 -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0 );
195 double fResultX
= m_fInitialXAngleRad
+ m_fAdditionalXAngleRad
;
196 double fResultY
= m_fInitialYAngleRad
+ m_fAdditionalYAngleRad
;
197 double fResultZ
= m_fInitialZAngleRad
+ m_fAdditionalZAngleRad
;
199 if(!m_bRightAngledAxes
)
201 if( m_eRotationDirection
!=ROTATIONDIRECTION_Z
)
203 ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
204 m_nInitialHorizontalAngleDegree
+m_nAdditionalHorizontalAngleDegree
, -(m_nInitialVerticalAngleDegree
+m_nAdditionalVerticalAngleDegree
)
205 , fResultX
, fResultY
, fResultZ
);
207 aCurrentTransform
.rotate( fResultX
, fResultY
, fResultZ
);
211 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fResultX
, fResultY
);
212 aCurrentTransform
.shearXY(fResultY
,-(fResultX
));
215 if(m_aWireframePolyPolygon
.count() && m_pScene
)
217 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(m_pScene
->GetViewContact());
218 const drawinglayer::geometry::ViewInformation3D
aViewInfo3D(rVCScene
.getViewInformation3D());
219 const basegfx::B3DHomMatrix
aWorldToView(aViewInfo3D
.getDeviceToView() * aViewInfo3D
.getProjection() * aViewInfo3D
.getOrientation());
220 const basegfx::B3DHomMatrix
aTransform(aWorldToView
* aCurrentTransform
);
222 // transform to relative scene coordinates
223 basegfx::B2DPolyPolygon
aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(m_aWireframePolyPolygon
, aTransform
));
225 // transform to 2D view coordinates
226 aPolyPolygon
.transform(rVCScene
.getObjectTransformation());
228 sdr::overlay::OverlayPolyPolygonStriped
* pNew
= new ::sdr::overlay::OverlayPolyPolygonStriped(aPolyPolygon
);
229 rOverlayManager
.add(*pNew
);
230 addToOverlayObjectList(*pNew
);
233 //.............................................................................
235 //.............................................................................
237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */