Salome HOME
updated copyright message
[modules/gui.git] / src / SVTK / SVTK_SetRotationPointDlg.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME VTKViewer : build VTK viewer into Salome desktop
24 //  File   : 
25 //  Author : 
26
27 #include "SVTK_SetRotationPointDlg.h"
28 #include "SVTK_ViewWindow.h"
29 #include "SVTK_RenderWindowInteractor.h"
30 #include "SVTK_Event.h"
31 #include "SVTK_InteractorStyle.h"
32
33 #include "VTKViewer_Utilities.h"
34
35 #include "QtxAction.h"
36
37 #include <QLineEdit>
38 #include <QGroupBox>
39 #include <QLabel>
40 #include <QPushButton>
41 #include <QMenu>
42 #include <QGridLayout>
43 #include <QDoubleValidator>
44 #include <QCheckBox>
45
46 #include <vtkCallbackCommand.h>
47 #include <vtkInteractorStyle.h>
48
49 /*!
50   Constructor
51 */
52 SVTK_SetRotationPointDlg
53 ::SVTK_SetRotationPointDlg(QtxAction* theAction,
54                            SVTK_ViewWindow* theParent,
55                            const char* theName):
56   ViewerTools_DialogBase(theAction,
57                          theParent, 
58                          theName),
59   myMainWindow(theParent),
60   myRWInteractor(theParent->GetInteractor()),
61   myPriority(0.0),
62   myEventCallbackCommand(vtkCallbackCommand::New())
63 {
64   setWindowTitle(tr("DLG_TITLE"));
65   setSizeGripEnabled(true);
66
67   // Create layout for this dialog
68   QGridLayout* layoutDlg = new QGridLayout (this);
69   layoutDlg->setSpacing(6);
70   layoutDlg->setMargin(11);
71
72   // Create check box "Use Bounding Box Center"
73   QHBoxLayout* aCheckBox = new QHBoxLayout;
74
75   myIsBBCenter = new QCheckBox(tr("USE_BBCENTER"));
76   myIsBBCenter->setChecked(true);
77   aCheckBox->addWidget(myIsBBCenter);
78   connect(myIsBBCenter, SIGNAL(stateChanged(int)), SLOT(onBBCenterChecked()));
79
80   // Create croup button with radio buttons
81   myGroupBoxSel = new QGroupBox( "", this );
82   QVBoxLayout *vbox = new QVBoxLayout( myGroupBoxSel );
83   vbox->setMargin(11);
84   vbox->addStretch(1);
85   
86   // Create "Set to Origin" button
87   myToOrigin = new QPushButton(myGroupBoxSel);
88   myToOrigin->setText(tr("LBL_TOORIGIN"));
89   vbox->addWidget(myToOrigin);
90   connect(myToOrigin, SIGNAL(clicked()), this, SLOT(onToOrigin()));
91
92   // Create "Gravity Center of Select Object" button
93   mySelectPoint = new QPushButton(tr("LBL_SELECTPOINT"));
94   mySelectPoint->setCheckable(true);
95
96   QMenu* menuType = new QMenu( this );
97   mySelectActions[ menuType->addAction( tr("LBL_POINT") ) ] = NodeSelection;
98   mySelectActions[ menuType->addAction( tr("LBL_EDGE") ) ] = EdgeSelection;
99   mySelectActions[ menuType->addAction( tr("LBL_FACE") ) ] = FaceSelection;
100   mySelectActions[ menuType->addAction( tr("LBL_VOLUME") ) ] = VolumeSelection;
101   connect( menuType, SIGNAL( triggered( QAction* ) ),  this, SLOT( onSelectMenu( QAction* ) ) );
102
103   mySelectPoint->setMenu( menuType );
104   vbox->addWidget(mySelectPoint);
105
106   // Create croup box with grid layout
107   myGroupBoxCoord = new QGroupBox(this);
108   myGroupBoxCoord->setObjectName("GroupBox");
109   QHBoxLayout* aHBoxLayout = new QHBoxLayout(myGroupBoxCoord);
110   aHBoxLayout->setMargin(11);
111   aHBoxLayout->setSpacing(6);
112
113   // "X" coordinate
114   QLabel* TextLabelX = new QLabel (tr("LBL_X"), myGroupBoxCoord );
115   TextLabelX->setObjectName("TextLabelX");
116   TextLabelX->setFixedWidth(15);
117   myX = new QLineEdit(myGroupBoxCoord);
118   myX->setValidator(new QDoubleValidator(myX));
119   myX->setText(QString::number(0.0));
120   connect(myX, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged()));
121
122   // "Y" coordinate
123   QLabel* TextLabelY = new QLabel (tr("LBL_Y"), myGroupBoxCoord );
124   TextLabelY->setObjectName("TextLabelY");
125   TextLabelY->setFixedWidth(15);
126   myY = new QLineEdit(myGroupBoxCoord);
127   myY->setValidator(new QDoubleValidator(myY));
128   myY->setText(QString::number(0.0));
129   connect(myY, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged()));
130
131   // "Z" coordinate
132   QLabel* TextLabelZ = new QLabel (tr("LBL_Z"), myGroupBoxCoord );
133   TextLabelZ->setObjectName("TextLabelZ");
134   TextLabelZ->setFixedWidth(15);
135   myZ = new QLineEdit(myGroupBoxCoord);
136   myZ->setValidator(new QDoubleValidator(myZ));
137   myZ->setText(QString::number(0.0));
138   connect(myZ, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged()));
139
140   // Layout widgets in the horizontal group box
141   aHBoxLayout->addWidget(TextLabelX);
142   aHBoxLayout->addWidget(myX);
143   aHBoxLayout->addWidget(TextLabelY);
144   aHBoxLayout->addWidget(myY);
145   aHBoxLayout->addWidget(TextLabelZ);
146   aHBoxLayout->addWidget(myZ);
147
148   // "Close" button
149   QGroupBox* aGroupBox = new QGroupBox(this);
150   QHBoxLayout* aHBoxLayout2 = new QHBoxLayout(aGroupBox);
151   aHBoxLayout2->setMargin(11);
152   aHBoxLayout2->setSpacing(6);
153
154   QPushButton* m_bClose = new QPushButton(tr("&Close"), aGroupBox );
155   m_bClose->setObjectName("m_bClose");
156   m_bClose->setAutoDefault(true);
157   m_bClose->setFixedSize(m_bClose->sizeHint());
158   connect(m_bClose, SIGNAL(clicked()), this, SLOT(onClickClose()));
159
160   // Layout buttons
161   aHBoxLayout2->addWidget(m_bClose);
162
163   // Layout top level widgets
164   layoutDlg->addLayout(aCheckBox,0,0);
165   layoutDlg->addWidget(myGroupBoxSel,1,0);
166   layoutDlg->addWidget(myGroupBoxCoord,2,0);
167   layoutDlg->addWidget(aGroupBox,3,0);
168   
169   setEnabled(myGroupBoxSel,!myIsBBCenter->isChecked());
170   setEnabled(myGroupBoxCoord,!myIsBBCenter->isChecked());
171
172   this->resize(400, this->sizeHint().height());
173
174   myEventCallbackCommand->Delete();
175   myEventCallbackCommand->SetClientData(this);
176   myEventCallbackCommand->SetCallback(SVTK_SetRotationPointDlg::ProcessEvents);
177 }
178
179 /*
180  *  Destroys the object and frees any allocated resources
181  */
182 SVTK_SetRotationPointDlg
183 ::~SVTK_SetRotationPointDlg()
184 {
185   // no need to delete child widgets, Qt does it all for us
186 }
187
188 void
189 SVTK_SetRotationPointDlg
190 ::addObserver()
191 {
192   vtkInteractorStyle* aIStyle = myRWInteractor->GetInteractorStyle();
193   if( !IsObserverAdded( aIStyle ) ) {
194     aIStyle->AddObserver(SVTK::BBCenterChanged, myEventCallbackCommand.GetPointer(), myPriority);
195     aIStyle->AddObserver(SVTK::RotationPointChanged, myEventCallbackCommand.GetPointer(), myPriority);
196   }
197 }
198
199 /*!
200   Return true if it is the first show for this dialog
201 */
202 bool
203 SVTK_SetRotationPointDlg
204 ::IsFirstShown()
205 {
206   return myIsBBCenter->isChecked() && myX->text().toDouble() == 0.
207     && myY->text().toDouble() == 0. && myZ->text().toDouble() == 0.;
208 }
209
210 /*!
211   Processes events
212 */
213 void 
214 SVTK_SetRotationPointDlg
215 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
216                 unsigned long theEvent,
217                 void* theClientData, 
218                 void* theCallData)
219 {
220   SVTK_SetRotationPointDlg* self = reinterpret_cast<SVTK_SetRotationPointDlg*>(theClientData);
221   double* aCoord = (double*)theCallData;
222   
223   switch ( theEvent ) {
224   case SVTK::BBCenterChanged:
225     if ( self->myIsBBCenter->isChecked()
226          ||
227          IsBBEmpty(self->myMainWindow->getRenderer()) )
228     {
229       if ( aCoord )
230       {
231         self->myX->setText( QString::number(aCoord[0]) );
232         self->myY->setText( QString::number(aCoord[1]) );
233         self->myZ->setText( QString::number(aCoord[2]) );
234       }
235     }
236     break;
237   case SVTK::RotationPointChanged:
238     if ( aCoord )
239     {
240       self->myX->setText( QString::number(aCoord[0]) );
241       self->myY->setText( QString::number(aCoord[1]) );
242       self->myZ->setText( QString::number(aCoord[2]) );
243     }
244     if ( !self->myIsBBCenter->isChecked() )
245       self->mySelectPoint->toggle();
246   }
247 }
248
249 bool
250 SVTK_SetRotationPointDlg
251 ::IsObserverAdded( vtkInteractorStyle* theInteractorStyle )
252 {
253   bool isAdded = false;
254   for( int i = 0; i < myInteractorStyleList.count(); i++ )
255     if( myInteractorStyleList.at(i) == theInteractorStyle )
256       isAdded = true;
257
258   if( !isAdded )
259     myInteractorStyleList.append( theInteractorStyle );
260
261   return isAdded;
262 }
263
264 void 
265 SVTK_SetRotationPointDlg
266 ::setEnabled(QGroupBox* theGrp, const bool theState)
267 {
268   QObjectList aChildren(theGrp->children());
269   QObject* anObj;
270   for(int i = 0; i < aChildren.size(); i++)
271   {
272     anObj = aChildren.at(i);
273     if (anObj !=0 && anObj->inherits("QLineEdit"))
274       ((QLineEdit*)anObj)->setReadOnly(!theState);
275     if (anObj !=0 && anObj->inherits("QPushButton"))
276       ((QLineEdit*)anObj)->setEnabled(theState);
277   }
278   
279 }
280
281 void 
282 SVTK_SetRotationPointDlg
283 ::onBBCenterChecked()
284 {
285   setEnabled(myGroupBoxSel,!myIsBBCenter->isChecked());
286   setEnabled(myGroupBoxCoord,!myIsBBCenter->isChecked());
287   
288   if ( myIsBBCenter->isChecked() )
289   { 
290     if ( mySelectPoint->isChecked() )
291       mySelectPoint->toggle();
292     // activate mode : the rotation point is the center of the bounding box
293     // send the data to the SVTK_InteractorStyle: set the type of the rotation point
294     //                                            calculate coordinates of the rotation point
295     myMainWindow->activateSetRotationGravity();
296   }
297   else
298   {
299     QString aX = myX->text();
300     myX->setText(QString::number(aX.toDouble()+1.));
301     myX->setText(aX);
302   }
303 }
304
305 void
306 SVTK_SetRotationPointDlg
307 ::onToOrigin()
308 {
309   mySelectPoint->setChecked( false );
310   myX->setText(QString::number(0.0));
311   myY->setText(QString::number(0.0));
312   myZ->setText(QString::number(0.0));
313 }
314
315 void
316 SVTK_SetRotationPointDlg
317 ::onSelectMenu( QAction* theAction )
318 {
319   mySelectPoint->setChecked( true );
320   myMainWindow->activateStartPointSelection( mySelectActions[theAction] );
321 }
322
323 void
324 SVTK_SetRotationPointDlg
325 ::onCoordChanged()
326 {
327   if ( !myIsBBCenter->isChecked() ) {
328     if ( mySelectPoint->isChecked()
329          &&
330          ( myX->hasFocus() || myY->hasFocus() || myZ->hasFocus() ) )
331       mySelectPoint->toggle();
332     double aCenter[3] = {myX->text().toDouble(), 
333                                        myY->text().toDouble(), 
334                                        myZ->text().toDouble()};
335     myMainWindow->activateSetRotationSelected((void*)aCenter);
336   }
337   else
338     myMainWindow->activateSetRotationGravity();
339 }
340
341 void
342 SVTK_SetRotationPointDlg
343 ::onClickClose()
344 {
345   reject();
346 }
347
348