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