1 /*=========================================================================
6 Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
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.
12 See License_v1.2.txt for the full ParaView license.
13 A copy of this license can be obtained by contacting
16 Clifton Park, NY 12065
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.
31 =========================================================================*/
32 #include "vtkPVAxesWidget.h"
34 #include "vtkActor2D.h"
35 #include "vtkCallbackCommand.h"
36 #include "vtkCamera.h"
37 #include "vtkCoordinate.h"
38 #include "vtkObjectFactory.h"
39 #include "vtkPoints.h"
40 #include "vtkPolyData.h"
41 #include "vtkPolyDataMapper2D.h"
42 #include "vtkProperty.h"
43 #include "vtkProperty2D.h"
44 #include "vtkPVAxesActor.h"
45 #include "vtkRenderer.h"
46 #include "vtkRenderWindow.h"
47 #include "vtkRenderWindowInteractor.h"
49 vtkStandardNewMacro(vtkPVAxesWidget);
50 vtkCxxRevisionMacro(vtkPVAxesWidget, "$Revision$");
52 vtkCxxSetObjectMacro(vtkPVAxesWidget, AxesActor, vtkPVAxesActor);
53 vtkCxxSetObjectMacro(vtkPVAxesWidget, ParentRenderer, vtkRenderer);
55 //----------------------------------------------------------------------------
56 class vtkPVAxesWidgetObserver : public vtkCommand
59 static vtkPVAxesWidgetObserver *New()
60 {return new vtkPVAxesWidgetObserver;};
62 vtkPVAxesWidgetObserver()
67 virtual void Execute(vtkObject* wdg, unsigned long event, void *calldata)
71 this->AxesWidget->ExecuteEvent(wdg, event, calldata);
75 vtkPVAxesWidget *AxesWidget;
78 //----------------------------------------------------------------------------
79 vtkPVAxesWidget::vtkPVAxesWidget()
81 this->StartEventObserverId = 0;
83 this->EventCallbackCommand->SetCallback(vtkPVAxesWidget::ProcessEvents);
85 this->Observer = vtkPVAxesWidgetObserver::New();
86 this->Observer->AxesWidget = this;
87 this->Renderer = vtkRenderer::New();
88 this->Renderer->SetViewport(0.0, 0.0, 0.2, 0.2);
89 this->Renderer->SetLayer(1);
90 this->Renderer->InteractiveOff();
91 this->Priority = 0.55;
92 this->AxesActor = vtkPVAxesActor::New();
93 this->Renderer->AddActor(this->AxesActor);
94 this->AxesActor->AddToRender(this->Renderer); // tmp
96 this->ParentRenderer = NULL;
99 this->MouseCursorState = vtkPVAxesWidget::Outside;
103 this->Interactive = 1;
105 this->Outline = vtkPolyData::New();
106 this->Outline->Allocate();
107 vtkPoints *points = vtkPoints::New();
109 ptIds[4] = ptIds[0] = points->InsertNextPoint(1, 1, 0);
110 ptIds[1] = points->InsertNextPoint(2, 1, 0);
111 ptIds[2] = points->InsertNextPoint(2, 2, 0);
112 ptIds[3] = points->InsertNextPoint(1, 2, 0);
113 this->Outline->SetPoints(points);
114 this->Outline->InsertNextCell(VTK_POLY_LINE, 5, ptIds);
115 vtkCoordinate *tcoord = vtkCoordinate::New();
116 tcoord->SetCoordinateSystemToDisplay();
117 vtkPolyDataMapper2D *mapper = vtkPolyDataMapper2D::New();
118 mapper->SetInput(this->Outline);
119 mapper->SetTransformCoordinate(tcoord);
120 this->OutlineActor = vtkActor2D::New();
121 this->OutlineActor->SetMapper(mapper);
122 this->OutlineActor->SetPosition(0, 0);
123 this->OutlineActor->SetPosition2(1, 1);
130 //----------------------------------------------------------------------------
131 vtkPVAxesWidget::~vtkPVAxesWidget()
133 this->Observer->Delete();
134 this->AxesActor->Delete();
135 this->OutlineActor->Delete();
136 this->Outline->Delete();
137 this->SetParentRenderer(NULL);
138 this->Renderer->Delete();
141 //----------------------------------------------------------------------------
142 void vtkPVAxesWidget::SetEnabled(int enabling)
144 if (!this->Interactor)
146 vtkErrorMacro("The interactor must be set prior to enabling/disabling widget");
155 if (!this->ParentRenderer)
157 vtkErrorMacro("The parent renderer must be set prior to enabling this widget");
163 if ( this->EventCallbackCommand )
165 vtkRenderWindowInteractor *i = this->Interactor;
166 i->AddObserver(vtkCommand::MouseMoveEvent,
167 this->EventCallbackCommand, this->Priority);
168 i->AddObserver(vtkCommand::LeftButtonPressEvent,
169 this->EventCallbackCommand, this->Priority);
170 i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
171 this->EventCallbackCommand, this->Priority);
174 this->ParentRenderer->GetRenderWindow()->AddRenderer(this->Renderer);
175 if (this->ParentRenderer->GetRenderWindow()->GetNumberOfLayers() < 2)
177 this->ParentRenderer->GetRenderWindow()->SetNumberOfLayers(2);
179 this->AxesActor->SetVisibility(1);
180 // We need to copy the camera before the compositing observer is called.
181 // Compositing temporarily changes the camera to display an image.
182 this->StartEventObserverId =
183 this->ParentRenderer->AddObserver(vtkCommand::StartEvent,this->Observer,1);
184 this->InvokeEvent(vtkCommand::EnableEvent, NULL);
194 this->Interactor->RemoveObserver(this->EventCallbackCommand);
196 this->AxesActor->SetVisibility(0);
197 if (this->ParentRenderer)
199 if (this->ParentRenderer->GetRenderWindow())
201 this->ParentRenderer->GetRenderWindow()->RemoveRenderer(this->Renderer);
202 this->AxesActor->ReleaseGraphicsResources(this->ParentRenderer->GetRenderWindow());
204 if (this->StartEventObserverId != 0)
206 this->ParentRenderer->RemoveObserver(this->StartEventObserverId);
210 this->InvokeEvent(vtkCommand::DisableEvent, NULL);
214 //----------------------------------------------------------------------------
215 void vtkPVAxesWidget::ExecuteEvent(vtkObject *vtkNotUsed(o),
216 unsigned long vtkNotUsed(event),
217 void *vtkNotUsed(calldata))
219 if (!this->ParentRenderer)
224 vtkCamera *cam = this->ParentRenderer->GetActiveCamera();
225 double pos[3], fp[3], viewup[3];
226 cam->GetPosition(pos);
227 cam->GetFocalPoint(fp);
228 cam->GetViewUp(viewup);
230 cam = this->Renderer->GetActiveCamera();
231 cam->SetPosition(pos);
232 cam->SetFocalPoint(fp);
233 cam->SetViewUp(viewup);
234 this->Renderer->ResetCamera();
236 this->SquareRenderer();
239 void vtkPVAxesWidget::UpdateCursorIcon()
243 this->SetMouseCursor(vtkPVAxesWidget::Outside);
252 int *parentSize = this->ParentRenderer->GetSize();
254 int x = this->Interactor->GetEventPosition()[0];
255 int y = this->Interactor->GetEventPosition()[1];
256 double xNorm = x / (double)parentSize[0];
257 double yNorm = y / (double)parentSize[1];
260 this->Renderer->GetViewport(pos);
262 int pState = this->MouseCursorState;
264 if (xNorm > pos[0] && xNorm < pos[2] && yNorm > pos[1] && yNorm < pos[3])
266 this->MouseCursorState = vtkPVAxesWidget::Inside;
268 else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[3]) < .02)
270 this->MouseCursorState = vtkPVAxesWidget::TopLeft;
272 else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[3]) < .02)
274 this->MouseCursorState = vtkPVAxesWidget::TopRight;
276 else if (fabs(xNorm-pos[0]) < .02 && fabs(yNorm-pos[1]) < .02)
278 this->MouseCursorState = vtkPVAxesWidget::BottomLeft;
280 else if (fabs(xNorm-pos[2]) < .02 && fabs(yNorm-pos[1]) < .02)
282 this->MouseCursorState = vtkPVAxesWidget::BottomRight;
286 this->MouseCursorState = vtkPVAxesWidget::Outside;
289 if (pState == this->MouseCursorState)
294 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
296 this->Renderer->RemoveActor(this->OutlineActor);
300 this->Renderer->AddActor(this->OutlineActor);
302 this->Interactor->Render();
304 this->SetMouseCursor(this->MouseCursorState);
307 //----------------------------------------------------------------------------
308 void vtkPVAxesWidget::SetMouseCursor(int cursorState)
312 case vtkPVAxesWidget::Outside:
313 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_DEFAULT);
315 case vtkPVAxesWidget::Inside:
316 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZEALL);
318 case vtkPVAxesWidget::TopLeft:
319 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENW);
321 case vtkPVAxesWidget::TopRight:
322 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENE);
324 case vtkPVAxesWidget::BottomLeft:
325 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESW);
327 case vtkPVAxesWidget::BottomRight:
328 this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZESE);
333 //----------------------------------------------------------------------------
334 void vtkPVAxesWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
337 void* vtkNotUsed(calldata))
339 vtkPVAxesWidget *self =
340 reinterpret_cast<vtkPVAxesWidget*>(clientdata);
342 if (!self->GetInteractive())
349 case vtkCommand::LeftButtonPressEvent:
350 self->OnButtonPress();
352 case vtkCommand::MouseMoveEvent:
355 case vtkCommand::LeftButtonReleaseEvent:
356 self->OnButtonRelease();
361 //----------------------------------------------------------------------------
362 void vtkPVAxesWidget::OnButtonPress()
364 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
369 this->SetMouseCursor(this->MouseCursorState);
371 this->StartPosition[0] = this->Interactor->GetEventPosition()[0];
372 this->StartPosition[1] = this->Interactor->GetEventPosition()[1];
375 this->EventCallbackCommand->SetAbortFlag(1);
376 this->StartInteraction();
377 this->InvokeEvent(vtkCommand::StartInteractionEvent, NULL);
380 //----------------------------------------------------------------------------
381 void vtkPVAxesWidget::OnButtonRelease()
383 if (this->MouseCursorState == vtkPVAxesWidget::Outside)
389 this->EndInteraction();
390 this->InvokeEvent(vtkCommand::EndInteractionEvent, NULL);
393 //----------------------------------------------------------------------------
394 void vtkPVAxesWidget::OnMouseMove()
398 switch (this->MouseCursorState)
400 case vtkPVAxesWidget::Inside:
403 case vtkPVAxesWidget::TopLeft:
404 this->ResizeTopLeft();
406 case vtkPVAxesWidget::TopRight:
407 this->ResizeTopRight();
409 case vtkPVAxesWidget::BottomLeft:
410 this->ResizeBottomLeft();
412 case vtkPVAxesWidget::BottomRight:
413 this->ResizeBottomRight();
417 this->UpdateCursorIcon();
418 this->EventCallbackCommand->SetAbortFlag(1);
419 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
423 this->UpdateCursorIcon();
427 //----------------------------------------------------------------------------
428 void vtkPVAxesWidget::MoveWidget()
430 int x = this->Interactor->GetEventPosition()[0];
431 int y = this->Interactor->GetEventPosition()[1];
433 int dx = x - this->StartPosition[0];
434 int dy = y - this->StartPosition[1];
436 this->StartPosition[0] = x;
437 this->StartPosition[1] = y;
439 int *size = this->ParentRenderer->GetSize();
440 double dxNorm = dx / (double)size[0];
441 double dyNorm = dy / (double)size[1];
443 double *vp = this->Renderer->GetViewport();
446 newPos[0] = vp[0] + dxNorm;
447 newPos[1] = vp[1] + dyNorm;
448 newPos[2] = vp[2] + dxNorm;
449 newPos[3] = vp[3] + dyNorm;
453 this->StartPosition[0] = 0;
455 newPos[2] = vp[2] - vp[0];
459 this->StartPosition[1] = 0;
461 newPos[3] = vp[3] - vp[1];
465 this->StartPosition[0] = (int)(size[0] - size[0] * (vp[2]-vp[0]));
466 newPos[0] = 1 - (vp[2]-vp[0]);
471 this->StartPosition[1] = (int)(size[1] - size[1]*(vp[3]-vp[1]));
472 newPos[1] = 1 - (vp[3]-vp[1]);
476 this->Renderer->SetViewport(newPos);
477 this->Interactor->Render();
480 //----------------------------------------------------------------------------
481 void vtkPVAxesWidget::ResizeTopLeft()
483 int x = this->Interactor->GetEventPosition()[0];
484 int y = this->Interactor->GetEventPosition()[1];
486 int dx = x - this->StartPosition[0];
487 int dy = y - this->StartPosition[1];
489 int *size = this->ParentRenderer->GetSize();
490 double dxNorm = dx / (double)size[0];
491 double dyNorm = dy / (double)size[1];
495 double absDx = fabs(dxNorm);
496 double absDy = fabs(dyNorm);
509 double *vp = this->Renderer->GetViewport();
511 this->StartPosition[0] = x;
512 this->StartPosition[1] = y;
515 newPos[0] = useX ? vp[0] + change : vp[0] - change;
518 newPos[3] = useX ? vp[3] - change : vp[3] + change;
522 this->StartPosition[0] = 0;
525 if (newPos[0] >= newPos[2]-0.01)
527 newPos[0] = newPos[2] - 0.01;
531 this->StartPosition[1] = size[1];
534 if (newPos[3] <= newPos[1]+0.01)
536 newPos[3] = newPos[1] + 0.01;
539 this->Renderer->SetViewport(newPos);
540 this->Interactor->Render();
543 //----------------------------------------------------------------------------
544 void vtkPVAxesWidget::ResizeTopRight()
546 int x = this->Interactor->GetEventPosition()[0];
547 int y = this->Interactor->GetEventPosition()[1];
549 int dx = x - this->StartPosition[0];
550 int dy = y - this->StartPosition[1];
552 int *size = this->ParentRenderer->GetSize();
553 double dxNorm = dx / (double)size[0];
554 double dyNorm = dy / (double)size[1];
557 double absDx = fabs(dxNorm);
558 double absDy = fabs(dyNorm);
569 double *vp = this->Renderer->GetViewport();
571 this->StartPosition[0] = x;
572 this->StartPosition[1] = y;
577 newPos[2] = vp[2] + change;
578 newPos[3] = vp[3] + change;
582 this->StartPosition[0] = size[0];
585 if (newPos[2] <= newPos[0]+0.01)
587 newPos[2] = newPos[0] + 0.01;
591 this->StartPosition[1] = size[1];
594 if (newPos[3] <= newPos[1]+0.01)
596 newPos[3] = newPos[1] + 0.01;
599 this->Renderer->SetViewport(newPos);
600 this->Interactor->Render();
603 //----------------------------------------------------------------------------
604 void vtkPVAxesWidget::ResizeBottomLeft()
606 int x = this->Interactor->GetEventPosition()[0];
607 int y = this->Interactor->GetEventPosition()[1];
609 int dx = x - this->StartPosition[0];
610 int dy = y - this->StartPosition[1];
612 int *size = this->ParentRenderer->GetSize();
613 double dxNorm = dx / (double)size[0];
614 double dyNorm = dy / (double)size[1];
615 double *vp = this->Renderer->GetViewport();
618 double absDx = fabs(dxNorm);
619 double absDy = fabs(dyNorm);
630 this->StartPosition[0] = x;
631 this->StartPosition[1] = y;
634 newPos[0] = vp[0] + change;
635 newPos[1] = vp[1] + change;
641 this->StartPosition[0] = 0;
644 if (newPos[0] >= newPos[2]-0.01)
646 newPos[0] = newPos[2] - 0.01;
650 this->StartPosition[1] = 0;
653 if (newPos[1] >= newPos[3]-0.01)
655 newPos[1] = newPos[3] - 0.01;
658 this->Renderer->SetViewport(newPos);
659 this->Interactor->Render();
662 //----------------------------------------------------------------------------
663 void vtkPVAxesWidget::ResizeBottomRight()
665 int x = this->Interactor->GetEventPosition()[0];
666 int y = this->Interactor->GetEventPosition()[1];
668 int dx = x - this->StartPosition[0];
669 int dy = y - this->StartPosition[1];
671 int *size = this->ParentRenderer->GetSize();
672 double dxNorm = dx / (double)size[0];
673 double dyNorm = dy / (double)size[1];
675 double *vp = this->Renderer->GetViewport();
679 double absDx = fabs(dxNorm);
680 double absDy = fabs(dyNorm);
693 this->StartPosition[0] = x;
694 this->StartPosition[1] = y;
698 newPos[1] = useX ? vp[1] - change : vp[1] + change;
699 newPos[2] = useX ? vp[2] + change : vp[2] - change;
704 this->StartPosition[0] = size[0];
707 if (newPos[2] <= newPos[0]+0.01)
709 newPos[2] = newPos[0] + 0.01;
713 this->StartPosition[1] = 0;
716 if (newPos[1] >= newPos[3]-0.01)
718 newPos[1] = newPos[3]-0.01;
721 this->Renderer->SetViewport(newPos);
722 this->Interactor->Render();
725 //----------------------------------------------------------------------------
726 void vtkPVAxesWidget::SquareRenderer()
728 int *size = this->Renderer->GetSize();
729 if (size[0] == 0 || size[1] == 0)
735 this->Renderer->GetViewport(vp);
737 double deltaX = vp[2] - vp[0];
738 double newDeltaX = size[1] * deltaX / (double)size[0];
739 double deltaY = vp[3] - vp[1];
740 double newDeltaY = size[0] * deltaY / (double)size[1];
746 if (size[0] > size[1])
748 newDeltaX = size[1] / (double)size[0];
754 newDeltaY = size[0] / (double)size[1];
762 vp[3] = vp[1] + newDeltaY;
766 vp[1] = vp[3] - newDeltaY;
772 vp[2] = vp[0] + newDeltaX;
776 vp[0] = vp[2] - newDeltaX;
780 this->Renderer->SetViewport(vp);
782 this->Renderer->NormalizedDisplayToDisplay(vp[0], vp[1]);
783 this->Renderer->NormalizedDisplayToDisplay(vp[2], vp[3]);
785 vtkPoints *points = this->Outline->GetPoints();
786 points->SetPoint(0, vp[0]+1, vp[1]+1, 0);
787 points->SetPoint(1, vp[2]-1, vp[1]+1, 0);
788 points->SetPoint(2, vp[2]-1, vp[3]-1, 0);
789 points->SetPoint(3, vp[0]+1, vp[3]-1, 0);
792 //----------------------------------------------------------------------------
793 void vtkPVAxesWidget::SetInteractive(int state)
795 if (this->Interactive != state)
797 this->Interactive = state;
802 this->OnButtonRelease();
803 this->MouseCursorState = vtkPVAxesWidget::Outside;
804 this->Renderer->RemoveActor(this->OutlineActor);
805 if (this->Interactor)
807 this->SetMouseCursor(this->MouseCursorState);
808 // this->Interactor->Render();
813 //----------------------------------------------------------------------------
814 void vtkPVAxesWidget::SetOutlineColor(double r, double g, double b)
816 this->OutlineActor->GetProperty()->SetColor(r, g, b);
817 if (this->Interactor)
819 // this->Interactor->Render();
823 //----------------------------------------------------------------------------
824 double* vtkPVAxesWidget::GetOutlineColor()
826 return this->OutlineActor->GetProperty()->GetColor();
829 //----------------------------------------------------------------------------
830 void vtkPVAxesWidget::SetAxisLabelColor(double r, double g, double b)
832 this->AxesActor->GetXAxisLabelProperty()->SetColor(r, g, b);
833 this->AxesActor->GetYAxisLabelProperty()->SetColor(r, g, b);
834 this->AxesActor->GetZAxisLabelProperty()->SetColor(r, g, b);
837 //----------------------------------------------------------------------------
838 double* vtkPVAxesWidget::GetAxisLabelColor()
840 return this->AxesActor->GetXAxisLabelProperty()->GetColor();
843 //----------------------------------------------------------------------------
844 vtkRenderer* vtkPVAxesWidget::GetParentRenderer()
846 return this->ParentRenderer;
849 //----------------------------------------------------------------------------
850 void vtkPVAxesWidget::SetViewport(double minX, double minY,
851 double maxX, double maxY)
853 this->Renderer->SetViewport(minX, minY, maxX, maxY);
856 //----------------------------------------------------------------------------
857 double* vtkPVAxesWidget::GetViewport()
859 return this->Renderer->GetViewport();
862 //----------------------------------------------------------------------------
863 void vtkPVAxesWidget::PrintSelf(ostream& os, vtkIndent indent)
865 this->Superclass::PrintSelf(os, indent);
867 os << indent << "AxesActor: " << this->AxesActor << endl;
868 os << indent << "Interactive: " << this->Interactive << endl;