1 //---------------------------------------------------------------------------
2 #include <vcl.h>
3 #pragma hdrstop
4 
5 #include <vcl\Sysutils.hpp>
6 
7 #include "vtkBorlandRenderWindow.h"
8 
9 #include "vtkInteractorStyleSwitch.h"
10 #include "vtkInteractorStyleFlight.h"
11 #include "vtkInteractorStyleImage.h"
12 #include "vtkInteractorStyleUser.h"
13 
14 #pragma package(smart_init)
15 
16 //---------------------------------------------------------------------------
17 // ValidCtrCheck is used to assure that the components created do not have
18 // any pure virtual functions.
19 //
ValidCtrCheck(TvtkBorlandRenderWindow *)20 static inline void ValidCtrCheck(TvtkBorlandRenderWindow *)
21 {
22   new TvtkBorlandRenderWindow(NULL);
23 }
24 
25 //---------------------------------------------------------------------------
26 namespace Vtkborlandrenderwindow
27 {
Register()28   void __fastcall PACKAGE Register()
29     {
30     TComponentClass classes[1] = {__classid(TvtkBorlandRenderWindow)};
31     RegisterComponents("Samples", classes, 0);
32     }
33 }
34 
35 //---------------------------------------------------------------------------
TvtkBorlandRenderWindow(TComponent * Owner)36 __fastcall TvtkBorlandRenderWindow::TvtkBorlandRenderWindow(TComponent* Owner)
37         : inherited(Owner)
38 {
39   // Do want these
40   ControlStyle << csCaptureMouse << csClickEvents << csOpaque << csDoubleClicks;
41   // Don't want these
42   ControlStyle >> csAcceptsControls >> csSetCaption;
43 
44   FUsevtkInteractor   = true;
45   FInteractorMode     = IM_TrackballCamera;
46   FInteractor         = 0;
47   FOnVtkClose         = 0;
48   FRenderWindow       = 0;
49   FRenderer           = 0;
50   FAbortCallback      = vtkAbortCallback::New();
51 }
52 
53 //---------------------------------------------------------------------------
~TvtkBorlandRenderWindow()54 __fastcall TvtkBorlandRenderWindow::~TvtkBorlandRenderWindow()
55 {
56     // Delete this first because Renderwindow has a hold on it too
57   if ( FInteractor )
58     {
59     FInteractor->Delete();
60     FInteractor = 0;
61     }
62   if ( FRenderer )
63     {
64     FRenderer->GetViewProps()->RemoveAllItems();
65     FRenderWindow->RemoveRenderer(FRenderer);
66     FRenderer->Delete();
67     FRenderer = 0;
68     }
69   if ( FRenderWindow )
70     {
71     FRenderWindow->RemoveObserver(FAbortCallback);
72     FRenderWindow->Delete();
73     FRenderWindow = 0;
74     }
75   FAbortCallback->Delete();
76 }
77 
78 //---------------------------------------------------------------------------
GetRenderWindow(void)79 vtkWin32OpenGLRenderWindow * __fastcall TvtkBorlandRenderWindow::GetRenderWindow(void)
80 {
81   if ( ! FRenderWindow )
82     {
83     // Stuff the renderwindow into our window
84     FRenderWindow = vtkWin32OpenGLRenderWindow::New();
85     FRenderWindow->AddObserver( vtkCommand::AbortCheckEvent, FAbortCallback);
86     FRenderWindow->SetParentId(Parent->Handle);
87     FRenderWindow->SetWindowId(Handle);
88     FRenderWindow->DoubleBufferOn();
89     FRenderWindow->SwapBuffersOn();
90     // Frame to avoid unsightly garbage during initial
91     // display which may be long when a complex scene is first rendered
92     FRenderWindow->Frame();
93     Invalidate();
94     }
95     // We create the interactor here because it makes maintenance better
96   if (!FInteractor)
97     {
98     FInteractor = vtkWin32RenderWindowInteractor::New();
99     FInteractor->SetRenderWindow(FRenderWindow);
100     FInteractor->SetInstallMessageProc(false);
101     SetInteractorMode(FInteractorMode);
102     FInteractor->UpdateSize(Width,Height);
103     FInteractor->Initialize();
104     }
105   return FRenderWindow;
106 }
107 
108 //---------------------------------------------------------------------------
GetInteractor(void)109 vtkWin32RenderWindowInteractor * __fastcall TvtkBorlandRenderWindow::GetInteractor(void)
110 {
111   if (FRenderWindow)
112     {
113     if (!FInteractor)
114       {
115       throw Exception("Window exists but no Interactor, this shouldn't happen");
116       }
117     }
118   else
119     {
120     this->GetRenderWindow();
121     }
122   return FInteractor;
123 }
124 
125 //---------------------------------------------------------------------------
GetRenderer(void)126 vtkRenderer * __fastcall TvtkBorlandRenderWindow::GetRenderer(void)
127 {
128   if (!FRenderer)
129     {
130     FRenderer = vtkRenderer::New();
131     GetRenderWindow()->AddRenderer(FRenderer);
132     FRenderer->ResetCamera();
133     DWORD  L = ColorToRGB(Color);
134     double rgb[3] = { GetRValue(L)/255.0, GetGValue(L)/255.0, GetBValue(L)/255.0 };
135     FRenderer->SetBackground(rgb);
136     }
137   return FRenderer;
138 }
139 
140 //---------------------------------------------------------------------------
SetInteractorMode(const vtkBorlandInteractorMode & im)141 void __fastcall TvtkBorlandRenderWindow::SetInteractorMode(const vtkBorlandInteractorMode& im)
142 {
143   if ( im <= IM_TrackballActor && im >= IM_JoystickCamera )
144     {
145     vtkInteractorStyleSwitch *iass = vtkInteractorStyleSwitch::SafeDownCast(FInteractor->GetInteractorStyle());
146     if (!iass)
147       {
148       iass = vtkInteractorStyleSwitch::New();
149       FInteractor->SetInteractorStyle(iass);
150       iass->Delete();
151       }
152 
153     switch ( im )
154       {
155       case IM_JoystickCamera: iass->SetCurrentStyleToJoystickCamera(); break;
156       case IM_JoystickActor: iass->SetCurrentStyleToJoystickActor(); break;
157       case IM_TrackballCamera: iass->SetCurrentStyleToTrackballCamera(); break;
158       case IM_TrackballActor: iass->SetCurrentStyleToTrackballActor(); break;
159       default: break;
160       }
161       FInteractorMode = im;
162     }
163     else if (im==IM_Flight)
164       {
165       vtkInteractorStyleFlight *iafl = vtkInteractorStyleFlight::SafeDownCast(FInteractor->GetInteractorStyle());
166       if (!iafl)
167         {
168         iafl = vtkInteractorStyleFlight::New();
169         FInteractor->SetInteractorStyle(iafl);
170         iafl->Delete();
171         }
172       FInteractorMode = IM_Flight;
173       }
174     else if (im==IM_Image)
175       {
176       vtkInteractorStyleImage *iasi = vtkInteractorStyleImage::SafeDownCast(FInteractor->GetInteractorStyle());
177       if (!iasi)
178         {
179         iasi = vtkInteractorStyleImage::New();
180         FInteractor->SetInteractorStyle(iasi);
181         iasi->Delete();
182         }
183       FInteractorMode = IM_Image;
184       }
185     else if (im==IM_User)
186       {
187       vtkInteractorStyleUser *iasu = vtkInteractorStyleUser::SafeDownCast(FInteractor->GetInteractorStyle());
188       if (!iasu)
189         {
190         iasu = vtkInteractorStyleUser::New();
191         FInteractor->SetInteractorStyle(iasu);
192         iasu->Delete();
193         }
194       FInteractorMode = IM_User;
195       }
196     else
197       {
198       return;
199       }
200 }
201 
202 //---------------------------------------------------------------------------
203 // Paint
204 //---------------------------------------------------------------------------
Paint(void)205 void __fastcall TvtkBorlandRenderWindow::Paint(void)
206 {
207   if (FRenderWindow)
208     {
209     try
210       {
211       FRenderWindow->Render();
212       }
213     catch (...)
214       {
215       // Some error trap should occurr here
216       ShowMessage("An exception occurred whilst rendering");
217       }
218     }
219   else
220     { // Design time or before RenderWindow creation
221     inherited::Paint();
222     }
223 }
224 
225 //---------------------------------------------------------------------------
226 // Event handlers
227 //---------------------------------------------------------------------------
WMEraseBkgnd(TWMEraseBkgnd & Message)228 void __fastcall TvtkBorlandRenderWindow::WMEraseBkgnd(TWMEraseBkgnd &Message)
229 {
230   if (!FRenderWindow)
231     {
232     inherited::Dispatch(&Message);
233     }
234   else
235     {
236     Message.Result = 1; // No, but thanks for asking.
237     }
238 }
239 
240 //---------------------------------------------------------------------------
WMGetDlgCode(TMessage & Message)241 void __fastcall TvtkBorlandRenderWindow::WMGetDlgCode(TMessage &Message)
242 {
243   Message.Result = DLGC_WANTARROWS;
244 }
245 
246 //---------------------------------------------------------------------------
WMChar(TWMKey & Message)247 void __fastcall TvtkBorlandRenderWindow::WMChar(TWMKey &Message)
248 {
249   switch (Message.CharCode)
250     {
251     case 'e':
252     case 'E':
253     case 'q':
254     case 'Q': if (!FOnVtkClose || (FOnVtkClose && FOnVtkClose(this)))
255                 {
256                 FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
257                 }
258               break;
259     default:  FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
260     }
261 }
262 
263 //---------------------------------------------------------------------------
WMKeyDown(TWMKey & Message)264 void __fastcall TvtkBorlandRenderWindow::WMKeyDown(TWMKey &Message)
265 {
266   FInteractor->OnKeyDown(Handle,Message.CharCode, 0, 0);
267 }
268 
269 //---------------------------------------------------------------------------
WMKeyUp(TWMKey & Message)270 void __fastcall TvtkBorlandRenderWindow::WMKeyUp(TWMKey &Message)
271 {
272   FInteractor->OnKeyUp(Handle,Message.CharCode, 0, 0);
273 }
274 
275 //---------------------------------------------------------------------------
MouseMove(TShiftState shift,int x,int y)276 void __fastcall TvtkBorlandRenderWindow::MouseMove(TShiftState shift, int x, int y )
277 {
278   if(this->OnMouseMove && shift.Contains(ssCtrl))
279     {
280     this->OnMouseMove(this,shift,x,y);
281     return;
282     }
283 
284   if (FInteractor && FUsevtkInteractor)
285     {
286     int flags = 0;
287     if (shift.Contains(ssShift)) flags += MK_SHIFT;
288     if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
289     FInteractor->OnMouseMove(Handle, flags, x, y );
290     }
291 }
292 
293 //---------------------------------------------------------------------------
MouseDown(TMouseButton button,TShiftState shift,int x,int y)294 void __fastcall TvtkBorlandRenderWindow::MouseDown(TMouseButton button, TShiftState shift, int x, int y )
295 {
296   if (::GetFocus()!=Handle) SetFocus();
297 
298   if(this->OnMouseDown && shift.Contains(ssCtrl))
299     {
300     this->OnMouseDown(this,button,shift,x,y);
301     return;
302     }
303 
304   if (FInteractor && FUsevtkInteractor)
305     {
306     int flags = 0;
307     if (shift.Contains(ssShift)) flags += MK_SHIFT;
308     if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
309     switch (button)
310       {
311       case mbLeft:   FInteractor->OnLButtonDown(Handle, flags, x,y); break;
312       case mbRight:  FInteractor->OnRButtonDown(Handle, flags, x,y); break;
313       case mbMiddle: FInteractor->OnMButtonDown(Handle, flags, x,y); break;
314       }
315     }
316 }
317 
318 //---------------------------------------------------------------------------
MouseUp(TMouseButton button,TShiftState shift,int x,int y)319 void __fastcall TvtkBorlandRenderWindow::MouseUp(TMouseButton button, TShiftState shift, int x, int y )
320 {
321   if(this->OnMouseUp  && shift.Contains(ssCtrl))
322     {
323     this->OnMouseUp(this,button,shift,x,y);
324     return;
325     }
326 
327   if (FInteractor && FUsevtkInteractor)
328     {
329     int flags = 0;
330     if (shift.Contains(ssShift)) flags += MK_SHIFT;
331     if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
332     switch (button)
333       {
334       case mbLeft:   FInteractor->OnLButtonUp(Handle, flags, x,y); break;
335       case mbRight:  FInteractor->OnRButtonUp(Handle, flags, x,y); break;
336       case mbMiddle: FInteractor->OnMButtonUp(Handle, flags, x,y); break;
337       }
338     }
339 }
340 
341 //---------------------------------------------------------------------------
Resize(void)342 void __fastcall TvtkBorlandRenderWindow::Resize(void)
343 {
344   if (FInteractor)
345     {
346     FInteractor->OnSize(this->Handle, 0, this->Width, this->Height);
347     }
348 }
349 
350 //---------------------------------------------------------------------------
WMTimer(TWMTimer & Message)351 void __fastcall TvtkBorlandRenderWindow::WMTimer(TWMTimer &Message)
352 {
353   if (FInteractor)
354     {
355     FInteractor->OnTimer(Handle,Message.TimerID);
356     }
357 }
358 
359 //---------------------------------------------------------------------------
DoMouseWheelDown(TShiftState Shift,const TPoint & MousePos)360 bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelDown(TShiftState Shift, const TPoint &MousePos)
361 {
362   bool result;
363   if (this->OnMouseWheelDown && Shift.Contains(ssCtrl))
364     {
365     this->OnMouseWheelDown(this,Shift,MousePos,result);
366     return result;
367     }
368 
369   if (FInteractor && FUsevtkInteractor)
370     {
371     int flags = 0;
372     if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
373     if (Shift.Contains(ssCtrl))  { flags += MK_CONTROL; }
374     FInteractor->OnMouseWheelBackward(Handle, flags, MousePos.x,MousePos.y);
375     result = true;
376     }
377   return result;
378 }
379 
380 //---------------------------------------------------------------------------
DoMouseWheelUp(TShiftState Shift,const TPoint & MousePos)381 bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelUp(TShiftState Shift, const TPoint &MousePos)
382 {
383   bool result;
384   if (this->OnMouseWheelUp && Shift.Contains(ssCtrl))
385     {
386     this->OnMouseWheelUp(this,Shift,MousePos,result);
387     return result;
388     }
389 
390   if (FInteractor && FUsevtkInteractor)
391     {
392     int flags = 0;
393     if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
394     if (Shift.Contains(ssCtrl))  { flags += MK_CONTROL; }
395     FInteractor->OnMouseWheelForward(Handle, flags, MousePos.x,MousePos.y);
396     result = true;
397     }
398   return result;
399 }
400 
401 
402 
403 
404