Commit 76aee645 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[CHANGE] - float properties now also use the slider/edit widgets

parent 5d7070c4
......@@ -22,6 +22,7 @@
//
//---------------------------------------------------------------------------
#include <sstream>
#include <cmath>
#include <string>
......@@ -35,19 +36,26 @@
WPropertyDoubleWidget::WPropertyDoubleWidget( WPropDouble property, QGridLayout* propertyGrid, QWidget* parent ):
WPropertyWidget( property, propertyGrid, parent ),
m_doubleProperty( property ),
m_spin( &m_parameterWidgets ),
m_slider( Qt::Horizontal, &m_parameterWidgets ),
m_edit( &m_parameterWidgets ),
m_layout( &m_parameterWidgets )
{
// initialize members
m_parameterWidgets.setLayout( &m_layout );
m_edit.resize( m_edit.minimumSizeHint().width() , m_edit.size().height() );
m_edit.setMaximumWidth( m_edit.minimumSizeHint().width() );
// layout both against each other
m_layout.addWidget( &m_spin );
m_layout.addWidget( &m_slider );
m_layout.addWidget( &m_edit );
m_parameterWidgets.setLayout( &m_layout );
update();
// connect the modification signal of the edit and slider with our callback
connect( &m_spin, SIGNAL( editingFinished() ), this, SLOT( spinChanged() ) );
connect( &m_slider, SIGNAL( valueChanged( int ) ), this, SLOT( sliderChanged( int ) ) );
connect( &m_edit, SIGNAL( returnPressed() ), this, SLOT( editChanged() ) );
connect( &m_edit, SIGNAL( textEdited( const QString& ) ), this, SLOT( textEdited( const QString& ) ) );
}
WPropertyDoubleWidget::~WPropertyDoubleWidget()
......@@ -55,53 +63,129 @@ WPropertyDoubleWidget::~WPropertyDoubleWidget()
// cleanup
}
/**
* Helper function converting a double into a nice formatted string.
*
* \param value the value to convert
*
* \return a string containing the double in a nicely formatted way.
*/
std::string toString( double value )
{
std::ostringstream o;
o.precision( 5 );
o << value;
return o.str();
}
void WPropertyDoubleWidget::update()
{
// get the min constraint
WPVDouble::PropertyConstraintMin minC = m_doubleProperty->getMin();
double min = 0.0;
m_min = 0;
if ( minC.get() )
{
min = minC->getMin();
m_min = minC->getMin();
}
else
{
WLogger::getLogger()->addLogMessage(
std::string( "The property has no minimum constraint. You should define it to avoid unexpected behaviour." ) +
std::string( "Using default (" + boost::lexical_cast< std::string >( min ) + ")." ),
std::string( "Using default (" + boost::lexical_cast< std::string >( m_min ) + ")." ),
"PropertyWidget( " + m_doubleProperty->getName() + " )", LL_WARNING );
}
// get the max constraint
WPVDouble::PropertyConstraintMax maxC = m_doubleProperty->getMax();
double max = 100.0;
m_max = 100;
if ( maxC.get() )
{
max = maxC->getMax();
m_max = maxC->getMax();
}
else
{
WLogger::getLogger()->addLogMessage(
std::string( "The property has no maximum constraint. You should define it to avoid unexpected behaviour." ) +
std::string( "Using default (" + boost::lexical_cast< std::string >( max ) + ")." ),
std::string( "Using default (" + boost::lexical_cast< std::string >( m_max ) + ")." ),
"PropertyWidget( " + m_doubleProperty->getName() + " )", LL_WARNING );
}
// setup the slider
m_spin.setMinimum( min );
m_spin.setMaximum( max );
// set display precision
m_spin.setDecimals( 5 );
m_slider.setMinimum( 0 );
m_slider.setMaximum( 100 );
// calculate maximum size of the text widget.
// XXX: this is not the optimal way but works for now
// int length = m_min < 0 ? 5 : 4; // reserve some extra space for the "-" in negative numbers
// double fmax = std::max( std::abs( m_min ), std::abs( m_max ) ); // use the number with the most numbers
// while ( ( fmax / 10 ) >= 1.0 )
// {
// ++length;
// fmax /= 10.0;
// }
int length = 6; // use fixed length to have a uniform look among several widgets
// resize the text widget
//m_edit.setMaxLength( length );
m_edit.setMaximumWidth( m_edit.minimumSizeHint().width() * length / 2 );
m_edit.setMinimumWidth( m_edit.minimumSizeHint().width() * length / 2 );
m_edit.resize( m_edit.minimumSizeHint().width() * length / 2, m_edit.size().height() );
// set the initial values
m_spin.setValue( m_doubleProperty->get() );
m_spin.setSingleStep( ( max - min ) / 100.0 );
m_edit.setText( QString( toString( m_doubleProperty->get() ).c_str() ) );
m_slider.setValue( toPercent( m_doubleProperty->get() ) );
}
void WPropertyDoubleWidget::spinChanged()
int WPropertyDoubleWidget::toPercent( double value )
{
return 100.0 * ( ( value - m_min ) / ( m_max - m_min ) );
}
double WPropertyDoubleWidget::fromPercent( int perc )
{
return ( static_cast< double >( perc ) / 100.0 ) * ( m_max - m_min ) + m_min;
}
void WPropertyDoubleWidget::sliderChanged( int value )
{
// set to the property
invalidate( !m_doubleProperty->set( m_spin.value() ) );
invalidate( !m_doubleProperty->set( fromPercent( value ) ) ); // NOTE: set automatically checks the validity of the value
// set the value in the line edit
m_edit.setText( QString( toString( m_doubleProperty->get() ).c_str() ) );
}
void WPropertyDoubleWidget::editChanged()
{
// set the value in the line edit
bool valid;
double value = m_edit.text().toDouble( &valid );
if ( !valid )
{
invalidate();
return;
}
// update slider
m_slider.setValue( toPercent( value ) );
// set to the property
invalidate( !m_doubleProperty->set( value ) ); // NOTE: set automatically checks the validity of the value
}
void WPropertyDoubleWidget::textEdited( const QString& text )
{
// this method does NOT set the property actually, but tries to validate it
bool valid;
double value = text.toDouble( &valid );
if ( !valid )
{
invalidate();
return;
}
// simply check validity
invalidate( !m_doubleProperty->accept( value ) );
}
......@@ -27,7 +27,8 @@
#include <string>
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QLineEdit>
#include <QtGui/QSlider>
#include <QtGui/QHBoxLayout>
#include "WPropertyWidget.h"
......@@ -67,23 +68,70 @@ protected:
WPropDouble m_doubleProperty;
/**
* Spin box for doubles
* The slider allowing modification of the integer value
*/
QDoubleSpinBox m_spin;
QSlider m_slider;
/**
* The edit field showing the value of the slider
*/
QLineEdit m_edit;
/**
* Layout used to position the label and the checkbox
*/
QHBoxLayout m_layout;
/**
* Converts a given value to a percentage between m_min and m_max.
*
* \param value the value.
*
* \return the percentage.
*/
int toPercent( double value );
/**
* Converts the given percentage to the real double value using m_min and m_max.
*
* \param perc the percentage.
*
* \return the real double value.
*/
double fromPercent( int perc );
/**
* The current minimum value.
*/
double m_min;
/**
* The current maximum value.
*/
double m_max;
private:
public slots:
/**
* Called whenever return is pressed or the spin box has a chaged value and looses focus
* Called whenever the slider changes
*
* \param value the new value
*/
void sliderChanged( int value );
/**
* Called whenever the edit field changes
*/
void editChanged();
/**
* Called when the text in m_edit changes.
*
* \param text
*/
void spinChanged();
void textEdited( const QString& text );
};
#endif // WPROPERTYDOUBLEWIDGET_H
......
......@@ -102,13 +102,15 @@ void WPropertyIntWidget::update()
// calculate maximum size of the text widget.
// XXX: this is not the optimal way but works for now
int length = min < 0 ? 2 : 1; // reserve some extra space for the "-" in negative numbers
float fmax = static_cast<float>( std::max( std::abs( min ), std::abs( max ) ) ); // use the number with the most numbers
while ( ( fmax / 10 ) >= 1.0 )
{
++length;
fmax /= 10.0;
}
// int length = min < 0 ? 3 : 2; // reserve some extra space for the "-" in negative numbers
// float fmax = static_cast<float>( std::max( std::abs( min ), std::abs( max ) ) ); // use the number with the most numbers
// while ( ( fmax / 10 ) >= 1.0 )
// {
// ++length;
// fmax /= 10.0;
// }
int length = 6; // use fixed length to have a uniform look among several widgets
// resize the text widget
m_edit.setMaxLength( length );
m_edit.setMaximumWidth( m_edit.minimumSizeHint().width() * length / 2 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment