From 2ed442ea98cd22d2e868e0d134c1068b4da20c68 Mon Sep 17 00:00:00 2001 From: ouv Date: Thu, 23 May 2013 13:02:24 +0000 Subject: [PATCH] Issue 0001620: External 20621: C2/C3, 3D graph --- src/LightApp/LightApp_Application.cxx | 54 +- src/LightApp/LightApp_Application.h | 3 +- src/LightApp/resources/LightApp_msg_en.ts | 10 +- src/LightApp/resources/LightApp_msg_fr.ts | 14 +- src/SVTK/Plot3d_ViewManager.cxx | 36 + src/SVTK/Plot3d_ViewManager.h | 40 + src/SVTK/Plot3d_ViewModel.cxx | 46 + src/SVTK/Plot3d_ViewModel.h | 44 + src/SVTK/SVTK_CubeAxesActor2D.cxx | 12 +- src/SVTK/SVTK_CubeAxesActor2D.h | 8 +- src/SVTK/SVTK_CubeAxesDlg.cxx | 8 + src/SVTK/SVTK_CubeAxesDlg.h | 2 + src/SVTK/SVTK_DoubleSpinBox.cxx | 1249 +++++++++++++++++++++ src/SVTK/SVTK_DoubleSpinBox.h | 205 ++++ src/SVTK/SVTK_InteractorStyle.cxx | 21 +- src/SVTK/SVTK_InteractorStyle.h | 5 + src/SVTK/SVTK_NonIsometricDlg.cxx | 39 +- src/SVTK/SVTK_NonIsometricDlg.h | 8 +- src/SVTK/SVTK_Renderer.cxx | 28 + src/SVTK/SVTK_Renderer.h | 8 + src/SVTK/SVTK_ViewManager.cxx | 6 +- src/SVTK/SVTK_ViewManager.h | 4 +- src/SVTK/SVTK_ViewWindow.cxx | 151 ++- src/SVTK/SVTK_ViewWindow.h | 34 +- src/SVTK/resources/SVTK_images.ts | 4 + src/SVTK/resources/SVTK_msg_en.ts | 15 + src/SVTK/resources/vtk_view_mode_2d.png | Bin 0 -> 601 bytes 27 files changed, 1997 insertions(+), 57 deletions(-) create mode 100644 src/SVTK/Plot3d_ViewManager.cxx create mode 100644 src/SVTK/Plot3d_ViewManager.h create mode 100644 src/SVTK/Plot3d_ViewModel.cxx create mode 100644 src/SVTK/Plot3d_ViewModel.h create mode 100644 src/SVTK/SVTK_DoubleSpinBox.cxx create mode 100644 src/SVTK/SVTK_DoubleSpinBox.h create mode 100644 src/SVTK/resources/vtk_view_mode_2d.png diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 6710875aa..a6380cbdd 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -95,6 +95,15 @@ #endif #endif +#ifndef DISABLE_PLOT3DVIEWER +#ifndef DISABLE_SALOMEOBJECT + #include + #include + #include "LightApp_VTKSelector.h" + #include +#endif +#endif + #ifndef DISABLE_OCCVIEWER #include #ifndef DISABLE_SALOMEOBJECT @@ -605,17 +614,20 @@ void LightApp_Application::createActions() #ifndef DISABLE_PLOT2DVIEWER createActionForViewer( NewPlot2dId, newWinMenu, QString::number( 1 ), Qt::ALT+Qt::Key_P ); #endif +#ifndef DISABLE_PLOT3DVIEWER + createActionForViewer( NewPlot3dId, newWinMenu, QString::number( 2 ), Qt::ALT+Qt::Key_L ); +#endif #ifndef DISABLE_OCCVIEWER - createActionForViewer( NewOCCViewId, newWinMenu, QString::number( 2 ), Qt::ALT+Qt::Key_O ); + createActionForViewer( NewOCCViewId, newWinMenu, QString::number( 3 ), Qt::ALT+Qt::Key_O ); #endif #ifndef DISABLE_VTKVIEWER - createActionForViewer( NewVTKViewId, newWinMenu, QString::number( 3 ), Qt::ALT+Qt::Key_K ); + createActionForViewer( NewVTKViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_K ); #endif #ifndef DISABLE_QXGRAPHVIEWER - createActionForViewer( NewQxGraphViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_C ); + createActionForViewer( NewQxGraphViewId, newWinMenu, QString::number( 5 ), Qt::ALT+Qt::Key_C ); #endif #ifndef DISABLE_GRAPHICSVIEWER - createActionForViewer( NewGraphicsViewId, newWinMenu, QString::number( 5 ), Qt::ALT+Qt::Key_R ); + createActionForViewer( NewGraphicsViewId, newWinMenu, QString::number( 6 ), Qt::ALT+Qt::Key_R ); #endif createAction( RestoreDefaultId, tr( "TOT_RESTORE_DEFAULT" ), QIcon(), @@ -718,6 +730,11 @@ void LightApp_Application::onNewWindow() type = Plot2d_Viewer::Type(); break; #endif +#ifndef DISABLE_PLOT3DVIEWER + case NewPlot3dId: + type = Plot3d_Viewer::Type(); + break; +#endif #ifndef DISABLE_OCCVIEWER case NewOCCViewId: type = OCCViewer_Viewer::Type(); @@ -842,6 +859,12 @@ void LightApp_Application::updateCommandsStatus() a->setEnabled( activeStudy() ); #endif +#ifndef DISABLE_PLOT3DVIEWER + a = action( NewPlot3dId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif + #ifndef DISABLE_OCCVIEWER a = action( NewOCCViewId ); if( a ) @@ -1330,6 +1353,29 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) ); } } +#endif +#ifndef DISABLE_PLOT3DVIEWER +#ifndef DISABLE_SALOMEOBJECT + if ( vmType == Plot3d_Viewer::Type() ) + { + viewMgr = new Plot3d_ViewManager( activeStudy(), desktop() ); + Plot3d_Viewer* vm = dynamic_cast( viewMgr->getViewModel() ); + if( vm ) + { + vm->setProjectionMode( resMgr->integerValue( "VTKViewer", "projection_mode", vm->projectionMode() ) ); + vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) ); + vm->setTrihedronSize( resMgr->doubleValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ), + resMgr->booleanValue( "VTKViewer", "relative_size", vm->trihedronRelative() ) ); + vm->setInteractionStyle( resMgr->integerValue( "VTKViewer", "navigation_mode", vm->interactionStyle() ) ); + vm->setIncrementalSpeed( resMgr->integerValue( "VTKViewer", "speed_value", vm->incrementalSpeed() ), + resMgr->integerValue( "VTKViewer", "speed_mode", vm->incrementalSpeedMode() ) ); + vm->setSpacemouseButtons( resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", vm->spacemouseBtn(1) ), + resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", vm->spacemouseBtn(2) ), + resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", vm->spacemouseBtn(3) ) ); + new LightApp_VTKSelector( vm, mySelMgr ); + } + } +#endif #endif //#ifndef DISABLE_SUPERVGRAPHVIEWER // if( vmType == SUPERVGraph_Viewer::Type() ) diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index 3815ec437..1a0ae0c06 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -78,7 +78,8 @@ public: CloseId, CloseAllId, GroupAllId, RestoreDefaultId, RestoreFromPrefsId, PreferencesId, MRUId, ModulesListId, - NewGLViewId, NewPlot2dId, NewOCCViewId, NewVTKViewId, NewQxGraphViewId, + NewGLViewId, NewPlot2dId, NewPlot3dId, + NewOCCViewId, NewVTKViewId, NewQxGraphViewId, NewGraphicsViewId, UserID }; protected: diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 6cdfcf194..3c8b56c66 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -351,18 +351,22 @@ CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS NEW_WINDOW_2 - &OCC view + P&lot3d view NEW_WINDOW_3 - VT&K view + &OCC view NEW_WINDOW_4 - &QxGraph view + VT&K view NEW_WINDOW_5 + &QxGraph view + + + NEW_WINDOW_6 G&raphics view diff --git a/src/LightApp/resources/LightApp_msg_fr.ts b/src/LightApp/resources/LightApp_msg_fr.ts index b88a546b7..9a2e14cae 100755 --- a/src/LightApp/resources/LightApp_msg_fr.ts +++ b/src/LightApp/resources/LightApp_msg_fr.ts @@ -343,26 +343,30 @@ CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS NEW_WINDOW_0 - Vue &GL + Vue &GL NEW_WINDOW_1 - Vue &Plot2d + Vue &Plot2d NEW_WINDOW_2 - Vue &OCC + Vue P&lot3d NEW_WINDOW_3 - Vue VT&K + Vue &OCC NEW_WINDOW_4 - Vue &QxGraph + Vue VT&K NEW_WINDOW_5 + Vue &QxGraph + + + NEW_WINDOW_6 Vue Qx&Scene diff --git a/src/SVTK/Plot3d_ViewManager.cxx b/src/SVTK/Plot3d_ViewManager.cxx new file mode 100644 index 000000000..0b8e48048 --- /dev/null +++ b/src/SVTK/Plot3d_ViewManager.cxx @@ -0,0 +1,36 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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 for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "Plot3d_ViewManager.h" +#include "Plot3d_ViewModel.h" + +/*! + Constructor +*/ +Plot3d_ViewManager::Plot3d_ViewManager( SUIT_Study* study, SUIT_Desktop* theDesktop ) +: SVTK_ViewManager( study, theDesktop, new Plot3d_Viewer() ) +{ + setTitle( Plot3d_ViewManager::tr( "PLOT3D_VIEW_TITLE" ) ); +} + +/*! + Destructor +*/ +Plot3d_ViewManager::~Plot3d_ViewManager() +{ +} diff --git a/src/SVTK/Plot3d_ViewManager.h b/src/SVTK/Plot3d_ViewManager.h new file mode 100644 index 000000000..61fa7fb37 --- /dev/null +++ b/src/SVTK/Plot3d_ViewManager.h @@ -0,0 +1,40 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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 for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef PLOT3D_VIEWMANAGER_H +#define PLOT3D_VIEWMANAGER_H + +#include "SVTK.h" +#include "SVTK_ViewManager.h" + +class SUIT_Desktop; + +//! Extend Plot3d_ViewManager to deal with Plot3d_Viewer +class SVTK_EXPORT Plot3d_ViewManager : public SVTK_ViewManager +{ + Q_OBJECT + +public: + //! Construct the view manager + Plot3d_ViewManager( SUIT_Study* study, SUIT_Desktop* ); + + //! Destroy the view manager + virtual ~Plot3d_ViewManager(); +}; + +#endif diff --git a/src/SVTK/Plot3d_ViewModel.cxx b/src/SVTK/Plot3d_ViewModel.cxx new file mode 100644 index 000000000..5037c5ca1 --- /dev/null +++ b/src/SVTK/Plot3d_ViewModel.cxx @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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 for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "Plot3d_ViewModel.h" + +#include "SVTK_ViewWindow.h" + +/*! + Constructor +*/ +Plot3d_Viewer::Plot3d_Viewer() +{ +} + +/*! + Destructor +*/ +Plot3d_Viewer::~Plot3d_Viewer() +{ +} + +/*!Create new instance of view window on desktop \a theDesktop. + *\retval SUIT_ViewWindow* - created view window pointer. + */ +SUIT_ViewWindow* Plot3d_Viewer::createView( SUIT_Desktop* theDesktop ) +{ + SUIT_ViewWindow* aViewWindow = SVTK_Viewer::createView( theDesktop ); + if( SVTK_ViewWindow* aSVTKViewWindow = dynamic_cast( aViewWindow ) ) + aSVTKViewWindow->SetMode2DEnabled( true ); + return aViewWindow; +} diff --git a/src/SVTK/Plot3d_ViewModel.h b/src/SVTK/Plot3d_ViewModel.h new file mode 100644 index 000000000..3aaeabf33 --- /dev/null +++ b/src/SVTK/Plot3d_ViewModel.h @@ -0,0 +1,44 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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 for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef PLOT3D_VIEWMODEL_H +#define PLOT3D_VIEWMODEL_H + +#include "SVTK.h" +#include "SVTK_ViewModel.h" + +//! Extends interface #SVTK_Viewer +class SVTK_EXPORT Plot3d_Viewer : public SVTK_Viewer +{ + Q_OBJECT; + +public: + //! Define string representation of the viewer type + static QString Type() { return "Plot3d"; } + + Plot3d_Viewer(); + virtual ~Plot3d_Viewer(); + + //! See #SUIT_ViewModel::createView + virtual SUIT_ViewWindow* createView( SUIT_Desktop* ); + + //! See #SUIT_ViewModel::getType + virtual QString getType() const { return Type(); } +}; + +#endif diff --git a/src/SVTK/SVTK_CubeAxesActor2D.cxx b/src/SVTK/SVTK_CubeAxesActor2D.cxx index f8e65b9b9..31b442484 100644 --- a/src/SVTK/SVTK_CubeAxesActor2D.cxx +++ b/src/SVTK/SVTK_CubeAxesActor2D.cxx @@ -127,6 +127,7 @@ SVTK_CubeAxesActor2D::SVTK_CubeAxesActor2D() aTLProp->Delete(); + this->IsInvertedGrid = false; } SVTK_CubeAxesActor2D::~SVTK_CubeAxesActor2D() @@ -462,9 +463,9 @@ int SVTK_CubeAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport) // YCoords coordinates for Y grid vtkFloatArray *YCoords = vtkFloatArray::New(); #ifndef WIN32 - for(int i=0;iInsertNextValue(val); @@ -549,6 +550,13 @@ int SVTK_CubeAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport) if ( vtkMath::Dot(vecs[4],aCDirection) < vtkMath::Dot(vecs[5],aCDirection)) replaceXZ = true; + if( GetIsInvertedGrid() ) + { + replaceXY = !replaceXY; + replaceYZ = !replaceYZ; + replaceXZ = !replaceXZ; + } + if(replaceXY) this->planeXY->SetExtent(0,numOfLabelsX, 0,numOfLabelsY, numOfLabelsZ,numOfLabelsZ); else this->planeXY->SetExtent(0,numOfLabelsX, 0,numOfLabelsY, 0,0); diff --git a/src/SVTK/SVTK_CubeAxesActor2D.h b/src/SVTK/SVTK_CubeAxesActor2D.h index 27cbf657f..71ca0669a 100644 --- a/src/SVTK/SVTK_CubeAxesActor2D.h +++ b/src/SVTK/SVTK_CubeAxesActor2D.h @@ -82,7 +82,10 @@ public: void SetTransform(VTKViewer_Transform* theTransform); VTKViewer_Transform* GetTransform(); - + + vtkSetMacro(IsInvertedGrid, bool); + vtkGetMacro(IsInvertedGrid, bool); + protected: SVTK_CubeAxesActor2D(); ~SVTK_CubeAxesActor2D(); @@ -105,6 +108,9 @@ private: vtkPolyDataMapper *rgridMapperXZ; vtkSmartPointer m_Transform; + + bool IsInvertedGrid; + private: SVTK_CubeAxesActor2D(const SVTK_CubeAxesActor2D&); // Not implemented. void operator=(const SVTK_CubeAxesActor2D&); // Not implemented. diff --git a/src/SVTK/SVTK_CubeAxesDlg.cxx b/src/SVTK/SVTK_CubeAxesDlg.cxx index 8126a0a4d..c8f46c7b9 100644 --- a/src/SVTK/SVTK_CubeAxesDlg.cxx +++ b/src/SVTK/SVTK_CubeAxesDlg.cxx @@ -474,6 +474,14 @@ void SVTK_CubeAxesDlg::Update() myIsVisible->setChecked(myActor->GetVisibility() ? true : false); } +/*! + Show/hide tab with Z-dimension controls +*/ +void SVTK_CubeAxesDlg::SetDimensionZEnabled( const bool theIsEnabled ) +{ + myTabWg->setTabEnabled( 2, theIsEnabled ); +} + /*! Verify validity of entry data */ diff --git a/src/SVTK/SVTK_CubeAxesDlg.h b/src/SVTK/SVTK_CubeAxesDlg.h index 05a3dbda7..e43cb6d5c 100644 --- a/src/SVTK/SVTK_CubeAxesDlg.h +++ b/src/SVTK/SVTK_CubeAxesDlg.h @@ -59,6 +59,8 @@ public: void Update(); + void SetDimensionZEnabled( const bool theIsEnabled ); + private slots: void onOk(); bool onApply(); diff --git a/src/SVTK/SVTK_DoubleSpinBox.cxx b/src/SVTK/SVTK_DoubleSpinBox.cxx new file mode 100644 index 000000000..0a5177a0a --- /dev/null +++ b/src/SVTK/SVTK_DoubleSpinBox.cxx @@ -0,0 +1,1249 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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 for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "SVTK_DoubleSpinBox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//****************************************************************************** +// QDblRangeControl class +//****************************************************************************** + +/*! + Constructs a range control with min value 0.00, max value 99.99, + line step 0.1, page step 1.00, precision 6, double precision 10e-6, + convertion flag 'g' and initial value 0.00. +*/ +QDblRangeControl::QDblRangeControl() +{ + prec = 6; + dblPrec = 10e-6; + convFlag = 'g'; + minVal = roundPrecision( 0.00 ); + maxVal = roundPrecision( 99.99 ); + line = roundPrecision( 0.10 ); + page = roundPrecision( 1.00 ); + prevVal = roundPrecision( -0.10 ); + val = bound( 0.00 ); +} + +/*! + Constructs a range control whose value can never be smaller than + or greater than , whose line step size is + and page step size is and whose value is + initially (which is guaranteed to be in range using bound()), + precision is , double precision is and + convertion flag is +*/ +QDblRangeControl::QDblRangeControl( double minValue, double maxValue, + double lineStep, double pageStep, + double value, + int precision, + double dblPrecision, + char cFlag ) +{ + prec = precision; + dblPrec = dblPrecision; + convFlag = cFlag; + minVal = roundPrecision( minValue ); + maxVal = roundPrecision( maxValue ); + line = roundPrecision( qAbs( lineStep ) ); + page = roundPrecision( qAbs( pageStep ) ); + prevVal = roundPrecision( minVal - 0.1 ); + val = bound( value ); +} + +/*! + Destroys the range control +*/ +QDblRangeControl::~QDblRangeControl() +{ +} + +/*! + Returns the current range control value. This is guaranteed to be + within the range [minValue(), maxValue()]. +*/ +inline double QDblRangeControl::value() const +{ return val; } + +/*! + Sets the range control's value to and forces it to be within + the legal range. + Calls the virtual valueChange() function if the new value is + different from the previous value. The old value can still be + retrieved using prevValue(). +*/ +void QDblRangeControl::setValue( double value ) +{ + directSetValue( value ); + if ( !equal(prevVal, val ) ) + valueChange(); +} + +/*! + Equivalent to {setValue( value() + pageStep() )}. + If the value is changed, then valueChange() is called. +*/ +void QDblRangeControl::addPage() +{ + setValue( value() + pageStep() ); +} + +/*! + Equivalent to {setValue( value() - pageStep() )}. + If the value is changed, then valueChange() is called. +*/ +void QDblRangeControl::subtractPage() +{ + setValue( value() - pageStep() ); +} + +/*! + Equivalent to {setValue( value() + lineStep() )}. + If the value is changed, then valueChange() is called. +*/ +void QDblRangeControl::addLine() +{ + setValue( value() + lineStep() ); +} + +/*! + Equivalent to {setValue( value() - lineStep() )}. + If the value is changed, then valueChange() is called. +*/ +void QDblRangeControl::subtractLine() +{ + setValue( value() - lineStep() ); +} + +/*! + Returns the current minimum value of the range. +*/ +inline double QDblRangeControl::minValue() const +{ return minVal; } + +/*! + Returns the current maximum value of the range. +*/ +inline double QDblRangeControl::maxValue() const +{ return maxVal; } + +/*! + Sets the range control's min value to and its max value + to . + + Calls the virtual rangeChange() function if one or both of the new + min and max values are different from the previous setting. Calls + the virtual valueChange() function if the current value is adjusted + because it was outside the new range. + + If is smaller than , becomes the + only legal value. +*/ +void QDblRangeControl::setRange( double minValue, double maxValue ) +{ + minValue = roundPrecision( minValue ); + maxValue = roundPrecision( maxValue ); + if ( minValue > maxValue ) { + maxValue = minValue; + } + if ( equal( minValue, minVal ) && equal( maxValue, maxVal ) ) + return; + minVal = minValue; + maxVal = maxValue; + double tmp = bound( val ); + rangeChange(); + if ( !equal( tmp, val ) ) { + prevVal = val; + val = tmp; + valueChange(); + } +} + +/*! + Sets the current minimum value of the range to . + If necessary, the maxValue() is adjusted so that the range remains + valid. +*/ +void QDblRangeControl::setMinValue( double minVal ) +{ + double maxVal = maxValue(); + if ( maxVal < minVal ) + maxVal = minVal; + setRange( minVal, maxVal ); +} + +/*! + Sets the current maximum value of the range to . + If necessary, the minValue() is adjusted so that the range remains + valid. +*/ +void QDblRangeControl::setMaxValue( double maxVal ) +{ + double minVal = minValue(); + if ( minVal > maxVal ) + minVal = maxVal; + setRange( minVal, maxVal ); +} + +/*! + Returns the current line step. +*/ +inline double QDblRangeControl::lineStep() const +{ return line; } + +/*! + Returns the current page step. +*/ +inline double QDblRangeControl::pageStep() const +{ return page; } + +/*! + Sets the range line step to and page step to . + Calls the virtual stepChange() function if the new line step and/or + page step are different from the previous settings. +*/ +void QDblRangeControl::setSteps( double lineStep, double pageStep ) +{ + lineStep = roundPrecision( qAbs( lineStep ) ); + pageStep = roundPrecision( qAbs( pageStep ) ); + if ( !equal( lineStep, line ) || !equal( pageStep, page ) ) { + line = lineStep; + page = pageStep; + stepChange(); + } +} + +/*! + Returs precision ( see QString::setNum() for details ) +*/ +int QDblRangeControl::precision() const +{ return prec; } + +/*! + Sets precision ( see QString::setNum() for details ) +*/ +void QDblRangeControl::setPrecision( int precision ) +{ + if ( precision > 0 && prec != precision ) { + prec = precision; + setRange( minValue(), maxValue() ); + setSteps( lineStep(), pageStep() ); + } +} + +/*! + Returns double precision which is used for rounding amd comparing + of double numbers +*/ +double QDblRangeControl::dblPrecision() const +{ return dblPrec; } + +/*! + Sets double precision which is used for rounding amd comparing + of double numbers +*/ +void QDblRangeControl::setDblPrecision( double dblPrecision ) +{ + dblPrecision = qAbs( dblPrecision ); + if ( dblPrecision > 0 && dblPrecision != dblPrec ) { + dblPrec = dblPrecision; + setRange( minValue(), maxValue() ); + setSteps( lineStep(), pageStep() ); + } +} + +/*! + Returns convertion flag ( see QString::setNum() for details ) +*/ +char QDblRangeControl::convertFlag() const +{ return convFlag; } + +/*! + Sets convertion flag ( see QString::setNum() for details ) +*/ +void QDblRangeControl::setConvertFlag( char cFlag ) +{ + if ( ( cFlag == 'f' || cFlag == 'F' || cFlag == 'e' || + cFlag == 'E' || cFlag == 'g' || cFlag == 'G' ) && + ( cFlag != convFlag ) ) { + convFlag = cFlag; + setRange( minValue(), maxValue() ); + setSteps( lineStep(), pageStep() ); + } +} + +/*! + Forces the value to be within the range from minValue() to + maxValue() inclusive, and returns the result. + + This function is provided so that you can easily force other numbers + than value() into the allowed range. You do not need to call it in + order to use QDblRangeControl itself. +*/ +double QDblRangeControl::bound( double v ) const +{ + if ( v < minVal ) + return minVal; + if ( v > maxVal ) + return maxVal; + return roundPrecision( v ); +} + +/*! + Sets the range control value directly without calling valueChange(). + Forces the new value to be within the legal range. + + You will rarely have to call this function. However, if you want to + change the range control's value inside the overloaded method + valueChange(), setValue() would call the function valueChange() + again. To avoid this recursion you must use directSetValue() + instead. +*/ +void QDblRangeControl::directSetValue( double value ) +{ + prevVal = val; + val = bound( value ); +} + +/*! + Returns the previous value of the range control. "Previous value" + means the value before the last change occurred. Setting a new range + may affect the value, too, because the value is forced to be inside + the specified range. When the range control is initially created, + this is the same as value(). + + prevValue() can be outside the current legal range if a call to + setRange() causes the current value to change. For example, if the + range was [0, 1000] and the current value is 500, setRange(0, 400) + makes value() return 400 and prevValue() return 500. +*/ +inline double QDblRangeControl::prevValue() const +{ return prevVal; } + +/*! + This virtual function is called whenever the range control value + changes. You can reimplement it if you want to be notified when the + value changes. The default implementation does nothing. + + Note that this method is called after the value changed. The previous + value can be retrieved using prevValue(). +*/ +void QDblRangeControl::valueChange() +{ +} + +/*! + This virtual function is called whenever the range control's range + changes. You can reimplement it if you want to be notified when the range + changes. The default implementation does nothing. + + Note that this method is called after the range changed. +*/ +void QDblRangeControl::rangeChange() +{ +} + +/*! + This virtual function is called whenever the range control's + line/page step settings change. You can reimplement it if you want + to be notified when the step changes. The default implementation + does nothing. + + Note that this method is called after the step settings change. +*/ +void QDblRangeControl::stepChange() +{ +} + +/*! + returns true if values qre equal ( with tolerance = dblPrecision() ) +*/ +bool QDblRangeControl::equal( double first, double second ) const +{ + return qAbs( first - second ) < dblPrecision(); +} + +/*! + Retuns rounded value +*/ +double QDblRangeControl::roundPrecision( double value) const +{ + bool bOk; + QString convertor; + convertor.setNum( value, convertFlag(), precision() ); + double newValue = convertor.toDouble(&bOk); + if ( bOk ) { + if ( qAbs( newValue ) < dblPrecision() ) + newValue = 0.0; + } + else { + newValue = value; + } + return newValue; +} + +//****************************************************************************** +// QAD_SpinBox class +//****************************************************************************** + +/*! + Returns true if ends by [ static ] +*/ +static bool endsWith(const QString& str, const QString& substr) +{ +#if QT_VERSION < 0x030000 + if ( str.length() < substr.length() ) + return false; + return ( str.right( substr.length() ) == substr ); +#else + return str.endsWith(substr); +#endif +} + +/*! + Validator class for double value spin box +*/ +class SVTK_DoubleSpinBoxValidator: public QDoubleValidator +{ +public: + SVTK_DoubleSpinBoxValidator( SVTK_DoubleSpinBox* sb, const char* name ); + + State validate( QString& str, int& pos ) const; + +private: + SVTK_DoubleSpinBox* spinBox; +}; + +SVTK_DoubleSpinBoxValidator::SVTK_DoubleSpinBoxValidator( SVTK_DoubleSpinBox* sb, const char* name ) +: QDoubleValidator( sb ), + spinBox( sb ) +{ +} + +/*! + Validates data entered +*/ +QValidator::State SVTK_DoubleSpinBoxValidator::validate( QString& str, int& pos ) const +{ + QString pref = spinBox->prefix(); + QString suff = spinBox->suffix(); + uint overhead = pref.length() + suff.length(); + State state = Invalid; + + ((QDoubleValidator *) this)->setRange( spinBox->minValue(), + spinBox->maxValue() ); + if ( overhead == 0 ) { + state = QDoubleValidator::validate( str, pos ); + } else { + if ( str.length() >= overhead && + str.startsWith(pref) && + endsWith(str, suff) ) { + QString core = str.mid( pref.length(), str.length() - overhead ); + int corePos = pos - pref.length(); + state = QDoubleValidator::validate( core, corePos ); + pos = corePos + pref.length(); + str.replace( pref.length(), str.length() - overhead, core ); + } else { + state = QDoubleValidator::validate( str, pos ); + if ( state == Invalid ) { + // simplified(), cf. SVTK_DoubleSpinBox::interpretText() + QString special = spinBox->specialValueText().simplified(); + QString candidate = str.simplified(); + + if ( special.startsWith(candidate) ) { + if ( candidate.length() == special.length() ) { + state = Acceptable; + } else { + state = Intermediate; + } + } + } + } + } + return state; +} + +/*! + Creates a spin box with min value 0.00, max value 99.99, + line step 0.1, precision 6, double precision 10e-6, + convertion flag 'g' and initial value 0.00. +*/ +SVTK_DoubleSpinBox::SVTK_DoubleSpinBox( QWidget* parent ) +: QFrame(parent), + QDblRangeControl() +{ + initSpinBox(); +} + +/*! + Constructor + Creates a spin box with min value , max value , + line step , precision , double precision , + convertion flag and initial value +*/ +SVTK_DoubleSpinBox::SVTK_DoubleSpinBox( QWidget* parent, + double minValue, + double maxValue, + double step, + int precision, + double dblPrecision, + char cFlag ) +: QFrame( parent ), + QDblRangeControl( minValue, maxValue, step, step, minValue, precision, dblPrecision, cFlag ) +{ + initSpinBox(); +} + +/*! + Destructor +*/ +SVTK_DoubleSpinBox::~SVTK_DoubleSpinBox() +{} + +/*! + Internal initialization. +*/ +void SVTK_DoubleSpinBox::initSpinBox() +{ + wrap = FALSE; + edited = FALSE; + butSymbols = UpDownArrows; + selreq = FALSE; + + up = new QPushButton( this ); + up->setFocusPolicy( Qt::NoFocus ); + up->setAutoDefault( FALSE ); + up->setAutoRepeat( TRUE ); + + down = new QPushButton( this ); + down->setFocusPolicy( Qt::NoFocus ); + down->setAutoDefault( FALSE ); + down->setAutoRepeat( TRUE ); + + validate = new SVTK_DoubleSpinBoxValidator( this, "validator" ); + vi = new QLineEdit( this ); + vi->setFrame( FALSE ); + setFocusProxy( vi ); + setFocusPolicy( Qt::StrongFocus ); + vi->setValidator( validate ); + vi->installEventFilter( this ); + + setFrameStyle( Panel | Sunken ); + setLineWidth( 2 ); + +// setPalettePropagation( AllChildren ); +// setFontPropagation( AllChildren ); + + setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ) ); + updateDisplay(); + + connect( up, SIGNAL(pressed()), SLOT(stepUp()) ); + connect( down, SIGNAL(pressed()), SLOT(stepDown()) ); + connect( vi, SIGNAL(textChanged(const QString&)), SLOT(textChanged()) ); +} + +/*! + Returns the current text of the spin box, including any prefix() and suffix(). +*/ +QString SVTK_DoubleSpinBox::text() const +{ + return vi->text(); +} + +/*! + Returns a copy of the current text of the spin box with any prefix + and/or suffix and white space at the start and end removed. +*/ +QString SVTK_DoubleSpinBox::cleanText() const +{ + QString s = QString(text()).simplified(); + if ( !prefix().isEmpty() ) { + QString px = QString(prefix()).simplified(); + int len = px.length(); + if ( len && s.left(len) == px ) // Remove _only_ if it is the prefix + s.remove( 0, len ); + } + if ( !suffix().isEmpty() ) { + QString sx = QString(suffix()).simplified(); + int len = sx.length(); + if ( len && s.right(len) == sx ) // Remove _only_ if it is the suffix + s.truncate( s.length() - len ); + } + return s.simplified(); +} + +/*! + Sets the special-value text to text. If set, the spin box will + display this text instead of a numeric value whenever the current + value is equal to minVal(). Typically used for indicating that this + choice has a special (default) meaning. +*/ +void SVTK_DoubleSpinBox::setSpecialValueText( const QString &text ) +{ + specText = text; + updateDisplay(); +} + +/*! + Returns the currently special-value text, or a null string if no + special-value text is currently set. +*/ +QString SVTK_DoubleSpinBox::specialValueText() const +{ + if ( specText.isEmpty() ) + return QString::null; + else + return specText; +} + +/*! + Sets the prefix to . The prefix is prepended to the start of + the displayed value. Typical use is to indicate the unit of + measurement to the user. +*/ +void SVTK_DoubleSpinBox::setPrefix( const QString &text ) +{ + pfix = text; + updateDisplay(); +} + +/*! + Sets the suffix to . The suffix is appended to the end of the + displayed value. Typical use is to indicate the unit of measurement + to the user. +*/ +void SVTK_DoubleSpinBox::setSuffix( const QString &text ) +{ + sfix = text; + updateDisplay(); +} + +/*! + Returns the currently set prefix, or a null string if no prefix is set. +*/ +QString SVTK_DoubleSpinBox::prefix() const +{ + if ( pfix.isEmpty() ) + return QString::null; + else + return pfix; +} + +/*! + Returns the currently set suffix, or a null string if no suffix is set. +*/ +QString SVTK_DoubleSpinBox::suffix() const +{ + if ( sfix.isEmpty() ) + return QString::null; + else + return sfix; +} + +/*! + Setting wrapping to TRUE will allow the value to be stepped from the + highest value to the lowest, and vice versa. By default, wrapping is + turned off. +*/ +void SVTK_DoubleSpinBox::setWrapping( bool on ) +{ + wrap = on; + updateDisplay(); +} + +/*! + Returns the current setWrapping() value. +*/ +bool SVTK_DoubleSpinBox::wrapping() const +{ + return wrap; +} + +/*! + Reimplementation +*/ +QSize SVTK_DoubleSpinBox::sizeHint() const +{ + ensurePolished(); + QFontMetrics fm = fontMetrics(); + int h = vi->sizeHint().height(); + if ( h < 12 ) // ensure enough space for the button pixmaps + h = 12; + int w = 35; // minimum width for the value + int wx = fm.width( ' ' )*2; + QString s; + + SVTK_DoubleSpinBox* that = (SVTK_DoubleSpinBox*)this; + s = prefix() + that->mapValueToText( that->minValue() ) + suffix(); + w = qMax( w, fm.width( s ) + wx); + s = prefix() + that->mapValueToText( that->maxValue() ) + suffix(); + w = qMax(w, fm.width( s ) + wx ); + if ( !specialValueText().isEmpty() ) { + s = specialValueText(); + w = qMax( w, fm.width( s ) + wx ); + } + QSize r( h * 8/5 // ~ buttons width + + w // widest value + + frameWidth() * 2, // left/right frame + frameWidth() * 2 // top/bottom frame + + h // font height + ); + return r.expandedTo( QApplication::globalStrut() ); +} + +/*! + Does the layout of the lineedit and the buttons +*/ +void SVTK_DoubleSpinBox::arrangeWidgets() +{ + if ( !up || !down ) // may happen if the application has a pointer error + return; + + QSize bs; // no, it's short for 'button size' + bs.setHeight( height()/2 - frameWidth() ); + if ( bs.height() < 8 ) + bs.setHeight( 8 ); + bs.setWidth( bs.height() * 8 / 5 ); // 1.6 - approximate golden mean + setFrameRect( QRect( 0, 0, 0, 0 ) ); + + if ( up->size() != bs || down->size() != bs ) { + up->resize( bs ); + down->resize( bs ); + updateButtonSymbols(); + } + + int y = frameWidth(); + int x = width() - y - bs.width(); + up->move( x, y ); + down->move( x, height() - y - up->height() ); + vi->setGeometry( frameWidth(), frameWidth(), + x - frameWidth(), height() - 2*frameWidth() ); +} + +/*! + Sets the current value of the spin box to . This is + QRangeControl::setValue() made available as a slot. +*/ +void SVTK_DoubleSpinBox::setValue( double value ) +{ + QDblRangeControl::setValue( value ); +} + +/*! + Increases the current value one step, wrapping as necessary. This is + the same as clicking on the pointing-up button, and can be used for + e.g. keyboard accelerators. +*/ +void SVTK_DoubleSpinBox::stepUp() +{ + if ( edited ) + interpretText(); + if ( wrapping() && ( value()+lineStep() > maxValue() ) ) + setValue( minValue() ); + else + addLine(); +} + +/*! + Decreases the current value one step, wrapping as necessary. This is + the same as clicking on the pointing-down button, and can be used + for e.g. keyboard accelerators. +*/ +void SVTK_DoubleSpinBox::stepDown() +{ + if ( edited ) + interpretText(); + if ( wrapping() && ( value()-lineStep() < minValue() ) ) + setValue( maxValue() ); + else + subtractLine(); +} + +/*! + Intercepts and handles those events coming to the embedded QLineEdit + which have special meaning for the SVTK_DoubleSpinBox. +*/ +bool SVTK_DoubleSpinBox::eventFilter( QObject* obj, QEvent* ev ) +{ + if ( obj != vi ) + return FALSE; + + if ( ev->type() == QEvent::KeyPress ) { + QKeyEvent* k = (QKeyEvent*)ev; + + bool retval = FALSE; // workaround for MSVC++ optimization bug + if( (k->key() == Qt::Key_Tab) || (k->key() == Qt::Key_Backtab) ){ + if ( edited ) + interpretText(); + qApp->sendEvent( this, ev ); + retval = TRUE; + } if ( k->key() == Qt::Key_Up ) { + stepUp(); + retval = TRUE; + } else if ( k->key() == Qt::Key_Down ) { + stepDown(); + retval = TRUE; + } else if ( k->key() == Qt::Key_Return ) { + interpretText(); + return FALSE; + } + if ( retval ) + return retval; + } else if ( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide ) { + if ( edited ) { + interpretText(); + } + return FALSE; + } + return FALSE; +} + +/*! + Reimplementation +*/ +void SVTK_DoubleSpinBox::leaveEvent( QEvent* ) +{ + if ( edited ) + interpretText(); +} + +/*! + Reimplementation +*/ +void SVTK_DoubleSpinBox::resizeEvent( QResizeEvent* ) +{ + arrangeWidgets(); +} + +/*! + Reimplementation +*/ +void SVTK_DoubleSpinBox::wheelEvent( QWheelEvent * e ) +{ + e->accept(); + static float offset = 0; + static SVTK_DoubleSpinBox* offset_owner = 0; + if (offset_owner != this) { + offset_owner = this; + offset = 0; + } + offset += -e->delta()/120; + if (qAbs(offset) < 1) + return; + int ioff = int(offset); + int i; + for (i=0; i 0 ? stepDown() : stepUp(); + offset -= ioff; +} + +/*! + This method gets called by QRangeControl whenever the value has changed. + Updates the display and emits the valueChanged() signals. +*/ +void SVTK_DoubleSpinBox::valueChange() +{ + selreq = hasFocus(); + updateDisplay(); + selreq = FALSE; + emit valueChanged( value() ); + emit valueChanged( currentValueText() ); +} + +/*! + This method gets called by QRangeControl whenever the range has + changed. It adjusts the default validator and updates the display. +*/ +void SVTK_DoubleSpinBox::rangeChange() +{ + updateDisplay(); +} + +/*! + Sets the validator to . The validator controls what keyboard + input is accepted when the user is editing in the value field. The + default is to use a suitable QIntValidator. +*/ +void SVTK_DoubleSpinBox::setValidator( const QValidator* v ) +{ + if ( vi ) + vi->setValidator( v ); +} +/*! + Returns the validator which constrains editing for this spin box if + there is any, or else 0. +*/ +const QValidator* SVTK_DoubleSpinBox::validator() const +{ + return vi ? vi->validator() : 0; +} + +/*! + Updates the contents of the embedded QLineEdit to reflect current + value, using mapValueToText(). Also enables/disables the push + buttons accordingly. +*/ +void SVTK_DoubleSpinBox::updateDisplay() +{ + vi->setUpdatesEnabled( FALSE ); + vi->setText( currentValueText() ); + if ( selreq && isVisible() && ( hasFocus() || vi->hasFocus() ) ) { + selectAll(); + } else { + if ( !suffix().isEmpty() && + endsWith(vi->text(), suffix()) ) + vi->setCursorPosition( vi->text().length() - suffix().length() ); + } + vi->setUpdatesEnabled( TRUE ); + vi->repaint( vi->contentsRect() ); // immediate repaint needed for some reason + edited = FALSE; + + up->setEnabled( isEnabled() && (wrapping() || value() < maxValue()) ); + down->setEnabled( isEnabled() && (wrapping() || value() > minValue()) ); + vi->setEnabled( isEnabled() ); +} + +/*! + SVTK_DoubleSpinBox calls this after the user has manually edited the contents + of the spin box (not using the up/down buttons/keys). + The default implementation of this function interprets the new text + using mapTextToValue(). If mapTextToValue() is successful, it + changes the spin box' value. If not the value if left unchanged. +*/ +void SVTK_DoubleSpinBox::interpretText() +{ + bool ok = TRUE; + bool done = FALSE; + double newVal = 0; + if ( !specialValueText().isEmpty() ) { + QString s = QString(text()).simplified(); + QString t = QString(specialValueText()).simplified(); + if ( s == t ) { + newVal = minValue(); + done = TRUE; + } + } + if ( !done ) + newVal = mapTextToValue( &ok ); + if ( ok ) + setValue( newVal ); + updateDisplay(); // Sometimes redundant +} + +/*! + Returns a pointer to the embedded 'up' button. +*/ + +QPushButton* SVTK_DoubleSpinBox::upButton() const +{ + return up; +} + +/*! + Returns a pointer to the embedded 'down' button. +*/ +QPushButton* SVTK_DoubleSpinBox::downButton() const +{ + return down; +} + +/*! + Returns a pointer to the embedded QLineEdit. +*/ +QLineEdit* SVTK_DoubleSpinBox::editor() const +{ + return vi; +} + +/*! + This slot gets called whenever the user edits the text of the spin box. +*/ +void SVTK_DoubleSpinBox::textChanged() +{ + edited = TRUE; // This flag is cleared in updateDisplay() +}; + +/*! + This virtual function is used by the spin box whenever it needs to + display value . The default implementation returns a string + containing printed in the standard way. +*/ + +QString SVTK_DoubleSpinBox::mapValueToText( double v ) +{ + QString s; + s.setNum( v, convertFlag(), precision() ); + return s; +} + +/*! + This virtual function is used by the spin box whenever it needs to + interpret the text entered by the user as a value. The default + implementation tries to interpret it as an integer in the standard + way, and returns the double value. +*/ +double SVTK_DoubleSpinBox::mapTextToValue( bool* ok ) +{ + QString s = text(); + double newVal = s.toDouble( ok ); + if ( !(*ok) && !( prefix().isNull() && suffix().isNull() ) ) {// Try removing any pre/suffix + s = cleanText(); + newVal = s.toDouble( ok ); + } + return newVal; +} + +/*! + Returns the full text calculated from the current value, including any + prefix, suffix or special-value text. +*/ +QString SVTK_DoubleSpinBox::currentValueText() +{ + QString s; + if ( (value() <= minValue()) && !specialValueText().isEmpty() ) { + s = specialValueText(); + } else { + s = prefix(); + s.append( mapValueToText( value() ) ); + s.append( suffix() ); + } + return s; +} + +/*! + Reimplementation +*/ +void SVTK_DoubleSpinBox::setEnabled( bool on ) +{ + bool b = isEnabled(); + QFrame::setEnabled( on ); + if ( isEnabled() != b ) { + // ## enabledChange() might have been a better choice + updateDisplay(); + } +} + +/*! + Reimplementation +*/ +void SVTK_DoubleSpinBox::styleChange( QStyle& old ) +{ + setFrameStyle( Panel | Sunken ); + arrangeWidgets(); + QWidget::styleChange( old ); +} + +/*! + Sets the spin box to display on its buttons. + can be either (the default) or . +*/ +void SVTK_DoubleSpinBox::setButtonSymbols( ButtonSymbols newSymbols ) +{ + if ( buttonSymbols() == newSymbols ) + return; + butSymbols = newSymbols; + updateButtonSymbols(); +} + +/*! + Returns the current button symbol mode. The default is +*/ +SVTK_DoubleSpinBox::ButtonSymbols SVTK_DoubleSpinBox::buttonSymbols() const +{ + return butSymbols; +} + +/*! + This function uses the pixmap cache for a Different Reason: the + pixmap cache also preserves QPixmap::serialNumber(). by doing + this, QAbstractButton::setPixmap() is able to avoid flicker e.g. when the + spin box is resized in such a way that the height of the buttons + does not change (common the default size policy). +*/ +void SVTK_DoubleSpinBox::updateButtonSymbols() +{ + QString key( QString::fromLatin1( "$qt$SVTK_DoubleSpinBox$" ) ); + bool pmSym = buttonSymbols() == PlusMinus; + key += QString::fromLatin1( pmSym ? "+-" : "^v" ); + key += QString::number( down->height() ); + QString upKey = key + QString::fromLatin1( "$up" ); + QString dnKey = key + QString::fromLatin1( "$down" ); + QBitmap upBm; + QBitmap dnBm; + + bool found = QPixmapCache::find( dnKey, dnBm ) + && QPixmapCache::find( upKey, upBm ); + + if ( !found ) { + QPainter p; + if ( pmSym ) { + int h = down->height()-4; + if ( h < 3 ) + return; + else if ( h == 4 ) + h = 3; + else if ( (h > 6) && (h & 1) ) + h--; + h -= ( h / 8 ) * 2; // Empty border + if( dnBm.isNull() ) + dnBm = QBitmap( h, h ); + else + dnBm.scaled( h, h ); + p.begin( &dnBm ); + p.eraseRect( 0, 0, h, h ); + p.setBrush( Qt::color1 ); + int c = h/2; + p.drawLine( 0, c, h, c ); + if ( !(h & 1) ) + p.drawLine( 0, c-1, h, c-1 ); + p.end(); + upBm = dnBm; + p.begin( &upBm ); + p.drawLine( c, 0, c, h ); + if ( !(h & 1) ) + p.drawLine( c-1, 0, c-1, h ); + p.end(); + } + else { + int w = down->width()-4; + if ( w < 3 ) + return; + else if ( !(w & 1) ) + w--; + w -= ( w / 7 ) * 2; // Empty border + int h = w/2 + 2; // Must have empty row at foot of arrow + if( dnBm.isNull() ) + dnBm = QBitmap( w, h ); + else + dnBm.scaled( w, h ); + p.begin( &dnBm ); + p.eraseRect( 0, 0, w, h ); + QPolygon a; + a.setPoints( 3, 0, 1, w-1, 1, h-2, h-1 ); + p.setBrush( Qt::color1 ); + p.drawPolygon( a ); + p.end(); +#ifndef QT_NO_TRANSFORMATIONS + QMatrix wm; + wm.scale( 1, -1 ); + upBm = dnBm.transformed( wm ); +#else + if( upBm.isNull() ) + upBm = QBitmap( w, h ); + else + upBm.scaled( w, h ); + p.begin( &upBm ); + p.eraseRect( 0, 0, w, h ); + a.setPoints( 3, 0, h-2, w-1, h-2, h-2, 0 ); + p.setBrush( color1 ); + p.drawPolygon( a ); + p.end(); +#endif + } + QPixmapCache::insert( dnKey, dnBm ); + QPixmapCache::insert( upKey, upBm ); + } + down->setIcon( QIcon( dnBm ) ); + up->setIcon( QIcon( upBm ) ); +} + +/*! + Returns minimum value, reimplementaion +*/ +double SVTK_DoubleSpinBox::minValue() +{ + return QDblRangeControl::minValue(); +} + +/*! + Returns maximum value, reimplementaion +*/ +double SVTK_DoubleSpinBox::maxValue() +{ + return QDblRangeControl::maxValue(); +} + +/*! + Sets minimum value, reimplementaion +*/ +void SVTK_DoubleSpinBox::setMinValue( double minValue ) +{ + QDblRangeControl::setMinValue( minValue ); +} + +/*! + Sets maximum value, reimplementaion +*/ +void SVTK_DoubleSpinBox::setMaxValue( double maxValue ) +{ + QDblRangeControl::setMaxValue( maxValue ); +} + +/*! + Returns step size, reimplementaion +*/ +double SVTK_DoubleSpinBox::lineStep() +{ + return QDblRangeControl::lineStep(); +} + +/*! + Sets step size +*/ +void SVTK_DoubleSpinBox::setLineStep( double step ) +{ + setSteps( step, pageStep() ); +} + +/*! + Returns value of the spin box, reimplementaion +*/ +double SVTK_DoubleSpinBox::value() +{ + SVTK_DoubleSpinBox* that = ( SVTK_DoubleSpinBox* ) this; + if ( edited ) { + that->edited = FALSE; // avoid recursion + that->interpretText(); + } + return QDblRangeControl::value(); +} + +/*! + Selects all the text in the editor of the spinbox. +*/ +//#include "utilities.h" + +void SVTK_DoubleSpinBox::selectAll() +{ + int overhead = prefix().length() + suffix().length(); + if ( !overhead || currentValueText() == specialValueText() ) { + vi->selectAll(); + } else { + vi->setSelection( prefix().length(), vi->text().length() - overhead ); + } +} diff --git a/src/SVTK/SVTK_DoubleSpinBox.h b/src/SVTK/SVTK_DoubleSpinBox.h new file mode 100644 index 000000000..eff31933c --- /dev/null +++ b/src/SVTK/SVTK_DoubleSpinBox.h @@ -0,0 +1,205 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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 for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef SVTK_DoubleSpinBox_H +#define SVTK_DoubleSpinBox_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include + +class SVTK_EXPORT QDblRangeControl +{ +public: + QDblRangeControl(); + QDblRangeControl( double minValue, double maxValue, + double lineStep, double pageStep, + double value, + int precision = 6, + double dblPrecision = 1e-6, + char cFlag = 'g'); + virtual ~QDblRangeControl(); + double value() const; + void setValue( double ); + void addPage(); + void subtractPage(); + void addLine(); + void subtractLine(); + + double minValue() const; + double maxValue() const; + void setRange( double minValue, double maxValue ); + void setMinValue( double minVal ); + void setMaxValue( double minVal ); + + double lineStep() const; + double pageStep() const; + void setSteps( double line, double page ); + + int precision() const; + void setPrecision( int precision ); + double dblPrecision() const; + void setDblPrecision( double dblPrecision ); + char convertFlag() const; + void setConvertFlag( char cFlag ); + + double bound( double ) const; + +protected: + void directSetValue( double val ); + double prevValue() const; + + virtual void valueChange(); + virtual void rangeChange(); + virtual void stepChange(); + bool equal( double first, double second ) const; + double roundPrecision( double value) const; + +private: + double minVal, maxVal; + double line, page; + double val, prevVal; + int prec; + double dblPrec; + char convFlag; + +private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QDblRangeControl( const QDblRangeControl & ); + QDblRangeControl &operator=( const QDblRangeControl & ); +#endif +}; + +class QPushButton; +class QLineEdit; +class QValidator; + +class SVTK_EXPORT SVTK_DoubleSpinBox: public QFrame, public QDblRangeControl +{ + Q_OBJECT + + friend class CATHAREGUI_DataSpinBoxDbl; + +public: + SVTK_DoubleSpinBox( QWidget* parent ); + SVTK_DoubleSpinBox( QWidget* parent, + double minValue, + double maxValue, + double step, + int precision = 6, + double dblPrecision = 1e-6, + char cFlag = 'g' ); + ~SVTK_DoubleSpinBox(); + + QString text() const; + + virtual QString prefix() const; + virtual QString suffix() const; + virtual QString cleanText() const; + + virtual void setSpecialValueText( const QString &text ); + QString specialValueText() const; + + virtual void setWrapping( bool on ); + bool wrapping() const; + + enum ButtonSymbols { UpDownArrows, PlusMinus }; + void setButtonSymbols( ButtonSymbols ); + ButtonSymbols buttonSymbols() const; + + virtual void setValidator( const QValidator* v ); + const QValidator* validator() const; + + QSize sizeHint() const; + + double minValue(); + double maxValue(); + void setMinValue( double ); + void setMaxValue( double ); + double lineStep(); + void setLineStep( double ); + double value(); + +public slots: + virtual void setValue( double ); + virtual void setPrefix( const QString &text ); + virtual void setSuffix( const QString &text ); + virtual void stepUp(); + virtual void stepDown(); + virtual void setEnabled( bool ); + virtual void selectAll(); + +signals: + void valueChanged( double value ); + void valueChanged( const QString &valueText ); + +protected: + virtual QString mapValueToText( double value ); + virtual double mapTextToValue( bool* ok ); + QString currentValueText(); + + virtual void updateDisplay(); + virtual void interpretText(); + + QPushButton* upButton() const; + QPushButton* downButton() const; + QLineEdit* editor() const; + + virtual void valueChange(); + virtual void rangeChange(); + + bool eventFilter( QObject* obj, QEvent* ev ); + void resizeEvent( QResizeEvent* ev ); + void wheelEvent( QWheelEvent * ); + void leaveEvent( QEvent* ); + + void styleChange( QStyle& ); + +protected slots: + void textChanged(); + +private: + void initSpinBox(); + + ButtonSymbols butSymbols; + QPushButton* up; + QPushButton* down; + QLineEdit* vi; + QValidator* validate; + QString pfix; + QString sfix; + QString specText; + bool wrap; + bool edited; + bool selreq; + + void arrangeWidgets(); + void updateButtonSymbols(); + + private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + SVTK_DoubleSpinBox( const SVTK_DoubleSpinBox& ); + SVTK_DoubleSpinBox& operator=( const SVTK_DoubleSpinBox& ); +#endif + +}; + +#endif diff --git a/src/SVTK/SVTK_InteractorStyle.cxx b/src/SVTK/SVTK_InteractorStyle.cxx index d9286014f..127391593 100644 --- a/src/SVTK/SVTK_InteractorStyle.cxx +++ b/src/SVTK/SVTK_InteractorStyle.cxx @@ -93,7 +93,8 @@ SVTK_InteractorStyle::SVTK_InteractorStyle(): myControllerIncrement(SVTK_ControllerIncrement::New()), myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()), myHighlightSelectionPointActor(SVTK_Actor::New()), - myRectBand(0) + myRectBand(0), + myIsRotationEnabled( true ) { myPointPicker->Delete(); @@ -198,6 +199,9 @@ SVTK_SelectionEvent* SVTK_InteractorStyle::GetSelectionEventFlipY() void SVTK_InteractorStyle::RotateXY(int dx, int dy) { + if( !myIsRotationEnabled ) + return; + /* if(GetCurrentRenderer() == NULL) return; @@ -940,8 +944,11 @@ void SVTK_InteractorStyle::setCursor(const int operation) myCursorState = true; break; case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: - GetRenderWidget()->setCursor(myRotateCursor); - myCursorState = true; + if( myIsRotationEnabled ) + { + GetRenderWidget()->setCursor(myRotateCursor); + myCursorState = true; + } break; case VTK_INTERACTOR_STYLE_CAMERA_SPIN: GetRenderWidget()->setCursor(mySpinCursor); @@ -1709,6 +1716,14 @@ void SVTK_InteractorStyle::SetIncrementSpeed(const int theValue, const int theMo c->Delete(); } +/*! + Enable/disable rotation +*/ +void SVTK_InteractorStyle::SetIsRotationEnabled( const bool theState ) +{ + myIsRotationEnabled = theState; +} + /*! To get current increment controller */ diff --git a/src/SVTK/SVTK_InteractorStyle.h b/src/SVTK/SVTK_InteractorStyle.h index 1900025da..15d329e93 100644 --- a/src/SVTK/SVTK_InteractorStyle.h +++ b/src/SVTK/SVTK_InteractorStyle.h @@ -228,6 +228,9 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle int CurrentState() const { return State; } + //! Enable/disable rotation + void SetIsRotationEnabled( const bool theState ); + protected: SVTK_InteractorStyle(); ~SVTK_InteractorStyle(); @@ -350,6 +353,8 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle bool myBBFirstCheck; QRubberBand* myRectBand; //!< selection rectangle rubber band + + bool myIsRotationEnabled; }; #ifdef WIN32 diff --git a/src/SVTK/SVTK_NonIsometricDlg.cxx b/src/SVTK/SVTK_NonIsometricDlg.cxx index 826444148..e629f787d 100644 --- a/src/SVTK/SVTK_NonIsometricDlg.cxx +++ b/src/SVTK/SVTK_NonIsometricDlg.cxx @@ -29,8 +29,8 @@ #include "SVTK_NonIsometricDlg.h" #include "SVTK_ViewWindow.h" #include "SVTK_Renderer.h" +#include "SVTK_DoubleSpinBox.h" -#include "QtxDoubleSpinBox.h" #include "QtxAction.h" #include @@ -63,32 +63,35 @@ SVTK_NonIsometricDlg // Create croup box with grid layout QGroupBox* aGroupBox = new QGroupBox(this); aGroupBox->setObjectName("GroupBox"); - QHBoxLayout* aHBoxLayout = new QHBoxLayout(aGroupBox); - aHBoxLayout->setMargin(11); - aHBoxLayout->setSpacing(6); + QGridLayout* aGridLayout = new QGridLayout(aGroupBox); + aGridLayout->setMargin(11); + aGridLayout->setSpacing(6); // "X" scaling QLabel* TextLabelX = new QLabel (tr("LBL_X"), aGroupBox); TextLabelX->setObjectName("TextLabelX"); TextLabelX->setFixedWidth(15); - m_sbXcoeff = new QtxDoubleSpinBox(-VTK_LARGE_FLOAT, VTK_LARGE_FLOAT, 0.1, aGroupBox); - m_sbXcoeff->setMinimumWidth(80); + //m_sbXcoeff = new QtxDoubleSpinBox(-VTK_LARGE_FLOAT, VTK_LARGE_FLOAT, 0.1, aGroupBox); + m_sbXcoeff = new SVTK_DoubleSpinBox(aGroupBox, 0, VTK_DOUBLE_MAX, 0.1, 37, 1E-37 ); + m_sbXcoeff->setMinimumWidth(300); m_sbXcoeff->setValue(1.0); // "Y" scaling QLabel* TextLabelY = new QLabel (tr("LBL_Y"), aGroupBox); TextLabelY->setObjectName("TextLabelY"); TextLabelY->setFixedWidth(15); - m_sbYcoeff = new QtxDoubleSpinBox(-VTK_LARGE_FLOAT, VTK_LARGE_FLOAT, 0.1, aGroupBox); - m_sbYcoeff->setMinimumWidth(80); + //m_sbYcoeff = new QtxDoubleSpinBox(-VTK_LARGE_FLOAT, VTK_LARGE_FLOAT, 0.1, aGroupBox); + m_sbYcoeff = new SVTK_DoubleSpinBox(aGroupBox, 0, VTK_DOUBLE_MAX, 0.1, 37, 1E-37 ); + m_sbYcoeff->setMinimumWidth(300); m_sbYcoeff->setValue(1.0); // "Z" scaling QLabel* TextLabelZ = new QLabel (tr("LBL_Z"), aGroupBox); TextLabelZ->setObjectName("TextLabelZ"); TextLabelZ->setFixedWidth(15); - m_sbZcoeff = new QtxDoubleSpinBox(-VTK_LARGE_FLOAT, VTK_LARGE_FLOAT, 0.1, aGroupBox); - m_sbZcoeff->setMinimumWidth(80); + //m_sbZcoeff = new QtxDoubleSpinBox(-VTK_LARGE_FLOAT, VTK_LARGE_FLOAT, 0.1, aGroupBox); + m_sbZcoeff = new SVTK_DoubleSpinBox(aGroupBox, 0, VTK_DOUBLE_MAX, 0.1, 37, 1E-37 ); + m_sbZcoeff->setMinimumWidth(300); m_sbZcoeff->setValue(1.0); // Create button @@ -96,14 +99,14 @@ SVTK_NonIsometricDlg m_bReset->setObjectName("m_bReset"); // Layout widgets in the group box - aHBoxLayout->addWidget(TextLabelX); - aHBoxLayout->addWidget(m_sbXcoeff); - aHBoxLayout->addWidget(TextLabelY); - aHBoxLayout->addWidget(m_sbYcoeff); - aHBoxLayout->addWidget(TextLabelZ); - aHBoxLayout->addWidget(m_sbZcoeff); - //aHBoxLayout->addStretch(); - aHBoxLayout->addWidget(m_bReset); + aGridLayout->addWidget(TextLabelX, 0, 0); + aGridLayout->addWidget(m_sbXcoeff, 0, 1); + aGridLayout->addWidget(TextLabelY, 1, 0); + aGridLayout->addWidget(m_sbYcoeff, 1, 1); + aGridLayout->addWidget(TextLabelZ, 2, 0); + aGridLayout->addWidget(m_sbZcoeff, 2, 1); + //aGridLayout->addStretch(); + aGridLayout->addWidget(m_bReset, 3, 0, 1, 2); // OK, CANCEL, Apply button QGroupBox* aGroupBox2 = new QGroupBox(this); diff --git a/src/SVTK/SVTK_NonIsometricDlg.h b/src/SVTK/SVTK_NonIsometricDlg.h index 222f883e7..c8d0f2269 100644 --- a/src/SVTK/SVTK_NonIsometricDlg.h +++ b/src/SVTK/SVTK_NonIsometricDlg.h @@ -32,8 +32,8 @@ #include "SVTK_DialogBase.h" class SVTK_ViewWindow; +class SVTK_DoubleSpinBox; -class QtxDoubleSpinBox; class QtxAction; class QPushButton; @@ -55,9 +55,9 @@ public: protected: SVTK_ViewWindow *m_MainWindow; - QtxDoubleSpinBox* m_sbXcoeff; - QtxDoubleSpinBox* m_sbYcoeff; - QtxDoubleSpinBox* m_sbZcoeff; + SVTK_DoubleSpinBox* m_sbXcoeff; + SVTK_DoubleSpinBox* m_sbYcoeff; + SVTK_DoubleSpinBox* m_sbZcoeff; QPushButton* m_bReset; protected slots: diff --git a/src/SVTK/SVTK_Renderer.cxx b/src/SVTK/SVTK_Renderer.cxx index c2fd4ea62..3310e86e6 100644 --- a/src/SVTK/SVTK_Renderer.cxx +++ b/src/SVTK/SVTK_Renderer.cxx @@ -518,6 +518,20 @@ SVTK_Renderer return myTrihedron->GetVisibility() == VTKViewer_Trihedron::eOn; } +/*! + Set trihedron displayed on/off + \param theState - trihedron display state +*/ +void +SVTK_Renderer +::SetTrihedronDisplayed( const bool theState ) +{ + if( theState ) + myTrihedron->VisibilityOn(); + else + myTrihedron->VisibilityOff(); +} + /*! Toggle trihedron visibility */ @@ -561,6 +575,20 @@ SVTK_Renderer return myCubeAxes->GetVisibility() == 1; } +/*! + Set graduated rules displayed on/off + \param theState - graduated rules display state +*/ +void +SVTK_Renderer +::SetCubeAxesDisplayed( const bool theState ) +{ + if( theState ) + myCubeAxes->VisibilityOn(); + else + myCubeAxes->VisibilityOff(); +} + /*! Toggle graduated rules visibility */ diff --git a/src/SVTK/SVTK_Renderer.h b/src/SVTK/SVTK_Renderer.h index 1b08d5965..8efb2623b 100644 --- a/src/SVTK/SVTK_Renderer.h +++ b/src/SVTK/SVTK_Renderer.h @@ -152,6 +152,10 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject bool IsTrihedronDisplayed(); + //! Set trihedron displayed on/off + void + SetTrihedronDisplayed( const bool theState ); + //! Toggle trihedron visibility void OnViewTrihedron(); @@ -169,6 +173,10 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject bool IsCubeAxesDisplayed(); + //! Set graduated rules displayed on/off + void + SetCubeAxesDisplayed( const bool theState ); + //! Toggle graduated rules visibility void OnViewCubeAxes(); diff --git a/src/SVTK/SVTK_ViewManager.cxx b/src/SVTK/SVTK_ViewManager.cxx index b7856fdc7..9c47f9b60 100644 --- a/src/SVTK/SVTK_ViewManager.cxx +++ b/src/SVTK/SVTK_ViewManager.cxx @@ -24,8 +24,10 @@ /*! Constructor */ -SVTK_ViewManager::SVTK_ViewManager( SUIT_Study* study, SUIT_Desktop* theDesktop ) -: SUIT_ViewManager( study, theDesktop, new SVTK_Viewer() ) +SVTK_ViewManager::SVTK_ViewManager( SUIT_Study* theStudy, + SUIT_Desktop* theDesktop, + SUIT_ViewModel* theViewModel ) +: SUIT_ViewManager( theStudy, theDesktop, theViewModel ? theViewModel : new SVTK_Viewer() ) { setTitle( VTKViewer_ViewManager::tr( "VTK_VIEW_TITLE" ) ); } diff --git a/src/SVTK/SVTK_ViewManager.h b/src/SVTK/SVTK_ViewManager.h index 8ff4efcc9..672dd38a9 100644 --- a/src/SVTK/SVTK_ViewManager.h +++ b/src/SVTK/SVTK_ViewManager.h @@ -31,7 +31,9 @@ class SVTK_EXPORT SVTK_ViewManager : public SUIT_ViewManager public: //! Construct the view manager - SVTK_ViewManager( SUIT_Study* study, SUIT_Desktop* ); + SVTK_ViewManager( SUIT_Study*, + SUIT_Desktop*, + SUIT_ViewModel* = 0 ); //! Destroy the view manager virtual ~SVTK_ViewManager(); diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index e647b3c56..30ecde209 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -114,10 +114,13 @@ SVTK_ViewWindow::SVTK_ViewWindow(SUIT_Desktop* theDesktop): //myMainWindow(0), myView(NULL), myDumpImage(QImage()), - myKeyFreeInteractorStyle(SVTK_KeyFreeInteractorStyle::New()) + myStandardInteractorStyle(SVTK_InteractorStyle::New()), + myKeyFreeInteractorStyle(SVTK_KeyFreeInteractorStyle::New()), + myMode2D( false ) { setWindowFlags( windowFlags() & ~Qt::Window ); // specific of vtkSmartPointer + myStandardInteractorStyle->Delete(); myKeyFreeInteractorStyle->Delete(); } @@ -169,9 +172,7 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel) myViewParameterDlg = new SVTK_ViewParameterDlg ( getAction( ViewParametersId ), this, "SVTK_ViewParameterDlg" ); - SVTK_InteractorStyle* aStyle = SVTK_InteractorStyle::New(); - myInteractor->PushInteractorStyle(aStyle); - aStyle->Delete(); + myInteractor->PushInteractorStyle(myStandardInteractorStyle); myRecorder = SVTK_Recorder::New(); @@ -719,6 +720,112 @@ void SVTK_ViewWindow::onSwitchInteractionStyle(bool theOn) if ( a->isChecked() != theOn ) a->setChecked( theOn ); } +/*! + Toggle 2D mode on/off +*/ +void SVTK_ViewWindow::onMode2D( bool theOn ) +{ + myMode2D = theOn; + + getAction( ViewTrihedronId )->setVisible( !theOn ); + getAction( ChangeRotationPointId )->setVisible( !theOn ); + getAction( RotationId )->setVisible( !theOn ); + myViewsAction->setVisible( !theOn ); + getAction( ResetId )->setVisible( !theOn ); + + SVTK_ComboAction* a = ::qobject_cast( toolMgr()->action( ProjectionModeId ) ); + if( a ) + a->setVisible( !theOn ); + + if( theOn ) + { + myCubeAxesDlg->SetDimensionZEnabled( false ); + if( SVTK_CubeAxesActor2D* aCubeAxes = GetRenderer()->GetCubeAxes() ) + { + aCubeAxes->SetIsInvertedGrid( true ); + if( vtkAxisActor2D* aZAxis = aCubeAxes->GetZAxisActor2D() ) + { + aZAxis->SetTitleVisibility( 0 ); + aZAxis->SetLabelVisibility( 0 ); + aZAxis->SetTickVisibility( 0 ); + } + } + + storeViewState( myStored3DViewState ); + if( !restoreViewState( myStored2DViewState ) ) + { + // first time the action is toggled + GetRenderer()->SetTrihedronDisplayed( false ); + onTopView(); + onFitAll(); + } + + myStandardInteractorStyle->SetIsRotationEnabled( false ); + myKeyFreeInteractorStyle->SetIsRotationEnabled( false ); + } + else + { + myCubeAxesDlg->SetDimensionZEnabled( true ); + if( SVTK_CubeAxesActor2D* aCubeAxes = GetRenderer()->GetCubeAxes() ) + { + aCubeAxes->SetIsInvertedGrid( false ); + if( vtkAxisActor2D* aZAxis = aCubeAxes->GetZAxisActor2D() ) + { + aZAxis->SetTitleVisibility( 1 ); + aZAxis->SetLabelVisibility( 1 ); + aZAxis->SetTickVisibility( 1 ); + } + } + + storeViewState( myStored2DViewState ); + restoreViewState( myStored3DViewState ); + + myStandardInteractorStyle->SetIsRotationEnabled( true ); + myKeyFreeInteractorStyle->SetIsRotationEnabled( true ); + } +} + +/*! + Store 2D/3D view state + \param theViewState - view state to be stored +*/ +void SVTK_ViewWindow::storeViewState( ViewState& theViewState ) +{ + vtkCamera* aCamera = getRenderer()->GetActiveCamera(); + + theViewState.IsInitialized = true; + + aCamera->GetPosition( theViewState.Position ); + aCamera->GetFocalPoint( theViewState.FocalPoint ); + aCamera->GetViewUp( theViewState.ViewUp ); + theViewState.ParallelScale = aCamera->GetParallelScale(); + + theViewState.IsTrihedronDisplayed = GetRenderer()->IsTrihedronDisplayed(); +} + +/*! + Restore 2D/3D view state + \param theViewState - view state to be restored + \return true if the view state is initialized and can be restored +*/ +bool SVTK_ViewWindow::restoreViewState( ViewState theViewState ) +{ + vtkCamera* aCamera = getRenderer()->GetActiveCamera(); + if( theViewState.IsInitialized ) + { + GetRenderer()->SetTrihedronDisplayed( theViewState.IsTrihedronDisplayed ); + + aCamera->SetPosition( theViewState.Position ); + aCamera->SetFocalPoint( theViewState.FocalPoint ); + aCamera->SetViewUp( theViewState.ViewUp ); + aCamera->SetParallelScale( theViewState.ParallelScale ); + Repaint(); + + return true; + } + return false; +} + /*! Sets incremental speed \param theValue - new incremental speed @@ -1771,6 +1878,15 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchInteractionStyle(bool))); mgr->registerAction( anAction, SwitchInteractionStyleId ); + // Switch between 3D (default) and 2D modes + anAction = new QtxAction(tr("MNU_SVTK_MODE_2D"), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_MODE_2D" ) ), + tr( "MNU_SVTK_MODE_2D" ), 0, this); + anAction->setStatusTip(tr("DSC_SVTK_MODE_2D")); + anAction->setCheckable(true); + connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onMode2D(bool))); + mgr->registerAction( anAction, Mode2DId ); + // Start recording myStartAction = new QtxAction(tr("MNU_SVTK_RECORDING_START"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_RECORDING_START" ) ), @@ -1815,6 +1931,7 @@ void SVTK_ViewWindow::createToolBar() QtxActionToolMgr* mgr = toolMgr(); mgr->append( DumpId, myToolBar ); + mgr->append( Mode2DId, myToolBar ); mgr->append( SwitchInteractionStyleId, myToolBar ); mgr->append( ViewTrihedronId, myToolBar ); @@ -1833,14 +1950,14 @@ void SVTK_ViewWindow::createToolBar() mgr->append( RotationId, myToolBar ); - QtxMultiAction* aViewsAction = new QtxMultiAction( this ); - aViewsAction->insertAction( getAction( FrontId ) ); - aViewsAction->insertAction( getAction( BackId ) ); - aViewsAction->insertAction( getAction( TopId ) ); - aViewsAction->insertAction( getAction( BottomId ) ); - aViewsAction->insertAction( getAction( LeftId ) ); - aViewsAction->insertAction( getAction( RightId ) ); - mgr->append( aViewsAction, myToolBar ); + myViewsAction = new QtxMultiAction( this ); + myViewsAction->insertAction( getAction( FrontId ) ); + myViewsAction->insertAction( getAction( BackId ) ); + myViewsAction->insertAction( getAction( TopId ) ); + myViewsAction->insertAction( getAction( BottomId ) ); + myViewsAction->insertAction( getAction( LeftId ) ); + myViewsAction->insertAction( getAction( RightId ) ); + mgr->append( myViewsAction, myToolBar ); mgr->append( ResetId, myToolBar ); @@ -1855,6 +1972,9 @@ void SVTK_ViewWindow::createToolBar() mgr->append( PlayRecordingId, myRecordingToolBar ); mgr->append( PauseRecordingId, myRecordingToolBar ); mgr->append( StopRecordingId, myRecordingToolBar ); + + // the Mode2D action is enabled on demand + getAction( Mode2DId )->setVisible( false ); } void SVTK_ViewWindow::onUpdateRate(bool theIsActivate) @@ -2020,3 +2140,10 @@ void SVTK_ViewWindow::hideEvent( QHideEvent * theEvent ) emit Hide( theEvent ); } +/*! + Show/hide the Mode2D action +*/ +void SVTK_ViewWindow::SetMode2DEnabled( const bool theIsEnabled ) +{ + getAction( Mode2DId )->setVisible( theIsEnabled ); +} diff --git a/src/SVTK/SVTK_ViewWindow.h b/src/SVTK/SVTK_ViewWindow.h index 0afebefce..f3c86f980 100755 --- a/src/SVTK/SVTK_ViewWindow.h +++ b/src/SVTK/SVTK_ViewWindow.h @@ -55,12 +55,14 @@ class SVTK_NonIsometricDlg; class SVTK_UpdateRateDlg; class SVTK_CubeAxesDlg; class SVTK_SetRotationPointDlg; +class SVTK_InteractorStyle; class SVTK_KeyFreeInteractorStyle; class SVTK_ViewParameterDlg; class SVTK_Recorder; class vtkObject; class QtxAction; +class QtxMultiAction; namespace SVTK { @@ -246,6 +248,9 @@ class SVTK_EXPORT SVTK_ViewWindow : public SUIT_ViewWindow //! To invoke a VTK event on #SVTK_RenderWindowInteractor instance void InvokeEvent(unsigned long theEvent, void* theCallData); + //! Show/hide the Mode2D action + void SetMode2DEnabled( const bool theIsEnabled ); + signals: void Show( QShowEvent * ); void Hide( QHideEvent * ); @@ -282,6 +287,7 @@ public slots: void onViewParameters(bool theIsActivate); void onSwitchInteractionStyle(bool theOn); + void onMode2D(bool theOn); void onStartRecording(); void onPlayRecording(); @@ -345,6 +351,25 @@ protected: void doSetVisualParameters( const QString& ); void SetEventDispatcher(vtkObject* theDispatcher); + struct ViewState + { + bool IsInitialized; + double Position[3]; + double FocalPoint[3]; + double ViewUp[3]; + double ParallelScale; + bool IsTrihedronDisplayed; + + ViewState() + { + IsInitialized = false; + ParallelScale = 0.0; + IsTrihedronDisplayed = false; + } + }; + void storeViewState( ViewState& theViewState ); + bool restoreViewState( ViewState theViewState ); + QImage dumpViewContent(); virtual QString filter() const; @@ -360,7 +385,7 @@ protected: ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ResetId, ViewTrihedronId, NonIsometric, GraduatedAxes, UpdateRate, - ProjectionModeId, ViewParametersId, SwitchInteractionStyleId, + ProjectionModeId, ViewParametersId, SwitchInteractionStyleId, Mode2DId, StartRecordingId, PlayRecordingId, PauseRecordingId, StopRecordingId }; @@ -369,6 +394,7 @@ protected: SVTK_ViewModelBase* myModel; SVTK_RenderWindowInteractor* myInteractor; + vtkSmartPointer myStandardInteractorStyle; vtkSmartPointer myKeyFreeInteractorStyle; QString myVisualParams; // used for delayed setting of view parameters @@ -384,6 +410,8 @@ protected: QSize myPreRecordingMinSize; QSize myPreRecordingMaxSize; + QtxMultiAction* myViewsAction; + SVTK_Recorder* myRecorder; QtxAction* myStartAction; QtxAction* myPlayAction; @@ -393,6 +421,10 @@ protected: int myToolBar; int myRecordingToolBar; + bool myMode2D; + ViewState myStored2DViewState; + ViewState myStored3DViewState; + private: QImage myDumpImage; }; diff --git a/src/SVTK/resources/SVTK_images.ts b/src/SVTK/resources/SVTK_images.ts index 38b7285ff..9ac9e1b59 100644 --- a/src/SVTK/resources/SVTK_images.ts +++ b/src/SVTK/resources/SVTK_images.ts @@ -49,5 +49,9 @@ ICON_SVTK_RECORDING_STOP vtk_view_recording_stop.png + + ICON_SVTK_MODE_2D + vtk_view_mode_2d.png + diff --git a/src/SVTK/resources/SVTK_msg_en.ts b/src/SVTK/resources/SVTK_msg_en.ts index e8467cd57..9e00c762d 100644 --- a/src/SVTK/resources/SVTK_msg_en.ts +++ b/src/SVTK/resources/SVTK_msg_en.ts @@ -177,6 +177,14 @@ MNU_SVTK_STYLE_SWITCH Interaction Style Switch + + DSC_SVTK_MODE_2D + Toggle 2D mode + + + MNU_SVTK_MODE_2D + Toggle 2D mode + SVTK_CubeAxesDlg @@ -609,4 +617,11 @@ Please, refer to the documentation. Change background... + + Plot3d_ViewManager + + PLOT3D_VIEW_TITLE + Plot3d scene:%M - viewer:%V + + diff --git a/src/SVTK/resources/vtk_view_mode_2d.png b/src/SVTK/resources/vtk_view_mode_2d.png new file mode 100644 index 0000000000000000000000000000000000000000..2dcf3e4827e4cc6843c8293f5a6229bced30819d GIT binary patch literal 601 zcmV-f0;c_mP)6#51@SO(PfyQWGc&VE#>U3e zjf{+@g@uLnR##VBqFV}c855M&5fc;p%F4?6pNEI%I};Pr|Jc~rGLRfl{2~Jb!+%ar z&KLar{2$oa*+FXl04;S#b}2l3Ky*${PKk(!$glMD^zg2(E?#bK?hn$^(pNxoK>8>b z7uO3AyREH_v8k!al8=w?jk2=xvyP4qcC21*X=xE?Y;05jv4IAP0$uaf($ex6h%X@_ zaT4gNH^3l)hncsx_Y#n+fj%>U`4nehTU%Ri0eQWmqQVx$my(h?#lgYx7GxmEd+qJ* zOfD`ic|ZgIrKF^oLBpRJt6?@aHtRrP1Pq@@m>AH@$AMyRYiep(Ko}$jjJ$r33rkB& z&0#@@9J`F&-QBD}TUP)B{VPzD6>5l9QB_JOz>i8nOVGbQY?psN4qefvKPh>L5fc!#F_K zO$8>83&5DZ3^GhmQ1Gsrn%V}CoW8#PJW)~6E5Mk22uv=IwY9Y`Bqb%~VNHjWV1hY? n5Qb$>P?&@A`!FcJ2AzQbH(f%XNtspg00000NkvXXu0mjf<1GH} literal 0 HcmV?d00001 -- 2.39.2