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 "VCartesianGrid.hxx"
21 #include "Tickmarks.hxx"
22 #include "PlottingPositionHelper.hxx"
23 #include "ShapeFactory.hxx"
24 #include "ObjectIdentifier.hxx"
26 #include "CommonConverters.hxx"
27 #include "AxisHelper.hxx"
28 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
29 #include <com/sun/star/drawing/LineStyle.hpp>
32 #include <boost/scoped_ptr.hpp>
36 using namespace ::com::sun::star
;
37 using namespace ::com::sun::star::chart2
;
38 using ::com::sun::star::uno::Reference
;
39 using ::com::sun::star::uno::Sequence
;
43 Sequence
< double > P0
;
44 Sequence
< double > P1
;
45 Sequence
< double > P2
;
47 GridLinePoints( const PlottingPositionHelper
* pPosHelper
, sal_Int32 nDimensionIndex
48 , CuboidPlanePosition eLeftWallPos
=CuboidPlanePosition_Left
49 , CuboidPlanePosition eBackWallPos
=CuboidPlanePosition_Back
50 , CuboidPlanePosition eBottomPos
=CuboidPlanePosition_Bottom
);
51 void update( double fScaledTickValue
);
53 sal_Int32 m_nDimensionIndex
;
56 GridLinePoints::GridLinePoints( const PlottingPositionHelper
* pPosHelper
, sal_Int32 nDimensionIndex
57 , CuboidPlanePosition eLeftWallPos
58 , CuboidPlanePosition eBackWallPos
59 , CuboidPlanePosition eBottomPos
)
60 : m_nDimensionIndex(nDimensionIndex
)
62 double MinX
= pPosHelper
->getLogicMinX();
63 double MinY
= pPosHelper
->getLogicMinY();
64 double MinZ
= pPosHelper
->getLogicMinZ();
65 double MaxX
= pPosHelper
->getLogicMaxX();
66 double MaxY
= pPosHelper
->getLogicMaxY();
67 double MaxZ
= pPosHelper
->getLogicMaxZ();
69 pPosHelper
->doLogicScaling( &MinX
,&MinY
,&MinZ
);
70 pPosHelper
->doLogicScaling( &MaxX
,&MaxY
,&MaxZ
);
72 if(!pPosHelper
->isMathematicalOrientationX())
78 if(!pPosHelper
->isMathematicalOrientationY())
84 if(pPosHelper
->isMathematicalOrientationZ())//z axis in draw is reverse to mathematical
90 bool bSwapXY
= pPosHelper
->isSwapXAndY();
96 //P0: point on 'back' wall, not on 'left' wall
97 //P1: point on both walls
98 //P2: point on 'left' wall not on 'back' wall
100 P0
[0]=P1
[0]=P2
[0]= (CuboidPlanePosition_Left
== eLeftWallPos
|| bSwapXY
) ? MinX
: MaxX
;
101 P0
[1]=P1
[1]=P2
[1]= (CuboidPlanePosition_Left
== eLeftWallPos
|| !bSwapXY
) ? MinY
: MaxY
;
102 P0
[2]=P1
[2]=P2
[2]= (CuboidPlanePosition_Back
== eBackWallPos
) ? MinZ
: MaxZ
;
104 if(m_nDimensionIndex
==0)
106 P0
[1]= (CuboidPlanePosition_Left
== eLeftWallPos
|| !bSwapXY
) ? MaxY
: MinY
;
107 P2
[2]= (CuboidPlanePosition_Back
== eBackWallPos
) ? MaxZ
: MinZ
;
108 if( CuboidPlanePosition_Bottom
!= eBottomPos
&& !bSwapXY
)
111 else if(m_nDimensionIndex
==1)
113 P0
[0]= (CuboidPlanePosition_Left
== eLeftWallPos
|| bSwapXY
) ? MaxX
: MinX
;
114 P2
[2]= (CuboidPlanePosition_Back
== eBackWallPos
) ? MaxZ
: MinZ
;
115 if( CuboidPlanePosition_Bottom
!= eBottomPos
&& bSwapXY
)
118 else if(m_nDimensionIndex
==2)
120 P0
[0]= (CuboidPlanePosition_Left
== eLeftWallPos
|| bSwapXY
) ? MaxX
: MinX
;
121 P2
[1]= (CuboidPlanePosition_Left
== eLeftWallPos
|| !bSwapXY
) ? MaxY
: MinY
;
122 if( CuboidPlanePosition_Bottom
!= eBottomPos
)
132 void GridLinePoints::update( double fScaledTickValue
)
134 P0
[m_nDimensionIndex
] = P1
[m_nDimensionIndex
] = P2
[m_nDimensionIndex
] = fScaledTickValue
;
137 void addLine2D( drawing::PointSequenceSequence
& rPoints
, sal_Int32 nIndex
138 , const GridLinePoints
& rScaledLogicPoints
139 , const Reference
< XTransformation
> & xTransformation
142 drawing::Position3D aPA
= SequenceToPosition3D( xTransformation
->transform( rScaledLogicPoints
.P0
) );
143 drawing::Position3D aPB
= SequenceToPosition3D( xTransformation
->transform( rScaledLogicPoints
.P1
) );
145 rPoints
[nIndex
].realloc(2);
146 rPoints
[nIndex
][0].X
= static_cast<sal_Int32
>(aPA
.PositionX
);
147 rPoints
[nIndex
][0].Y
= static_cast<sal_Int32
>(aPA
.PositionY
);
148 rPoints
[nIndex
][1].X
= static_cast<sal_Int32
>(aPB
.PositionX
);
149 rPoints
[nIndex
][1].Y
= static_cast<sal_Int32
>(aPB
.PositionY
);
152 void addLine3D( drawing::PolyPolygonShape3D
& rPoints
, sal_Int32 nIndex
153 , const GridLinePoints
& rBasePoints
154 , const Reference
< XTransformation
> & xTransformation
)
156 drawing::Position3D aPoint
= SequenceToPosition3D( xTransformation
->transform( rBasePoints
.P0
) );
157 AddPointToPoly( rPoints
, aPoint
, nIndex
);
158 aPoint
= SequenceToPosition3D( xTransformation
->transform( rBasePoints
.P1
) );
159 AddPointToPoly( rPoints
, aPoint
, nIndex
);
160 aPoint
= SequenceToPosition3D( xTransformation
->transform( rBasePoints
.P2
) );
161 AddPointToPoly( rPoints
, aPoint
, nIndex
);
164 VCartesianGrid::VCartesianGrid( sal_Int32 nDimensionIndex
, sal_Int32 nDimensionCount
165 , const Sequence
< Reference
< beans::XPropertySet
> > & rGridPropertiesList
)
166 : VAxisOrGridBase( nDimensionIndex
, nDimensionCount
)
167 , m_aGridPropertiesList( rGridPropertiesList
)
169 m_pPosHelper
= new PlottingPositionHelper();
172 VCartesianGrid::~VCartesianGrid()
178 void VCartesianGrid::fillLinePropertiesFromGridModel( ::std::vector
<VLineProperties
>& rLinePropertiesList
179 , const Sequence
< Reference
< beans::XPropertySet
> > & rGridPropertiesList
)
181 rLinePropertiesList
.clear();
182 if( !rGridPropertiesList
.getLength() )
185 VLineProperties aLineProperties
;
186 for( sal_Int32 nN
=0; nN
< rGridPropertiesList
.getLength(); nN
++ )
188 if(!AxisHelper::isGridVisible( rGridPropertiesList
[nN
] ))
189 aLineProperties
.LineStyle
= uno::makeAny( drawing::LineStyle_NONE
);
191 aLineProperties
.initFromPropertySet( rGridPropertiesList
[nN
] );
192 rLinePropertiesList
.push_back(aLineProperties
);
196 void VCartesianGrid::createShapes()
198 if(!m_aGridPropertiesList
.getLength())
200 //somehow equal to axis tickmarks
202 //create named group shape
203 Reference
< drawing::XShapes
> xGroupShape_Shapes(
204 this->createGroupShape( m_xLogicTarget
, m_aCID
) );
206 if(!xGroupShape_Shapes
.is())
209 ::std::vector
<VLineProperties
> aLinePropertiesList
;
210 fillLinePropertiesFromGridModel( aLinePropertiesList
, m_aGridPropertiesList
);
212 //create all scaled tickmark values
213 boost::scoped_ptr
< TickFactory
> apTickFactory( this->createTickFactory() );
214 TickFactory
& aTickFactory
= *apTickFactory
.get();
215 TickInfoArraysType aAllTickInfos
;
216 aTickFactory
.getAllTicks( aAllTickInfos
);
218 //create tick mark line shapes
219 TickInfoArraysType::iterator aDepthIter
= aAllTickInfos
.begin();
220 const TickInfoArraysType::const_iterator aDepthEnd
= aAllTickInfos
.end();
222 if(aDepthIter
== aDepthEnd
)//no tickmarks at all
225 sal_Int32 nLinePropertiesCount
= aLinePropertiesList
.size();
226 for( sal_Int32 nDepth
=0
227 ; aDepthIter
!= aDepthEnd
&& nDepth
< nLinePropertiesCount
228 ; ++aDepthIter
, nDepth
++ )
230 if( !aLinePropertiesList
[nDepth
].isLineVisible() )
233 Reference
< drawing::XShapes
> xTarget( xGroupShape_Shapes
);
236 xTarget
.set( this->createGroupShape( m_xLogicTarget
237 , ObjectIdentifier::addChildParticle( m_aCID
, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_SUBGRID
, nDepth
-1 ) )
240 xTarget
.set( xGroupShape_Shapes
);
246 GridLinePoints
aGridLinePoints( m_pPosHelper
, m_nDimensionIndex
);
248 sal_Int32 nPointCount
= (*aDepthIter
).size();
249 drawing::PointSequenceSequence
aPoints(nPointCount
);
251 TickInfoArrayType::const_iterator aTickIter
= (*aDepthIter
).begin();
252 const TickInfoArrayType::const_iterator aTickEnd
= (*aDepthIter
).end();
253 sal_Int32 nRealPointCount
= 0;
254 for( ; aTickIter
!= aTickEnd
; ++aTickIter
)
256 if( !(*aTickIter
).bPaintIt
)
258 aGridLinePoints
.update( (*aTickIter
).fScaledTickValue
);
259 addLine2D( aPoints
, nRealPointCount
, aGridLinePoints
, m_pPosHelper
->getTransformationScaledLogicToScene() );
262 aPoints
.realloc(nRealPointCount
);
263 m_pShapeFactory
->createLine2D( xTarget
, aPoints
, &aLinePropertiesList
[nDepth
] );
265 //prepare polygon for handle shape:
266 drawing::PointSequenceSequence
aHandlesPoints(1);
267 sal_Int32 nOldHandleCount
= aHandlesPoints
[0].getLength();
268 aHandlesPoints
[0].realloc(nOldHandleCount
+nRealPointCount
);
269 for( sal_Int32 nN
= 0; nN
<nRealPointCount
; nN
++)
270 aHandlesPoints
[0][nOldHandleCount
+nN
] = aPoints
[nN
][1];
272 //create handle shape:
273 VLineProperties aHandleLineProperties
;
274 aHandleLineProperties
.LineStyle
= uno::makeAny( drawing::LineStyle_NONE
);
275 Reference
< drawing::XShape
> xHandleShape
=
276 m_pShapeFactory
->createLine2D( xTarget
, aHandlesPoints
, &aHandleLineProperties
);
277 ::chart::AbstractShapeFactory::setShapeName( xHandleShape
, "HandlesOnly" );
279 else //if(2!=m_nDimension)
281 GridLinePoints
aGridLinePoints( m_pPosHelper
, m_nDimensionIndex
, m_eLeftWallPos
, m_eBackWallPos
, m_eBottomPos
);
283 sal_Int32 nPointCount
= (*aDepthIter
).size();
284 drawing::PolyPolygonShape3D aPoints
;
285 aPoints
.SequenceX
.realloc(nPointCount
);
286 aPoints
.SequenceY
.realloc(nPointCount
);
287 aPoints
.SequenceZ
.realloc(nPointCount
);
289 TickInfoArrayType::const_iterator aTickIter
= (*aDepthIter
).begin();
290 const TickInfoArrayType::const_iterator aTickEnd
= (*aDepthIter
).end();
291 sal_Int32 nRealPointCount
= 0;
292 sal_Int32 nPolyIndex
= 0;
293 for( ; aTickIter
!= aTickEnd
; ++aTickIter
, ++nPolyIndex
)
295 if( !(*aTickIter
).bPaintIt
)
298 aGridLinePoints
.update( (*aTickIter
).fScaledTickValue
);
299 addLine3D( aPoints
, nPolyIndex
, aGridLinePoints
, m_pPosHelper
->getTransformationScaledLogicToScene() );
302 aPoints
.SequenceX
.realloc(nRealPointCount
);
303 aPoints
.SequenceY
.realloc(nRealPointCount
);
304 aPoints
.SequenceZ
.realloc(nRealPointCount
);
305 m_pShapeFactory
->createLine3D( xTarget
, aPoints
, aLinePropertiesList
[nDepth
] );
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */