WPropertyIntWidget.cpp 5.92 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 25
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------

#include <iostream>
26
#include <cmath>
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
27 28
#include <string>
#include <algorithm>
29

30 31
#include <boost/lexical_cast.hpp>

32
#include "../../../common/WLogger.h"
33 34
#include "../../../common/WPropertyVariable.h"

35 36
#include "WPropertyIntWidget.h"

37 38 39
WPropertyIntWidget::WPropertyIntWidget( WPropInt property, QGridLayout* propertyGrid, QWidget* parent ):
    WPropertyWidget( property, propertyGrid, parent ),
    m_intProperty( property ),
40 41
    m_slider( Qt::Horizontal, &m_parameterWidgets ),
    m_edit( &m_parameterWidgets ),
42 43 44
    m_layout( &m_parameterWidgets ),
    m_asText( &m_informationWidgets ),
    m_infoLayout( &m_informationWidgets )
45 46
{
    // initialize members
47
    m_edit.resize( m_edit.minimumSizeHint().width(), m_edit.size().height() );
48 49 50 51 52
    m_edit.setMaximumWidth( m_edit.minimumSizeHint().width() );

    // layout both against each other
    m_layout.addWidget( &m_slider );
    m_layout.addWidget( &m_edit );
53 54
    m_parameterWidgets.setLayout( &m_layout );

55 56 57 58
    // Information Output ( Property Purpose = PV_PURPOSE_INFORMATION )
    m_infoLayout.addWidget( &m_asText );
    m_informationWidgets.setLayout( &m_infoLayout );

59 60 61
    update();

    // connect the modification signal of the edit and slider with our callback
62
    connect( &m_slider, SIGNAL( sliderMoved( int ) ), this, SLOT( sliderChanged( int ) ) );
63 64 65 66 67 68 69 70 71 72 73
    connect( &m_edit, SIGNAL( returnPressed() ), this, SLOT( editChanged() ) );
    connect( &m_edit, SIGNAL( textEdited( const QString& ) ), this, SLOT( textEdited( const QString& ) ) );
}

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

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

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

    // setup the slider
    m_slider.setMinimum( min );
    m_slider.setMaximum( max );

    // calculate maximum size of the text widget.
    // XXX: this is not the optimal way but works for now
110 111 112 113 114 115 116 117 118
    // 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

119
    // resize the text widget
120
    // m_edit.setMaxLength( length );
121
    m_edit.setMaximumWidth( m_edit.minimumSizeHint().width() * length / 2 );
122 123
    // m_edit.setMinimumWidth( m_edit.minimumSizeHint().width() * length / 4 );
    // m_edit.resize( m_edit.minimumSizeHint().width() * length / 4, m_edit.size().height() );
124 125

    // set the initial values
126 127
    QString valStr = QString( boost::lexical_cast< std::string >( m_intProperty->get() ).c_str() );
    m_edit.setText( valStr );
128
    m_slider.setValue( m_intProperty->get() );
129 130 131

    // do not forget to update the label
    m_asText.setText( valStr );
132 133 134 135 136
}

void WPropertyIntWidget::sliderChanged( int value )
{
    // set the value in the line edit
137
    m_edit.setText( QString( boost::lexical_cast< std::string >( value ).c_str() ) );
138 139

    // set to the property
140
    invalidate( !m_intProperty->set( value ) );    // NOTE: set automatically checks the validity of the value
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
}

void WPropertyIntWidget::editChanged()
{
    // set the value in the line edit
    bool valid;
    int value = m_edit.text().toInt( &valid );
    if ( !valid )
    {
        invalidate();
        return;
    }

    // update slider
    m_slider.setValue( value );

157 158 159 160 161 162 163 164
    // set to the property
    invalidate( !m_intProperty->set( value ) );    // NOTE: set automatically checks the validity of the value
}

void WPropertyIntWidget::textEdited( const QString& text )
{
    // this method does NOT set the property actually, but tries to validate it
    bool valid;
165
    int value = text.toInt( &valid );
166
    if ( !valid )
167 168
    {
        invalidate();
169
        return;
170
    }
171 172 173

    // simply check validity
    invalidate( !m_intProperty->accept( value ) );
174 175
}