Salome HOME
a0127e2f6915860877fd82d4b23cbcc9233c1eac
[modules/gui.git] / src / VTKViewer / VTKViewer_FramedTextActor.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "VTKViewer_FramedTextActor.h"
21
22 #include <vtkCellArray.h>
23 #include <vtkObjectFactory.h>
24 #include <vtkPoints.h>
25 #include <vtkPolyData.h>
26 #include <vtkPolyDataMapper2D.h>
27 #include <vtkProperty2D.h>
28 #include <vtkRenderer.h>
29 #include <vtkTextActor.h>
30 #include <vtkTextMapper.h>
31 #include <vtkTextProperty.h>
32 #include <vtkTimeStamp.h>
33 #include <vtkViewport.h>
34 #include <vtkWindow.h>
35
36 #include <QStringList>
37
38 #define TEXT_MARGIN    4
39 #define OFFSET_SPACING 2
40
41 //VSR: uncomment below macro to support unicode text properly in SALOME
42 //     current commented out due to regressions
43 //#define PAL22528_UNICODE
44
45 namespace
46 {
47   QString fromUtf8( const char* txt )
48   {
49 #ifdef PAL22528_UNICODE
50     return QString::fromUtf8( txt );
51 #else
52     return QString( txt );
53 #endif
54   }
55   std::string toUtf8( const QString& txt )
56   {
57 #ifdef PAL22528_UNICODE
58     return txt.toUtf8().constData();
59 #else
60     return txt.toLatin1().constData();
61 #endif
62   }
63 }
64
65 //==================================================================
66 vtkStandardNewMacro(VTKViewer_FramedTextActor)
67
68 //==================================================================
69 // function : VTKViewer_FramedTextActor
70 // purpose  :
71 //==================================================================
72 VTKViewer_FramedTextActor::VTKViewer_FramedTextActor()
73 {
74   PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
75
76   myTransparency=0.;
77   myBar = vtkPolyData::New();
78   myBarMapper = vtkPolyDataMapper2D::New();
79   myBarMapper->SetInputData(myBar);
80   myBarActor = vtkActor2D::New();
81   myBarActor->SetMapper(myBarMapper);
82   myBarActor->GetProperty()->SetOpacity(1.-myTransparency);  
83   myBarActor->GetProperty()->SetColor(.5, .5, .5); 
84
85   myTextProperty = vtkTextProperty::New();
86   myTextProperty->SetFontSize(12);
87   myTextProperty->SetBold(0);
88   myTextProperty->SetItalic(0);
89   myTextProperty->SetShadow(1);
90   myTextProperty->SetFontFamilyToArial();
91   
92   myTextActor=vtkTextActor::New();
93   myTextActor->SetTextProperty(myTextProperty);
94
95   myBarActor->SetVisibility(1);
96   myTextActor->SetVisibility(1);
97   myBarActor->SetPickable(0);
98   myTextActor->SetPickable(0);
99
100   myModePosition = BelowPoint;
101   myLayoutType = Vertical;
102
103   for(int i=0; i<4; i++) {
104     myWorldPoint[i] = 0.;
105   }
106   myDistance=10.;
107
108   myTextMargin = TEXT_MARGIN;
109
110   myHorizontalOffset = 0;
111   myVerticalOffset = 0;
112
113   myMoveFrameFlag = 0;
114 }
115
116 //==================================================================
117 // function : ~
118 // purpose  :
119 //==================================================================
120 VTKViewer_FramedTextActor::~VTKViewer_FramedTextActor()
121 {
122   myTextActor->Delete();
123   myTextProperty->Delete();
124   myBarActor->Delete();
125   myBarMapper->Delete();
126   myBar->Delete();
127 }
128
129 //==================================================================
130 // function : SetVisibility
131 // purpose  :
132 //==================================================================
133 void VTKViewer_FramedTextActor::SetVisibility (int theVisibility)
134 {
135   myBarActor->SetVisibility(theVisibility);
136   myTextActor->SetVisibility(theVisibility);
137 }
138
139 //==================================================================
140 // function : GetVisibility
141 // purpose  :
142 //==================================================================
143 int VTKViewer_FramedTextActor::GetVisibility() 
144 {
145   return myBarActor->GetVisibility();
146 }
147
148 //==================================================================
149 // function : SetPickable
150 // purpose  :
151 //==================================================================
152 void VTKViewer_FramedTextActor::SetPickable (int thePickability) 
153 {
154   myBarActor->SetPickable(thePickability);
155   myTextActor->SetPickable(thePickability);
156 }
157
158 //==================================================================
159 // function : GetPickable
160 // purpose  :
161 //==================================================================
162 int VTKViewer_FramedTextActor::GetPickable()
163 {
164   return myBarActor->GetPickable();
165 }
166
167 //==================================================================
168 // function : GetSize
169 // purpose  :
170 //==================================================================
171 void VTKViewer_FramedTextActor::GetSize(vtkRenderer* vport, double theSize[2]) const
172 {
173   myTextActor->GetSize(vport, theSize);
174   theSize[0] = theSize[0] + 2 * GetTextMargin() + OFFSET_SPACING;
175   theSize[1] = theSize[1] + 2 * GetTextMargin() + OFFSET_SPACING;
176 }
177
178 //==================================================================
179 // function : SetForegroundColor
180 // purpose  :
181 //==================================================================
182 void VTKViewer_FramedTextActor::SetForegroundColor(const double r,
183                                                    const double g,
184                                                    const double b)
185 {
186   myTextProperty->SetColor(r, g, b);
187   myTextActor->GetTextProperty()->ShallowCopy(myTextProperty);
188   Modified();
189 }
190
191 //==================================================================
192 // function : GetForegroundColor
193 // purpose  :
194 //==================================================================
195 void VTKViewer_FramedTextActor::GetForegroundColor(double& r,
196                                                    double& g,
197                                                    double& b)
198 {
199   double aColor[3];
200   myTextProperty->GetColor(aColor);
201   r = aColor[0];
202   g = aColor[1];
203   b = aColor[2];
204 }
205
206 //==================================================================
207 // function : SetBackgroundColor
208 // purpose  :
209 //==================================================================
210 void VTKViewer_FramedTextActor::SetBackgroundColor(const double r,
211                                                    const double g,
212                                                    const double b)
213 {
214   myBarActor->GetProperty()->SetColor(r, g, b);
215   Modified();
216 }
217
218 //==================================================================
219 // function : GetBackgroundColor
220 // purpose  :
221 //==================================================================
222 void VTKViewer_FramedTextActor::GetBackgroundColor(double& r,
223                                                    double& g,
224                                                    double& b)
225 {
226   double aColor[3];
227   myBarActor->GetProperty()->GetColor(aColor);
228   r = aColor[0];
229   g = aColor[1];
230   b = aColor[2];
231 }
232
233 //==================================================================
234 // function : SetTransparency
235 // purpose  :
236 //==================================================================
237 void VTKViewer_FramedTextActor::SetTransparency(const double theTransparency)
238 {
239   if (theTransparency>=0.  && theTransparency<=1.){
240     myTransparency=theTransparency;
241     myBarActor->GetProperty()->SetOpacity(1.-myTransparency);  
242     Modified();
243   }
244 }
245
246 //==================================================================
247 // function : GetTransparency
248 // purpose  :
249 //==================================================================
250 double VTKViewer_FramedTextActor::GetTransparency()const
251 {
252   return myTransparency;
253 }
254
255 //==================================================================
256 // function : SetTextMargin
257 // purpose  :
258 //==================================================================
259 void VTKViewer_FramedTextActor::SetTextMargin(const int theMargin)
260 {
261   if( theMargin >= 0 ) {
262     myTextMargin = theMargin;
263     Modified();
264   }
265 }
266
267 //==================================================================
268 // function : GetTextMargin
269 // purpose  :
270 //==================================================================
271 int VTKViewer_FramedTextActor::GetTextMargin() const
272 {
273   return myTextMargin;
274 }
275
276 //==================================================================
277 // function : SetOffset
278 // purpose  :
279 //==================================================================
280 void VTKViewer_FramedTextActor::SetOffset(const double theOffset[2])
281 {
282   myHorizontalOffset = theOffset[0];
283   myVerticalOffset = theOffset[1];
284   Modified();
285 }
286
287 //==================================================================
288 // function : SetText
289 // purpose  :
290 //==================================================================
291 void VTKViewer_FramedTextActor::SetText(const char* theText)
292 {
293   // remove whitespaces from from the start and the end
294   // additionally, consider a case of multi-string text
295   QString aString(fromUtf8(theText));
296
297   QStringList aTrimmedStringList;
298   QStringList aStringList = aString.split("\n");
299   QStringListIterator anIter(aStringList);
300   while(anIter.hasNext())
301     aTrimmedStringList.append(anIter.next().trimmed());
302
303   myTextActor->SetInput(toUtf8(aTrimmedStringList.join("\n")).c_str());
304   Modified();
305 }
306
307 //==================================================================
308 // function : GetText
309 // purpose  :
310 //==================================================================
311 char* VTKViewer_FramedTextActor::GetText()
312 {
313   return myTextActor->GetInput();
314 }
315
316 //==================================================================
317 // function : SetModePosition
318 // purpose  :
319 //==================================================================
320 void VTKViewer_FramedTextActor::SetModePosition(const int theMode)
321 {
322   myModePosition = theMode;
323   Modified();
324 }
325
326 //==================================================================
327 // function : GetModePosition
328 // purpose  :
329 //==================================================================
330 int VTKViewer_FramedTextActor::GetModePosition()const
331 {
332   return myModePosition;
333 }
334
335 //==================================================================
336 // function : SetLayoutType
337 // purpose  :
338 //==================================================================
339 void VTKViewer_FramedTextActor::SetLayoutType(const int theType)
340 {
341   myLayoutType = theType;
342   Modified();
343 }
344
345 //==================================================================
346 // function : GetLayoutType
347 // purpose  :
348 //==================================================================
349 int VTKViewer_FramedTextActor::GetLayoutType() const
350 {
351   return myLayoutType;
352 }
353
354 //==================================================================
355 // function : SetWorldPoint
356 // purpose  :
357 //==================================================================
358 void VTKViewer_FramedTextActor::SetWorldPoint(const double theWorldPoint[4])
359 {
360   for(int i = 0; i<4; ++i) {
361     myWorldPoint[i] = theWorldPoint[i];
362   } 
363   Modified();
364 }
365
366 //==================================================================
367 // function : GetWorldPoint
368 // purpose  :
369 //==================================================================
370 const double* VTKViewer_FramedTextActor::GetWorldPoint()const 
371 {
372   return myWorldPoint;
373 }
374
375 //==================================================================
376 // function : SetDistance
377 // purpose  :
378 //==================================================================
379 void VTKViewer_FramedTextActor::SetDistance(const double theDistance)
380 {
381   myDistance=theDistance;
382 }
383
384 //==================================================================
385 // function : GetDistance
386 // purpose  :
387 //==================================================================
388 double VTKViewer_FramedTextActor::GetDistance()const
389 {
390   return myDistance;
391 }
392
393 //==================================================================
394 // function : SetMoveFrameFlag
395 // purpose  : If moveFrameFlag is true, then frame with text is moved
396 //            under world point
397 //==================================================================
398 void VTKViewer_FramedTextActor::SetMoveFrameFlag(const int theMoveFrameFlag)
399 {
400   if(myMoveFrameFlag != theMoveFrameFlag) {
401     myMoveFrameFlag = theMoveFrameFlag;
402     Modified();
403   }
404 }
405
406 //==================================================================
407 // function : GetDistance
408 // purpose  :
409 //==================================================================
410 int VTKViewer_FramedTextActor::GetMoveFrameFlag() const
411 {
412   return myMoveFrameFlag;
413 }
414
415
416 //==================================================================
417 // function : ReleaseGraphicsResources
418 // purpose  :
419 //==================================================================
420 void VTKViewer_FramedTextActor::ReleaseGraphicsResources(vtkWindow *win)
421 {
422   myTextActor->ReleaseGraphicsResources(win);
423   myBarActor->ReleaseGraphicsResources(win);
424 }
425
426 //==================================================================
427 // function : RenderOverlay
428 // purpose  :
429 //==================================================================
430 int VTKViewer_FramedTextActor::RenderOverlay(vtkViewport *viewport)
431 {
432   int renderedSomething = 0;
433   renderedSomething +=myTextActor->RenderOverlay(viewport);
434   renderedSomething +=myBarActor->RenderOverlay(viewport);
435   return renderedSomething;
436 }
437
438 //==================================================================
439 // function : RenderOpaqueGeometry
440 // purpose  :
441 //==================================================================
442 int 
443 VTKViewer_FramedTextActor
444 ::RenderOpaqueGeometry(vtkViewport *theViewport)
445 {
446   int anIsRenderedSomething = 0;
447
448   int* aViewportSize = theViewport->GetSize();
449   int aViewPortWidth = aViewportSize[0];
450   int aViewPortHeight = aViewportSize[1];
451   if(aViewPortWidth == 1 || aViewPortHeight == 1)
452     return anIsRenderedSomething;
453
454   if(!myTextActor->GetInput())
455     return anIsRenderedSomething;
456
457   myBar->Initialize();
458
459   int aNbPoints = 4;
460   vtkPoints *aPoints = vtkPoints::New();
461   aPoints->SetNumberOfPoints(aNbPoints);
462   myBar->SetPoints(aPoints);
463   aPoints->Delete();
464
465   vtkCellArray *aPolys = vtkCellArray::New();
466   aPolys->Allocate(aPolys->EstimateSize(1,4));
467   vtkIdType aPointsIds[4] = {0, 1, 3, 2};
468   aPolys->InsertNextCell(4,aPointsIds);
469   myBar->SetPolys(aPolys);
470   aPolys->Delete(); 
471
472   double aTextSize[2]; 
473   myTextActor->GetSize(theViewport, aTextSize);
474   int aBarWidth = aTextSize[0];
475   int aBarHeight = aTextSize[1];
476
477   int aTextMargin = GetTextMargin();
478
479   double xMin = 0.0;
480   double xMax = 0.0;
481   double yMin = -aBarHeight/2 - aTextMargin;
482   double yMax =  aBarHeight/2 + aTextMargin;
483
484   int aHorizontalOffset = GetLayoutType() == Horizontal ? myHorizontalOffset : 0;
485   int aVerticalOffset = GetLayoutType() == Vertical ? myVerticalOffset : 0;
486
487   if( myModePosition == BelowPoint )
488   {
489     theViewport->SetWorldPoint(myWorldPoint);
490     theViewport->WorldToDisplay();
491
492     double aSelectionPoint[3];
493     theViewport->GetDisplayPoint(aSelectionPoint);
494     double u = aSelectionPoint[0];
495     double v = aSelectionPoint[1] - myDistance;
496     if(myMoveFrameFlag)
497       v -= aBarHeight/2.;
498     theViewport->ViewportToNormalizedViewport(u, v);
499     PositionCoordinate->SetValue(u, v);
500
501     myTextProperty->SetJustificationToCentered();
502
503     xMin = -aBarWidth/2 - aTextMargin;
504     xMax =  aBarWidth/2 + aTextMargin;
505   }
506   else // except BelowPoint, only TopLeft and TopRight modes are supported at this moment
507   {
508     double x = 0, xOffset = aHorizontalOffset + aTextMargin + OFFSET_SPACING;
509     double y = 0, yOffset = aVerticalOffset + aTextMargin + OFFSET_SPACING;
510
511     if( myModePosition == TopLeft )
512     {
513       x = xOffset;
514       y = aViewPortHeight - yOffset - aBarHeight/2;
515       myTextProperty->SetJustificationToLeft();
516
517       xMin =            - aTextMargin;
518       xMax =  aBarWidth + aTextMargin;
519     }
520     else if( myModePosition == TopRight )
521     {
522       x = aViewPortWidth - xOffset;
523       y = aViewPortHeight - yOffset - aBarHeight/2;
524       myTextProperty->SetJustificationToRight();
525
526       xMin = -aBarWidth - aTextMargin;
527       xMax =              aTextMargin;
528     }
529
530     PositionCoordinate->SetValue(x / (double)aViewPortWidth,
531                                  y / (double)aViewPortHeight);
532   }
533
534
535   aPoints->SetPoint(0, xMin, yMax, 0.0);
536   aPoints->SetPoint(1, xMin, yMin, 0.0);
537   aPoints->SetPoint(2, xMax, yMax, 0.0);
538   aPoints->SetPoint(3, xMax, yMin, 0.0);
539
540   myTextProperty->SetVerticalJustificationToCentered();
541
542   myBarActor ->GetPositionCoordinate()->SetReferenceCoordinate(PositionCoordinate);
543   myTextActor->GetPositionCoordinate()->SetReferenceCoordinate(PositionCoordinate);
544
545   myBuildTime.Modified();
546
547   return anIsRenderedSomething;
548 }