Salome HOME
Upgrade to paraview 5.4
[modules/gui.git] / src / SVTK / salomevtkPVAxesWidget.cxx
1 /*=========================================================================
2
3    Program: ParaView
4    Module:    $RCSfile$
5
6    Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
7    All rights reserved.
8
9    ParaView is a free software; you can redistribute it and/or modify it
10    under the terms of the ParaView license version 1.2. 
11
12    See License_v1.2.txt for the full ParaView license.
13    A copy of this license can be obtained by contacting
14    Kitware Inc.
15    28 Corporate Drive
16    Clifton Park, NY 12065
17    USA
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 =========================================================================*/
32 // VSR 03/12/2014: the original file vtkPVAxesWidget.cxx has been renamed to salomevtkPVAxesWidget.cxx
33 // to avoid collisions with native VTK/ParaView classes
34
35 #include "salomevtkPVAxesWidget.h"   // changed by SALOME
36 #include "salomevtkPVAxesActor.h"    // changed by SALOME
37
38 #include "vtkActor2D.h"
39 #include "vtkCallbackCommand.h"
40 #include "vtkCamera.h"
41 #include "vtkCoordinate.h"
42 #include "vtkObjectFactory.h"
43 #include "vtkPoints.h"
44 #include "vtkPolyData.h"
45 #include "vtkPolyDataMapper2D.h"
46 #include "vtkProperty.h"
47 #include "vtkProperty2D.h"
48 #include "vtkRenderer.h"
49 #include "vtkRenderWindow.h"
50 #include "vtkRenderWindowInteractor.h"
51
52 // VSR 03/12/2014: we put classes copied from VTK/ParaView to the specific namespace
53 // to avoid collisions with native VTK/ParaView classes
54 namespace salomevtk
55 {
56
57 vtkStandardNewMacro(vtkPVAxesWidget);
58
59 vtkCxxSetObjectMacro(vtkPVAxesWidget, AxesActor, vtkPVAxesActor);
60 vtkCxxSetObjectMacro(vtkPVAxesWidget, ParentRenderer, vtkRenderer);
61
62 //----------------------------------------------------------------------------
63 class vtkPVAxesWidgetObserver : public vtkCommand
64 {
65 public:
66   static vtkPVAxesWidgetObserver *New()
67     {return new vtkPVAxesWidgetObserver;};
68   
69   vtkPVAxesWidgetObserver()
70     {
71       this->AxesWidget = 0;
72     }
73   
74   virtual void Execute(vtkObject* wdg, unsigned long event, void *calldata)
75     {
76       if (this->AxesWidget)
77         {
78         this->AxesWidget->ExecuteEvent(wdg, event, calldata);
79         }
80     }
81   
82   vtkPVAxesWidget *AxesWidget;
83 };
84
85 //----------------------------------------------------------------------------
86 vtkPVAxesWidget::vtkPVAxesWidget()
87 {
88   this->StartEventObserverId = 0;
89
90   this->EventCallbackCommand->SetCallback(vtkPVAxesWidget::ProcessEvents);
91   
92   this->Observer = vtkPVAxesWidgetObserver::New();
93   this->Observer->AxesWidget = this;
94   this->Renderer = vtkRenderer::New();
95   this->Renderer->SetViewport(0.0, 0.0, 0.2, 0.2);
96   this->Renderer->SetLayer(1);
97   this->Renderer->InteractiveOff();
98   this->Priority = 0.55;
99   this->AxesActor = vtkPVAxesActor::New();
100   this->Renderer->AddActor(this->AxesActor);
101   this->AxesActor->AddToRender(this->Renderer); // tmp
102   
103   this->ParentRenderer = NULL;
104   
105   this->Moving = 0;
106   this->MouseCursorState = vtkPVAxesWidget::Outside;
107
108   this->StartTag = 0;
109   
110   this->Interactive = 1;
111   
112   this->Outline = vtkPolyData::New();
113   this->Outline->Allocate();
114   vtkPoints *points = vtkPoints::New();
115   vtkIdType ptIds[5];
116   ptIds[4] = ptIds[0] = points->InsertNextPoint(1, 1, 0);
117   ptIds[1] = points->InsertNextPoint(2, 1, 0);
118   ptIds[2] = points->InsertNextPoint(2, 2, 0);
119   ptIds[3] = points->InsertNextPoint(1, 2, 0);
120   this->Outline->SetPoints(points);
121   this->Outline->InsertNextCell(VTK_POLY_LINE, 5, ptIds);
122   vtkCoordinate *tcoord = vtkCoordinate::New();
123   tcoord->SetCoordinateSystemToDisplay();
124   vtkPolyDataMapper2D *mapper = vtkPolyDataMapper2D::New();
125   mapper->SetInputData(this->Outline);
126   mapper->SetTransformCoordinate(tcoord);
127   this->OutlineActor = vtkActor2D::New();
128   this->OutlineActor->SetMapper(mapper);
129   this->OutlineActor->SetPosition(0, 0);
130   this->OutlineActor->SetPosition2(1, 1);
131   
132   points->Delete();
133   mapper->Delete();
134   tcoord->Delete();
135 }
136
137 //----------------------------------------------------------------------------
138 vtkPVAxesWidget::~vtkPVAxesWidget()
139 {
140   this->Observer->Delete();
141   this->AxesActor->Delete();
142   this->OutlineActor->Delete();
143   this->Outline->Delete();
144   this->SetParentRenderer(NULL);
145   this->Renderer->Delete();
146 }
147
148 //----------------------------------------------------------------------------
149 void vtkPVAxesWidget::SetEnabled(int enabling)
150 {
151   if (!this->Interactor)
152     {
153     vtkErrorMacro("The interactor must be set prior to enabling/disabling widget");
154     }
155   
156   if (enabling)
157     {
158     if (this->Enabled)
159       {
160       return;
161       }
162     if (!this->ParentRenderer)
163       {
164       vtkErrorMacro("The parent renderer must be set prior to enabling this widget");
165       return;
166       }
167
168     this->Enabled = 1;
169     
170     if ( this->EventCallbackCommand )
171       {
172       vtkRenderWindowInteractor *i = this->Interactor;
173       i->AddObserver(vtkCommand::MouseMoveEvent,
174         this->EventCallbackCommand, this->Priority);
175       i->AddObserver(vtkCommand::LeftButtonPressEvent,
176         this->EventCallbackCommand, this->Priority);
177       i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
178         this->EventCallbackCommand, this->Priority);
179       }
180     
181     this->ParentRenderer->GetRenderWindow()->AddRenderer(this->Renderer);
182     if (this->ParentRenderer->GetRenderWindow()->GetNumberOfLayers() < 2)
183       {
184       this->ParentRenderer->GetRenderWindow()->SetNumberOfLayers(2);
185       }
186     this->AxesActor->SetVisibility(1);
187     // We need to copy the camera before the compositing observer is called.
188     // Compositing temporarily changes the camera to display an image.
189     this->StartEventObserverId = 
190       this->ParentRenderer->AddObserver(vtkCommand::StartEvent,this->Observer,1);
191     this->InvokeEvent(vtkCommand::EnableEvent, NULL);
192     }
193   else
194     {
195     if (!this->Enabled)
196       {
197       return;
198       }
199     
200     this->Enabled = 0;
201     this->Interactor->RemoveObserver(this->EventCallbackCommand);
202     
203     this->AxesActor->SetVisibility(0);
204     if (this->ParentRenderer)
205       {
206       if (this->ParentRenderer->GetRenderWindow())
207         {
208         this->ParentRenderer->GetRenderWindow()->RemoveRenderer(this->Renderer);
209         this->AxesActor->ReleaseGraphicsResources(this->ParentRenderer->GetRenderWindow());
210         }
211       if (this->StartEventObserverId != 0)
212         {
213         this->ParentRenderer->RemoveObserver(this->StartEventObserverId);
214         }
215       }
216     
217     this->InvokeEvent(vtkCommand::DisableEvent, NULL);
218     }
219 }
220
221 //----------------------------------------------------------------------------
222 void vtkPVAxesWidget::ExecuteEvent(vtkObject *vtkNotUsed(o),
223                                    unsigned long vtkNotUsed(event),
224                                    void *vtkNotUsed(calldata))
225 {
226   if (!this->ParentRenderer)
227     {
228     return;
229     }
230   
231   vtkCamera *cam = this->ParentRenderer->GetActiveCamera();
232   double pos[3], fp[3], viewup[3];
233   cam->GetPosition(pos);
234   cam->GetFocalPoint(fp);
235   cam->GetViewUp(viewup);
236   
237   cam = this->Renderer->GetActiveCamera();
238   cam->SetPosition(pos);
239   cam->SetFocalPoint(fp);
240   cam->SetViewUp(viewup);
241   this->Renderer->ResetCamera();
242   
243   this->SquareRenderer();
244 }
245
246 void vtkPVAxesWidget::UpdateCursorIcon()
247 {
248   if (!this->Enabled)
249     {
250     this->SetMouseCursor(vtkPVAxesWidget::Outside);
251     return;
252     }
253   
254   if (this->Moving)
255     {
256     return;
257     }
258   
259   int *parentSize = this->ParentRenderer->GetSize();
260   
261   int x = this->Interactor->GetEventPosition()[0];
262   int y = this->Interactor->GetEventPosition()[1];
263   double xNorm = x / (double)parentSize[0];
264   double yNorm = y / (double)parentSize[1];
265   
266   double pos[4];
267   this->Renderer->GetViewport(pos);
268   
269   int pState = this->MouseCursorState;
270   
271   if (xNorm > pos[0] && xNorm < pos[2] && yNorm > pos[1] && yNorm < pos[3])
272     {
273     this->MouseCursorState = vtkPVAxesWidget::Inside;
274     }
275   else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[3]) < .02)
276     {
277     this->MouseCursorState = vtkPVAxesWidget::TopLeft;
278     }
279   else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[3]) < .02)
280     {
281     this->MouseCursorState = vtkPVAxesWidget::TopRight;
282     }
283   else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[1]) < .02)
284     {
285     this->MouseCursorState = vtkPVAxesWidget::BottomLeft;
286     }
287   else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[1]) < .02)
288     {
289     this->MouseCursorState = vtkPVAxesWidget::BottomRight;
290     }
291   else
292     {
293     this->MouseCursorState = vtkPVAxesWidget::Outside;
294     }
295
296   if (pState == this->MouseCursorState)
297     {
298     return;
299     }
300   
301   if (this->MouseCursorState == vtkPVAxesWidget::Outside)
302     {
303     this->Renderer->RemoveActor(this->OutlineActor);
304     }
305   else
306     {
307     this->Renderer->AddActor(this->OutlineActor);
308     }
309   this->Interactor->Render();
310   
311   this->SetMouseCursor(this->MouseCursorState);
312 }
313
314 //----------------------------------------------------------------------------
315 void vtkPVAxesWidget::SetMouseCursor(int cursorState)
316 {
317   switch (cursorState)
318     {
319     case vtkPVAxesWidget::Outside:
320       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_DEFAULT);
321       break;
322     case vtkPVAxesWidget::Inside:
323       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZEALL);
324       break;
325     case vtkPVAxesWidget::TopLeft:
326       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENW);
327       break;
328     case vtkPVAxesWidget::TopRight:
329       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENE);
330       break;
331     case vtkPVAxesWidget::BottomLeft:
332       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESW);
333       break;
334     case vtkPVAxesWidget::BottomRight:
335       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESE);
336       break;
337     }
338 }
339
340 //----------------------------------------------------------------------------
341 void vtkPVAxesWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
342                                     unsigned long event,
343                                     void *clientdata,
344                                     void* vtkNotUsed(calldata))
345 {
346   vtkPVAxesWidget *self =
347     reinterpret_cast<vtkPVAxesWidget*>(clientdata);
348
349   if (!self->GetInteractive())
350     {
351     return;
352     }
353   
354   switch (event)
355     {
356     case vtkCommand::LeftButtonPressEvent:
357       self->OnButtonPress();
358       break;
359     case vtkCommand::MouseMoveEvent:
360       self->OnMouseMove();
361       break;
362     case vtkCommand::LeftButtonReleaseEvent:
363       self->OnButtonRelease();
364       break;
365     }
366 }
367
368 //----------------------------------------------------------------------------
369 void vtkPVAxesWidget::OnButtonPress()
370 {
371   if (this->MouseCursorState == vtkPVAxesWidget::Outside)
372     {
373     return;
374     }
375   
376   this->SetMouseCursor(this->MouseCursorState);
377
378   this->StartPosition[0] = this->Interactor->GetEventPosition()[0];
379   this->StartPosition[1] = this->Interactor->GetEventPosition()[1];
380   
381   this->Moving = 1;
382   this->EventCallbackCommand->SetAbortFlag(1);
383   this->StartInteraction();
384   this->InvokeEvent(vtkCommand::StartInteractionEvent, NULL);
385 }
386
387 //----------------------------------------------------------------------------
388 void vtkPVAxesWidget::OnButtonRelease()
389 {
390   if (this->MouseCursorState == vtkPVAxesWidget::Outside)
391     {
392     return;
393     }
394   
395   this->Moving = 0;
396   this->EndInteraction();
397   this->InvokeEvent(vtkCommand::EndInteractionEvent, NULL);
398 }
399
400 //----------------------------------------------------------------------------
401 void vtkPVAxesWidget::OnMouseMove()
402 {
403   if (this->Moving)
404     {
405     switch (this->MouseCursorState)
406       {
407       case vtkPVAxesWidget::Inside:
408         this->MoveWidget();
409         break;
410       case vtkPVAxesWidget::TopLeft:
411         this->ResizeTopLeft();
412         break;
413       case vtkPVAxesWidget::TopRight:
414         this->ResizeTopRight();
415         break;
416       case vtkPVAxesWidget::BottomLeft:
417         this->ResizeBottomLeft();
418         break;
419       case vtkPVAxesWidget::BottomRight:
420         this->ResizeBottomRight();
421         break;
422       }
423     
424     this->UpdateCursorIcon();
425     this->EventCallbackCommand->SetAbortFlag(1);
426     this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
427     }
428   else
429     {
430     this->UpdateCursorIcon();
431     }
432 }
433
434 //----------------------------------------------------------------------------
435 void vtkPVAxesWidget::MoveWidget()
436 {
437   int x = this->Interactor->GetEventPosition()[0];
438   int y = this->Interactor->GetEventPosition()[1];
439   
440   int dx = x - this->StartPosition[0];
441   int dy = y - this->StartPosition[1];
442
443   this->StartPosition[0] = x;
444   this->StartPosition[1] = y;
445
446   int *size = this->ParentRenderer->GetSize();
447   double dxNorm = dx / (double)size[0];
448   double dyNorm = dy / (double)size[1];
449   
450   double *vp = this->Renderer->GetViewport();
451   
452   double newPos[4];
453   newPos[0] = vp[0] + dxNorm;
454   newPos[1] = vp[1] + dyNorm;
455   newPos[2] = vp[2] + dxNorm;
456   newPos[3] = vp[3] + dyNorm;
457
458   if (newPos[0] < 0)
459     {
460     this->StartPosition[0] = 0;
461     newPos[0] = 0;
462     newPos[2] = vp[2] - vp[0];
463     }
464   if (newPos[1] < 0)
465     {
466     this->StartPosition[1] = 0;
467     newPos[1] = 0;
468     newPos[3] = vp[3] - vp[1];
469     }
470   if (newPos[2] > 1)
471     {
472     this->StartPosition[0] = (int)(size[0] - size[0] * (vp[2]-vp[0]));
473     newPos[0] = 1 - (vp[2]-vp[0]);
474     newPos[2] = 1;
475     }
476   if (newPos[3] > 1)
477     {
478     this->StartPosition[1] = (int)(size[1] - size[1]*(vp[3]-vp[1]));
479     newPos[1] = 1 - (vp[3]-vp[1]);
480     newPos[3] = 1;
481     }
482
483   this->Renderer->SetViewport(newPos);
484   this->Interactor->Render();
485 }
486
487 //----------------------------------------------------------------------------
488 void vtkPVAxesWidget::ResizeTopLeft()
489 {
490   int x = this->Interactor->GetEventPosition()[0];
491   int y = this->Interactor->GetEventPosition()[1];
492   
493   int dx = x - this->StartPosition[0];
494   int dy = y - this->StartPosition[1];
495   
496   int *size = this->ParentRenderer->GetSize();
497   double dxNorm = dx / (double)size[0];
498   double dyNorm = dy / (double)size[1];
499   
500   int useX;
501   double change;
502   double absDx = fabs(dxNorm);
503   double absDy = fabs(dyNorm);
504   
505   if (absDx > absDy)
506     {
507     change = dxNorm;
508     useX = 1;
509     }
510   else
511     {
512     change = dyNorm;
513     useX = 0;
514     }
515   
516   double *vp = this->Renderer->GetViewport();
517   
518   this->StartPosition[0] = x;
519   this->StartPosition[1] = y;
520   
521   double newPos[4];
522   newPos[0] = useX ? vp[0] + change : vp[0] - change;
523   newPos[1] = vp[1];
524   newPos[2] = vp[2];
525   newPos[3] = useX ? vp[3] - change : vp[3] + change;
526   
527   if (newPos[0] < 0)
528     {
529     this->StartPosition[0] = 0;
530     newPos[0] = 0;
531     }
532   if (newPos[0] >= newPos[2]-0.01)
533     {
534     newPos[0] = newPos[2] - 0.01;
535     }
536   if (newPos[3] > 1)
537     {
538     this->StartPosition[1] = size[1];
539     newPos[3] = 1;
540     }
541   if (newPos[3] <= newPos[1]+0.01)
542     {
543     newPos[3] = newPos[1] + 0.01;
544     }
545   
546   this->Renderer->SetViewport(newPos);
547   this->Interactor->Render();
548 }
549
550 //----------------------------------------------------------------------------
551 void vtkPVAxesWidget::ResizeTopRight()
552 {
553   int x = this->Interactor->GetEventPosition()[0];
554   int y = this->Interactor->GetEventPosition()[1];
555   
556   int dx = x - this->StartPosition[0];
557   int dy = y - this->StartPosition[1];
558   
559   int *size = this->ParentRenderer->GetSize();
560   double dxNorm = dx / (double)size[0];
561   double dyNorm = dy / (double)size[1];
562
563   double change;
564   double absDx = fabs(dxNorm);
565   double absDy = fabs(dyNorm);
566   
567   if (absDx > absDy)
568     {
569     change = dxNorm;
570     }
571   else
572     {
573     change = dyNorm;
574     }
575   
576   double *vp = this->Renderer->GetViewport();
577   
578   this->StartPosition[0] = x;
579   this->StartPosition[1] = y;
580   
581   double newPos[4];
582   newPos[0] = vp[0];
583   newPos[1] = vp[1];
584   newPos[2] = vp[2] + change;
585   newPos[3] = vp[3] + change;
586   
587   if (newPos[2] > 1)
588     {
589     this->StartPosition[0] = size[0];
590     newPos[2] = 1;
591     }
592   if (newPos[2] <= newPos[0]+0.01)
593     {
594     newPos[2] = newPos[0] + 0.01;
595     }
596   if (newPos[3] > 1)
597     {
598     this->StartPosition[1] = size[1];
599     newPos[3] = 1;
600     }
601   if (newPos[3] <= newPos[1]+0.01)
602     {
603     newPos[3] = newPos[1] + 0.01;
604     }
605   
606   this->Renderer->SetViewport(newPos);
607   this->Interactor->Render();
608 }
609
610 //----------------------------------------------------------------------------
611 void vtkPVAxesWidget::ResizeBottomLeft()
612 {
613   int x = this->Interactor->GetEventPosition()[0];
614   int y = this->Interactor->GetEventPosition()[1];
615   
616   int dx = x - this->StartPosition[0];
617   int dy = y - this->StartPosition[1];
618   
619   int *size = this->ParentRenderer->GetSize();
620   double dxNorm = dx / (double)size[0];
621   double dyNorm = dy / (double)size[1];
622   double *vp = this->Renderer->GetViewport();
623   
624   double change;
625   double absDx = fabs(dxNorm);
626   double absDy = fabs(dyNorm);
627   
628   if (absDx > absDy)
629     {
630     change = dxNorm;
631     }
632   else
633     {
634     change = dyNorm;
635     }
636   
637   this->StartPosition[0] = x;
638   this->StartPosition[1] = y;
639   
640   double newPos[4];
641   newPos[0] = vp[0] + change;
642   newPos[1] = vp[1] + change;
643   newPos[2] = vp[2];
644   newPos[3] = vp[3];
645   
646   if (newPos[0] < 0)
647     {
648     this->StartPosition[0] = 0;
649     newPos[0] = 0;
650     }
651   if (newPos[0] >= newPos[2]-0.01)
652     {
653     newPos[0] = newPos[2] - 0.01;
654     }
655   if (newPos[1] < 0)
656     {
657     this->StartPosition[1] = 0;
658     newPos[1] = 0;
659     }
660   if (newPos[1] >= newPos[3]-0.01)
661     {
662     newPos[1] = newPos[3] - 0.01;
663     }
664   
665   this->Renderer->SetViewport(newPos);
666   this->Interactor->Render();
667 }
668
669 //----------------------------------------------------------------------------
670 void vtkPVAxesWidget::ResizeBottomRight()
671 {
672   int x = this->Interactor->GetEventPosition()[0];
673   int y = this->Interactor->GetEventPosition()[1];
674   
675   int dx = x - this->StartPosition[0];
676   int dy = y - this->StartPosition[1];
677   
678   int *size = this->ParentRenderer->GetSize();
679   double dxNorm = dx / (double)size[0];
680   double dyNorm = dy / (double)size[1];
681   
682   double *vp = this->Renderer->GetViewport();
683   
684   int useX;
685   double change;
686   double absDx = fabs(dxNorm);
687   double absDy = fabs(dyNorm);
688   
689   if (absDx > absDy)
690     {
691     change = dxNorm;
692     useX = 1;
693     }
694   else
695     {
696     change = dyNorm;
697     useX = 0;
698     }
699   
700   this->StartPosition[0] = x;
701   this->StartPosition[1] = y;
702   
703   double newPos[4];
704   newPos[0] = vp[0];
705   newPos[1] = useX ? vp[1] - change : vp[1] + change;
706   newPos[2] = useX ? vp[2] + change : vp[2] - change;
707   newPos[3] = vp[3];
708   
709   if (newPos[2] > 1)
710     {
711     this->StartPosition[0] = size[0];
712     newPos[2] = 1;
713     }
714   if (newPos[2] <= newPos[0]+0.01)
715     {
716     newPos[2] = newPos[0] + 0.01;
717     }
718   if (newPos[1] < 0)
719     {
720     this->StartPosition[1] = 0;
721     newPos[1] = 0;
722     }
723   if (newPos[1] >= newPos[3]-0.01)
724     {
725     newPos[1] = newPos[3]-0.01;
726     }
727   
728   this->Renderer->SetViewport(newPos);
729   this->Interactor->Render();
730 }
731
732 //----------------------------------------------------------------------------
733 void vtkPVAxesWidget::SquareRenderer()
734 {
735   int *size = this->Renderer->GetSize();
736   if (size[0] == 0 || size[1] == 0)
737     {
738     return;
739     }
740   
741   double vp[4];
742   this->Renderer->GetViewport(vp);
743   
744   double deltaX = vp[2] - vp[0];
745   double newDeltaX = size[1] * deltaX / (double)size[0];
746   double deltaY = vp[3] - vp[1];
747   double newDeltaY = size[0] * deltaY / (double)size[1];
748
749   if (newDeltaX > 1)
750     {
751     if (newDeltaY > 1)
752       {
753       if (size[0] > size[1])
754         {
755         newDeltaX = size[1] / (double)size[0];
756         newDeltaY = 1;
757         }
758       else
759         {
760         newDeltaX = 1;
761         newDeltaY = size[0] / (double)size[1];
762         }
763       vp[0] = vp[1] = 0;
764       vp[2] = newDeltaX;
765       vp[3] = newDeltaY;
766       }
767     else
768       {
769       vp[3] = vp[1] + newDeltaY;
770       if (vp[3] > 1)
771         {
772         vp[3] = 1;
773         vp[1] = vp[3] - newDeltaY;
774         }
775       }
776     }
777   else
778     {
779     vp[2] = vp[0] + newDeltaX;
780     if (vp[2] > 1)
781       {
782       vp[2] = 1;
783       vp[0] = vp[2] - newDeltaX;
784       }
785     }
786   
787   this->Renderer->SetViewport(vp);
788   
789   this->Renderer->NormalizedDisplayToDisplay(vp[0], vp[1]);
790   this->Renderer->NormalizedDisplayToDisplay(vp[2], vp[3]);
791   
792   vtkPoints *points = this->Outline->GetPoints();
793   points->SetPoint(0, vp[0]+1, vp[1]+1, 0);
794   points->SetPoint(1, vp[2]-1, vp[1]+1, 0);
795   points->SetPoint(2, vp[2]-1, vp[3]-1, 0);
796   points->SetPoint(3, vp[0]+1, vp[3]-1, 0);
797 }
798
799 //----------------------------------------------------------------------------
800 void vtkPVAxesWidget::SetInteractive(int state)
801 {
802   if (this->Interactive != state)
803     {
804     this->Interactive = state;
805     }
806   
807   if (!state)
808     {
809     this->OnButtonRelease();
810     this->MouseCursorState = vtkPVAxesWidget::Outside;
811     this->Renderer->RemoveActor(this->OutlineActor);
812     if (this->Interactor)
813       {
814       this->SetMouseCursor(this->MouseCursorState);
815       // this->Interactor->Render();
816       }
817     }
818 }
819
820 //----------------------------------------------------------------------------
821 void vtkPVAxesWidget::SetOutlineColor(double r, double g, double b)
822 {
823   this->OutlineActor->GetProperty()->SetColor(r, g, b);
824   if (this->Interactor)
825     {
826 //    this->Interactor->Render();
827     }
828 }
829
830 //----------------------------------------------------------------------------
831 double* vtkPVAxesWidget::GetOutlineColor()
832 {
833   return this->OutlineActor->GetProperty()->GetColor();
834 }
835
836 //----------------------------------------------------------------------------
837 void vtkPVAxesWidget::SetAxisLabelColor(double r, double g, double b)
838 {
839   this->AxesActor->GetXAxisLabelProperty()->SetColor(r, g, b);
840   this->AxesActor->GetYAxisLabelProperty()->SetColor(r, g, b);
841   this->AxesActor->GetZAxisLabelProperty()->SetColor(r, g, b);
842 }
843
844 //----------------------------------------------------------------------------
845 double* vtkPVAxesWidget::GetAxisLabelColor()
846 {
847   return this->AxesActor->GetXAxisLabelProperty()->GetColor();
848 }
849
850 //----------------------------------------------------------------------------
851 vtkRenderer* vtkPVAxesWidget::GetParentRenderer()
852 {
853   return this->ParentRenderer;
854 }
855
856 //----------------------------------------------------------------------------
857 void vtkPVAxesWidget::SetViewport(double minX, double minY,
858                                   double maxX, double maxY)
859 {
860   this->Renderer->SetViewport(minX, minY, maxX, maxY);
861 }
862
863 //----------------------------------------------------------------------------
864 double* vtkPVAxesWidget::GetViewport()
865 {
866   return this->Renderer->GetViewport();
867 }
868
869 //----------------------------------------------------------------------------
870 void vtkPVAxesWidget::PrintSelf(ostream& os, vtkIndent indent)
871 {
872   this->Superclass::PrintSelf(os, indent);
873   
874   os << indent << "AxesActor: " << this->AxesActor << endl;
875   os << indent << "Interactive: " << this->Interactive << endl;
876 }
877
878 } // end of salomevtk namespace