WPropertyDoubleWidget.cpp 6.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

25
#include <sstream>
26
#include <cmath>
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
27
#include <string>
28 29 30 31 32 33 34 35 36 37 38

#include <boost/lexical_cast.hpp>

#include "../../../common/WLogger.h"
#include "../../../common/WPropertyVariable.h"

#include "WPropertyDoubleWidget.h"

WPropertyDoubleWidget::WPropertyDoubleWidget( WPropDouble property, QGridLayout* propertyGrid, QWidget* parent ):
    WPropertyWidget( property, propertyGrid, parent ),
    m_doubleProperty( property ),
39 40
    m_slider( Qt::Horizontal, &m_parameterWidgets ),
    m_edit( &m_parameterWidgets ),
41
    m_layout( &m_parameterWidgets )
42 43
{
    // initialize members
44
    m_edit.resize( m_edit.minimumSizeHint().width() *.8 , m_edit.size().height() );
45
    m_edit.setMaximumWidth( m_edit.minimumSizeHint().width() );
46 47

    // layout both against each other
48 49 50 51
    m_layout.addWidget( &m_slider );
    m_layout.addWidget( &m_edit );

    m_parameterWidgets.setLayout( &m_layout );
52

53 54 55
    update();

    // connect the modification signal of the edit and slider with our callback
56 57 58
    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& ) ) );
59 60 61 62 63 64 65
}

WPropertyDoubleWidget::~WPropertyDoubleWidget()
{
    // cleanup
}

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
/**
 * 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();
}

81 82
void WPropertyDoubleWidget::update()
{
83 84
    // get the min constraint
    WPVDouble::PropertyConstraintMin minC = m_doubleProperty->getMin();
85
    m_min = 0;
86 87
    if ( minC.get() )
    {
88
        m_min = minC->getMin();
89 90 91 92
    }
    else
    {
        WLogger::getLogger()->addLogMessage(
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
93
                std::string( "The property has no minimum constraint. You should define it to avoid unexpected behaviour." ) +
94
                std::string( "Using default (" + boost::lexical_cast< std::string >( m_min ) + ")." ),
95 96 97 98 99
                "PropertyWidget( " + m_doubleProperty->getName() + " )", LL_WARNING );
    }

    // get the max constraint
    WPVDouble::PropertyConstraintMax maxC = m_doubleProperty->getMax();
100
    m_max = 100;
101 102
    if ( maxC.get() )
    {
103
        m_max = maxC->getMax();
104 105 106 107
    }
    else
    {
        WLogger::getLogger()->addLogMessage(
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
108
                std::string( "The property has no maximum constraint. You should define it to avoid unexpected behaviour." ) +
109
                std::string( "Using default (" + boost::lexical_cast< std::string >( m_max ) + ")." ),
110 111 112 113
                "PropertyWidget( " + m_doubleProperty->getName() + " )", LL_WARNING );
    }

    // setup the slider
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    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 );
131 132
//     m_edit.setMinimumWidth( m_edit.minimumSizeHint().width() * length / 4 );
//     m_edit.resize( m_edit.minimumSizeHint().width() * length / 2, m_edit.size().height() );
133

134
    // set the initial values
135 136
    m_edit.setText( QString( toString( m_doubleProperty->get() ).c_str() ) );
    m_slider.setValue( toPercent( m_doubleProperty->get() ) );
137 138
}

139 140 141 142 143 144 145 146 147 148 149
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 )
150 151
{
    // set to the property
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
    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 ) );
190 191
}