0021985: Vista/WIndows 7 compatibility issues reported by the community
[occt.git] / samples / mfc / standard / Common / OCC_2dView.cpp
1 // OCC_2dView.cpp: implementation of the OCC_2dView class.
2 //
3 //////////////////////////////////////////////////////////////////////
4 #include "stdafx.h"
5
6 #include "OCC_2dView.h"
7
8 #include "OCC_2dApp.h"
9 #include "OCC_2dDoc.h"
10 #include "resource2d\RectangularGrid.h"
11 #include "resource2d\CircularGrid.h"
12
13 #include "Quantity_Color.hxx"
14 #include "Quantity_NameOfColor.hxx"
15
16 #define ValZWMin 1
17
18 // the key for multi selection :
19 #define MULTISELECTIONKEY MK_SHIFT
20
21 // the key for shortcut ( use to activate dynamic rotation, panning )
22 #define CASCADESHORTCUTKEY MK_CONTROL
23
24 // define in witch case you want to display the popup
25 #define POPUPONBUTTONDOWN
26
27 /////////////////////////////////////////////////////////////////////////////
28 // OCC_2dView
29
30 IMPLEMENT_DYNCREATE(OCC_2dView, CView)
31
32 BEGIN_MESSAGE_MAP(OCC_2dView, CView)
33         //{{AFX_MSG_MAP(OCC_2dView)
34                 // NOTE - the ClassWizard will add and remove mapping macros here.
35                 //    DO NOT EDIT what you see in these blocks of generated code!
36         ON_COMMAND(ID_FILE_EXPORT_IMAGE, OnFileExportImage)
37     ON_COMMAND(ID_BUTTON2DGridRectLines, OnBUTTONGridRectLines)
38         ON_COMMAND(ID_BUTTON2DGridRectPoints, OnBUTTONGridRectPoints)
39         ON_COMMAND(ID_BUTTON2DGridCircLines, OnBUTTONGridCircLines)
40         ON_COMMAND(ID_BUTTON2DGridCircPoints, OnBUTTONGridCircPoints)
41         ON_COMMAND(ID_BUTTON2DGridValues, OnBUTTONGridValues)
42     ON_UPDATE_COMMAND_UI(ID_BUTTON2DGridValues, OnUpdateBUTTONGridValues)
43         ON_COMMAND(ID_BUTTON2DGridCancel, OnBUTTONGridCancel)
44         ON_UPDATE_COMMAND_UI(ID_BUTTON2DGridCancel, OnUpdateBUTTONGridCancel)
45     ON_WM_LBUTTONDOWN()
46         ON_WM_LBUTTONUP()
47         ON_WM_MBUTTONDOWN()
48         ON_WM_MBUTTONUP()
49         ON_WM_RBUTTONDOWN()
50         ON_WM_RBUTTONUP()
51         ON_WM_MOUSEMOVE()
52         ON_WM_SIZE()
53         ON_COMMAND(ID_BUTTON2DFitAll, OnBUTTONFitAll)
54         ON_COMMAND(ID_BUTTON2DGlobPanning, OnBUTTONGlobPanning)
55         ON_COMMAND(ID_BUTTON2DPanning, OnBUTTONPanning)
56         ON_COMMAND(ID_BUTTON2DZoomProg, OnBUTTONZoomProg)
57         ON_COMMAND(ID_BUTTON2DZoomWin, OnBUTTONZoomWin)
58         ON_UPDATE_COMMAND_UI(ID_BUTTON2DGlobPanning, OnUpdateBUTTON2DGlobPanning)
59         ON_UPDATE_COMMAND_UI(ID_BUTTON2DPanning, OnUpdateBUTTON2DPanning)
60         ON_UPDATE_COMMAND_UI(ID_BUTTON2DZoomProg, OnUpdateBUTTON2DZoomProg)
61         ON_UPDATE_COMMAND_UI(ID_BUTTON2DZoomWin, OnUpdateBUTTON2DZoomWin)
62         ON_COMMAND(ID_Modify_ChangeBackground ,OnChangeBackground)
63         //}}AFX_MSG_MAP
64 END_MESSAGE_MAP()
65
66 /////////////////////////////////////////////////////////////////////////////
67 // OCC_2dView construction/destruction
68
69 OCC_2dView::OCC_2dView()
70 {
71         // TODO: add construction code here
72   myCurrentMode = CurAction2d_Nothing;
73   m_Pen = NULL;
74 }
75
76 OCC_2dView::~OCC_2dView()
77 {
78   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
79   aViewer->RemoveView(myV2dView);
80   if (m_Pen) delete m_Pen;
81
82 }
83
84 BOOL OCC_2dView::PreCreateWindow(CREATESTRUCT& cs)
85 {
86         // TODO: Modify the Window class or styles here by modifying
87         //  the CREATESTRUCT cs
88
89         return CView::PreCreateWindow(cs);
90 }
91
92 /////////////////////////////////////////////////////////////////////////////
93 // OCC_2dView drawing
94
95 void OCC_2dView::OnDraw(CDC* pDC)
96 {
97         if (!myV2dView.IsNull())
98         myV2dView->Update();
99 }
100
101 void OCC_2dView::OnInitialUpdate()
102 {
103         CView::OnInitialUpdate();
104
105         Handle(WNT_Window) aWNTWindow;
106         aWNTWindow = new WNT_Window(((OCC_2dApp*)AfxGetApp())->GetGraphicDevice(),GetSafeHwnd());         
107     aWNTWindow->SetBackground(Quantity_NOC_MATRAGRAY);
108
109         Handle(WNT_WDriver)  aDriver= new WNT_WDriver(aWNTWindow);
110         myV2dView = new V2d_View(aDriver, ((OCC_2dDoc*)GetDocument())->GetViewer2D(),0,0,50);
111
112     // initialyse the grids dialogs
113     TheRectangularGridDialog.Create(CRectangularGrid::IDD, NULL);
114     TheCircularGridDialog.Create(CCircularGrid::IDD, NULL);
115     TheRectangularGridDialog.SetViewer (((OCC_2dDoc*)GetDocument())->GetViewer2D());
116     TheCircularGridDialog.SetViewer (((OCC_2dDoc*)GetDocument())->GetViewer2D());
117
118         Standard_Integer w=100 , h=100 ;   /* Debug Matrox                         */
119         aWNTWindow->Size (w,h) ;           /* Keeps me unsatisfied (rlb).....      */
120                                            /* Resize is not supposed to be done on */
121                                            /* Matrox                               */
122                                            /* I suspect another problem elsewhere  */
123         ::PostMessage ( GetSafeHwnd () , WM_SIZE , SIZE_RESTORED , w + h*65536 ) ;
124
125 }
126
127 void OCC_2dView::OnFileExportImage()
128 {
129 CFileDialog dlg(FALSE,_T("*.BMP"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
130                _T("BMP Files (*.BMP)|*.bmp |GIF Files (*.GIF)|*.gif | PNG Files (*.PNG)|*.png"
131                   "|JPEG Files (*.JPEG)|*.jpeg | PPM Files (*.PPM)|*.ppm | TIFF Files (*.TIFF)"
132                   "|*.tiff | TGA Files (*.TGA)|*.tga | EXR Files (*.EXR)|*.exr||"), 
133                NULL );
134
135 if (dlg.DoModal() == IDOK) 
136 {
137  SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
138  CString filename = dlg.GetPathName();
139  Handle(WNT_Window) aWNTWindow=
140  Handle(WNT_Window)::DownCast(myV2dView->Driver()->Window());
141  aWNTWindow->Dump ((Standard_CString)(LPCTSTR)filename);
142  SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
143 }
144 }
145
146 /////////////////////////////////////////////////////////////////////////////
147 // OCC_2dView diagnostics
148
149 #ifdef _DEBUG
150 void OCC_2dView::AssertValid() const
151 {
152         CView::AssertValid();
153 }
154
155 void OCC_2dView::Dump(CDumpContext& dc) const
156 {
157         CView::Dump(dc);
158 }
159
160 CDocument* OCC_2dView::GetDocument() // non-debug version is inline
161 {
162         //ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(OCC_2dDoc)));
163         return m_pDocument;
164 }
165 #endif //_DEBUG
166 #include <V2d_RectangularGrid.hxx>
167 void OCC_2dView::OnBUTTONGridRectLines() 
168 {
169   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
170   aViewer->SetGridColor(Quantity_Color(Quantity_NOC_WHITE), Quantity_Color(Quantity_NOC_WHITE));
171   aViewer->ActivateGrid(Aspect_GT_Rectangular,
172                                                    Aspect_GDM_Lines);
173   
174   if (TheCircularGridDialog.IsWindowVisible())
175   {
176     TheCircularGridDialog.ShowWindow(SW_HIDE);
177     TheRectangularGridDialog.UpdateValues();
178     TheRectangularGridDialog.ShowWindow(SW_SHOW);
179   }
180 }
181
182 void OCC_2dView::OnBUTTONGridRectPoints() 
183 {
184   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
185   aViewer->ActivateGrid(Aspect_GT_Rectangular,
186                                                    Aspect_GDM_Points);
187   aViewer->SetGridColor(Quantity_Color(Quantity_NOC_WHITE), Quantity_Color(Quantity_NOC_WHITE));
188   if (TheCircularGridDialog.IsWindowVisible())
189   {
190     TheCircularGridDialog.ShowWindow(SW_HIDE);
191     TheRectangularGridDialog.UpdateValues();
192     TheRectangularGridDialog.ShowWindow(SW_SHOW);
193   }
194 }
195
196 void OCC_2dView::OnBUTTONGridCircLines() 
197 {
198   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
199   aViewer->SetGridColor(Quantity_Color(Quantity_NOC_WHITE), Quantity_Color(Quantity_NOC_WHITE));
200   aViewer->ActivateGrid(Aspect_GT_Circular,
201                                                    Aspect_GDM_Lines);
202  
203
204   if (TheRectangularGridDialog.IsWindowVisible())
205   {
206     TheRectangularGridDialog.ShowWindow(SW_HIDE);
207     TheCircularGridDialog.UpdateValues();
208     TheCircularGridDialog.ShowWindow(SW_SHOW);
209   }
210 }
211
212 void OCC_2dView::OnBUTTONGridCircPoints() 
213 {
214   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
215   aViewer->SetGridColor(Quantity_Color(Quantity_NOC_WHITE), Quantity_Color(Quantity_NOC_WHITE)); 
216   aViewer->ActivateGrid(Aspect_GT_Circular,
217                                                    Aspect_GDM_Points);
218   if (TheRectangularGridDialog.IsWindowVisible())
219   {
220     TheRectangularGridDialog.ShowWindow(SW_HIDE);
221     TheCircularGridDialog.UpdateValues();
222     TheCircularGridDialog.ShowWindow(SW_SHOW);
223   }
224 }
225
226 void OCC_2dView::OnBUTTONGridValues() 
227 {
228   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
229   Aspect_GridType  TheGridtype = aViewer->GridType();
230
231   switch( TheGridtype ) 
232   {
233     case  Aspect_GT_Rectangular:
234       TheRectangularGridDialog.UpdateValues();
235       TheRectangularGridDialog.ShowWindow(SW_SHOW);
236         break;
237     case  Aspect_GT_Circular:
238       TheCircularGridDialog.UpdateValues();
239       TheCircularGridDialog.ShowWindow(SW_SHOW);
240         break;
241     default :
242                 Standard_Failure::Raise("invalid Aspect_GridType");
243   }
244 }
245 void OCC_2dView::OnUpdateBUTTONGridValues(CCmdUI* pCmdUI) 
246 {
247   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
248   pCmdUI-> Enable( aViewer->IsActive() );
249 }
250
251 void OCC_2dView::OnBUTTONGridCancel() 
252 {       
253   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
254   aViewer->DeactivateGrid();
255   TheRectangularGridDialog.ShowWindow(SW_HIDE);
256   TheCircularGridDialog.ShowWindow(SW_HIDE);
257   aViewer->Update();
258 }
259 void OCC_2dView::OnUpdateBUTTONGridCancel(CCmdUI* pCmdUI) 
260 {
261   Handle(V2d_Viewer) aViewer = myV2dView->Viewer();
262   pCmdUI-> Enable( aViewer->IsActive() );       
263 }
264
265 void OCC_2dView::OnLButtonDown(UINT nFlags, CPoint point) 
266 {
267   //  save the current mouse coordinate in min 
268   myXmin=point.x;  myYmin=point.y;
269   myXmax=point.x;  myYmax=point.y;
270
271   if ( nFlags & CASCADESHORTCUTKEY ) 
272           {
273             // Button MB1 down Control :start zomming 
274         // 
275           }
276         else // if ( MULTISELECTIONKEY )
277           {
278         switch (myCurrentMode)
279         {
280          case CurAction2d_Nothing : // start a drag
281              DragEvent2D(point.x,point.y,-1);
282          break;
283          case CurAction2d_DynamicZooming : // nothing
284          break;
285          case CurAction2d_WindowZooming : // nothing
286          break;
287          case CurAction2d_DynamicPanning :// nothing
288          break;
289          case CurAction2d_GlobalPanning :// nothing
290         break;
291         default :
292            Standard_Failure::Raise(" incompatible Current Mode ");
293         break;
294         }
295     }
296 }
297
298
299 void OCC_2dView::OnLButtonUp(UINT nFlags, CPoint point) 
300 {
301         // TODO: Add your message handler code here and/or call default
302    if ( nFlags & CASCADESHORTCUTKEY ) 
303           {
304         return;
305           }
306         else // if ( Ctrl )
307           {
308         switch (myCurrentMode)
309         {
310          case CurAction2d_Nothing :
311          if (point.x == myXmin && point.y == myYmin)
312          { // no offset between down and up --> selectEvent
313             myXmax=point.x;  
314             myYmax=point.y;
315             if (nFlags & MULTISELECTIONKEY )
316               MultiInputEvent2D(point.x,point.y);
317             else
318               InputEvent2D     (point.x,point.y);
319          } else
320          {
321             DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
322             myXmax=point.x;  
323             myYmax=point.y;
324                     if (nFlags & MULTISELECTIONKEY)
325                                 MultiDragEvent2D(point.x,point.y,1);
326                         else
327                                 DragEvent2D(point.x,point.y,1);
328          }
329          break;
330          case CurAction2d_DynamicZooming :
331              // 
332                myCurrentMode = CurAction2d_Nothing;
333          break;
334          case CurAction2d_WindowZooming :
335            myXmax=point.x;     myYmax=point.y;
336            DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
337                if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
338                                          // Test if the zoom window is greater than a minimale window.
339                         {
340                           // Do the zoom window between Pmin and Pmax
341                           myV2dView->WindowFit(myXmin,myYmin,myXmax,myYmax);  
342                         }  
343                myCurrentMode = CurAction2d_Nothing;
344          break;
345          case CurAction2d_DynamicPanning :
346            myCurrentMode = CurAction2d_Nothing;
347          break;
348          case CurAction2d_GlobalPanning :
349                myV2dView->Place(point.x,point.y,myCurZoom); 
350                myCurrentMode = CurAction2d_Nothing;
351         break;
352         default :
353            Standard_Failure::Raise(" incompatible Current Mode ");
354         break;
355         } //switch (myCurrentMode)
356     } //        else // if ( CASCADESHORTCUTKEY )       
357 }
358
359 void OCC_2dView::OnMButtonDown(UINT nFlags, CPoint point) 
360 {
361    if ( nFlags & CASCADESHORTCUTKEY ) 
362           {
363         // Button MB2 down + CASCADESHORTCUTKEY : panning init  
364         // 
365           }
366
367 }
368
369 void OCC_2dView::OnMButtonUp(UINT nFlags, CPoint point) 
370 {
371    if ( nFlags & CASCADESHORTCUTKEY ) 
372           {
373         // Button MB2 up + CASCADESHORTCUTKEY : panning stop 
374         // 
375           }
376
377 }
378
379 void OCC_2dView::OnRButtonDown(UINT nFlags, CPoint point) 
380 {
381 #ifdef POPUPONBUTTONDOWN
382    if ( !(nFlags & CASCADESHORTCUTKEY) ) 
383             Popup2D(point.x,point.y);
384 #endif
385 }
386
387 void OCC_2dView::OnRButtonUp(UINT nFlags, CPoint point) 
388 {
389 #ifndef POPUPONBUTTONDOWN
390    if ( !(nFlags & CASCADESHORTCUTKEY) ) 
391             Popup2D(point.x,point.y);
392 #endif
393 }
394
395 void OCC_2dView::OnMouseMove(UINT nFlags, CPoint point) 
396 {
397     //   ============================  LEFT BUTTON =======================
398   if ( (nFlags & MK_LBUTTON) &! (nFlags & MK_RBUTTON) ) // Left + Right is specific
399     {
400      if ( nFlags & CASCADESHORTCUTKEY ) 
401           {
402             // move with MB1 and CASCADESHORTCUTKEY : on the dynamic zooming  
403             // Do the zoom in function of mouse's coordinates  
404             myV2dView->Zoom(myXmax,myYmax,point.x,point.y); 
405             // save the current mouse coordinate in min 
406                 myXmax = point.x; 
407         myYmax = point.y;       
408           }
409           else // if ( CASCADESHORTCUTKEY )
410           {
411         switch (myCurrentMode)
412         {
413          case CurAction2d_Nothing :
414                    myXmax = point.x;     myYmax = point.y;      
415            DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
416           DragEvent2D(myXmax,myYmax,0);  
417            DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True);
418          break;
419          case CurAction2d_DynamicZooming :
420                myV2dView->Zoom(myXmax,myYmax,point.x,point.y); 
421                // save the current mouse coordinate in min \n";
422                myXmax=point.x;  myYmax=point.y;
423          break;
424          case CurAction2d_WindowZooming :
425                    myXmax = point.x; myYmax = point.y;  
426            DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
427            DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
428          break;
429          case CurAction2d_DynamicPanning :
430                    myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
431                    myXmax = point.x; myYmax = point.y;  
432          break;
433          case CurAction2d_GlobalPanning : // nothing           
434         break;
435         default :
436            Standard_Failure::Raise(" incompatible Current Mode ");
437         break;
438         }//  switch (myCurrentMode)
439       }// if ( nFlags & CASCADESHORTCUTKEY )  else 
440     } else //   if ( nFlags & MK_LBUTTON) 
441     //   ============================  MIDDLE BUTTON =======================
442     if ( nFlags & MK_MBUTTON)
443     {
444      if ( nFlags & CASCADESHORTCUTKEY ) 
445           {
446                 myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
447                 myXmax = point.x; myYmax = point.y;     
448
449           }
450     } else //  if ( nFlags & MK_MBUTTON)
451     //   ============================  RIGHT BUTTON =======================
452     if ( (nFlags & MK_RBUTTON) &! (nFlags & MK_LBUTTON) ) // Left + Right is specific
453     {
454     }else //if ( nFlags & MK_RBUTTON)
455     if ( (nFlags & MK_RBUTTON) && (nFlags & MK_LBUTTON) )
456     {
457       // in case of Left + Right : same as Middle
458      if ( nFlags & CASCADESHORTCUTKEY ) 
459           {
460                 myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
461                 myXmax = point.x; myYmax = point.y;     
462           }
463     }else //if ( nFlags & MK_RBUTTON)&& (nFlags & MK_LBUTTON) 
464     //   ============================  NO BUTTON =======================
465     {  // No buttons 
466           myXmax = point.x; myYmax = point.y;   
467           if (nFlags & MULTISELECTIONKEY)
468                 MultiMoveEvent2D(point.x,point.y);
469           else
470                 MoveEvent2D(point.x,point.y);
471     }
472 }
473
474
475 void OCC_2dView::OnSize(UINT nType, int cx, int cy) 
476 {
477     // Take care : This fonction is call before OnInitialUpdate
478         if (!myV2dView.IsNull())
479       myV2dView->MustBeResized(V2d_TOWRE_ENLARGE_OBJECTS); 
480
481 }
482
483 void OCC_2dView::OnBUTTONFitAll() 
484 {
485   myV2dView->Fitall();
486 }
487
488 void OCC_2dView::OnBUTTONGlobPanning() 
489 {
490   //save the current zoom value
491   myCurZoom = myV2dView->Zoom();  
492
493   // Do a Global Zoom 
494   //myV2dView->Fitall();
495
496   // Set the mode
497   myCurrentMode = CurAction2d_GlobalPanning;
498 }
499 void OCC_2dView::OnBUTTONPanning() 
500 {
501   myCurrentMode = CurAction2d_DynamicPanning;
502 }
503 void OCC_2dView::OnBUTTONZoomProg() 
504 {
505   myCurrentMode = CurAction2d_DynamicZooming;
506 }
507 void OCC_2dView::OnBUTTONZoomWin() 
508 {
509   myCurrentMode = CurAction2d_WindowZooming;
510 }
511 void OCC_2dView::OnChangeBackground() 
512 {
513         Standard_Real R1, G1, B1;
514     Handle(Aspect_WindowDriver) aWindowDriver = myV2dView->Driver();
515     Handle(Aspect_Window) aWindow = aWindowDriver->Window();
516     Aspect_Background ABack = aWindow->Background();
517     Quantity_Color aColor = ABack.Color();
518     aColor.Values(R1,G1,B1,Quantity_TOC_RGB);
519         COLORREF m_clr ;
520         m_clr = RGB(R1*255,G1*255,B1*255);
521
522         CColorDialog dlgColor(m_clr);
523         if (dlgColor.DoModal() == IDOK)
524         {
525                 m_clr = dlgColor.GetColor();
526                 R1 = GetRValue(m_clr)/255.;
527                 G1 = GetGValue(m_clr)/255.;
528                 B1 = GetBValue(m_clr)/255.;
529         aColor.SetValues(R1,G1,B1,Quantity_TOC_RGB);
530         ABack.SetColor(aColor);
531         aWindow->SetBackground(ABack);
532         myV2dView->Update();
533         }       
534 }
535
536
537 void OCC_2dView::OnUpdateBUTTON2DGlobPanning(CCmdUI* pCmdUI) 
538 {
539     pCmdUI->SetCheck (myCurrentMode == CurAction2d_GlobalPanning);
540         pCmdUI->Enable   (myCurrentMode != CurAction2d_GlobalPanning);  
541 }
542
543 void OCC_2dView::OnUpdateBUTTON2DPanning(CCmdUI* pCmdUI) 
544 {
545     pCmdUI->SetCheck (myCurrentMode == CurAction2d_DynamicPanning);
546         pCmdUI->Enable   (myCurrentMode != CurAction2d_DynamicPanning);         
547 }
548
549 void OCC_2dView::OnUpdateBUTTON2DZoomProg(CCmdUI* pCmdUI) 
550 {
551     pCmdUI->SetCheck (myCurrentMode == CurAction2d_DynamicZooming);
552         pCmdUI->Enable   (myCurrentMode != CurAction2d_DynamicZooming); 
553 }
554
555 void OCC_2dView::OnUpdateBUTTON2DZoomWin(CCmdUI* pCmdUI) 
556 {
557     pCmdUI->SetCheck (myCurrentMode == CurAction2d_WindowZooming);
558         pCmdUI->Enable   (myCurrentMode != CurAction2d_WindowZooming);          
559 }
560
561
562 void OCC_2dView::DrawRectangle2D(const Standard_Integer  MinX    ,
563                                                             const Standard_Integer  MinY    ,
564                                         const Standard_Integer  MaxX ,
565                                                             const Standard_Integer  MaxY ,
566                                                             const Standard_Boolean  Draw , 
567                                         const LineStyle aLineStyle)
568 {
569     static int m_DrawMode;
570     if  (!m_Pen && aLineStyle ==Solid )
571         {m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;}
572     else if (!m_Pen && aLineStyle ==Dot )
573         {m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0));   m_DrawMode = R2_XORPEN;}
574     else if (!m_Pen && aLineStyle == ShortDash)
575         {m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0));    m_DrawMode = R2_XORPEN;}
576     else if (!m_Pen && aLineStyle == LongDash)
577         {m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0));      m_DrawMode = R2_NOTXORPEN;}
578     else if (aLineStyle == Default) 
579         { m_Pen = NULL; m_DrawMode = R2_MERGEPENNOT;}
580
581     CPen* aOldPen;
582     CClientDC clientDC(this);
583     if (m_Pen) aOldPen = clientDC.SelectObject(m_Pen);
584     clientDC.SetROP2(m_DrawMode);
585
586     static              Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
587     static              Standard_Boolean m_IsVisible;
588
589     if ( m_IsVisible && !Draw) // move or up  : erase at the old position 
590     {
591      clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
592      clientDC.LineTo(StoredMaxX,StoredMaxY); 
593          clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
594      m_IsVisible = false;
595     }
596
597     StoredMinX = min ( MinX, MaxX );
598     StoredMinY = min ( MinY, MaxY );
599     StoredMaxX = max ( MinX, MaxX );
600     StoredMaxY = max ( MinY, MaxY);
601
602     if (Draw) // move : draw
603     {
604      clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
605      clientDC.LineTo(StoredMaxX,StoredMaxY); 
606          clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
607      m_IsVisible = true;
608    }
609
610     if (m_Pen) clientDC.SelectObject(aOldPen);
611 }
612
613
614
615 // =====================================================================
616
617 //-----------------------------------------------------------------------------------------
618 //
619 //-----------------------------------------------------------------------------------------
620 void OCC_2dView::DragEvent2D(const Standard_Integer  x        ,
621                                                   const Standard_Integer  y        ,
622                                                   const Standard_Integer  TheState )
623 {
624   // TheState == -1  button down
625   // TheState ==  0  move
626   // TheState ==  1  button up
627
628     static Standard_Integer theButtonDownX=0;
629     static Standard_Integer theButtonDownY=0;
630
631         if (TheState == -1)
632     {
633       theButtonDownX=x;
634       theButtonDownY=y;
635     }
636
637   if (TheState == 0)
638   {
639         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->MoveTo(theButtonDownX,theButtonDownY,x,y,myV2dView);
640   }
641
642   if (TheState == 1)
643   {
644         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->Select(true);
645   }
646
647 }
648
649
650 //-----------------------------------------------------------------------------------------
651 //
652 //-----------------------------------------------------------------------------------------
653 void OCC_2dView::InputEvent2D(const Standard_Integer  x     ,
654                                                    const Standard_Integer  y     ) 
655 {
656         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->Select(true);
657
658 }
659
660 //-----------------------------------------------------------------------------------------
661 //
662 //-----------------------------------------------------------------------------------------
663 void OCC_2dView::MoveEvent2D(const Standard_Integer  x       ,
664                                                   const Standard_Integer  y       ) 
665 {
666   static bool LastIsGridActiveStatus = Standard_True;
667   if (myV2dView->Viewer()->IsActive() )  // about the grid
668     { myV2dView->ShowHit(x,y); LastIsGridActiveStatus = Standard_True;}
669   if (!myV2dView->Viewer()->IsActive() && LastIsGridActiveStatus )  // about the grid
670     {myV2dView->EraseHit(); LastIsGridActiveStatus = Standard_False;}
671
672         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->MoveTo(x,y,myV2dView);  
673
674
675 }
676
677 //-----------------------------------------------------------------------------------------
678 //
679 //-----------------------------------------------------------------------------------------
680 void OCC_2dView::MultiMoveEvent2D(const Standard_Integer  x       ,
681                                                            const Standard_Integer  y      ) 
682 {
683 // MultiMoveEvent2D means we move the mouse in a multi selection mode
684 ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->MoveTo(x,y,myV2dView);
685
686 }
687
688 //-----------------------------------------------------------------------------------------
689 //
690 //-----------------------------------------------------------------------------------------
691 void OCC_2dView::MultiDragEvent2D(const Standard_Integer  x        ,
692                                                            const Standard_Integer  y        ,
693                                                            const Standard_Integer  TheState) 
694 {
695     static Standard_Integer theButtonDownX=0;
696     static Standard_Integer theButtonDownY=0;
697
698         if (TheState == -1)
699     {
700       theButtonDownX=x;
701       theButtonDownY=y;
702     }
703
704   if (TheState == 0)
705   {
706         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->MoveTo(theButtonDownX,theButtonDownY,x,y,myV2dView);
707   }
708
709   if (TheState == 1)
710   {
711         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->ShiftSelect(true);
712   }
713 }
714
715
716 //-----------------------------------------------------------------------------------------
717 //
718 //-----------------------------------------------------------------------------------------
719 void OCC_2dView::MultiInputEvent2D(const Standard_Integer  x       ,
720                                                                 const Standard_Integer  y       ) 
721 {
722         ((OCC_2dDoc*)GetDocument())->GetInteractiveContext2D()->ShiftSelect(true);
723 }
724
725 //-----------------------------------------------------------------------------------------
726 //
727 //-----------------------------------------------------------------------------------------
728 void  OCC_2dView::Popup2D(const Standard_Integer  x,
729                                            const Standard_Integer  y ) 
730 {
731   CMenu menu;
732   CMenu* pPopup ;
733
734   // load the 'normal' popup     
735   VERIFY(menu.LoadMenu(IDR_Popup2D));
736   // activate the sub menu '0'
737   pPopup= menu.GetSubMenu(0);
738   ASSERT(pPopup != NULL);
739
740   // display the popup
741   POINT winCoord = { x , y };
742
743
744   ClientToScreen ( &winCoord);
745   pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON , winCoord.x, winCoord.y , AfxGetMainWnd());
746         
747 }
748
749 void OCC_2dView::FitAll()
750 {
751   myV2dView->Fitall();
752 }