0031521: Samples - update MFC ImportExport sample to use AIS_ViewController
[occt.git] / samples / mfc / standard / Common / OCC_BaseView.cpp
1 // OCC_BaseView.cpp: implementation of the OCC_BaseView class.
2 //
3 //////////////////////////////////////////////////////////////////////
4
5 #include <stdafx.h>
6 #include "OCC_BaseView.h"
7
8 BEGIN_MESSAGE_MAP(OCC_BaseView, CView)
9   ON_WM_SIZE()
10   ON_WM_MOUSEMOVE()
11   ON_WM_MOUSEWHEEL()
12   ON_WM_MOUSELEAVE()
13   ON_WM_NCMOUSEMOVE()
14   ON_WM_LBUTTONDOWN()
15   ON_WM_LBUTTONUP()
16   ON_WM_MBUTTONDOWN()
17   ON_WM_MBUTTONUP()
18   ON_WM_RBUTTONDOWN()
19   ON_WM_RBUTTONUP()
20 END_MESSAGE_MAP()
21
22 //=======================================================================
23 //function : Constructor
24 //purpose  :
25 //=======================================================================
26 OCC_BaseView::OCC_BaseView()
27 : myUpdateRequests (0),
28   myCurZoom (0.0),
29   myCurrentMode (CurAction3d_Nothing)
30 {
31   myDefaultGestures = myMouseGestureMap;
32 }
33
34 //=======================================================================
35 //function : Destructor
36 //purpose  :
37 //=======================================================================
38 OCC_BaseView::~OCC_BaseView()
39 {
40   //
41 }
42
43 //=======================================================================
44 //function : GetDocument
45 //purpose  :
46 //=======================================================================
47 OCC_BaseDoc* OCC_BaseView::GetDocument() // non-debug version is inline
48 {
49         return (OCC_BaseDoc*)m_pDocument;
50 }
51
52 // =======================================================================
53 // function : PostNcDestroy
54 // purpose  :
55 // =======================================================================
56 void OCC_BaseView::PostNcDestroy()
57 {
58   if (!myView.IsNull())
59   {
60     myView->Remove();
61     myView.Nullify();
62   }
63   CView::PostNcDestroy();
64 }
65
66 // =======================================================================
67 // function : PreCreateWindow
68 // purpose  :
69 // =======================================================================
70 BOOL OCC_BaseView::PreCreateWindow (CREATESTRUCT& cs)
71 {
72   cs.lpszClass = ::AfxRegisterWndClass (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
73   return CView::PreCreateWindow (cs);
74 }
75
76 // =======================================================================
77 // function : OnInitialUpdate
78 // purpose  :
79 // =======================================================================
80 void OCC_BaseView::OnInitialUpdate()
81 {
82   myCurrentMode = CurAction3d_Nothing;
83   CView::OnInitialUpdate();
84   if (!myView.IsNull())
85   {
86     return;
87   }
88
89   myView = GetAISContext()->CurrentViewer()->CreateView();
90   myView->SetImmediateUpdate (false);
91   myView->SetComputedMode (Standard_False);
92
93   Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (myView->Viewer()->Driver());
94   myView->Camera()->SetProjectionType (aDriver->Options().contextStereo
95                                      ? Graphic3d_Camera::Projection_Stereo
96                                      : Graphic3d_Camera::Projection_Orthographic);
97
98   Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
99   myView->SetWindow (aWNTWindow);
100   if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
101
102   myView->Redraw();
103   myView->Invalidate();
104 }
105
106 // ================================================================
107 // Function : GetAISContext
108 // Purpose  :
109 // ================================================================
110 const Handle(AIS_InteractiveContext)& OCC_BaseView::GetAISContext() const
111 {
112   return ((OCC_BaseDoc*)m_pDocument)->GetInteractiveContext();
113 }
114
115 // ================================================================
116 // Function : update3dView
117 // Purpose  :
118 // ================================================================
119 void OCC_BaseView::update3dView()
120 {
121   if (!myView.IsNull())
122   {
123     if (++myUpdateRequests == 1)
124     {
125       Invalidate (FALSE);
126       UpdateWindow();
127     }
128   }
129 }
130
131 // ================================================================
132 // Function : redraw3dView
133 // Purpose  :
134 // ================================================================
135 void OCC_BaseView::redraw3dView()
136 {
137   if (!myView.IsNull())
138   {
139     FlushViewEvents (GetAISContext(), myView, true);
140   }
141 }
142
143 // ================================================================
144 // Function : handleViewRedraw
145 // Purpose  :
146 // ================================================================
147 void OCC_BaseView::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
148                                       const Handle(V3d_View)& theView)
149 {
150   myUpdateRequests = 0;
151   AIS_ViewController::handleViewRedraw (theCtx, theView);
152 }
153
154 // ================================================================
155 // Function : OnSelectionChanged
156 // Purpose  :
157 // ================================================================
158 void OCC_BaseView::OnSelectionChanged (const Handle(AIS_InteractiveContext)& theCtx,
159                                        const Handle(V3d_View)& theView)
160 {
161   AIS_ViewController::OnSelectionChanged (theCtx, theView);
162   GetDocument()->OnSelectionChanged (theCtx, theView);
163 }
164
165 // =======================================================================
166 // function : OnDraw
167 // purpose  :
168 // =======================================================================
169 void OCC_BaseView::OnDraw (CDC* )
170 {
171   // always redraw immediate layer (dynamic highlighting) on Paint event,
172   // and redraw entire view content only when it is explicitly invalidated (V3d_View::Invalidate())
173   myView->InvalidateImmediate();
174   FlushViewEvents (GetAISContext(), myView, true);
175 }
176
177 // =======================================================================
178 // function : defineMouseGestures
179 // purpose  :
180 // =======================================================================
181 void OCC_BaseView::defineMouseGestures()
182 {
183   myMouseGestureMap.Clear();
184   AIS_MouseGesture aRot = AIS_MouseGesture_RotateOrbit;
185   switch (myCurrentMode)
186   {
187     case CurAction3d_Nothing:
188     {
189       myMouseGestureMap = myDefaultGestures;
190       break;
191     }
192     case CurAction3d_DynamicZooming:
193     {
194       myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_Zoom);
195       break;
196     }
197     case CurAction3d_GlobalPanning:
198     {
199       break;
200     }
201     case CurAction3d_WindowZooming:
202     {
203       myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_ZoomWindow);
204       break;
205     }
206     case CurAction3d_DynamicPanning:
207     {
208       myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_Pan);
209       break;
210     }
211     case CurAction3d_DynamicRotation:
212     {
213       myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, aRot);
214       break;
215     }
216   }
217 }
218
219 // =======================================================================
220 // function : OnMouseMove
221 // purpose  :
222 // =======================================================================
223 void OCC_BaseView::OnMouseMove (UINT theFlags, CPoint thePoint)
224 {
225   TRACKMOUSEEVENT aMouseEvent;          // for WM_MOUSELEAVE
226   aMouseEvent.cbSize = sizeof(aMouseEvent);
227   aMouseEvent.dwFlags = TME_LEAVE;
228   aMouseEvent.hwndTrack = m_hWnd;
229   aMouseEvent.dwHoverTime = HOVER_DEFAULT;
230   if (!::_TrackMouseEvent (&aMouseEvent)) { TRACE("Track ERROR!\n"); }
231
232   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
233   if (UpdateMousePosition (Graphic3d_Vec2i (thePoint.x, thePoint.y), PressedMouseButtons(), aFlags, false))
234   {
235     update3dView();
236   }
237 }
238
239 // =======================================================================
240 // function : OnLButtonDown
241 // purpose  :
242 // =======================================================================
243 void OCC_BaseView::OnLButtonDown (UINT theFlags, CPoint thePoint)
244 {
245   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
246   PressMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_LeftButton, aFlags, false);
247   update3dView();
248 }
249
250 // =======================================================================
251 // function : OnLButtonUp
252 // purpose  :
253 // =======================================================================
254 void OCC_BaseView::OnLButtonUp (UINT theFlags, CPoint thePoint)
255 {
256   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
257   ReleaseMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_LeftButton, aFlags, false);
258   if (myCurrentMode == CurAction3d_GlobalPanning)
259   {
260     myView->Place (thePoint.x, thePoint.y, myCurZoom);
261     myView->Invalidate();
262   }
263   if (myCurrentMode != CurAction3d_Nothing)
264   {
265     setCurrentAction (CurAction3d_Nothing);
266   }
267   update3dView();
268 }
269
270 // =======================================================================
271 // function : OnMButtonDown
272 // purpose  :
273 // =======================================================================
274 void OCC_BaseView::OnMButtonDown (UINT theFlags, CPoint thePoint)
275 {
276   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
277   PressMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_MiddleButton, aFlags, false);
278   update3dView();
279 }
280
281 // =======================================================================
282 // function : OnMButtonUp
283 // purpose  :
284 // =======================================================================
285 void OCC_BaseView::OnMButtonUp (UINT theFlags, CPoint thePoint)
286 {
287   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
288   ReleaseMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_MiddleButton, aFlags, false);
289   update3dView();
290   if (myCurrentMode != CurAction3d_Nothing)
291   {
292     setCurrentAction (CurAction3d_Nothing);
293   }
294 }
295
296 // =======================================================================
297 // function : OnRButtonDown
298 // purpose  :
299 // =======================================================================
300 void OCC_BaseView::OnRButtonDown (UINT theFlags, CPoint thePoint)
301 {
302   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
303   PressMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_RightButton, aFlags, false);
304   update3dView();
305   myClickPos.SetValues (thePoint.x, thePoint.y);
306 }
307
308 // =======================================================================
309 // function : OnRButtonUp
310 // purpose  :
311 // =======================================================================
312 void OCC_BaseView::OnRButtonUp (UINT theFlags, CPoint thePoint)
313 {
314   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
315   ReleaseMouseButton (Graphic3d_Vec2i (thePoint.x, thePoint.y), Aspect_VKeyMouse_RightButton, aFlags, false);
316   update3dView();
317   if (myCurrentMode != CurAction3d_Nothing)
318   {
319     setCurrentAction (CurAction3d_Nothing);
320   }
321   if (aFlags == Aspect_VKeyFlags_NONE
322    && (myClickPos - Graphic3d_Vec2i (thePoint.x, thePoint.y)).cwiseAbs().maxComp() <= 4)
323   {
324     GetDocument()->Popup (thePoint.x, thePoint.y, myView);
325   }
326 }
327
328 // =======================================================================
329 // function : OnMouseWheel
330 // purpose  :
331 // =======================================================================
332 BOOL OCC_BaseView::OnMouseWheel (UINT theFlags, short theDelta, CPoint thePoint)
333 {
334   const Standard_Real aDeltaF = Standard_Real(theDelta) / Standard_Real(WHEEL_DELTA);
335   CPoint aCursorPnt = thePoint;
336   ScreenToClient (&aCursorPnt);
337   const Graphic3d_Vec2i  aPos (aCursorPnt.x, aCursorPnt.y);
338   const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theFlags);
339   if (UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags)))
340   {
341     update3dView();
342   }
343   return true;
344 }
345
346 // =======================================================================
347 // function : OnSize
348 // purpose  :
349 // =======================================================================
350 void OCC_BaseView::OnSize (UINT nType, int cx, int cy)
351 {
352   CView::OnSize (nType, cx, cy);
353   if (cx != 0
354    && cy != 0
355    && !myView.IsNull())
356   {
357     myView->Window()->DoResize();
358     myView->MustBeResized();
359     myView->Invalidate();
360     update3dView();
361   }
362 }
363
364 // =======================================================================
365 // function : OnMouseLeave
366 // purpose  :
367 // =======================================================================
368 void OCC_BaseView::OnMouseLeave()
369 {
370   CPoint aCursorPos;
371   if (GetCursorPos (&aCursorPos))
372   {
373     ReleaseMouseButton (Graphic3d_Vec2i (aCursorPos.x, aCursorPos.y),
374                         PressedMouseButtons(),
375                         Aspect_VKeyMouse_NONE,
376                         false);
377   }
378 }