0027736: Samples - rectangle selection issues within MFC sample Viewer3d
[occt.git] / samples / mfc / standard / 10_Convert / src / WNT / OCCDemoView.cpp
1 // OCCDemoView.cpp : implementation of the COCCDemoView class
2 //
3
4 #include "stdafx.h"
5 #include "MainFrm.h"
6 #include "OCCDemo.h"
7 #include "OCCDemoDoc.h"
8 #include "OCCDemoView.h"
9
10 #include <AIS_RubberBand.hxx>
11 #include <Graphic3d_GraphicDriver.hxx>
12
13 #define ValZWMin 1
14
15 #ifdef _DEBUG
16 #undef THIS_FILE
17 static char THIS_FILE[] = __FILE__;
18 #endif
19
20 /////////////////////////////////////////////////////////////////////////////
21 // COCCDemoView
22
23 IMPLEMENT_DYNCREATE(COCCDemoView, CView)
24
25 BEGIN_MESSAGE_MAP(COCCDemoView, CView)
26         //{{AFX_MSG_MAP(COCCDemoView)
27         ON_COMMAND(ID_BUTTONAxo, OnBUTTONAxo)
28         ON_COMMAND(ID_BUTTONBack, OnBUTTONBack)
29         ON_COMMAND(ID_BUTTONBottom, OnBUTTONBottom)
30         ON_COMMAND(ID_BUTTONFront, OnBUTTONFront)
31         ON_COMMAND(ID_BUTTONHlrOn, OnBUTTONHlrOn)
32         ON_COMMAND(ID_BUTTONLeft, OnBUTTONLeft)
33         ON_COMMAND(ID_BUTTONPan, OnBUTTONPan)
34         ON_COMMAND(ID_BUTTONPanGlo, OnBUTTONPanGlo)
35         ON_COMMAND(ID_BUTTONReset, OnBUTTONReset)
36         ON_COMMAND(ID_BUTTONRight, OnBUTTONRight)
37         ON_COMMAND(ID_BUTTONRot, OnBUTTONRot)
38         ON_COMMAND(ID_BUTTONTop, OnBUTTONTop)
39         ON_COMMAND(ID_BUTTONZoomAll, OnBUTTONZoomAll)
40         ON_WM_SIZE()
41         ON_COMMAND(ID_BUTTONZoomProg, OnBUTTONZoomProg)
42         ON_COMMAND(ID_BUTTONZoomWin, OnBUTTONZoomWin)
43         ON_WM_LBUTTONDOWN()
44         ON_WM_LBUTTONUP()
45         ON_WM_MOUSEMOVE()
46         ON_WM_RBUTTONDOWN()
47         ON_WM_RBUTTONUP()
48         ON_UPDATE_COMMAND_UI(ID_BUTTONPanGlo, OnUpdateBUTTONPanGlo)
49         ON_UPDATE_COMMAND_UI(ID_BUTTONPan, OnUpdateBUTTONPan)
50         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomProg, OnUpdateBUTTONZoomProg)
51         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomWin, OnUpdateBUTTONZoomWin)
52         ON_UPDATE_COMMAND_UI(ID_BUTTONRot, OnUpdateBUTTONRot)
53         ON_COMMAND(ID_BUTTONWire, OnBUTTONWire)
54         ON_COMMAND(ID_BUTTONShade, OnBUTTONShade)
55         ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOn, OnUpdateBUTTONHlrOn)
56         ON_UPDATE_COMMAND_UI(ID_BUTTONShade, OnUpdateBUTTONShade)
57         ON_UPDATE_COMMAND_UI(ID_BUTTONWire, OnUpdateBUTTONWire)
58         //}}AFX_MSG_MAP
59 END_MESSAGE_MAP()
60
61 /////////////////////////////////////////////////////////////////////////////
62 // COCCDemoView construction/destruction
63
64 COCCDemoView::COCCDemoView()
65 {
66   myXmin=0;
67   myYmin=0;  
68   myXmax=0;
69   myYmax=0;
70   myCurZoom=0;
71   myCurrentMode = CurAction3d_Nothing;
72   myVisMode = VIS_SHADE;
73   myRect = new AIS_RubberBand (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0);
74   myGraphicDriver = ((COCCDemoApp*)AfxGetApp())->GetGraphicDriver();
75 }
76
77 COCCDemoView::~COCCDemoView()
78 {
79         if (!myView.IsNull())
80     myView->Remove();
81 }
82
83 BOOL COCCDemoView::PreCreateWindow(CREATESTRUCT& cs)
84 {
85   // TODO: Modify the Window class or styles here by modifying
86   //  the CREATESTRUCT cs
87   cs.lpszClass = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
88   return CView::PreCreateWindow(cs);
89 }
90
91 /////////////////////////////////////////////////////////////////////////////
92 // COCCDemoView drawing
93
94 void COCCDemoView::OnInitialUpdate() 
95 {
96   CView::OnInitialUpdate();
97   
98   myView = GetDocument()->GetViewer()->CreateView();
99   myView->SetViewMappingDefault();
100   myView->SetViewOrientationDefault();
101
102   Handle(WNT_Window) aWNTWindow = new WNT_Window(GetSafeHwnd ());
103   myView->SetWindow(aWNTWindow);
104   if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
105
106   myCurrentMode = CurAction3d_Nothing;
107   myVisMode = VIS_SHADE;
108   RedrawVisMode();
109 }
110
111 void COCCDemoView::OnDraw(CDC* /*pDC*/)
112 {
113         COCCDemoDoc* pDoc = GetDocument();
114         ASSERT_VALID(pDoc);
115         // TODO: add draw code for native data here
116   myView->Redraw();
117 }
118
119 /////////////////////////////////////////////////////////////////////////////
120 // COCCDemoView diagnostics
121
122 #ifdef _DEBUG
123 void COCCDemoView::AssertValid() const
124 {
125         CView::AssertValid();
126 }
127
128 void COCCDemoView::Dump(CDumpContext& dc) const
129 {
130         CView::Dump(dc);
131 }
132
133 COCCDemoDoc* COCCDemoView::GetDocument() // non-debug version is inline
134 {
135         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COCCDemoDoc)));
136         return (COCCDemoDoc*)m_pDocument;
137 }
138 #endif //_DEBUG
139
140 /////////////////////////////////////////////////////////////////////////////
141 // COCCDemoView message handlers
142
143 void COCCDemoView::OnSize(UINT nType, int cx, int cy)
144 {
145   CView::OnSize (nType, cx, cy);
146   if (!myView.IsNull())
147     myView->MustBeResized();
148 }
149
150 void COCCDemoView::OnBUTTONBack() 
151
152   myView->SetProj(V3d_Ypos);
153 }
154
155 void COCCDemoView::OnBUTTONFront() 
156
157         myView->SetProj(V3d_Yneg);
158 }
159
160 void COCCDemoView::OnBUTTONBottom() 
161
162         myView->SetProj(V3d_Zneg); 
163 }
164
165 void COCCDemoView::OnBUTTONTop() 
166
167         myView->SetProj(V3d_Zpos); 
168 }
169
170 void COCCDemoView::OnBUTTONLeft() 
171
172         myView->SetProj(V3d_Xneg);
173 }
174
175 void COCCDemoView::OnBUTTONRight() 
176
177         myView->SetProj(V3d_Xpos);
178 }
179
180 void COCCDemoView::OnBUTTONAxo() 
181
182         myView->SetProj(V3d_XposYnegZpos); 
183 }
184
185 void COCCDemoView::OnBUTTONPan() 
186 {
187   myCurrentMode = CurAction3d_DynamicPanning;
188 }
189
190 void COCCDemoView::OnBUTTONPanGlo() 
191 {
192   // save the current zoom value 
193   myCurZoom = myView->Scale();
194   // Do a Global Zoom 
195   myView->FitAll();
196   // Set the mode 
197   myCurrentMode = CurAction3d_GlobalPanning;
198 }
199
200 void COCCDemoView::OnBUTTONReset() 
201 {
202   myView->Reset();
203 }
204
205 void COCCDemoView::OnBUTTONRot() 
206 {
207   myCurrentMode = CurAction3d_DynamicRotation;
208 }
209
210 void COCCDemoView::OnBUTTONZoomAll() 
211 {
212   myView->FitAll();
213   myView->ZFitAll();
214 }
215
216 void COCCDemoView::OnBUTTONZoomProg() 
217 {
218   myCurrentMode = CurAction3d_DynamicZooming;
219 }
220
221 void COCCDemoView::OnBUTTONZoomWin() 
222 {
223   myCurrentMode = CurAction3d_WindowZooming;
224 }
225
226 void COCCDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
227 {
228   //  save the current mouse coordinate in min 
229   myXmin=point.x;  myYmin=point.y;
230   myXmax=point.x;  myYmax=point.y;
231   
232   if ( ! (nFlags & MK_CONTROL) ) 
233   {
234     if (myCurrentMode == CurAction3d_DynamicRotation)
235     {
236       myView->SetComputedMode(Standard_False);
237       myView->StartRotation(point.x,point.y);  
238     }
239   }
240 }
241
242 void COCCDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
243 {
244   if ( !(nFlags & MK_CONTROL) )
245   {
246     switch (myCurrentMode)
247     {
248     case CurAction3d_Nothing :
249       myXmax=point.x;  
250       myYmax=point.y;
251       break;
252     case CurAction3d_DynamicZooming :
253       myCurrentMode = CurAction3d_Nothing;
254       break;
255     case CurAction3d_WindowZooming :
256       DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
257       myXmax=point.x;
258       myYmax=point.y;
259       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
260         // Test if the zoom window is greater than a minimale window.
261       {
262         // Do the zoom window between Pmin and Pmax
263         myView->WindowFitAll(myXmin,myYmin,myXmax,myYmax);  
264       }  
265       myCurrentMode = CurAction3d_Nothing;
266       break;
267     case CurAction3d_DynamicPanning :
268       myCurrentMode = CurAction3d_Nothing;
269       break;
270     case CurAction3d_GlobalPanning :
271       myView->Place(point.x,point.y,myCurZoom); 
272       myCurrentMode = CurAction3d_Nothing;
273       break;
274     case  CurAction3d_DynamicRotation :
275       if (myVisMode == VIS_HLR)
276       {
277         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
278         myView->SetComputedMode(Standard_True);
279         myView->Redraw();
280         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
281       }
282       myCurrentMode = CurAction3d_Nothing;
283       break;
284     } //switch (myCurrentMode)
285   }
286 }
287
288 void COCCDemoView::OnRButtonDown(UINT nFlags, CPoint point) 
289 {
290   if ( nFlags & MK_CONTROL ) 
291   {
292     myView->SetComputedMode(Standard_False);
293     myView->StartRotation(point.x,point.y);  
294   }
295 }
296
297 void COCCDemoView::OnRButtonUp(UINT /*nFlags*/, CPoint /*point*/) 
298 {
299   if (myVisMode == VIS_HLR)
300   {
301     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
302     myView->SetComputedMode(Standard_True);
303     myView->Redraw();
304     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
305   }
306 }
307
308 void COCCDemoView::OnMouseMove(UINT nFlags, CPoint point) 
309 {
310   //   ============================  LEFT BUTTON =======================
311   if ( nFlags & MK_LBUTTON)
312   {
313     if ( nFlags & MK_CONTROL ) 
314     {
315       // move with MB1 and Control : on the dynamic zooming  
316       // Do the zoom in function of mouse's coordinates  
317       myView->Zoom(myXmax,myYmax,point.x,point.y); 
318       // save the current mouse coordinate in max
319       myXmax = point.x; 
320       myYmax = point.y; 
321     }
322     else // if ( Ctrl )
323     {
324       switch (myCurrentMode)
325       {
326       case CurAction3d_Nothing :
327         myXmax = point.x;
328         myYmax = point.y;
329         break;
330       case CurAction3d_DynamicZooming :
331         myView->Zoom(myXmax,myYmax,point.x,point.y); 
332         // save the current mouse coordinate in max;
333         myXmax=point.x;
334         myYmax=point.y;
335         break;
336       case CurAction3d_WindowZooming :
337         myXmax = point.x; myYmax = point.y;     
338         DrawRectangle (myXmin, myYmin, myXmax, myYmax, Standard_True, Aspect_TOL_DASH);
339         break;
340       case CurAction3d_DynamicPanning :
341         myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
342         myXmax = point.x; myYmax = point.y;     
343         break;
344       case CurAction3d_GlobalPanning : // nothing           
345         break;
346       case  CurAction3d_DynamicRotation :
347         myView->Rotation(point.x,point.y);
348         myView->Redraw();
349         break;
350       }
351     }
352   }
353   //   ============================  MIDDLE BUTTON =======================
354   else if ( nFlags & MK_MBUTTON)
355   {
356     if ( nFlags & MK_CONTROL ) 
357     {
358       myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
359       myXmax = point.x; myYmax = point.y;       
360     }
361   }
362   //   ============================  RIGHT BUTTON =======================
363   else if ( nFlags & MK_RBUTTON)
364   {
365     if ( nFlags & MK_CONTROL ) 
366     {
367       myView->Rotation(point.x,point.y);
368     }
369   }
370   //   ============================  NO BUTTON =======================
371   else
372   {
373     myXmax = point.x;
374     myYmax = point.y;   
375   }
376 }
377
378 void COCCDemoView::OnUpdateBUTTONPanGlo(CCmdUI* pCmdUI) 
379 {
380   pCmdUI->SetCheck (myCurrentMode == CurAction3d_GlobalPanning);
381         pCmdUI->Enable   (myCurrentMode != CurAction3d_GlobalPanning);  
382 }
383
384 void COCCDemoView::OnUpdateBUTTONPan(CCmdUI* pCmdUI) 
385 {
386   pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicPanning);
387         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicPanning );        
388 }
389
390 void COCCDemoView::OnUpdateBUTTONZoomProg(CCmdUI* pCmdUI) 
391 {
392   pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicZooming );
393         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicZooming); 
394 }
395
396 void COCCDemoView::OnUpdateBUTTONZoomWin(CCmdUI* pCmdUI) 
397 {
398   pCmdUI->SetCheck (myCurrentMode == CurAction3d_WindowZooming);
399         pCmdUI->Enable   (myCurrentMode != CurAction3d_WindowZooming);  
400 }
401
402 void COCCDemoView::OnUpdateBUTTONRot(CCmdUI* pCmdUI) 
403 {
404   pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicRotation);
405         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicRotation);        
406 }
407
408 void COCCDemoView::DrawRectangle (Standard_Integer theMinX,
409                                   Standard_Integer theMinY,
410                                   Standard_Integer theMaxX,
411                                   Standard_Integer theMaxY,
412                                   Standard_Boolean theToDraw,
413                                   Aspect_TypeOfLine theLineType)
414 {
415   const Handle(AIS_InteractiveContext)& aCtx = GetDocument()->GetAISContext();
416   if (!theToDraw)
417   {
418     aCtx->Remove (myRect, false);
419     aCtx->CurrentViewer()->RedrawImmediate();
420     return;
421   }
422
423   CRect aRect;
424   GetWindowRect (aRect);
425   myRect->SetLineType (theLineType);
426   myRect->SetRectangle (theMinX, aRect.Height() - theMinY, theMaxX, aRect.Height() - theMaxY);
427   if (!aCtx->IsDisplayed (myRect))
428   {
429     aCtx->Display (myRect, false);
430   }
431   else
432   {
433     aCtx->Redisplay (myRect, false);
434   }
435   aCtx->CurrentViewer()->RedrawImmediate();
436 }
437
438 void COCCDemoView::InitButtons()
439 {
440   myXmin=0;
441   myYmin=0;  
442   myXmax=0;
443   myYmax=0;
444   myCurZoom=0;
445   myCurrentMode = CurAction3d_Nothing;
446 }
447
448 void COCCDemoView::Reset()
449 {
450   InitButtons();
451   myVisMode = VIS_SHADE;
452   if (!myView.IsNull())
453   {
454     RedrawVisMode();
455     myView->Reset();
456   }
457 }
458
459 void COCCDemoView::RedrawVisMode()
460 {
461   switch (myVisMode)
462   {
463   case VIS_WIREFRAME:
464     GetDocument()->GetAISContext()->SetDisplayMode (AIS_WireFrame, Standard_True);
465     myView->SetComputedMode (Standard_False);
466     myView->Redraw();
467     break;
468   case VIS_SHADE:
469     GetDocument()->GetAISContext()->SetDisplayMode (AIS_Shaded, Standard_True);
470     myView->SetComputedMode (Standard_False);
471     myView->Redraw();
472     break;
473   case VIS_HLR:
474     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
475     myView->SetComputedMode (Standard_True);
476     myView->Redraw();
477     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
478     GetDocument()->GetAISContext()->SetDisplayMode (AIS_WireFrame, Standard_True);
479     break;
480   }
481 }
482
483 void COCCDemoView::OnBUTTONWire() 
484 {
485   myVisMode = VIS_WIREFRAME;
486   RedrawVisMode();
487 }
488
489 void COCCDemoView::OnBUTTONShade() 
490 {
491   myVisMode = VIS_SHADE;
492   RedrawVisMode();
493 }
494
495 void COCCDemoView::OnBUTTONHlrOn() 
496 {
497   myVisMode = VIS_HLR;
498   RedrawVisMode();
499 }
500
501 void COCCDemoView::OnUpdateBUTTONWire(CCmdUI* pCmdUI) 
502 {
503   pCmdUI->SetCheck (myVisMode == VIS_WIREFRAME);
504         pCmdUI->Enable   (myVisMode != VIS_WIREFRAME);  
505 }
506
507 void COCCDemoView::OnUpdateBUTTONShade(CCmdUI* pCmdUI) 
508 {
509   pCmdUI->SetCheck (myVisMode == VIS_SHADE);
510         pCmdUI->Enable   (myVisMode != VIS_SHADE);      
511 }
512
513 void COCCDemoView::OnUpdateBUTTONHlrOn(CCmdUI* pCmdUI) 
514 {
515   pCmdUI->SetCheck (myVisMode == VIS_HLR);
516         pCmdUI->Enable   (myVisMode != VIS_HLR);        
517 }
518
519 void COCCDemoView::GetViewAt (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
520 {
521   myView->At (theX, theY, theZ);
522 }
523
524 void COCCDemoView::SetViewAt (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
525 {
526   myView->SetAt (theX, theY, theZ);
527 }
528
529 void COCCDemoView::GetViewEye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z)
530 {
531         myView->Eye(X,Y,Z);
532 }
533
534 void COCCDemoView::SetViewEye(Standard_Real X, Standard_Real Y, Standard_Real Z)
535 {
536         myView->SetEye(X,Y,Z);
537 }
538
539 Standard_Real COCCDemoView::GetViewScale()
540 {
541         return myView->Scale();
542 }
543
544 void COCCDemoView::SetViewScale(Standard_Real Coef)
545 {
546         myView->SetScale(Coef);
547 }
548
549 void COCCDemoView::Translate (const Standard_Real theX, const Standard_Real theY)
550 {
551   myView->Panning (theX, theY);
552 }