1 | // |
---|
2 | // ******************************************************************** |
---|
3 | // * License and Disclaimer * |
---|
4 | // * * |
---|
5 | // * The Geant4 software is copyright of the Copyright Holders of * |
---|
6 | // * the Geant4 Collaboration. It is provided under the terms and * |
---|
7 | // * conditions of the Geant4 Software License, included in the file * |
---|
8 | // * LICENSE and available at http://cern.ch/geant4/license . These * |
---|
9 | // * include a list of copyright holders. * |
---|
10 | // * * |
---|
11 | // * Neither the authors of this software system, nor their employing * |
---|
12 | // * institutes,nor the agencies providing financial support for this * |
---|
13 | // * work make any representation or warranty, express or implied, * |
---|
14 | // * regarding this software system or assume any liability for its * |
---|
15 | // * use. Please see the license in the file LICENSE and URL above * |
---|
16 | // * for the full disclaimer and the limitation of liability. * |
---|
17 | // * * |
---|
18 | // * This code implementation is the result of the scientific and * |
---|
19 | // * technical work of the GEANT4 collaboration. * |
---|
20 | // * By using, copying, modifying or distributing the software (or * |
---|
21 | // * any work based on the software) you agree to acknowledge its * |
---|
22 | // * use in resulting scientific publications, and indicate your * |
---|
23 | // * acceptance of all terms of the Geant4 Software license. * |
---|
24 | // ******************************************************************** |
---|
25 | // |
---|
26 | // |
---|
27 | // $Id: G4OpenInventorWinViewer.cc,v 1.25 2006/06/29 21:22:22 gunter Exp $ |
---|
28 | // GEANT4 tag $Name: $ |
---|
29 | // |
---|
30 | /* |
---|
31 | * jck : 05 Feb 1997 : Initial Implementation |
---|
32 | * jck : 21 Apr 1997 : Mods for SoXtHepViewer |
---|
33 | * gb : on Win32 use an SoXtExaminerViewer. |
---|
34 | * gb : 05 April 2004 : creation. |
---|
35 | * gb : 09 November 2004 : Pulldown menu with the escape menu item. |
---|
36 | * gb 14 November 2004 : inherit G4OpenInventorViewer. |
---|
37 | */ |
---|
38 | |
---|
39 | #ifdef G4VIS_BUILD_OIWIN32_DRIVER |
---|
40 | |
---|
41 | // this : |
---|
42 | #include "G4OpenInventorWinViewer.hh" |
---|
43 | |
---|
44 | #include <Inventor/nodes/SoSelection.h> |
---|
45 | |
---|
46 | #include <Inventor/Win/SoWin.h> |
---|
47 | #include <Inventor/Win/viewers/SoWinExaminerViewer.h> |
---|
48 | |
---|
49 | #include "HEPVis/actions/SoGL2PSAction.h" |
---|
50 | |
---|
51 | #include "G4OpenInventor.hh" |
---|
52 | #include "G4OpenInventorSceneHandler.hh" |
---|
53 | #include "G4VInteractorManager.hh" |
---|
54 | |
---|
55 | #include <windowsx.h> |
---|
56 | |
---|
57 | // To have sizeChanged public : |
---|
58 | class Geant4_SoWinExaminerViewer : public SoWinExaminerViewer { |
---|
59 | public: |
---|
60 | Geant4_SoWinExaminerViewer(HWND parent,const char* name,SbBool embed) |
---|
61 | :SoWinExaminerViewer(parent,name,embed){} |
---|
62 | virtual void sizeChanged(const SbVec2s & size){ |
---|
63 | SoWinExaminerViewer::sizeChanged(size); |
---|
64 | } |
---|
65 | }; |
---|
66 | |
---|
67 | // File : |
---|
68 | #define ID_FILE_POSTSCRIPT 1 |
---|
69 | #define ID_FILE_PIXMAP_POSTSCRIPT 2 |
---|
70 | #define ID_FILE_INVENTOR 3 |
---|
71 | #define ID_FILE_ESCAPE 4 |
---|
72 | // Etc : |
---|
73 | #define ID_ETC_ERASE_DETECTOR 101 |
---|
74 | #define ID_ETC_ERASE_EVENT 102 |
---|
75 | #define ID_ETC_SET_SOLID 103 |
---|
76 | #define ID_ETC_SET_WIRE_FRAME 104 |
---|
77 | #define ID_ETC_SET_REDUCED_WIRE_FRAME 105 |
---|
78 | #define ID_ETC_SET_FULL_WIRE_FRAME 106 |
---|
79 | #define ID_ETC_SET_PREVIEW 107 |
---|
80 | #define ID_ETC_SET_PREVIEW_AND_FULL 108 |
---|
81 | #define ID_ETC_UPDATE_SCENE 109 |
---|
82 | #define ID_ETC_STATS 110 |
---|
83 | // Help : |
---|
84 | #define ID_HELP_CONTROLS 201 |
---|
85 | |
---|
86 | //static void SecondaryLoopPostAction (); |
---|
87 | |
---|
88 | static const char className[] = "G4OpenInventorShellWindow"; |
---|
89 | |
---|
90 | G4OpenInventorWinViewer::G4OpenInventorWinViewer( |
---|
91 | G4OpenInventorSceneHandler& sceneHandler |
---|
92 | ,const G4String& name) |
---|
93 | :G4OpenInventorViewer (sceneHandler, name) |
---|
94 | ,fShell(0) |
---|
95 | ,fViewer(0) |
---|
96 | { |
---|
97 | G4cout << "Window name: " << fName << G4endl; |
---|
98 | |
---|
99 | } |
---|
100 | |
---|
101 | |
---|
102 | void G4OpenInventorWinViewer::Initialise() { |
---|
103 | |
---|
104 | G4String wName = fName; |
---|
105 | |
---|
106 | int width = 600; |
---|
107 | int height = 600; |
---|
108 | |
---|
109 | HWND parent = (HWND)fInteractorManager->GetParentInteractor (); |
---|
110 | if(!parent) { |
---|
111 | //Create a shell window : |
---|
112 | G4String shellName = wName; |
---|
113 | shellName += "_shell"; |
---|
114 | static SbBool done = FALSE; |
---|
115 | if(done==FALSE) { |
---|
116 | HBRUSH brush = (HBRUSH) GetSysColorBrush(COLOR_BTNFACE); |
---|
117 | WNDCLASS wc; |
---|
118 | wc.style = CS_HREDRAW | CS_VREDRAW; |
---|
119 | wc.lpfnWndProc = (WNDPROC)WindowProc; |
---|
120 | wc.cbClsExtra = 0; |
---|
121 | wc.cbWndExtra = 0; |
---|
122 | wc.hInstance = ::GetModuleHandle(0); |
---|
123 | wc.hIcon = ::LoadIcon(0, IDI_APPLICATION); |
---|
124 | wc.hCursor = ::LoadCursor(0, IDC_ARROW); |
---|
125 | wc.hbrBackground = brush; |
---|
126 | wc.lpszMenuName = className; |
---|
127 | wc.lpszClassName = className; |
---|
128 | ::RegisterClass(&wc); |
---|
129 | done = TRUE; |
---|
130 | } |
---|
131 | |
---|
132 | width = fVP.GetWindowSizeHintX(); |
---|
133 | height = fVP.GetWindowSizeHintX(); |
---|
134 | |
---|
135 | HMENU menuBar = CreateMenu(); |
---|
136 | |
---|
137 | {HMENU casc = CreatePopupMenu(); |
---|
138 | ::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"File"); |
---|
139 | ::AppendMenu(casc,MF_STRING,ID_FILE_POSTSCRIPT,"PS (gl2ps)"); |
---|
140 | ::AppendMenu(casc,MF_STRING,ID_FILE_PIXMAP_POSTSCRIPT,"PS (pixmap)"); |
---|
141 | ::AppendMenu(casc,MF_STRING,ID_FILE_INVENTOR,"IV"); |
---|
142 | ::AppendMenu(casc,MF_STRING,ID_FILE_ESCAPE,"Escape");} |
---|
143 | |
---|
144 | {HMENU casc = CreatePopupMenu(); |
---|
145 | ::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"Etc"); |
---|
146 | ::AppendMenu(casc,MF_STRING,ID_ETC_ERASE_DETECTOR,"Erase detector"); |
---|
147 | ::AppendMenu(casc,MF_STRING,ID_ETC_ERASE_EVENT,"Erase event"); |
---|
148 | ::AppendMenu(casc,MF_STRING,ID_ETC_SET_SOLID,"Set solid"); |
---|
149 | //::AppendMenu(casc,MF_STRING,ID_ETC_SET_WIRE_FRAME,"Set (G4) wire frame"); |
---|
150 | ::AppendMenu(casc,MF_STRING,ID_ETC_SET_REDUCED_WIRE_FRAME, |
---|
151 | "Set (G4) reduced wire frame"); |
---|
152 | ::AppendMenu(casc,MF_STRING,ID_ETC_SET_FULL_WIRE_FRAME, |
---|
153 | "Set (G4) full wire frame"); |
---|
154 | ::AppendMenu(casc,MF_STRING,ID_ETC_SET_PREVIEW, |
---|
155 | "Visible mothers + invisible daughters"); |
---|
156 | ::AppendMenu(casc,MF_STRING,ID_ETC_SET_PREVIEW_AND_FULL, |
---|
157 | "Visible mothers + visible daughters"); |
---|
158 | ::AppendMenu(casc,MF_STRING,ID_ETC_UPDATE_SCENE,"Update scene"); |
---|
159 | ::AppendMenu(casc,MF_STRING,ID_ETC_STATS,"Scene graph stats");} |
---|
160 | |
---|
161 | {HMENU casc = CreatePopupMenu(); |
---|
162 | ::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"Help"); |
---|
163 | ::AppendMenu(casc,MF_STRING,ID_HELP_CONTROLS,"Controls");} |
---|
164 | |
---|
165 | fShell = ::CreateWindow(className, shellName.c_str(), |
---|
166 | WS_OVERLAPPEDWINDOW | |
---|
167 | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, |
---|
168 | CW_USEDEFAULT, CW_USEDEFAULT, |
---|
169 | width,height, |
---|
170 | 0,menuBar,::GetModuleHandle(0),0); |
---|
171 | // Retreive window and client sizez : |
---|
172 | RECT wrect,crect; |
---|
173 | GetWindowRect((HWND)fShell,&wrect); |
---|
174 | GetClientRect((HWND)fShell,&crect); |
---|
175 | int ww = wrect.right-wrect.left; |
---|
176 | int wh = wrect.bottom-wrect.top; |
---|
177 | int cw = crect.right-crect.left; |
---|
178 | int ch = crect.bottom-crect.top; |
---|
179 | // Compell client rect to be width height : |
---|
180 | MoveWindow((HWND)fShell,wrect.left,wrect.top,width+ww-cw,height+wh-ch,TRUE); |
---|
181 | ::SetWindowLong((HWND)fShell,GWL_USERDATA,LONG(this)); |
---|
182 | ::SetWindowText((HWND)fShell,shellName.c_str()); |
---|
183 | parent = fShell; |
---|
184 | fInteractorManager->AddShell(fShell); |
---|
185 | } else { |
---|
186 | char* str = fInteractorManager->GetCreationString(); |
---|
187 | if(str!=0) wName = str; |
---|
188 | } |
---|
189 | fViewer = new Geant4_SoWinExaminerViewer(parent,wName.c_str(),TRUE); |
---|
190 | |
---|
191 | // Have a GL2PS render action : |
---|
192 | const SbViewportRegion& vpRegion = fViewer->getViewportRegion(); |
---|
193 | fGL2PSAction = new SoGL2PSAction(vpRegion); |
---|
194 | fViewer->setGLRenderAction(fGL2PSAction); |
---|
195 | |
---|
196 | fViewer->setSize(SbVec2s(width,height)); |
---|
197 | fViewer->setSceneGraph(fSoSelection); |
---|
198 | fViewer->viewAll(); |
---|
199 | fViewer->saveHomePosition(); |
---|
200 | fViewer->setTitle(fName); |
---|
201 | fViewer->show(); |
---|
202 | if(fShell) { |
---|
203 | SoWin::show(fShell); |
---|
204 | fInteractorManager->FlushAndWaitExecution (); |
---|
205 | } |
---|
206 | fInteractorManager->SetCreatedInteractor (fViewer -> getWidget()); |
---|
207 | } |
---|
208 | |
---|
209 | G4OpenInventorWinViewer::~G4OpenInventorWinViewer () { |
---|
210 | if(fShell) fInteractorManager->RemoveShell(fShell); |
---|
211 | if(fViewer) { |
---|
212 | fViewer->setSceneGraph(0); |
---|
213 | delete fViewer; |
---|
214 | } |
---|
215 | if(fShell) { |
---|
216 | ::SetWindowLong((HWND)fShell,GWL_USERDATA,LONG(0)); |
---|
217 | ::DestroyWindow((HWND)fShell); |
---|
218 | } |
---|
219 | } |
---|
220 | |
---|
221 | void G4OpenInventorWinViewer::FinishView () { |
---|
222 | if(!fViewer) return; |
---|
223 | fViewer->viewAll(); |
---|
224 | fViewer->saveHomePosition(); |
---|
225 | } |
---|
226 | |
---|
227 | void G4OpenInventorWinViewer::SetView () { |
---|
228 | G4OpenInventorViewer::SetView (); |
---|
229 | if(!fViewer) return; |
---|
230 | // Background. |
---|
231 | G4Colour b = fVP.GetBackgroundColour (); |
---|
232 | fViewer->setBackgroundColor |
---|
233 | (SbColor((float)b.GetRed(),(float)b.GetGreen(),(float)b.GetBlue())); |
---|
234 | } |
---|
235 | void G4OpenInventorWinViewer::ViewerRender () { |
---|
236 | if(!fViewer) return; |
---|
237 | fViewer->render(); |
---|
238 | } |
---|
239 | |
---|
240 | SoCamera* G4OpenInventorWinViewer::GetCamera () { |
---|
241 | if(!fViewer) return 0; |
---|
242 | return fViewer->getCamera(); |
---|
243 | } |
---|
244 | |
---|
245 | |
---|
246 | ////////////////////////////////////////////////////////////////////////////// |
---|
247 | LRESULT CALLBACK G4OpenInventorWinViewer::WindowProc ( |
---|
248 | HWND aWindow |
---|
249 | ,UINT aMessage |
---|
250 | ,WPARAM aWParam |
---|
251 | ,LPARAM aLParam |
---|
252 | ) |
---|
253 | ////////////////////////////////////////////////////////////////////////////// |
---|
254 | // Below treatment of WM_SIZE, WM_SETFOCUS not necessary |
---|
255 | // with TGS, but needed with SoFree. WM_DESTROY needed for |
---|
256 | // 'main top level window' so that 'Close window' induces |
---|
257 | // the end of the task. |
---|
258 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// |
---|
259 | { |
---|
260 | switch (aMessage) { |
---|
261 | case WM_SIZE:{ // Assume one child window ! |
---|
262 | int width = LOWORD(aLParam); |
---|
263 | int height = HIWORD(aLParam); |
---|
264 | //printf("debug : G4SoWindow : WMS_SIZE : %d %d\n",width,height); |
---|
265 | G4OpenInventorWinViewer* This = |
---|
266 | (G4OpenInventorWinViewer*)::GetWindowLong(aWindow,GWL_USERDATA); |
---|
267 | if(This && This->fViewer) { |
---|
268 | This->fViewer->sizeChanged(SbVec2s(width,height)); |
---|
269 | } |
---|
270 | }return 0; |
---|
271 | case WM_SETFOCUS:{ // Assume one child window ! |
---|
272 | HWND hwnd = ::GetFirstChild(aWindow); |
---|
273 | if(hwnd!=0) ::SetFocus(hwnd); |
---|
274 | }return 0; |
---|
275 | case WM_DESTROY:{ |
---|
276 | //G4OpenInventorWinViewer* This = |
---|
277 | // (G4OpenInventorWinViewer*)::GetWindowLong(aWindow,GWL_USERDATA); |
---|
278 | //::PostQuitMessage(0); |
---|
279 | }return 0; |
---|
280 | case WM_COMMAND:{ |
---|
281 | G4OpenInventorWinViewer* This = |
---|
282 | (G4OpenInventorWinViewer*)::GetWindowLong(aWindow,GWL_USERDATA); |
---|
283 | if(This) { |
---|
284 | if(aLParam==0) { //From menu. |
---|
285 | // File : |
---|
286 | if(aWParam==ID_FILE_POSTSCRIPT) { |
---|
287 | This->WritePostScript(); |
---|
288 | } else if(aWParam==ID_FILE_PIXMAP_POSTSCRIPT) { |
---|
289 | This->WritePixmapPostScript(); |
---|
290 | } else if(aWParam==ID_FILE_INVENTOR) { |
---|
291 | This->WriteInventor(); |
---|
292 | } else if(aWParam==ID_FILE_ESCAPE) { |
---|
293 | This->Escape(); |
---|
294 | // Etc : |
---|
295 | } else if(aWParam==ID_ETC_ERASE_DETECTOR) { |
---|
296 | This->EraseDetector(); |
---|
297 | } else if(aWParam==ID_ETC_ERASE_EVENT) { |
---|
298 | This->EraseEvent(); |
---|
299 | } else if(aWParam==ID_ETC_SET_SOLID) { |
---|
300 | This->SetSolid(); |
---|
301 | } else if(aWParam==ID_ETC_SET_WIRE_FRAME) { |
---|
302 | This->SetWireFrame(); |
---|
303 | } else if(aWParam==ID_ETC_SET_REDUCED_WIRE_FRAME) { |
---|
304 | This->SetReducedWireFrame(true); |
---|
305 | } else if(aWParam==ID_ETC_SET_FULL_WIRE_FRAME) { |
---|
306 | This->SetReducedWireFrame(false); |
---|
307 | } else if(aWParam==ID_ETC_SET_PREVIEW) { |
---|
308 | This->SetPreview(); |
---|
309 | } else if(aWParam==ID_ETC_SET_PREVIEW_AND_FULL) { |
---|
310 | This->SetPreviewAndFull(); |
---|
311 | } else if(aWParam==ID_ETC_UPDATE_SCENE) { |
---|
312 | This->UpdateScene(); |
---|
313 | } else if(aWParam==ID_ETC_STATS) { |
---|
314 | This->SceneGraphStatistics(); |
---|
315 | // Help : |
---|
316 | } else if(aWParam==ID_HELP_CONTROLS) { |
---|
317 | G4cout << This->Help() << G4endl; |
---|
318 | } |
---|
319 | } |
---|
320 | } |
---|
321 | }return 0; |
---|
322 | default: |
---|
323 | return (::DefWindowProc(aWindow,aMessage,aWParam,aLParam)); |
---|
324 | } |
---|
325 | } |
---|
326 | |
---|
327 | #endif |
---|