Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <grid.hrc>
30 : : #include <cstdio>
31 : : #include <math.h> // for M_LN10 and M_E
32 : :
33 : : #define _USE_MATH_DEFINES
34 : : #include <cmath>
35 : : #undef _USE_MATH_DEFINES
36 : :
37 : : #include <grid.hxx>
38 : :
39 : : // for ::std::sort
40 : : #include <algorithm>
41 : :
42 : : ResId SaneResId( sal_uInt32 );
43 : :
44 : : /***********************************************************************
45 : : *
46 : : * GridWindow
47 : : *
48 : : ***********************************************************************/
49 : :
50 : : // ---------------------------------------------------------------------
51 : :
52 : 0 : GridWindow::GridWindow(double* pXValues, double* pYValues, int nValues, Window* pParent, sal_Bool bCutValues )
53 : : : ModalDialog( pParent, SaneResId( GRID_DIALOG ) ),
54 : : m_aGridArea( 50, 15, 100, 100 ),
55 : : m_pXValues( pXValues ),
56 : : m_pOrigYValues( pYValues ),
57 : : m_nValues( nValues ),
58 : : m_pNewYValues( NULL ),
59 : : m_bCutValues( bCutValues ),
60 : : m_aHandles(),
61 : : m_nDragIndex( 0xffffffff ),
62 : : m_aMarkerBitmap( Bitmap( SaneResId( GRID_DIALOG_HANDLE_BMP ) ), Color( 255, 255, 255 ) ),
63 : : m_aOKButton( this, SaneResId( GRID_DIALOG_OK_BTN ) ),
64 : : m_aCancelButton( this, SaneResId( GRID_DIALOG_CANCEL_BTN ) ),
65 : : m_aResetTypeBox( this, SaneResId( GRID_DIALOG_TYPE_BOX ) ),
66 [ # # ][ # # ]: 0 : m_aResetButton( this, SaneResId( GRID_DIALOG_RESET_BTN ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
67 : : {
68 [ # # ][ # # ]: 0 : sal_uInt16 nPos = m_aResetTypeBox.InsertEntry( String( SaneResId( RESET_TYPE_LINEAR_ASCENDING ) ) );
[ # # ][ # # ]
69 [ # # ]: 0 : m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_LINEAR_ASCENDING );
70 : :
71 [ # # ][ # # ]: 0 : nPos = m_aResetTypeBox.InsertEntry( String( SaneResId( RESET_TYPE_LINEAR_DESCENDING ) ) );
[ # # ][ # # ]
72 [ # # ]: 0 : m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_LINEAR_DESCENDING );
73 : :
74 [ # # ][ # # ]: 0 : nPos = m_aResetTypeBox.InsertEntry( String( SaneResId( RESET_TYPE_RESET ) ) );
[ # # ][ # # ]
75 [ # # ]: 0 : m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_RESET );
76 : :
77 [ # # ][ # # ]: 0 : nPos = m_aResetTypeBox.InsertEntry( String( SaneResId( RESET_TYPE_EXPONENTIAL ) ) );
[ # # ][ # # ]
78 [ # # ]: 0 : m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_EXPONENTIAL );
79 : :
80 [ # # ]: 0 : m_aResetTypeBox.SelectEntryPos( 0 );
81 : :
82 [ # # ]: 0 : m_aResetButton.SetClickHdl( LINK( this, GridWindow, ClickButtonHdl ) );
83 : :
84 [ # # ][ # # ]: 0 : SetMapMode( MapMode( MAP_PIXEL ) );
[ # # ]
85 : 0 : Size aSize = GetOutputSizePixel();
86 : 0 : Size aBtnSize = m_aOKButton.GetOutputSizePixel();
87 : 0 : m_aGridArea.setWidth( aSize.Width() - aBtnSize.Width() - 80 );
88 : 0 : m_aGridArea.setHeight( aSize.Height() - 40 );
89 : :
90 [ # # ][ # # ]: 0 : if( m_pOrigYValues && m_nValues )
91 : : {
92 [ # # ]: 0 : m_pNewYValues = new double[ m_nValues ];
93 : 0 : memcpy( m_pNewYValues, m_pOrigYValues, sizeof( double ) * m_nValues );
94 : : }
95 : :
96 : 0 : setBoundings( 0, 0, 1023, 1023 );
97 [ # # ]: 0 : computeExtremes();
98 : :
99 : : // create left and right marker as first and last entry
100 : 0 : m_BmOffX = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Width() >> 1);
101 : 0 : m_BmOffY = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Height() >> 1);
102 [ # # ][ # # ]: 0 : m_aHandles.push_back(impHandle(transform(findMinX(), findMinY()), m_BmOffX, m_BmOffY));
103 [ # # ][ # # ]: 0 : m_aHandles.push_back(impHandle(transform(findMaxX(), findMaxY()), m_BmOffX, m_BmOffY));
104 : :
105 [ # # ]: 0 : FreeResource();
106 : 0 : }
107 : :
108 : : // ---------------------------------------------------------------------
109 : :
110 [ # # ][ # # ]: 0 : GridWindow::~GridWindow()
[ # # ][ # # ]
[ # # ]
111 : : {
112 [ # # ]: 0 : if( m_pNewYValues )
113 [ # # ]: 0 : delete [] m_pNewYValues;
114 [ # # ]: 0 : }
115 : :
116 : : // ---------------------------------------------------------------------
117 : :
118 : 0 : double GridWindow::findMinX()
119 : : {
120 [ # # ]: 0 : if( ! m_pXValues )
121 : 0 : return 0.0;
122 : 0 : double fMin = m_pXValues[0];
123 [ # # ]: 0 : for( int i = 1; i < m_nValues; i++ )
124 [ # # ]: 0 : if( m_pXValues[ i ] < fMin )
125 : 0 : fMin = m_pXValues[ i ];
126 : 0 : return fMin;
127 : : }
128 : :
129 : : // ---------------------------------------------------------------------
130 : :
131 : 0 : double GridWindow::findMinY()
132 : : {
133 [ # # ]: 0 : if( ! m_pNewYValues )
134 : 0 : return 0.0;
135 : 0 : double fMin = m_pNewYValues[0];
136 [ # # ]: 0 : for( int i = 1; i < m_nValues; i++ )
137 [ # # ]: 0 : if( m_pNewYValues[ i ] < fMin )
138 : 0 : fMin = m_pNewYValues[ i ];
139 : 0 : return fMin;
140 : : }
141 : :
142 : : // ---------------------------------------------------------------------
143 : :
144 : 0 : double GridWindow::findMaxX()
145 : : {
146 [ # # ]: 0 : if( ! m_pXValues )
147 : 0 : return 0.0;
148 : 0 : double fMax = m_pXValues[0];
149 [ # # ]: 0 : for( int i = 1; i < m_nValues; i++ )
150 [ # # ]: 0 : if( m_pXValues[ i ] > fMax )
151 : 0 : fMax = m_pXValues[ i ];
152 : 0 : return fMax;
153 : : }
154 : :
155 : : // ---------------------------------------------------------------------
156 : :
157 : 0 : double GridWindow::findMaxY()
158 : : {
159 [ # # ]: 0 : if( ! m_pNewYValues )
160 : 0 : return 0.0;
161 : 0 : double fMax = m_pNewYValues[0];
162 [ # # ]: 0 : for( int i = 1; i < m_nValues; i++ )
163 [ # # ]: 0 : if( m_pNewYValues[ i ] > fMax )
164 : 0 : fMax = m_pNewYValues[ i ];
165 : 0 : return fMax;
166 : : }
167 : :
168 : : // ---------------------------------------------------------------------
169 : :
170 : 0 : void GridWindow::computeExtremes()
171 : : {
172 [ # # ][ # # ]: 0 : if( m_nValues && m_pXValues && m_pOrigYValues )
[ # # ]
173 : : {
174 : 0 : m_fMaxX = m_fMinX = m_pXValues[0];
175 : 0 : m_fMaxY = m_fMinY = m_pOrigYValues[0];
176 [ # # ]: 0 : for( int i = 1; i < m_nValues; i++ )
177 : : {
178 [ # # ]: 0 : if( m_pXValues[ i ] > m_fMaxX )
179 : 0 : m_fMaxX = m_pXValues[ i ];
180 [ # # ]: 0 : else if( m_pXValues[ i ] < m_fMinX )
181 : 0 : m_fMinX = m_pXValues[ i ];
182 [ # # ]: 0 : if( m_pOrigYValues[ i ] > m_fMaxY )
183 : 0 : m_fMaxY = m_pOrigYValues[ i ];
184 [ # # ]: 0 : else if( m_pOrigYValues[ i ] < m_fMinY )
185 : 0 : m_fMinY = m_pOrigYValues[ i ];
186 : : }
187 : 0 : setBoundings( m_fMinX, m_fMinY, m_fMaxX, m_fMaxY );
188 : : }
189 : 0 : }
190 : :
191 : : // ---------------------------------------------------------------------
192 : :
193 : 0 : Point GridWindow::transform( double x, double y )
194 : : {
195 : 0 : Point aRet;
196 : :
197 : 0 : aRet.X() = (long)( ( x - m_fMinX ) *
198 : 0 : (double)m_aGridArea.GetWidth() / ( m_fMaxX - m_fMinX )
199 : 0 : + m_aGridArea.Left() );
200 : 0 : aRet.Y() = (long)(
201 : 0 : m_aGridArea.Bottom() -
202 : : ( y - m_fMinY ) *
203 : 0 : (double)m_aGridArea.GetHeight() / ( m_fMaxY - m_fMinY ) );
204 : 0 : return aRet;
205 : : }
206 : :
207 : : // ---------------------------------------------------------------------
208 : :
209 : 0 : void GridWindow::transform( const Point& rOriginal, double& x, double& y )
210 : : {
211 : 0 : x = ( rOriginal.X() - m_aGridArea.Left() ) * (m_fMaxX - m_fMinX) / (double)m_aGridArea.GetWidth() + m_fMinX;
212 : 0 : y = ( m_aGridArea.Bottom() - rOriginal.Y() ) * (m_fMaxY - m_fMinY) / (double)m_aGridArea.GetHeight() + m_fMinY;
213 : 0 : }
214 : :
215 : : // ---------------------------------------------------------------------
216 : :
217 : 0 : void GridWindow::drawLine( double x1, double y1, double x2, double y2 )
218 : : {
219 [ # # ][ # # ]: 0 : DrawLine( transform( x1, y1 ), transform( x2, y2 ) );
220 : 0 : }
221 : :
222 : : // ---------------------------------------------------------------------
223 : :
224 : 0 : void GridWindow::computeChunk( double fMin, double fMax, double& fChunkOut, double& fMinChunkOut )
225 : : {
226 : : // get a nice chunk size like 10, 100, 25 or such
227 : 0 : fChunkOut = ( fMax - fMin ) / 6.0;
228 : 0 : int logchunk = (int)std::log10( fChunkOut );
229 : 0 : int nChunk = (int)( fChunkOut / std::exp( (double)(logchunk-1) * M_LN10 ) );
230 [ # # ]: 0 : if( nChunk >= 75 )
231 : 0 : nChunk = 100;
232 [ # # ]: 0 : else if( nChunk >= 35 )
233 : 0 : nChunk = 50;
234 [ # # ]: 0 : else if ( nChunk > 20 )
235 : 0 : nChunk = 25;
236 [ # # ]: 0 : else if ( nChunk >= 13 )
237 : 0 : nChunk = 20;
238 [ # # ]: 0 : else if( nChunk > 5 )
239 : 0 : nChunk = 10;
240 : : else
241 : 0 : nChunk = 5;
242 : 0 : fChunkOut = (double) nChunk * exp( (double)(logchunk-1) * M_LN10 );
243 : : // compute whole chunks fitting into fMin
244 : 0 : nChunk = (int)( fMin / fChunkOut );
245 : 0 : fMinChunkOut = (double)nChunk * fChunkOut;
246 [ # # ]: 0 : while( fMinChunkOut < fMin )
247 : 0 : fMinChunkOut += fChunkOut;
248 : 0 : }
249 : :
250 : : // ---------------------------------------------------------------------
251 : :
252 : 0 : void GridWindow::computeNew()
253 : : {
254 [ # # ]: 0 : if(2L == m_aHandles.size())
255 : : {
256 : : // special case: only left and right markers
257 : : double xleft, yleft;
258 : : double xright, yright;
259 [ # # ]: 0 : transform(m_aHandles[0L].maPos, xleft, yleft);
260 [ # # ]: 0 : transform(m_aHandles[1L].maPos, xright, yright );
261 : 0 : double factor = (yright-yleft)/(xright-xleft);
262 [ # # ]: 0 : for( int i = 0; i < m_nValues; i++ )
263 : : {
264 : 0 : m_pNewYValues[ i ] = yleft + ( m_pXValues[ i ] - xleft )*factor;
265 : : }
266 : : }
267 : : else
268 : : {
269 : : // sort markers
270 : 0 : std::sort(m_aHandles.begin(), m_aHandles.end());
271 : 0 : const int nSorted = m_aHandles.size();
272 : : int i;
273 : :
274 : : // get node arrays
275 : 0 : double* nodex = new double[ nSorted ];
276 : 0 : double* nodey = new double[ nSorted ];
277 : :
278 [ # # ]: 0 : for( i = 0L; i < nSorted; i++ )
279 : 0 : transform( m_aHandles[i].maPos, nodex[ i ], nodey[ i ] );
280 : :
281 [ # # ]: 0 : for( i = 0; i < m_nValues; i++ )
282 : : {
283 : 0 : double x = m_pXValues[ i ];
284 : 0 : m_pNewYValues[ i ] = interpolate( x, nodex, nodey, nSorted );
285 [ # # ]: 0 : if( m_bCutValues )
286 : : {
287 [ # # ]: 0 : if( m_pNewYValues[ i ] > m_fMaxY )
288 : 0 : m_pNewYValues[ i ] = m_fMaxY;
289 [ # # ]: 0 : else if( m_pNewYValues[ i ] < m_fMinY )
290 : 0 : m_pNewYValues[ i ] = m_fMinY;
291 : : }
292 : : }
293 : :
294 [ # # ]: 0 : delete [] nodex;
295 [ # # ]: 0 : delete [] nodey;
296 : : }
297 : 0 : }
298 : :
299 : : // ---------------------------------------------------------------------
300 : :
301 : 0 : double GridWindow::interpolate(
302 : : double x,
303 : : double* pNodeX,
304 : : double* pNodeY,
305 : : int nNodes )
306 : : {
307 : : // compute Lagrange interpolation
308 : 0 : double ret = 0;
309 [ # # ]: 0 : for( int i = 0; i < nNodes; i++ )
310 : : {
311 : 0 : double sum = pNodeY[ i ];
312 [ # # ]: 0 : for( int n = 0; n < nNodes; n++ )
313 : : {
314 [ # # ]: 0 : if( n != i )
315 : : {
316 : 0 : sum *= x - pNodeX[ n ];
317 : 0 : sum /= pNodeX[ i ] - pNodeX[ n ];
318 : : }
319 : : }
320 : 0 : ret += sum;
321 : : }
322 : 0 : return ret;
323 : : }
324 : :
325 : : // ---------------------------------------------------------------------
326 : :
327 : 0 : void GridWindow::setBoundings( double fMinX, double fMinY, double fMaxX, double fMaxY )
328 : : {
329 : 0 : m_fMinX = fMinX;
330 : 0 : m_fMinY = fMinY;
331 : 0 : m_fMaxX = fMaxX;
332 : 0 : m_fMaxY = fMaxY;
333 : :
334 : 0 : computeChunk( m_fMinX, m_fMaxX, m_fChunkX, m_fMinChunkX );
335 : 0 : computeChunk( m_fMinY, m_fMaxY, m_fChunkY, m_fMinChunkY );
336 : 0 : }
337 : :
338 : : // ---------------------------------------------------------------------
339 : :
340 : 0 : void GridWindow::drawGrid()
341 : : {
342 : : char pBuf[256];
343 [ # # ]: 0 : SetLineColor( Color( COL_BLACK ) );
344 : : // draw vertical lines
345 [ # # ]: 0 : for( double fX = m_fMinChunkX; fX < m_fMaxX; fX += m_fChunkX )
346 : : {
347 [ # # ]: 0 : drawLine( fX, m_fMinY, fX, m_fMaxY );
348 : : // draw tickmarks
349 [ # # ]: 0 : Point aPt = transform( fX, m_fMinY );
350 : 0 : std::sprintf( pBuf, "%g", fX );
351 [ # # ][ # # ]: 0 : String aMark( pBuf, osl_getThreadTextEncoding() );
352 [ # # ][ # # ]: 0 : Size aTextSize( GetTextWidth( aMark ), GetTextHeight() );
353 : 0 : aPt.X() -= aTextSize.Width()/2;
354 : 0 : aPt.Y() += aTextSize.Height()/2;
355 [ # # ]: 0 : DrawText( aPt, aMark );
356 [ # # ]: 0 : }
357 : : // draw horizontal lines
358 [ # # ]: 0 : for( double fY = m_fMinChunkY; fY < m_fMaxY; fY += m_fChunkY )
359 : : {
360 [ # # ]: 0 : drawLine( m_fMinX, fY, m_fMaxX, fY );
361 : : // draw tickmarks
362 [ # # ]: 0 : Point aPt = transform( m_fMinX, fY );
363 : 0 : std::sprintf( pBuf, "%g", fY );
364 [ # # ][ # # ]: 0 : String aMark( pBuf, osl_getThreadTextEncoding() );
365 [ # # ][ # # ]: 0 : Size aTextSize( GetTextWidth( aMark ), GetTextHeight() );
366 : 0 : aPt.X() -= aTextSize.Width() + 2;
367 : 0 : aPt.Y() -= aTextSize.Height()/2;
368 [ # # ]: 0 : DrawText( aPt, aMark );
369 [ # # ]: 0 : }
370 : :
371 : : // draw boundings
372 [ # # ]: 0 : drawLine( m_fMinX, m_fMinY, m_fMaxX, m_fMinY );
373 [ # # ]: 0 : drawLine( m_fMinX, m_fMaxY, m_fMaxX, m_fMaxY );
374 [ # # ]: 0 : drawLine( m_fMinX, m_fMinY, m_fMinX, m_fMaxY );
375 [ # # ]: 0 : drawLine( m_fMaxX, m_fMinY, m_fMaxX, m_fMaxY );
376 : 0 : }
377 : :
378 : : // ---------------------------------------------------------------------
379 : :
380 : 0 : void GridWindow::drawOriginal()
381 : : {
382 [ # # ][ # # ]: 0 : if( m_nValues && m_pXValues && m_pOrigYValues )
[ # # ]
383 : : {
384 [ # # ]: 0 : SetLineColor( Color( COL_RED ) );
385 [ # # ]: 0 : for( int i = 0; i < m_nValues-1; i++ )
386 : : {
387 : 0 : drawLine( m_pXValues[ i ], m_pOrigYValues[ i ],
388 : 0 : m_pXValues[ i+1 ], m_pOrigYValues[ i+1 ] );
389 : : }
390 : : }
391 : 0 : }
392 : :
393 : : // ---------------------------------------------------------------------
394 : :
395 : 0 : void GridWindow::drawNew()
396 : : {
397 [ # # ][ # # ]: 0 : if( m_nValues && m_pXValues && m_pNewYValues )
[ # # ]
398 : : {
399 [ # # ]: 0 : SetClipRegion( m_aGridArea );
400 [ # # ]: 0 : SetLineColor( Color( COL_YELLOW ) );
401 [ # # ]: 0 : for( int i = 0; i < m_nValues-1; i++ )
402 : : {
403 : 0 : drawLine( m_pXValues[ i ], m_pNewYValues[ i ],
404 : 0 : m_pXValues[ i+1 ], m_pNewYValues[ i+1 ] );
405 : : }
406 : 0 : SetClipRegion();
407 : : }
408 : 0 : }
409 : :
410 : : // ---------------------------------------------------------------------
411 : :
412 : 0 : void GridWindow::drawHandles()
413 : : {
414 [ # # ]: 0 : for(sal_uInt32 i(0L); i < m_aHandles.size(); i++)
415 : : {
416 : 0 : m_aHandles[i].draw(*this, m_aMarkerBitmap);
417 : : }
418 : 0 : }
419 : :
420 : : // ---------------------------------------------------------------------
421 : :
422 : 0 : void GridWindow::Paint( const Rectangle& rRect )
423 : : {
424 : 0 : ModalDialog::Paint( rRect );
425 : 0 : drawGrid();
426 : 0 : drawOriginal();
427 : 0 : drawNew();
428 : 0 : drawHandles();
429 : 0 : }
430 : :
431 : : // ---------------------------------------------------------------------
432 : :
433 : 0 : void GridWindow::MouseMove( const MouseEvent& rEvt )
434 : : {
435 [ # # ][ # # ]: 0 : if( rEvt.GetButtons() == MOUSE_LEFT && m_nDragIndex != 0xffffffff )
[ # # ]
436 : : {
437 : 0 : Point aPoint( rEvt.GetPosPixel() );
438 : :
439 [ # # ][ # # ]: 0 : if( m_nDragIndex == 0L || m_nDragIndex == m_aHandles.size() - 1L)
[ # # ]
440 : : {
441 : 0 : aPoint.X() = m_aHandles[m_nDragIndex].maPos.X();
442 : : }
443 : : else
444 : : {
445 [ # # ]: 0 : if(aPoint.X() < m_aGridArea.Left())
446 : 0 : aPoint.X() = m_aGridArea.Left();
447 [ # # ]: 0 : else if(aPoint.X() > m_aGridArea.Right())
448 : 0 : aPoint.X() = m_aGridArea.Right();
449 : : }
450 : :
451 [ # # ]: 0 : if( aPoint.Y() < m_aGridArea.Top() )
452 : 0 : aPoint.Y() = m_aGridArea.Top();
453 [ # # ]: 0 : else if( aPoint.Y() > m_aGridArea.Bottom() )
454 : 0 : aPoint.Y() = m_aGridArea.Bottom();
455 : :
456 [ # # ]: 0 : if( aPoint != m_aHandles[m_nDragIndex].maPos )
457 : : {
458 : 0 : m_aHandles[m_nDragIndex].maPos = aPoint;
459 [ # # ]: 0 : Invalidate( m_aGridArea );
460 : : }
461 : : }
462 : :
463 : 0 : ModalDialog::MouseMove( rEvt );
464 : 0 : }
465 : :
466 : : // ---------------------------------------------------------------------
467 : :
468 : 0 : void GridWindow::MouseButtonUp( const MouseEvent& rEvt )
469 : : {
470 [ # # ]: 0 : if( rEvt.GetButtons() == MOUSE_LEFT )
471 : : {
472 [ # # ]: 0 : if( m_nDragIndex != 0xffffffff )
473 : : {
474 : 0 : m_nDragIndex = 0xffffffff;
475 : 0 : computeNew();
476 : 0 : Invalidate( m_aGridArea );
477 : 0 : Paint( m_aGridArea );
478 : : }
479 : : }
480 : :
481 : 0 : ModalDialog::MouseButtonUp( rEvt );
482 : 0 : }
483 : :
484 : : // ---------------------------------------------------------------------
485 : :
486 : 0 : void GridWindow::MouseButtonDown( const MouseEvent& rEvt )
487 : : {
488 : 0 : Point aPoint( rEvt.GetPosPixel() );
489 : 0 : sal_uInt32 nMarkerIndex = 0xffffffff;
490 : :
491 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0L); nMarkerIndex == 0xffffffff && a < m_aHandles.size(); a++)
[ # # ]
492 : : {
493 [ # # ][ # # ]: 0 : if(m_aHandles[a].isHit(*this, aPoint))
494 : : {
495 : 0 : nMarkerIndex = a;
496 : : }
497 : : }
498 : :
499 [ # # ]: 0 : if( rEvt.GetButtons() == MOUSE_LEFT )
500 : : {
501 : : // user wants to drag a button
502 [ # # ]: 0 : if( nMarkerIndex != 0xffffffff )
503 : : {
504 : 0 : m_nDragIndex = nMarkerIndex;
505 : : }
506 : : }
507 [ # # ]: 0 : else if( rEvt.GetButtons() == MOUSE_RIGHT )
508 : : {
509 : : // user wants to add/delete a button
510 [ # # ]: 0 : if( nMarkerIndex != 0xffffffff )
511 : : {
512 [ # # ][ # # ]: 0 : if( nMarkerIndex != 0L && nMarkerIndex != m_aHandles.size() - 1L)
[ # # ]
513 : : {
514 : : // delete marker under mouse
515 [ # # ]: 0 : if( m_nDragIndex == nMarkerIndex )
516 : 0 : m_nDragIndex = 0xffffffff;
517 : :
518 [ # # ][ # # ]: 0 : m_aHandles.erase(m_aHandles.begin() + nMarkerIndex);
519 : : }
520 : : }
521 : : else
522 : : {
523 : 0 : m_BmOffX = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Width() >> 1);
524 : 0 : m_BmOffY = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Height() >> 1);
525 [ # # ]: 0 : m_aHandles.push_back(impHandle(aPoint, m_BmOffX, m_BmOffY));
526 : : }
527 : :
528 [ # # ]: 0 : computeNew();
529 [ # # ]: 0 : Invalidate( m_aGridArea );
530 [ # # ]: 0 : Paint( m_aGridArea );
531 : : }
532 : :
533 [ # # ]: 0 : ModalDialog::MouseButtonDown( rEvt );
534 : 0 : }
535 : :
536 : : // ---------------------------------------------------------------------
537 : :
538 : 0 : IMPL_LINK( GridWindow, ClickButtonHdl, Button*, pButton )
539 : : {
540 [ # # ]: 0 : if( pButton == &m_aResetButton )
541 : : {
542 : 0 : int nType = (int)(sal_IntPtr)m_aResetTypeBox.GetEntryData( m_aResetTypeBox.GetSelectEntryPos() );
543 [ # # # # : 0 : switch( nType )
# ]
544 : : {
545 : : case RESET_TYPE_LINEAR_ASCENDING:
546 : : {
547 [ # # ]: 0 : for( int i = 0; i < m_nValues; i++ )
548 : : {
549 : 0 : m_pNewYValues[ i ] = m_fMinY + (m_fMaxY-m_fMinY)/(m_fMaxX-m_fMinX)*(m_pXValues[i]-m_fMinX);
550 : : }
551 : : }
552 : 0 : break;
553 : : case RESET_TYPE_LINEAR_DESCENDING:
554 : : {
555 [ # # ]: 0 : for( int i = 0; i < m_nValues; i++ )
556 : : {
557 : 0 : m_pNewYValues[ i ] = m_fMaxY - (m_fMaxY-m_fMinY)/(m_fMaxX-m_fMinX)*(m_pXValues[i]-m_fMinX);
558 : : }
559 : : }
560 : 0 : break;
561 : : case RESET_TYPE_RESET:
562 : : {
563 [ # # ][ # # ]: 0 : if( m_pOrigYValues && m_pNewYValues && m_nValues )
[ # # ]
564 : 0 : memcpy( m_pNewYValues, m_pOrigYValues, m_nValues*sizeof(double) );
565 : : }
566 : 0 : break;
567 : : case RESET_TYPE_EXPONENTIAL:
568 : : {
569 [ # # ]: 0 : for( int i = 0; i < m_nValues; i++ )
570 : : {
571 : 0 : m_pNewYValues[ i ] = m_fMinY + (m_fMaxY-m_fMinY)*(std::exp((m_pXValues[i]-m_fMinX)/(m_fMaxX-m_fMinX))-1.0)/(M_E-1.0);
572 : : }
573 : : }
574 : 0 : break;
575 : :
576 : : default:
577 : 0 : break;
578 : : }
579 : :
580 [ # # ]: 0 : for(sal_uInt32 i(0L); i < m_aHandles.size(); i++)
581 : : {
582 : : // find nearest xvalue
583 : : double x, y;
584 [ # # ]: 0 : transform( m_aHandles[i].maPos, x, y );
585 : 0 : int nIndex = 0;
586 : 0 : double delta = std::fabs( x-m_pXValues[0] );
587 [ # # ]: 0 : for( int n = 1; n < m_nValues; n++ )
588 : : {
589 [ # # ]: 0 : if( delta > std::fabs( x - m_pXValues[ n ] ) )
590 : : {
591 : 0 : delta = std::fabs( x - m_pXValues[ n ] );
592 : 0 : nIndex = n;
593 : : }
594 : : }
595 [ # # ]: 0 : if( 0 == i )
596 [ # # ]: 0 : m_aHandles[i].maPos = transform( m_fMinX, m_pNewYValues[ nIndex ] );
597 [ # # ]: 0 : else if( m_aHandles.size() - 1L == i )
598 [ # # ]: 0 : m_aHandles[i].maPos = transform( m_fMaxX, m_pNewYValues[ nIndex ] );
599 : : else
600 [ # # ]: 0 : m_aHandles[i].maPos = transform( m_pXValues[ nIndex ], m_pNewYValues[ nIndex ] );
601 : : }
602 : :
603 : 0 : Invalidate( m_aGridArea );
604 [ # # ]: 0 : Paint(Rectangle());
605 : : }
606 : 0 : return 0;
607 : : }
608 : :
609 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|