1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkTexturedButtonRepresentation2D.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkTexturedButtonRepresentation2D.h"
16 #include "vtkBalloonRepresentation.h"
17 #include "vtkPolyDataMapper2D.h"
18 #include "vtkPolyData.h"
19 #include "vtkProperty2D.h"
20 #include "vtkRenderer.h"
21 #include "vtkInteractorObserver.h"
22 #include "vtkCoordinate.h"
23 #include "vtkRenderWindow.h"
24 #include "vtkCamera.h"
25 #include "vtkObjectFactory.h"
26 #include "vtkSmartPointer.h"
27 #include "vtkImageData.h"
28 #include "vtkCoordinate.h"
29 #include <map>
30 
31 vtkStandardNewMacro(vtkTexturedButtonRepresentation2D);
32 
33 vtkCxxSetObjectMacro(vtkTexturedButtonRepresentation2D,Property,vtkProperty2D);
34 vtkCxxSetObjectMacro(vtkTexturedButtonRepresentation2D,HoveringProperty,vtkProperty2D);
35 vtkCxxSetObjectMacro(vtkTexturedButtonRepresentation2D,SelectingProperty,vtkProperty2D);
36 
37 // Map of textures
38 class vtkTextureArray : public std::map<int,vtkSmartPointer<vtkImageData> > {};
39 typedef std::map<int,vtkSmartPointer<vtkImageData> >::iterator vtkTextureArrayIterator;
40 
41 
42 //----------------------------------------------------------------------
vtkTexturedButtonRepresentation2D()43 vtkTexturedButtonRepresentation2D::vtkTexturedButtonRepresentation2D()
44 {
45   // Configure the balloon
46   this->Balloon = vtkBalloonRepresentation::New();
47   this->Balloon->SetOffset(0,0);
48 
49   // Set up the initial properties
50   this->CreateDefaultProperties();
51 
52   // List of textures
53   this->TextureArray = new vtkTextureArray;
54 
55   // Anchor point assuming that the button is anchored in 3D
56   // If NULL, then the placement occurs in display space
57   this->Anchor = NULL;
58 
59 }
60 
61 //----------------------------------------------------------------------
~vtkTexturedButtonRepresentation2D()62 vtkTexturedButtonRepresentation2D::~vtkTexturedButtonRepresentation2D()
63 {
64   this->Balloon->Delete();
65 
66   if ( this->Property )
67     {
68     this->Property->Delete();
69     this->Property = NULL;
70     }
71 
72   if ( this->HoveringProperty )
73     {
74     this->HoveringProperty->Delete();
75     this->HoveringProperty = NULL;
76     }
77 
78   if ( this->SelectingProperty )
79     {
80     this->SelectingProperty->Delete();
81     this->SelectingProperty = NULL;
82     }
83 
84   delete this->TextureArray;
85 
86   if ( this->Anchor )
87     {
88     this->Anchor->Delete();
89     }
90 
91 }
92 
93 //-------------------------------------------------------------------------
94 void vtkTexturedButtonRepresentation2D::
SetButtonTexture(int i,vtkImageData * image)95 SetButtonTexture(int i, vtkImageData *image)
96 {
97   if ( i < 0 )
98     {
99     i = 0;
100     }
101   if ( i >= this->NumberOfStates )
102     {
103     i = this->NumberOfStates - 1;
104     }
105 
106   (*this->TextureArray)[i] = image;
107 }
108 
109 
110 //-------------------------------------------------------------------------
111 vtkImageData *vtkTexturedButtonRepresentation2D::
GetButtonTexture(int i)112 GetButtonTexture(int i)
113 {
114   if ( i < 0 )
115     {
116     i = 0;
117     }
118   if ( i >= this->NumberOfStates )
119     {
120     i = this->NumberOfStates - 1;
121     }
122 
123   vtkTextureArrayIterator iter = this->TextureArray->find(i);
124   if ( iter != this->TextureArray->end() )
125     {
126     return (*iter).second;
127     }
128   else
129     {
130     return NULL;
131     }
132 }
133 
134 //-------------------------------------------------------------------------
PlaceWidget(double bds[6])135 void vtkTexturedButtonRepresentation2D::PlaceWidget(double bds[6])
136 {
137   int i;
138   double bounds[6], center[3];
139 
140   this->AdjustBounds(bds, bounds, center);
141   for (i=0; i<6; i++)
142     {
143     this->InitialBounds[i] = bounds[i];
144     }
145   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
146                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
147                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
148 
149   if ( this->Anchor )
150     {//no longer in world space
151     this->Anchor->Delete();
152     this->Anchor = NULL;
153     }
154 
155   double e[2];
156   e[0] = static_cast<double>(bounds[0]);
157   e[1] = static_cast<double>(bounds[2]);
158   this->Balloon->StartWidgetInteraction(e);
159   this->Balloon->SetImageSize(static_cast<int>(bounds[1]-bounds[0]),
160                               static_cast<int>(bounds[3]-bounds[2]));
161 }
162 
163 //-------------------------------------------------------------------------
PlaceWidget(double anchor[3],int size[2])164 void vtkTexturedButtonRepresentation2D::PlaceWidget(double anchor[3], int size[2])
165 {
166   if ( ! this->Anchor )
167     {
168     this->Anchor = vtkCoordinate::New();
169     this->Anchor->SetCoordinateSystemToWorld();
170     }
171 
172   this->Anchor->SetValue(anchor);
173 
174   double e[2]; e[0] = e[1] = 0.0;
175   if ( this->Renderer )
176     {
177     double *p = this->Anchor->GetComputedDoubleDisplayValue(this->Renderer);
178     this->Balloon->SetRenderer(this->Renderer);
179     this->Balloon->StartWidgetInteraction(p);
180     e[0] = static_cast<double>(p[0]);
181     e[1] = static_cast<double>(p[1]);
182     }
183   else
184     {
185     this->Balloon->StartWidgetInteraction(e);
186     }
187 
188   this->Balloon->SetImageSize(size);
189 
190   this->InitialBounds[0] = e[0];
191   this->InitialBounds[1] = e[0]+size[0];
192   this->InitialBounds[2] = e[1];
193   this->InitialBounds[3] = e[1]+size[1];
194   this->InitialBounds[4] = this->InitialBounds[5] = 0.0;
195 
196   double *bounds = this->InitialBounds;
197   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
198                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
199                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
200 }
201 
202 
203 //-------------------------------------------------------------------------
204 int vtkTexturedButtonRepresentation2D
ComputeInteractionState(int X,int Y,int vtkNotUsed (modify))205 ::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify))
206 {
207   if ( this->Balloon->ComputeInteractionState(X,Y) == vtkBalloonRepresentation::OnImage )
208     {
209     this->InteractionState = vtkButtonRepresentation::Inside;
210     }
211   else
212     {
213     this->InteractionState = vtkButtonRepresentation::Outside;
214     }
215 
216   return this->InteractionState;
217 }
218 
219 //----------------------------------------------------------------------
Highlight(int highlight)220 void vtkTexturedButtonRepresentation2D::Highlight(int highlight)
221 {
222   this->Superclass::Highlight(highlight);
223 
224   vtkProperty2D *initialProperty = this->Balloon->GetImageProperty();
225   vtkProperty2D *selectedProperty;
226 
227   if ( highlight == vtkButtonRepresentation::HighlightHovering )
228     {
229     this->Balloon->SetImageProperty(this->HoveringProperty);
230     selectedProperty = this->HoveringProperty;
231     }
232   else if ( highlight == vtkButtonRepresentation::HighlightSelecting )
233     {
234     this->Balloon->SetImageProperty(this->SelectingProperty);
235     selectedProperty = this->SelectingProperty;
236     }
237   else //if ( highlight == vtkButtonRepresentation::HighlightNormal )
238     {
239     this->Balloon->SetImageProperty(this->Property);
240     selectedProperty = this->Property;
241     }
242 
243   if ( selectedProperty != initialProperty )
244     {
245     this->Modified();
246     }
247 }
248 
249 //----------------------------------------------------------------------
CreateDefaultProperties()250 void vtkTexturedButtonRepresentation2D::CreateDefaultProperties()
251 {
252   this->Property = vtkProperty2D::New();
253   this->Property->SetColor(0.9,0.9,0.9);
254 
255   this->HoveringProperty = vtkProperty2D::New();
256   this->HoveringProperty->SetColor(1,1,1);
257 
258   this->SelectingProperty = vtkProperty2D::New();
259   this->SelectingProperty->SetColor(0.5,0.5,0.5);
260 }
261 
262 //----------------------------------------------------------------------
BuildRepresentation()263 void vtkTexturedButtonRepresentation2D::BuildRepresentation()
264 {
265   // The net effect is to resize the handle
266   if ( this->GetMTime() > this->BuildTime ||
267        (this->Renderer &&
268         this->Renderer->GetActiveCamera()->GetMTime() > this->BuildTime) ||
269        (this->Renderer && this->Renderer->GetVTKWindow() &&
270         this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
271     {
272     this->Balloon->SetRenderer(this->Renderer);
273 
274     // Setup the texture
275     vtkTextureArrayIterator iter = this->TextureArray->find(this->State);
276     if ( iter != this->TextureArray->end() )
277       {
278       this->Balloon->SetBalloonImage((*iter).second);
279       }
280     else
281       {
282       this->Balloon->SetBalloonImage(NULL);
283       }
284 
285     // Update the position if anchored in world coordinates
286     if ( this->Anchor )
287       {
288       double *p = this->Anchor->GetComputedDoubleDisplayValue(this->Renderer);
289       this->Balloon->StartWidgetInteraction(p);
290       this->Balloon->Modified();
291       }
292 
293     this->BuildTime.Modified();
294     }
295 }
296 
297 
298 //----------------------------------------------------------------------
ShallowCopy(vtkProp * prop)299 void vtkTexturedButtonRepresentation2D::ShallowCopy(vtkProp *prop)
300 {
301   vtkTexturedButtonRepresentation2D *rep =
302     vtkTexturedButtonRepresentation2D::SafeDownCast(prop);
303   if ( rep )
304     {
305     this->Property->DeepCopy(rep->Property);
306     this->HoveringProperty->DeepCopy(rep->HoveringProperty);
307     this->SelectingProperty->DeepCopy(rep->SelectingProperty);
308 
309     vtkTextureArrayIterator iter;
310     for ( iter=rep->TextureArray->begin();
311           iter != rep->TextureArray->end(); ++iter )
312       {
313       (*this->TextureArray)[(*iter).first] = (*iter).second;
314       }
315     }
316   this->Superclass::ShallowCopy(prop);
317 }
318 
319 //----------------------------------------------------------------------
320 void vtkTexturedButtonRepresentation2D::
ReleaseGraphicsResources(vtkWindow * win)321 ReleaseGraphicsResources(vtkWindow *win)
322 {
323   this->Balloon->ReleaseGraphicsResources(win);
324 }
325 
326 //----------------------------------------------------------------------
327 int vtkTexturedButtonRepresentation2D::
RenderOverlay(vtkViewport * viewport)328 RenderOverlay(vtkViewport *viewport)
329 {
330   this->BuildRepresentation();
331 
332   return this->Balloon->RenderOverlay(viewport);
333 }
334 
335 //-----------------------------------------------------------------------------
336 int vtkTexturedButtonRepresentation2D::
HasTranslucentPolygonalGeometry()337 HasTranslucentPolygonalGeometry()
338 {
339   this->BuildRepresentation();
340 
341   return this->Balloon->HasTranslucentPolygonalGeometry();
342 }
343 
344 
345 //----------------------------------------------------------------------
GetBounds()346 double *vtkTexturedButtonRepresentation2D::GetBounds()
347 {
348   return NULL;
349 }
350 
351 //----------------------------------------------------------------------
GetActors(vtkPropCollection * pc)352 void vtkTexturedButtonRepresentation2D::GetActors(vtkPropCollection *pc)
353 {
354   this->Balloon->GetActors(pc);
355 }
356 
357 //----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)358 void vtkTexturedButtonRepresentation2D::PrintSelf(ostream& os, vtkIndent indent)
359 {
360   //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
361   this->Superclass::PrintSelf(os,indent);
362 
363   if ( this->Property )
364     {
365     os << indent << "Property: " << this->Property << "\n";
366     }
367   else
368     {
369     os << indent << "Property: (none)\n";
370     }
371 
372   if ( this->HoveringProperty )
373     {
374     os << indent << "Hovering Property: " << this->HoveringProperty << "\n";
375     }
376   else
377     {
378     os << indent << "Hovering Property: (none)\n";
379     }
380 
381   if ( this->SelectingProperty )
382     {
383     os << indent << "Selecting Property: " << this->SelectingProperty << "\n";
384     }
385   else
386     {
387     os << indent << "Selecting Property: (none)\n";
388     }
389 }
390