0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / ViewerTest / ViewerTest_EventManager.cxx
CommitLineData
b311480e 1// Created on: 1998-08-27
2// Created by: Robert COUBLANC
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
780ee4e2 17#include <ViewerTest_EventManager.hxx>
42cf5bc1 18
2108d9a2 19#include <AIS_AnimationCamera.hxx>
7fd59977 20#include <AIS_InteractiveContext.hxx>
49582f9d 21#include <AIS_Shape.hxx>
679ecdee 22#include <Aspect_Grid.hxx>
49582f9d 23#include <Draw.hxx>
08b7a39f 24#include <ViewerTest_ContinuousRedrawer.hxx>
49582f9d 25#include <ViewerTest_V3dView.hxx>
26
27Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 28
25e59720 29IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_EventManager,Standard_Transient)
92efcf78 30
2108d9a2 31//=======================================================================
32//function : GlobalViewAnimation
33//purpose :
34//=======================================================================
35const Handle(AIS_AnimationCamera)& ViewerTest_EventManager::GlobalViewAnimation()
36{
37 static Handle(AIS_AnimationCamera) THE_CAMERA_ANIM = new AIS_AnimationCamera ("ViewerTest_EventManager_ViewAnimation", Handle(V3d_View)());
d6fbb2ab 38 THE_CAMERA_ANIM->SetOwnDuration (0.5);
2108d9a2 39 return THE_CAMERA_ANIM;
40}
41
7fd59977 42//=======================================================================
43//function : ViewerTest_EventManager
679ecdee 44//purpose :
7fd59977 45//=======================================================================
679ecdee 46ViewerTest_EventManager::ViewerTest_EventManager (const Handle(V3d_View)& theView,
47 const Handle(AIS_InteractiveContext)& theCtx)
48: myCtx (theCtx),
49 myView (theView),
08b7a39f 50 myToPickPnt (Standard_False),
51 myIsTmpContRedraw (Standard_False)
2108d9a2 52{
53 myViewAnimation = GlobalViewAnimation();
d22962e4 54
55 addActionHotKeys (Aspect_VKey_NavForward, Aspect_VKey_W, Aspect_VKey_W | Aspect_VKeyFlags_SHIFT);
56 addActionHotKeys (Aspect_VKey_NavBackward , Aspect_VKey_S, Aspect_VKey_S | Aspect_VKeyFlags_SHIFT);
57 addActionHotKeys (Aspect_VKey_NavSlideLeft, Aspect_VKey_A, Aspect_VKey_A | Aspect_VKeyFlags_SHIFT);
58 addActionHotKeys (Aspect_VKey_NavSlideRight, Aspect_VKey_D, Aspect_VKey_D | Aspect_VKeyFlags_SHIFT);
59 addActionHotKeys (Aspect_VKey_NavRollCCW, Aspect_VKey_Q, Aspect_VKey_Q | Aspect_VKeyFlags_SHIFT);
60 addActionHotKeys (Aspect_VKey_NavRollCW, Aspect_VKey_E, Aspect_VKey_E | Aspect_VKeyFlags_SHIFT);
61
62 addActionHotKeys (Aspect_VKey_NavSpeedIncrease, Aspect_VKey_Plus, Aspect_VKey_Plus | Aspect_VKeyFlags_SHIFT,
63 Aspect_VKey_Equal,
64 Aspect_VKey_NumpadAdd, Aspect_VKey_NumpadAdd | Aspect_VKeyFlags_SHIFT);
65 addActionHotKeys (Aspect_VKey_NavSpeedDecrease, Aspect_VKey_Minus, Aspect_VKey_Minus | Aspect_VKeyFlags_SHIFT,
66 Aspect_VKey_NumpadSubtract, Aspect_VKey_NumpadSubtract | Aspect_VKeyFlags_SHIFT);
67
68 addActionHotKeys (Aspect_VKey_NavLookUp, Aspect_VKey_Up);
69 addActionHotKeys (Aspect_VKey_NavLookDown, Aspect_VKey_Down);
70 addActionHotKeys (Aspect_VKey_NavLookLeft, Aspect_VKey_Left);
71 addActionHotKeys (Aspect_VKey_NavLookRight, Aspect_VKey_Right);
72 addActionHotKeys (Aspect_VKey_NavSlideLeft, Aspect_VKey_Left | Aspect_VKeyFlags_SHIFT);
73 addActionHotKeys (Aspect_VKey_NavSlideRight, Aspect_VKey_Right | Aspect_VKeyFlags_SHIFT);
74 addActionHotKeys (Aspect_VKey_NavSlideUp, Aspect_VKey_Up | Aspect_VKeyFlags_SHIFT);
75 addActionHotKeys (Aspect_VKey_NavSlideDown, Aspect_VKey_Down | Aspect_VKeyFlags_SHIFT);
2108d9a2 76}
77
78//=======================================================================
79//function : ~ViewerTest_EventManager
80//purpose :
81//=======================================================================
82ViewerTest_EventManager::~ViewerTest_EventManager()
83{
84 if (!myViewAnimation.IsNull()
85 && myViewAnimation->View() == myView)
86 {
87 myViewAnimation->Stop();
88 myViewAnimation->SetView (Handle(V3d_View)());
89 }
90}
7fd59977 91
92//=======================================================================
49582f9d 93//function : UpdateMouseButtons
679ecdee 94//purpose :
7fd59977 95//=======================================================================
49582f9d 96bool ViewerTest_EventManager::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
97 Aspect_VKeyMouse theButtons,
98 Aspect_VKeyFlags theModifiers,
99 bool theIsEmulated)
7fd59977 100{
49582f9d 101 SetAllowRotation (!ViewerTest_V3dView::IsCurrentViewIn2DMode());
102
103 if (theButtons == Aspect_VKeyMouse_LeftButton)
679ecdee 104 {
49582f9d 105 if (myToPickPnt && (theModifiers & Aspect_VKeyFlags_CTRL) != 0)
679ecdee 106 {
49582f9d 107 Graphic3d_Vec3d anXYZ;
108 myView->Convert (thePoint.x(), thePoint.y(), anXYZ.x(), anXYZ.y(), anXYZ.z());
109 Draw::Set (myPickPntArgVec[0].ToCString(), anXYZ.x());
110 Draw::Set (myPickPntArgVec[1].ToCString(), anXYZ.y());
111 Draw::Set (myPickPntArgVec[2].ToCString(), anXYZ.z());
112 myToPickPnt = false;
679ecdee 113 }
114 }
115
49582f9d 116 return AIS_ViewController::UpdateMouseButtons (thePoint, theButtons, theModifiers, theIsEmulated);
7fd59977 117}
118
49582f9d 119//==============================================================================
120//function : ProcessExpose
679ecdee 121//purpose :
49582f9d 122//==============================================================================
123void ViewerTest_EventManager::ProcessExpose()
7fd59977 124{
49582f9d 125 if (!myView.IsNull())
780ee4e2 126 {
49582f9d 127 myView->Invalidate();
128 FlushViewEvents (myCtx, myView, true);
679ecdee 129 }
7fd59977 130}
131
08b7a39f 132//==============================================================================
133//function : handleViewRedraw
134//purpose :
135//==============================================================================
136void ViewerTest_EventManager::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
137 const Handle(V3d_View)& theView)
138{
139 AIS_ViewController::handleViewRedraw (theCtx, theView);
140
141 // On non-Windows platforms Aspect_Window::InvalidateContent() from rendering thread does not work as expected
142 // as in Tcl event loop the new message might go to sleep with new event remaining in queue.
143 // As a workaround - use dedicated background thread to ping Tcl event loop.
144 if (myToAskNextFrame)
145 {
146 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
147 if (!myIsTmpContRedraw
148 && (!aRedrawer.IsStarted() || aRedrawer.IsPaused()))
149 {
150 myIsTmpContRedraw = true;
151 #ifndef _WIN32
152 aRedrawer.Start (theView->Window(), 60.0);
153 #endif
154 }
155 }
156 else if (myIsTmpContRedraw)
157 {
158 myIsTmpContRedraw = false;
159 #ifndef _WIN32
160 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
161 aRedrawer.Pause();
162 #endif
163 }
164}
165
49582f9d 166//==============================================================================
167//function : ProcessConfigure
679ecdee 168//purpose :
49582f9d 169//==============================================================================
170void ViewerTest_EventManager::ProcessConfigure()
679ecdee 171{
49582f9d 172 if (!myView.IsNull())
679ecdee 173 {
49582f9d 174 myView->MustBeResized();
175 FlushViewEvents (myCtx, myView, true);
679ecdee 176 }
7fd59977 177}
178
d22962e4 179// =======================================================================
180// function : navigationKeyModifierSwitch
181// purpose :
182// =======================================================================
183bool ViewerTest_EventManager::navigationKeyModifierSwitch (unsigned int theModifOld,
184 unsigned int theModifNew,
185 double theTimeStamp)
186{
187 bool hasActions = false;
188 for (unsigned int aKeyIter = 0; aKeyIter < Aspect_VKey_ModifiersLower; ++aKeyIter)
189 {
190 if (!myKeys.IsKeyDown (aKeyIter))
191 {
192 continue;
193 }
194
195 Aspect_VKey anActionOld = Aspect_VKey_UNKNOWN, anActionNew = Aspect_VKey_UNKNOWN;
196 myNavKeyMap.Find (aKeyIter | theModifOld, anActionOld);
197 myNavKeyMap.Find (aKeyIter | theModifNew, anActionNew);
198 if (anActionOld == anActionNew)
199 {
200 continue;
201 }
202
203 if (anActionOld != Aspect_VKey_UNKNOWN)
204 {
205 myKeys.KeyUp (anActionOld, theTimeStamp);
206 }
207 if (anActionNew != Aspect_VKey_UNKNOWN)
208 {
209 hasActions = true;
210 myKeys.KeyDown (anActionNew, theTimeStamp);
211 }
212 }
213 return hasActions;
214}
215
216//=======================================================================
217//function : KeyDown
218//purpose :
219//=======================================================================
220void ViewerTest_EventManager::KeyDown (Aspect_VKey theKey,
221 double theTime,
222 double thePressure)
223{
224 const unsigned int aModifOld = myKeys.Modifiers();
225 AIS_ViewController::KeyDown (theKey, theTime, thePressure);
226
227 const unsigned int aModifNew = myKeys.Modifiers();
228 if (aModifNew != aModifOld
229 && navigationKeyModifierSwitch (aModifOld, aModifNew, theTime))
230 {
231 // modifier key just pressed
232 }
233
234 Aspect_VKey anAction = Aspect_VKey_UNKNOWN;
235 if (myNavKeyMap.Find (theKey | myKeys.Modifiers(), anAction)
236 && anAction != Aspect_VKey_UNKNOWN)
237 {
238 AIS_ViewController::KeyDown (anAction, theTime, thePressure);
239 }
240}
241
7fd59977 242//=======================================================================
49582f9d 243//function : KeyUp
679ecdee 244//purpose :
7fd59977 245//=======================================================================
49582f9d 246void ViewerTest_EventManager::KeyUp (Aspect_VKey theKey,
247 double theTime)
7fd59977 248{
d22962e4 249 const unsigned int aModifOld = myKeys.Modifiers();
49582f9d 250 AIS_ViewController::KeyUp (theKey, theTime);
d22962e4 251
252 Aspect_VKey anAction = Aspect_VKey_UNKNOWN;
253 if (myNavKeyMap.Find (theKey | myKeys.Modifiers(), anAction)
254 && anAction != Aspect_VKey_UNKNOWN)
255 {
256 AIS_ViewController::KeyUp (anAction, theTime);
257 ProcessKeyPress (anAction);
258 }
259
260 const unsigned int aModifNew = myKeys.Modifiers();
261 if (aModifNew != aModifOld
262 && navigationKeyModifierSwitch (aModifOld, aModifNew, theTime))
263 {
264 // modifier key released
265 }
266
267 ProcessKeyPress (theKey | aModifNew);
7fd59977 268}
269
49582f9d 270//==============================================================================
271//function : ProcessKeyPress
679ecdee 272//purpose :
49582f9d 273//==============================================================================
274void ViewerTest_EventManager::ProcessKeyPress (Aspect_VKey theKey)
7fd59977 275{
49582f9d 276 if (myCtx.IsNull()
277 || myView.IsNull())
679ecdee 278 {
279 return;
280 }
679ecdee 281
49582f9d 282 switch (theKey)
679ecdee 283 {
d22962e4 284 case Aspect_VKey_Backspace: // AXO
49582f9d 285 {
286 if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
287 {
288 myView->SetProj(V3d_XposYnegZpos);
289 }
290 break;
291 }
49582f9d 292 case Aspect_VKey_F:
293 {
294 if (myCtx->NbSelected() > 0)
295 {
296 myCtx->FitSelected (myView);
297 }
298 else
299 {
300 myView->FitAll();
301 }
302 break;
303 }
304 case Aspect_VKey_H: // HLR
305 {
306 std::cout << "HLR\n";
307 myView->SetComputedMode (!myView->ComputedMode());
308 myView->Redraw();
309 break;
310 }
311 case Aspect_VKey_P: // Type of HLR
312 {
313 myCtx->DefaultDrawer()->SetTypeOfHLR (myCtx->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo
314 ? Prs3d_TOH_PolyAlgo
315 : Prs3d_TOH_Algo);
316 if (myCtx->NbSelected() == 0)
317 {
318 AIS_ListOfInteractive aListOfShapes;
319 myCtx->DisplayedObjects (aListOfShapes);
320 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
321 {
322 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (anIter.Value()))
323 {
324 aShape->SetTypeOfHLR (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo
325 ? Prs3d_TOH_Algo
326 : Prs3d_TOH_PolyAlgo);
327 myCtx->Redisplay (aShape, Standard_False);
328 }
329 }
330 }
331 else
332 {
333 for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
334 {
335 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (myCtx->SelectedInteractive()))
336 {
337 aShape->SetTypeOfHLR (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo
338 ? Prs3d_TOH_Algo
339 : Prs3d_TOH_PolyAlgo);
340 myCtx->Redisplay (aShape, Standard_False);
341 }
342 }
343 }
344 myCtx->UpdateCurrentViewer();
345 break;
346 }
d22962e4 347 case Aspect_VKey_S | Aspect_VKeyFlags_CTRL:
348 case Aspect_VKey_W | Aspect_VKeyFlags_CTRL:
49582f9d 349 {
350 Standard_Integer aDispMode = AIS_Shaded;
d22962e4 351 if (theKey == (Aspect_VKey_S | Aspect_VKeyFlags_CTRL))
49582f9d 352 {
353 aDispMode = AIS_Shaded;
354 std::cout << "setup Shaded display mode\n";
355 }
356 else
357 {
358 aDispMode = AIS_WireFrame;
359 std::cout << "setup WireFrame display mode\n";
360 }
4754e164 361
49582f9d 362 if (myCtx->NbSelected() == 0)
363 {
364 myCtx->SetDisplayMode (aDispMode, true);
365 }
366 else
367 {
368 for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
369 {
370 myCtx->SetDisplayMode (myCtx->SelectedInteractive(), aDispMode, false);
371 }
372 myCtx->UpdateCurrentViewer();
373 }
374 break;
375 }
376 case Aspect_VKey_U: // Unset display mode
377 {
378 std::cout << "reset display mode to defaults\n";
379 if (myCtx->NbSelected() == 0)
380 {
381 myCtx->SetDisplayMode (AIS_WireFrame, true);
382 }
383 else
384 {
385 for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
386 {
387 myCtx->UnsetDisplayMode (myCtx->SelectedInteractive(), false);
388 }
389 myCtx->UpdateCurrentViewer();
390 }
391 break;
392 }
393 case Aspect_VKey_T:
394 {
395 if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
396 {
397 myView->SetProj (V3d_TypeOfOrientation_Zup_Top);
398 }
399 break;
400 }
401 case Aspect_VKey_B:
402 {
403 if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
404 {
405 myView->SetProj (V3d_TypeOfOrientation_Zup_Bottom);
406 }
407 break;
408 }
409 case Aspect_VKey_L:
410 {
411 if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
412 {
413 myView->SetProj (V3d_TypeOfOrientation_Zup_Left);
414 }
415 break;
416 }
417 case Aspect_VKey_R:
418 {
419 if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
420 {
421 myView->SetProj (V3d_TypeOfOrientation_Zup_Right);
422 }
423 break;
424 }
425 case Aspect_VKey_Comma:
426 {
427 myCtx->HilightNextDetected (myView);
428 break;
429 }
430 case Aspect_VKey_Period:
431 {
432 myCtx->HilightPreviousDetected (myView);
433 break;
434 }
435 case Aspect_VKey_Slash:
436 case Aspect_VKey_NumpadDivide:
437 {
438 Handle(Graphic3d_Camera) aCamera = myView->Camera();
439 if (aCamera->IsStereo())
440 {
441 aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
442 myView->Redraw();
443 }
444 break;
445 }
446 case Aspect_VKey_NumpadMultiply:
447 {
448 Handle(Graphic3d_Camera) aCamera = myView->Camera();
449 if (aCamera->IsStereo())
450 {
451 aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
452 myView->Redraw();
453 }
454 break;
455 }
456 case Aspect_VKey_Delete:
457 {
458 if (!myCtx.IsNull()
459 && myCtx->NbSelected() > 0)
460 {
461 Draw_Interprete ("verase");
462 }
463 break;
464 }
465 case Aspect_VKey_Escape:
466 {
467 if (!myCtx.IsNull()
468 && ViewerTest_EventManager::ToCloseViewOnEscape())
469 {
470 Draw_Interprete (ViewerTest_EventManager::ToExitOnCloseView() ? "exit" : "vclose");
471 }
d22962e4 472 break;
473 }
474 case Aspect_VKey_NavSpeedDecrease:
475 case Aspect_VKey_NavSpeedIncrease:
476 {
477 // handle slide speed
478 float aNewSpeed = theKey == Aspect_VKey_NavSpeedDecrease
479 ? myWalkSpeedRelative * 0.5f
480 : myWalkSpeedRelative * 2.0f;
481 if (aNewSpeed >= 0.00001f
482 && aNewSpeed <= 10.0f)
483 {
484 if (Abs (aNewSpeed - 0.1f) < 0.001f)
485 {
486 aNewSpeed = 0.1f;
487 }
488 myWalkSpeedRelative = aNewSpeed;
489 }
490 break;
49582f9d 491 }
492 }
4754e164 493
49582f9d 494 if (theKey >= Aspect_VKey_0
495 && theKey <= Aspect_VKey_7)
679ecdee 496 {
49582f9d 497 const Standard_Integer aSelMode = theKey - Aspect_VKey_0;
498 bool toEnable = true;
499 if (!myCtx.IsNull())
500 {
501 AIS_ListOfInteractive aPrsList;
502 myCtx->DisplayedObjects (aPrsList);
503 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next())
504 {
505 TColStd_ListOfInteger aModes;
506 myCtx->ActivatedModes (aPrsIter.Value(), aModes);
507 for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next())
508 {
509 if (aModeIter.Value() == aSelMode)
510 {
511 toEnable = false;
512 }
513 }
514 }
515 }
516 TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0");
517 Draw_Interprete (aCmd.ToCString());
679ecdee 518 }
c398b00e 519}