1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "VTKViewer_MarkerWidget.h"
21 #include "VTKViewer_MarkerUtils.h"
23 #include <SUIT_ResourceMgr.h>
24 #include <SUIT_Session.h>
26 #include <vtkImageData.h>
29 #include <QHBoxLayout>
33 const int SPACING = 6;
34 enum { TypeRole = Qt::UserRole, IdRole };
37 \class VTKViewer_MarkerWidget
38 \brief Widget for specifying point marker parameters
43 \param parent parent widget
45 VTKViewer_MarkerWidget::VTKViewer_MarkerWidget( QWidget* parent )
46 : QWidget( parent ), myCurrentIdx( -1 )
49 myTypeLab = new QLabel( tr( "TYPE" ), this );
50 myScaleLab = new QLabel( tr( "SCALE" ), this );
51 myType = new QComboBox( this );
52 myScale = new QSpinBox( this );
54 QHBoxLayout* ml = new QHBoxLayout( this );
56 ml->setSpacing( SPACING );
57 ml->addWidget( myTypeLab );
58 ml->addWidget( myType );
59 ml->addWidget( myScaleLab );
60 ml->addWidget( myScale );
61 myType->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
62 myScale->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
63 // connect signals/slots
64 connect( myType, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onTypeChanged( int ) ) );
72 VTKViewer_MarkerWidget::~VTKViewer_MarkerWidget()
77 \brief Set custom markers data
78 \param markerMap custom marker data (a map {index:texture})
80 void VTKViewer_MarkerWidget::setCustomMarkers( const VTK::MarkerMap& markerMap )
82 // store custom markers data
83 myCustomMarkers = markerMap;
84 // clear current custom markers
85 for ( int i = myType->count()-1; i >= 0; i-- ) {
86 int type = myType->itemData( i, TypeRole ).toInt();
87 if ( type == VTK::MT_USER )
88 myType->removeItem( i );
91 VTK::MarkerMap::const_iterator it;
92 for ( it = myCustomMarkers.begin(); it != myCustomMarkers.end(); ++it )
95 VTK::MarkerData markerData = it->second;
96 QPixmap icon = markerFromData( markerData );
99 int idx = myType->count()-1;
100 myType->insertItem( idx, icon, QString() );
101 myType->setItemData( idx, VTK::MT_USER, TypeRole );
102 myType->setItemData( idx, id, IdRole );
108 \brief Get custom markers data
109 \return custom marker data
111 VTK::MarkerMap VTKViewer_MarkerWidget::customMarkers() const
113 return myCustomMarkers;
117 \brief Add standard marker
118 The marker type specified with \a type must be > VTK::MT_USER
119 \param type marker type
120 \param icon marker icon
122 void VTKViewer_MarkerWidget::addMarker( VTK::MarkerType type, const QPixmap& icon )
124 if ( type > VTK::MT_USER ) {
125 int idx = (int)VTK::MT_USER - 1;
126 // find insertion index
127 while ( idx < myType->count()-1 ) {
128 if ( myType->itemData( idx, TypeRole ) == VTK::MT_USER )
132 myType->insertItem( idx, icon, QString() );
133 myType->setItemData( idx, type, TypeRole );
138 \brief Select specified standard marker as current one
139 \param type marker type
140 \param scale marker scale (optional parameter; can be omitted for extended markers)
142 void VTKViewer_MarkerWidget::setMarker( VTK::MarkerType type, VTK::MarkerScale scale )
144 if ( type != VTK::MT_USER ) {
145 for ( int i = 0; i < myType->count()-1; i++ ) {
146 if ( type == myType->itemData( i, TypeRole ).toInt() ) {
147 myType->setCurrentIndex( i );
152 if ( scale != VTK::MS_NONE )
153 myScale->setValue( qMax( (int)VTK::MS_10, qMin( (int)VTK::MS_70, (int)scale ) ) );
157 \brief Select specified custom marker as current one
158 \param id custom marker identifier
160 void VTKViewer_MarkerWidget::setCustomMarker( int id )
162 for ( int i = 0; i < myType->count()-1; i++ ) {
163 int type = myType->itemData( i, TypeRole ).toInt();
164 if ( type == VTK::MT_USER && id == myType->itemData( i, IdRole ).toInt() ) {
165 myType->setCurrentIndex( i );
172 \brief Get current marker's type.
173 For custom marker, VTK::MT_USER is returned and markerId() function
174 then returns its identifier.
175 \return currently selected marker type
177 VTK::MarkerType VTKViewer_MarkerWidget::markerType() const
179 return myType->itemData( myType->currentIndex(), TypeRole ).toInt();
183 \brief Get current marker's scale size.
184 For custom marker return value is undefined.
185 \return currently selected marker scale size
187 VTK::MarkerScale VTKViewer_MarkerWidget::markerScale() const
189 return myScale->value();
193 \bried Get currently selected custom marker's identifier.
194 For standard markers return value is VTK::MT_NONE.
196 int VTKViewer_MarkerWidget::markerId() const
198 int type = myType->itemData( myType->currentIndex(), TypeRole ).toInt();
199 return type == VTK::MT_USER ? myType->itemData( myType->currentIndex(), IdRole ).toInt() : VTK::MT_NONE;
203 \brief Get access to the internal marker type label
204 \return marker type label widget
206 QLabel* VTKViewer_MarkerWidget::typeLabel()
212 \brief Get access to the internal marker scale label
213 \return marker scale label widget
215 QLabel* VTKViewer_MarkerWidget::scaleLabel()
221 \brief Internal initialization
223 void VTKViewer_MarkerWidget::init()
225 myType->blockSignals( true );
227 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
228 // standard marker types
229 for ( int type = VTK::MT_POINT; type < VTK::MT_USER; type++ ) {
230 QString icoFile = QString( "ICON_VERTEX_MARKER_%1" ).arg( type );
231 QPixmap pixmap = resMgr->loadPixmap( "VTKViewer", tr( qPrintable( icoFile ) ) );
232 myType->addItem( pixmap, QString() );
233 myType->setItemData( myType->count()-1, type, TypeRole );
235 // standard marker sizes
236 myScale->setMinimum( (int)VTK::MS_10 );
237 myScale->setMaximum( (int)VTK::MS_70 );
238 // add item for loading custom textures
239 myType->addItem( "..." );
240 myType->setItemData( myType->count()-1, VTK::MT_NONE, TypeRole );
242 myType->blockSignals( false );
244 // set current item to first type in the list
245 myType->setCurrentIndex( 0 );
249 \brief Create icon from the custom marker data (texture)
250 \param markerData custom marker data
251 \return icon generated from texture specified with marker data
253 QPixmap VTKViewer_MarkerWidget::markerFromData( const VTK::MarkerData& markerData )
256 const VTK::MarkerTexture& texture = markerData.second;
257 // generate VTK image
258 vtkSmartPointer<vtkImageData> image = VTK::MakeVTKImage( texture, false );
259 // convert VTK image to icon
260 QImage qimage = VTK::ConvertToQImage( image.GetPointer() );
261 return qimage.isNull() ? QPixmap() : QPixmap::fromImage( qimage );
265 \brief Called when marker type is changed (by the user or programmatically)
266 \param index index of item being selected
268 void VTKViewer_MarkerWidget::onTypeChanged( int index )
270 if ( index == myType->count()-1 ) {
271 // browse new custom texture file item is selected
273 filters << tr( "Texture files (*.dat)" ) << tr( "All files (*)" );
274 QString fileName = SUIT_Session::session()->activeApplication()->getFileName( true,
276 filters.join( ";;" ),
277 tr( "LOAD_TEXTURE_TLT" ),
279 if ( !fileName.isEmpty() ) {
280 // load texture and add new marker
281 VTK::MarkerTexture texture;
282 if ( VTK::LoadTextureData( fileName, VTK::MS_NONE, texture ) ) {
283 int id = VTK::GetUniqueId( myCustomMarkers );
284 VTK::MarkerData& markerData = myCustomMarkers[ id ];
285 markerData.first = fileName.toStdString();
286 markerData.second = texture;
287 QPixmap icon = markerFromData( markerData );
288 if( !icon.isNull() ) {
289 int idx = myType->count()-1;
290 myType->blockSignals( true );
291 myType->insertItem( idx, icon, QString() );
292 myType->blockSignals( false );
293 myType->setItemData( idx, VTK::MT_USER, TypeRole );
294 myType->setItemData( idx, id, IdRole );
295 myType->setCurrentIndex( idx );
300 // if user cancelled texture loading or there was an error when loading texture
301 // reset to the previous item
302 myType->setCurrentIndex( myCurrentIdx );
306 myCurrentIdx = index;
308 int type = myType->itemData( index, TypeRole ).toInt();
309 myScale->setEnabled( type < VTK::MT_USER );
310 myScaleLab->setEnabled( type < VTK::MT_USER );