0031521: Samples - update MFC ImportExport sample to use AIS_ViewController
[occt.git] / samples / mfc / standard / Common / OCC_BaseView.cpp
index 1f5853a..a8531b7 100755 (executable)
@@ -5,24 +5,30 @@
 #include <stdafx.h>
 #include "OCC_BaseView.h"
 
+BEGIN_MESSAGE_MAP(OCC_BaseView, CView)
+  ON_WM_SIZE()
+  ON_WM_MOUSEMOVE()
+  ON_WM_MOUSEWHEEL()
+  ON_WM_MOUSELEAVE()
+  ON_WM_NCMOUSEMOVE()
+  ON_WM_LBUTTONDOWN()
+  ON_WM_LBUTTONUP()
+  ON_WM_MBUTTONDOWN()
+  ON_WM_MBUTTONUP()
+  ON_WM_RBUTTONDOWN()
+  ON_WM_RBUTTONUP()
+END_MESSAGE_MAP()
+
 //=======================================================================
 //function : Constructor
 //purpose  :
 //=======================================================================
 OCC_BaseView::OCC_BaseView()
-  : myXmin (0),
-    myYmin (0),
-    myXmax (0),
-    myYmax (0),
-    myCurZoom (0.0),
-    myRect (new AIS_RubberBand (Quantity_Color(Quantity_NOC_WHITE), Aspect_TOL_SOLID, 1.0) )
-{
-  myRect->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
-  if (myRect->ZLayer() != Graphic3d_ZLayerId_TopOSD)
-  {
-    myRect->SetZLayer (Graphic3d_ZLayerId_TopOSD);
-  }
-  
+: myUpdateRequests (0),
+  myCurZoom (0.0),
+  myCurrentMode (CurAction3d_Nothing)
+{
+  myDefaultGestures = myMouseGestureMap;
 }
 
 //=======================================================================
@@ -31,7 +37,7 @@ OCC_BaseView::OCC_BaseView()
 //=======================================================================
 OCC_BaseView::~OCC_BaseView()
 {
-
+  //
 }
 
 //=======================================================================
@@ -43,37 +49,330 @@ OCC_BaseDoc* OCC_BaseView::GetDocument() // non-debug version is inline
        return (OCC_BaseDoc*)m_pDocument;
 }
 
-//=======================================================================
-//function : drawRectangle
-//purpose  :
-//=======================================================================
-void OCC_BaseView::drawRectangle (const Standard_Integer theMinX,
-                                  const Standard_Integer theMinY,
-                                  const Standard_Integer theMaxX,
-                                  const Standard_Integer theMaxY,
-                                  const Handle(AIS_InteractiveContext)& theContext,
-                                  const Standard_Boolean toDraw)
-{
-  if (toDraw)
+// =======================================================================
+// function : PostNcDestroy
+// purpose  :
+// =======================================================================
+void OCC_BaseView::PostNcDestroy()
+{
+  if (!myView.IsNull())
+  {
+    myView->Remove();
+    myView.Nullify();
+  }
+  CView::PostNcDestroy();
+}
+
+// =======================================================================
+// function : PreCreateWindow
+// purpose  :
+// =======================================================================
+BOOL OCC_BaseView::PreCreateWindow (CREATESTRUCT& cs)
+{
+  cs.lpszClass = ::AfxRegisterWndClass (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
+  return CView::PreCreateWindow (cs);
+}
+
+// =======================================================================
+// function : OnInitialUpdate
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnInitialUpdate()
+{
+  myCurrentMode = CurAction3d_Nothing;
+  CView::OnInitialUpdate();
+  if (!myView.IsNull())
   {
-    CRect aRect;
-    GetWindowRect(aRect);
-    myRect->SetRectangle (theMinX, aRect.Height() - theMinY, theMaxX, aRect.Height() - theMaxY);
+    return;
+  }
+
+  myView = GetAISContext()->CurrentViewer()->CreateView();
+  myView->SetImmediateUpdate (false);
+  myView->SetComputedMode (Standard_False);
+
+  Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (myView->Viewer()->Driver());
+  myView->Camera()->SetProjectionType (aDriver->Options().contextStereo
+                                     ? Graphic3d_Camera::Projection_Stereo
+                                     : Graphic3d_Camera::Projection_Orthographic);
+
+  Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
+  myView->SetWindow (aWNTWindow);
+  if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
+
+  myView->Redraw();
+  myView->Invalidate();
+}
+
+// ================================================================
+// Function : GetAISContext
+// Purpose  :
+// ================================================================
+const Handle(AIS_InteractiveContext)& OCC_BaseView::GetAISContext() const
+{
+  return ((OCC_BaseDoc*)m_pDocument)->GetInteractiveContext();
+}
 
-    if (!theContext->IsDisplayed (myRect))
+// ================================================================
+// Function : update3dView
+// Purpose  :
+// ================================================================
+void OCC_BaseView::update3dView()
+{
+  if (!myView.IsNull())
+  {
+    if (++myUpdateRequests == 1)
+    {
+      Invalidate (FALSE);
+      UpdateWindow();
+    }
+  }
+}
+
+// ================================================================
+// Function : redraw3dView
+// Purpose  :
+// ================================================================
+void OCC_BaseView::redraw3dView()
+{
+  if (!myView.IsNull())
+  {
+    FlushViewEvents (GetAISContext(), myView, true);
+  }
+}
+
+// ================================================================
+// Function : handleViewRedraw
+// Purpose  :
+// ================================================================
+void OCC_BaseView::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
+                                      const Handle(V3d_View)& theView)
+{
+  myUpdateRequests = 0;
+  AIS_ViewController::handleViewRedraw (theCtx, theView);
+}
+
+// ================================================================
+// Function : OnSelectionChanged
+// Purpose  :
+// ================================================================
+void OCC_BaseView::OnSelectionChanged (const Handle(AIS_InteractiveContext)& theCtx,
+                                       const Handle(V3d_View)& theView)
+{
+  AIS_ViewController::OnSelectionChanged (theCtx, theView);
+  GetDocument()->OnSelectionChanged (theCtx, theView);
+}
+
+// =======================================================================
+// function : OnDraw
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnDraw (CDC* )
+{
+  // always redraw immediate layer (dynamic highlighting) on Paint event,
+  // and redraw entire view content only when it is explicitly invalidated (V3d_View::Invalidate())
+  myView->InvalidateImmediate();
+  FlushViewEvents (GetAISContext(), myView, true);
+}
+
+// =======================================================================
+// function : defineMouseGestures
+// purpose  :
+// =======================================================================
+void OCC_BaseView::defineMouseGestures()
+{
+  myMouseGestureMap.Clear();
+  AIS_MouseGesture aRot = AIS_MouseGesture_RotateOrbit;
+  switch (myCurrentMode)
+  {
+    case CurAction3d_Nothing:
+    {
+      myMouseGestureMap = myDefaultGestures;
+      break;
+    }
+    case CurAction3d_DynamicZooming:
     {
-      theContext->Display (myRect, Standard_False);
+      myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_Zoom);
+      break;
     }
-    else
+    case CurAction3d_GlobalPanning:
     {
-      theContext->Redisplay (myRect, Standard_False);
+      break;
     }
+    case CurAction3d_WindowZooming:
+    {
+      myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_ZoomWindow);
+      break;
+    }
+    case CurAction3d_DynamicPanning:
+    {
+      myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_Pan);
+      break;
+    }
+    case CurAction3d_DynamicRotation:
+    {
+      myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, aRot);
+      break;
+    }
+  }
+}
+
+// =======================================================================
+// function : OnMouseMove
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnMouseMove (UINT theFlags, CPoint thePoint)
+{
+  TRACKMOUSEEVENT aMouseEvent;          // for WM_MOUSELEAVE
+  aMouseEvent.cbSize = sizeof(aMouseEvent);
+  aMouseEvent.dwFlags = TME_LEAVE;
+  aMouseEvent.hwndTrack = m_hWnd;
+  aMouseEvent.dwHoverTime = HOVER_DEFAULT;
+  if (!::_TrackMouseEvent (&aMouseEvent)) { TRACE("Track ERROR!\n"); }
+
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  if (UpdateMousePosition (Graphic3d_Vec2i (thePoint.x, thePoint.y), PressedMouseButtons(), aFlags, false))
+  {
+    update3dView();
+  }
+}
+
+// =======================================================================
+// function : OnLButtonDown
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnLButtonDown (UINT theFlags, CPoint thePoint)
+{
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  PressMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_LeftButton, aFlags, false);
+  update3dView();
+}
+
+// =======================================================================
+// function : OnLButtonUp
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnLButtonUp (UINT theFlags, CPoint thePoint)
+{
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  ReleaseMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_LeftButton, aFlags, false);
+  if (myCurrentMode == CurAction3d_GlobalPanning)
+  {
+    myView->Place (thePoint.x, thePoint.y, myCurZoom);
+    myView->Invalidate();
   }
-  else
+  if (myCurrentMode != CurAction3d_Nothing)
   {
-    theContext->Remove (myRect, Standard_False);
+    setCurrentAction (CurAction3d_Nothing);
   }
+  update3dView();
+}
 
-  theContext->CurrentViewer()->RedrawImmediate();
+// =======================================================================
+// function : OnMButtonDown
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnMButtonDown (UINT theFlags, CPoint thePoint)
+{
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  PressMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_MiddleButton, aFlags, false);
+  update3dView();
 }
 
+// =======================================================================
+// function : OnMButtonUp
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnMButtonUp (UINT theFlags, CPoint thePoint)
+{
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  ReleaseMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_MiddleButton, aFlags, false);
+  update3dView();
+  if (myCurrentMode != CurAction3d_Nothing)
+  {
+    setCurrentAction (CurAction3d_Nothing);
+  }
+}
+
+// =======================================================================
+// function : OnRButtonDown
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnRButtonDown (UINT theFlags, CPoint thePoint)
+{
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  PressMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_RightButton, aFlags, false);
+  update3dView();
+  myClickPos.SetValues (thePoint.x, thePoint.y);
+}
+
+// =======================================================================
+// function : OnRButtonUp
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnRButtonUp (UINT theFlags, CPoint thePoint)
+{
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  ReleaseMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_RightButton, aFlags, false);
+  update3dView();
+  if (myCurrentMode != CurAction3d_Nothing)
+  {
+    setCurrentAction (CurAction3d_Nothing);
+  }
+  if (aFlags == Aspect_VKeyFlags_NONE
+   && (myClickPos - Graphic3d_Vec2i (thePoint.x, thePoint.y)).cwiseAbs().maxComp() <= 4)
+  {
+    GetDocument()->Popup (thePoint.x, thePoint.y, myView);
+  }
+}
+
+// =======================================================================
+// function : OnMouseWheel
+// purpose  :
+// =======================================================================
+BOOL OCC_BaseView::OnMouseWheel (UINT theFlags, short theDelta, CPoint thePoint)
+{
+  const Standard_Real aDeltaF = Standard_Real(theDelta) / Standard_Real(WHEEL_DELTA);
+  CPoint aCursorPnt = thePoint;
+  ScreenToClient (&aCursorPnt);
+  const Graphic3d_Vec2i  aPos (aCursorPnt.x, aCursorPnt.y);
+  const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
+  if (UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags)))
+  {
+    update3dView();
+  }
+  return true;
+}
+
+// =======================================================================
+// function : OnSize
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnSize (UINT nType, int cx, int cy)
+{
+  CView::OnSize (nType, cx, cy);
+  if (cx != 0
+   && cy != 0
+   && !myView.IsNull())
+  {
+    myView->Window()->DoResize();
+    myView->MustBeResized();
+    myView->Invalidate();
+    update3dView();
+  }
+}
+
+// =======================================================================
+// function : OnMouseLeave
+// purpose  :
+// =======================================================================
+void OCC_BaseView::OnMouseLeave()
+{
+  CPoint aCursorPos;
+  if (GetCursorPos (&aCursorPos))
+  {
+    ReleaseMouseButton (Graphic3d_Vec2i (aCursorPos.x, aCursorPos.y),
+                        PressedMouseButtons(),
+                        Aspect_VKeyMouse_NONE,
+                        false);
+  }
+}