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 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 } 109 DragMethod_RotateDiagram::~DragMethod_RotateDiagram() 110 { 111 } 112 void DragMethod_RotateDiagram::TakeSdrDragComment(String& /*rStr*/) const 113 { 114 } 115 bool DragMethod_RotateDiagram::BeginSdrDrag() 116 { 117 m_aStartPos = DragStat().GetStart(); 118 Show(); 119 return true; 120 } 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 } 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 } 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::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aPolyPolygon); 227 rOverlayManager.add(*pNew); 228 addToOverlayObjectList(*pNew); 229 } 230 } 231 //............................................................................. 232 } //namespace chart 233 //............................................................................. 234