mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-08 23:23:01 -06:00
383 lines
15 KiB
C++
383 lines
15 KiB
C++
//##################################################################################################
|
|
//
|
|
// Custom Visualization Core library
|
|
// Copyright (C) 2011-2013 Ceetron AS
|
|
//
|
|
// This library may be used under the terms of either the GNU General Public License or
|
|
// the GNU Lesser General Public License as follows:
|
|
//
|
|
// GNU General Public License Usage
|
|
// This library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
|
// for more details.
|
|
//
|
|
// GNU Lesser General Public License Usage
|
|
// This library 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 2.1 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library 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 at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
|
// for more details.
|
|
//
|
|
//##################################################################################################
|
|
|
|
#include "cafAnimationToolBar.h"
|
|
|
|
#include "cafPopupMenuButton.h"
|
|
|
|
#include <QAction>
|
|
#include <QComboBox>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QToolButton>
|
|
|
|
namespace caf
|
|
{
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
AnimationToolBar::AnimationToolBar( QWidget* parent /*= 0*/ )
|
|
: QToolBar( parent )
|
|
{
|
|
setObjectName( "AnimationToolBar" );
|
|
init();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
AnimationToolBar::AnimationToolBar( const QString& title, QWidget* parent /*= 0*/ )
|
|
: QToolBar( title, parent )
|
|
{
|
|
setObjectName( title );
|
|
init();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::init()
|
|
{
|
|
m_hasAutoTimeStepStrings = true;
|
|
m_slowFrameRate = 0.25;
|
|
m_fastFrameRate = 20;
|
|
|
|
// Create actions and widgets
|
|
m_animSkipToStartAction = new QAction( QIcon( ":/cafAnimControl/SkipToStart.svg" ), tr( "Skip to Start" ), this );
|
|
m_animStepBackwardAction = new QAction( QIcon( ":/cafAnimControl/StepBwd.svg" ), tr( "Step Backward" ), this );
|
|
m_animPauseAction = new QAction( QIcon( ":/cafAnimControl/Pause.svg" ), tr( "Pause" ), this );
|
|
m_animPlayAction = new QAction( QIcon( ":/cafAnimControl/Play.svg" ), tr( "Play" ), this );
|
|
m_animPlayPauseButton = new QToolButton( this );
|
|
m_animPlayPauseButton->setIcon( m_animPlayAction->icon() );
|
|
m_animPlayPauseButton->setToolTip( m_animPlayAction->toolTip() );
|
|
QObject::connect( m_animPlayPauseButton, SIGNAL( clicked() ), this, SLOT( playPauseChanged() ) );
|
|
|
|
m_animStepForwardAction = new QAction( QIcon( ":/cafAnimControl/StepFwd.svg" ), tr( "Step Forward" ), this );
|
|
m_animSkipToEndAction = new QAction( QIcon( ":/cafAnimControl/SkipToEnd.svg" ), tr( "Skip to End" ), this );
|
|
|
|
m_animRepeatFromStartAction =
|
|
new QAction( QIcon( ":/cafAnimControl/RepeatFromStart.svg" ), tr( "Repeat From start" ), this );
|
|
m_animRepeatFromStartAction->setCheckable( true );
|
|
|
|
m_animSpeedButton = new PopupMenuButton( this );
|
|
m_animSpeedButton->setIcon( QIcon( ":/cafAnimControl/Speed.svg" ) );
|
|
m_animSpeedButton->setToolTip( "Adjust Animation Speed" );
|
|
|
|
m_frameRateSlowLabel = new QLabel( this );
|
|
m_frameRateSlowLabel->setPixmap( QPixmap( ":/cafAnimControl/Slow.svg" ) );
|
|
m_frameRateSlowLabel->setToolTip( tr( "Slow" ) );
|
|
|
|
m_frameRateFastLabel = new QLabel( this );
|
|
m_frameRateFastLabel->setPixmap( QPixmap( ":/cafAnimControl/Fast.svg" ) );
|
|
m_frameRateFastLabel->setToolTip( tr( "Fast" ) );
|
|
m_frameRateFastLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
|
|
|
|
m_frameRateSlider = new QSlider( Qt::Horizontal, this );
|
|
m_frameRateSlider->setToolTip( tr( "Animation speed" ) );
|
|
m_frameRateSlider->setMinimumWidth( 100 );
|
|
|
|
m_animSpeedButton->addWidget( m_frameRateSlowLabel );
|
|
m_animSpeedButton->addWidget( m_frameRateSlider );
|
|
m_animSpeedButton->addWidget( m_frameRateFastLabel );
|
|
|
|
m_timestepCombo = new QComboBox( this );
|
|
m_timestepCombo->setSizeAdjustPolicy( QComboBox::AdjustToContents );
|
|
m_timestepCombo->setToolTip( tr( "Current Time Step" ) );
|
|
|
|
QAction* separator1 = new QAction( this );
|
|
separator1->setSeparator( true );
|
|
QAction* separator2 = new QAction( this );
|
|
separator2->setSeparator( true );
|
|
QAction* separator3 = new QAction( this );
|
|
separator3->setSeparator( true );
|
|
|
|
// Add actions and widgets to animation toolbar
|
|
addAction( m_animSkipToStartAction );
|
|
addAction( m_animStepBackwardAction );
|
|
addWidget( m_animPlayPauseButton );
|
|
addAction( m_animStepForwardAction );
|
|
addAction( m_animSkipToEndAction );
|
|
|
|
addAction( separator1 );
|
|
|
|
addAction( m_animRepeatFromStartAction );
|
|
|
|
addAction( separator2 );
|
|
|
|
addWidget( m_animSpeedButton );
|
|
|
|
addAction( separator3 );
|
|
|
|
addWidget( m_timestepCombo );
|
|
|
|
updateAnimationButtons();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::updateAnimationButtons()
|
|
{
|
|
bool isPlaying = m_activeAnimationControl && m_activeAnimationControl->isActive();
|
|
|
|
if ( isPlaying )
|
|
{
|
|
m_animPlayPauseButton->setIcon( m_animPauseAction->icon() );
|
|
m_animPlayPauseButton->setToolTip( m_animPauseAction->toolTip() );
|
|
}
|
|
else
|
|
{
|
|
m_animPlayPauseButton->setIcon( m_animPlayAction->icon() );
|
|
m_animPlayPauseButton->setToolTip( m_animPlayAction->toolTip() );
|
|
}
|
|
|
|
bool isAtStart = m_timestepCombo->count() == 0 || m_timestepCombo->currentIndex() == 0;
|
|
bool isAtEnd = m_timestepCombo->count() > 0 && m_timestepCombo->currentIndex() == m_timestepCombo->count() - 1;
|
|
|
|
// Going backwards actions disabled when we're stopped at the start
|
|
m_animSkipToStartAction->setEnabled( isPlaying || !isAtStart );
|
|
m_animStepBackwardAction->setEnabled( isPlaying || !isAtStart );
|
|
|
|
bool isRepeat = m_activeAnimationControl && m_activeAnimationControl->isRepeatingFromStart();
|
|
|
|
// Going forwards actions disabled when we're stopped at the end
|
|
m_animStepForwardAction->setEnabled( isPlaying || !isAtEnd );
|
|
m_animSkipToEndAction->setEnabled( isPlaying || !isAtEnd );
|
|
// ... however we allow playing if we have repeat on
|
|
m_animPlayPauseButton->setEnabled( isPlaying || isRepeat || !isAtEnd );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::connectAnimationControl( caf::FrameAnimationControl* animationControl )
|
|
{
|
|
// Animation action connections
|
|
if ( m_activeAnimationControl )
|
|
{
|
|
m_activeAnimationControl->disconnect( this, SLOT( slotUpdateAnimationGuiFromFrameIndex( int ) ) );
|
|
m_activeAnimationControl->disconnect( this, SLOT( slotUpdateTimestepList( int ) ) );
|
|
}
|
|
|
|
m_activeAnimationControl = animationControl;
|
|
|
|
m_animSkipToStartAction->disconnect();
|
|
m_animStepBackwardAction->disconnect();
|
|
m_animPauseAction->disconnect();
|
|
m_animPlayAction->disconnect();
|
|
m_animStepForwardAction->disconnect();
|
|
m_animSkipToEndAction->disconnect();
|
|
|
|
m_animRepeatFromStartAction->disconnect();
|
|
|
|
m_timestepCombo->disconnect();
|
|
m_frameRateSlider->disconnect();
|
|
|
|
if ( animationControl )
|
|
{
|
|
connect( m_animSkipToStartAction, SIGNAL( triggered() ), animationControl, SLOT( slotSkipToStart() ) );
|
|
connect( m_animStepBackwardAction, SIGNAL( triggered() ), animationControl, SLOT( slotStepBackward() ) );
|
|
connect( m_animPauseAction, SIGNAL( triggered() ), animationControl, SLOT( slotPause() ) );
|
|
connect( m_animPlayAction, SIGNAL( triggered() ), animationControl, SLOT( slotPlayFwd() ) );
|
|
connect( m_animStepForwardAction, SIGNAL( triggered() ), animationControl, SLOT( slotStepForward() ) );
|
|
connect( m_animSkipToEndAction, SIGNAL( triggered() ), animationControl, SLOT( slotSkipToEnd() ) );
|
|
|
|
m_animRepeatFromStartAction->setChecked( animationControl->isRepeatingFromStart() );
|
|
|
|
connect( m_animRepeatFromStartAction,
|
|
SIGNAL( triggered( bool ) ),
|
|
animationControl,
|
|
SLOT( slotRepeatFromStart( bool ) ) );
|
|
|
|
connect( m_timestepCombo, SIGNAL( currentIndexChanged( int ) ), animationControl, SLOT( setCurrentFrame( int ) ) );
|
|
connect( m_frameRateSlider, SIGNAL( valueChanged( int ) ), this, SLOT( slotFrameRateSliderChanged( int ) ) );
|
|
|
|
connect( animationControl, SIGNAL( changeFrame( int ) ), this, SLOT( slotUpdateAnimationGuiFromFrameIndex( int ) ) );
|
|
connect( animationControl, SIGNAL( frameCountChanged( int ) ), this, SLOT( slotUpdateTimestepList( int ) ) );
|
|
|
|
int timeout = animationControl->timeout();
|
|
double initialFrameRate = 1000;
|
|
if ( timeout > 0 ) initialFrameRate = 1000.0 / timeout;
|
|
setFrameRate( initialFrameRate );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::setFrameRate( double frameRate )
|
|
{
|
|
float sliderRange = m_frameRateSlider->maximum() - m_frameRateSlider->minimum();
|
|
|
|
float frameRateRange = m_fastFrameRate - m_slowFrameRate;
|
|
float normalizedSliderPosition = ( frameRate - m_slowFrameRate ) / frameRateRange;
|
|
float sliderTickValue = sliderRange * normalizedSliderPosition;
|
|
|
|
m_frameRateSlider->blockSignals( true );
|
|
m_frameRateSlider->setValue( static_cast<int>( sliderTickValue ) );
|
|
m_frameRateSlider->blockSignals( false );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::setTimeStepStrings( const QStringList& timeStepStrings )
|
|
{
|
|
if ( timeStepStrings.empty() )
|
|
{
|
|
m_hasAutoTimeStepStrings = true;
|
|
}
|
|
else
|
|
{
|
|
m_hasAutoTimeStepStrings = false;
|
|
}
|
|
|
|
m_timestepCombo->blockSignals( true );
|
|
m_timestepCombo->clear();
|
|
|
|
m_timestepCombo->addItems( timeStepStrings );
|
|
|
|
m_timestepCombo->blockSignals( false );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::setCurrentTimeStepIndex( int index )
|
|
{
|
|
m_timestepCombo->blockSignals( true );
|
|
m_timestepCombo->setCurrentIndex( index );
|
|
updateAnimationButtons();
|
|
m_timestepCombo->blockSignals( false );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::slotFrameRateSliderChanged( int sliderTickValue )
|
|
{
|
|
float sliderRange = m_frameRateSlider->maximum() - m_frameRateSlider->minimum();
|
|
float normalizedSliderPosition = sliderTickValue / sliderRange;
|
|
|
|
float frameRateRange = m_fastFrameRate - m_slowFrameRate;
|
|
float newFrameRate = m_slowFrameRate + frameRateRange * normalizedSliderPosition;
|
|
|
|
if ( newFrameRate > m_fastFrameRate )
|
|
{
|
|
newFrameRate = m_fastFrameRate;
|
|
}
|
|
|
|
if ( newFrameRate < m_slowFrameRate )
|
|
{
|
|
newFrameRate = m_slowFrameRate;
|
|
}
|
|
|
|
setFrameRate( newFrameRate );
|
|
|
|
if ( !m_activeAnimationControl.isNull() )
|
|
m_activeAnimationControl->setTimeout( (int)( 1.0 / newFrameRate * 1000 ) );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::setSlowFrameRate( float frameRate )
|
|
{
|
|
m_slowFrameRate = frameRate;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::setFastFrameRate( float frameRate )
|
|
{
|
|
m_fastFrameRate = frameRate;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::slotUpdateTimestepList( int frameCount )
|
|
{
|
|
QStringList timeStepNames;
|
|
for ( int vIdx = 0; vIdx < frameCount; ++vIdx )
|
|
{
|
|
timeStepNames.append( QString().setNum( vIdx ) );
|
|
}
|
|
m_timestepCombo->blockSignals( true );
|
|
|
|
m_timestepCombo->clear();
|
|
m_timestepCombo->addItems( timeStepNames );
|
|
updateAnimationButtons();
|
|
m_timestepCombo->blockSignals( false );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::playPauseChanged()
|
|
{
|
|
if ( m_activeAnimationControl->isActive() )
|
|
{
|
|
m_animPauseAction->trigger();
|
|
updateAnimationButtons();
|
|
}
|
|
else
|
|
{
|
|
m_animPlayAction->trigger();
|
|
updateAnimationButtons();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void AnimationToolBar::slotUpdateAnimationGuiFromFrameIndex( int value )
|
|
{
|
|
// Update only the combo box index, but do not set current frame
|
|
// Disconnect the signal temporarily when updating UI
|
|
|
|
disconnect( m_timestepCombo,
|
|
SIGNAL( currentIndexChanged( int ) ),
|
|
m_activeAnimationControl,
|
|
SLOT( setCurrentFrame( int ) ) );
|
|
m_timestepCombo->setCurrentIndex( value );
|
|
updateAnimationButtons();
|
|
connect( m_timestepCombo, SIGNAL( currentIndexChanged( int ) ), m_activeAnimationControl, SLOT( setCurrentFrame( int ) ) );
|
|
}
|
|
|
|
} // End namespace caf
|