1 /***************************************************************************
2 * Copyright (C) 2005, 2006 by Carsten Niehaus *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 ***************************************************************************/
21 #include "spectrumwidget.h"
23 #include "kalziumutils.h"
33 #include <QSizePolicy>
38 #if defined(Q_OS_SOLARIS)
42 SpectrumWidget::SpectrumWidget( QWidget
*parent
)
48 m_LMBPointCurrent
.setX( -1 );
49 m_LMBPointPress
.setX( -1 );
56 setType( EmissionSpectrum
);
58 setMinimumSize( 400, 230 );
59 setSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Expanding
);
60 setAttribute( Qt::WA_OpaquePaintEvent
, true );
63 void SpectrumWidget::paintEvent( QPaintEvent
* /*e*/ )
68 m_pixmap
= QPixmap( width(), height() );
69 m_pixmap
.fill( this, width(), height() );
73 p
.fillRect( 0, 0, width(), m_realHeight
, Qt::black
);
79 if ( m_LMBPointPress
.x() != -1 && m_LMBPointCurrent
.x() != -1 )
85 p2
.drawPixmap(0, 0, m_pixmap
);
88 void SpectrumWidget::drawZoomLine( QPainter
* p
)
90 p
->setPen( Qt::white
);
91 p
->drawLine( m_LMBPointPress
.x(), m_LMBPointPress
.y(), m_LMBPointCurrent
.x(), m_LMBPointPress
.y() );
92 p
->drawLine( m_LMBPointCurrent
.x(), m_LMBPointPress
.y()+10, m_LMBPointCurrent
.x(), m_LMBPointPress
.y()-10 );
93 p
->drawLine( m_LMBPointPress
.x(), m_LMBPointPress
.y()+10, m_LMBPointPress
.x(), m_LMBPointPress
.y()-10 );
96 void SpectrumWidget::paintBands( QPainter
* p
)
98 if ( m_type
== AbsorptionSpectrum
)
100 for ( double va
= startValue
; va
<= endValue
; va
+= 0.1 )
103 p
->setPen( linecolor( va
) );
104 p
->drawLine( x
,0,x
, m_realHeight
);
107 p
->setPen( Qt::black
);
114 foreach ( Spectrum::peak
* peak
, m_spectrum
->peaklist() )
116 if ( peak
->wavelength
< startValue
|| peak
->wavelength
> endValue
)
119 x
= xPos( peak
->wavelength
);
125 case EmissionSpectrum
:
126 p
->setPen( linecolor( peak
->wavelength
) );
127 p
->drawLine( x
,0,x
, m_realHeight
-1 );
129 p
->setPen( Qt::black
);
130 p
->drawLine( x
,m_realHeight
,x
, m_realHeight
);
133 case AbsorptionSpectrum
:
134 p
->setPen( Qt::black
);
135 p
->drawLine( x
,0,x
, m_realHeight
-1 );
143 QColor
SpectrumWidget::linecolor( double spectrum
)
146 wavelengthToRGB( spectrum
, r
,g
,b
);
153 void SpectrumWidget::wavelengthToRGB( double wavelength
, int& r
, int& g
, int& b
)
155 double blue
= 0.0, green
= 0.0, red
= 0.0, factor
= 0.0;
157 int wavelength_
= ( int ) floor( wavelength
);
158 if ( wavelength_
< 380 || wavelength_
> 780 )
160 //make everything white
164 else if ( wavelength_
> 380 && wavelength_
< 439 )
166 red
= -( wavelength
-440 ) / ( 440-380 );
170 else if ( wavelength_
> 440 && wavelength_
< 489 )
173 green
= ( wavelength
-440 ) / ( 490-440 );
176 else if ( wavelength_
> 490 && wavelength_
< 509 )
180 blue
= -( wavelength
-510 ) / ( 510-490 );
182 else if ( wavelength_
> 510 && wavelength_
< 579 )
184 red
= ( wavelength
-510 ) / ( 580-510 );
188 else if ( wavelength_
> 580 && wavelength_
< 644 )
191 green
= -( wavelength
-645 ) / ( 645-580 );
194 else if ( wavelength_
> 645 && wavelength_
< 780 )
201 if ( wavelength_
> 380 && wavelength_
< 419 )
202 factor
= 0.3 + 0.7*( wavelength
- 380 ) / ( 420 - 380 );
203 else if ( wavelength_
> 420 && wavelength_
< 700 )
205 else if ( wavelength_
> 701 && wavelength_
< 780 )
206 factor
= 0.3 + 0.7*( 780 - wavelength
) / ( 780 - 700 );
210 r
= Adjust( red
, factor
);
211 g
= Adjust( green
, factor
);
212 b
= Adjust( blue
, factor
);
215 int SpectrumWidget::Adjust( double color
, double factor
)
220 return qRound( IntensityMax
* pow( color
*factor
, Gamma
));
223 void SpectrumWidget::drawTickmarks( QPainter
* p
)
225 //the size of the text on the tickmarks
226 const int space
= 20;
228 //the distance between the tickmarks in pixel
231 //the total number of tickmarks to draw (small and long)
232 const int numberOfTickmarks
= ( int )floor( width()/d
);
236 for ( int i
= 0; i
< numberOfTickmarks
; i
++ )
239 {//long tickmarks plus text
240 p
->drawLine( i
*d
, m_realHeight
, i
*d
, m_realHeight
+10 );
243 i
*d
< width()-space
)
245 pos
= ( double ) ( i
*d
)/width();
246 p
->fillRect( i
*d
-space
, m_realHeight
+12, 2*space
, 15, Qt::white
);
247 p
->drawText( i
*d
-space
, m_realHeight
+12, 2*space
, 15, Qt::AlignCenter
, QString::number( KalziumUtils::strippedValue( Wavelength( pos
) ) ) );
250 else {//small tickmarks
251 p
->drawLine( i
*d
, m_realHeight
, i
*d
, m_realHeight
+5 );
256 void SpectrumWidget::keyPressEvent( QKeyEvent
*e
)
269 void SpectrumWidget::slotZoomOut()
271 kDebug() << "SpectrumWidget::slotZoomOut() "<< startValue
<< ":: "<< endValue
;
273 double diff
= endValue
- startValue
;
275 double offset
= diff
* 0.05;
277 endValue
= endValue
+ offset
;
278 startValue
= startValue
- offset
;
280 //check for invalid values
281 if ( startValue
< 0.0 )
284 if ( endValue
> 800.0 )
287 setBorders( startValue
, endValue
);
290 void SpectrumWidget::setBorders( double left
, double right
)
292 kDebug() << "setBorders " << left
<< ".."<< right
;
297 //round the startValue down and the endValue up
298 emit
bordersChanged( int(startValue
+0.5), int(endValue
+0.5) );
303 void SpectrumWidget::slotZoomIn()
305 kDebug() << "SpectrumWidget::slotZoomIn() "<< startValue
<< ":: "<< endValue
;
307 double diff
= endValue
- startValue
;
309 double offset
= diff
* 0.05;
311 endValue
= endValue
- offset
;
312 startValue
= startValue
+ offset
;
314 setBorders( startValue
, endValue
);
317 void SpectrumWidget::mouseMoveEvent( QMouseEvent
*e
)
319 m_LMBPointCurrent
= e
->pos();
323 void SpectrumWidget::mousePressEvent( QMouseEvent
*e
)
325 if ( e
->button() == Qt::LeftButton
)
326 m_LMBPointPress
= e
->pos();
327 if ( e
->button() == Qt::RightButton
)
330 findPeakFromMouseposition( Wavelength( ( double )e
->pos().x()/width() ) );
333 void SpectrumWidget::findPeakFromMouseposition( double wavelength
)
335 kDebug() << "SpectrumWidget::findPeakFromMouseposition()";
336 Spectrum::peak
*peak
= NULL
;
338 //find the difference in percent (1.0 is 100%, 0.1 is 10%)
341 bool foundWavelength
= false;
343 //find the highest intensity
344 foreach( Spectrum::peak
*currentPeak
, m_spectrum
->peaklist() )
346 double thisdif
= currentPeak
->wavelength
/ wavelength
;
348 if ( thisdif
< 0.9 || thisdif
> 1.1 )
351 if ( thisdif
> 1.0 ){//convert for example 1.3 to 0.7
360 foundWavelength
= true;
364 if ( foundWavelength
)
365 emit
peakSelected(peak
);
368 void SpectrumWidget::mouseReleaseEvent( QMouseEvent
*e
)
370 if ( e
->button() == Qt::LeftButton
)
372 int left
= (int)Wavelength( ( double )m_LMBPointPress
.x()/width() );
373 int right
= (int)Wavelength( ( double )e
->pos().x()/width() );
379 setBorders( right
, left
);
381 setBorders( left
, right
);
384 m_LMBPointPress
.setX( -1 );
385 m_LMBPointCurrent
.setX( -1 );
388 void SpectrumWidget::restart()
390 //set the minimum and maximum peak to the min/max wavelenght
391 //plus/minus ten. This makes then always visible
392 setBorders(m_spectrum
->minPeak()-10.0, m_spectrum
->maxPeak()+10.0);
395 #include "spectrumwidget.moc"