8209ab828d610113a4b743c986a6a6827b6ea413
[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_App.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   myV2dView->Remove();
79   if (m_Pen) delete m_Pen;
80 }
81
82 BOOL OCC_2dView::PreCreateWindow(CREATESTRUCT& cs)
83 {
84   // TODO: Modify the Window class or styles here by modifying
85   //  the CREATESTRUCT cs
86   return CView::PreCreateWindow(cs);
87 }
88
89 /////////////////////////////////////////////////////////////////////////////
90 // OCC_2dView drawing
91
92 void OCC_2dView::OnDraw(CDC* /*pDC*/)
93 {
94   if (!myV2dView.IsNull())
95     myV2dView->Update();
96 }
97
98 void OCC_2dView::OnInitialUpdate()
99 {
100   CView::OnInitialUpdate();
101
102   Handle(WNT_Window) aWNTWindow = new WNT_Window(GetSafeHwnd(),Quantity_NOC_MATRAGRAY);   
103   myV2dView =((OCC_2dDoc*)GetDocument())->GetViewer2D()->CreateView();
104   myV2dView->SetWindow(aWNTWindow);
105   myV2dView->SetZClippingType(V3d_OFF);
106   myV2dView->SetSurfaceDetail(V3d_TEX_ALL);
107   // initialize the grids dialogs
108   TheRectangularGridDialog.Create(CRectangularGrid::IDD, NULL);
109   TheCircularGridDialog.Create(CCircularGrid::IDD, NULL);
110   TheRectangularGridDialog.SetViewer (((OCC_2dDoc*)GetDocument())->GetViewer2D());
111   TheCircularGridDialog.SetViewer (((OCC_2dDoc*)GetDocument())->GetViewer2D());
112
113   Standard_Integer w=100 , h=100 ;   /* Debug Matrox                         */
114   aWNTWindow->Size (w,h) ;           /* Keeps me unsatisfied (rlb).....      */
115   /* Resize is not supposed to be done on */
116   /* Matrox                               */
117   /* I suspect another problem elsewhere  */
118   ::PostMessage ( GetSafeHwnd () , WM_SIZE , SIZE_RESTORED , w + h*65536 ) ;
119
120 }
121
122 void OCC_2dView::OnFileExportImage()
123 {
124   GetDocument()->ExportView (myV2dView);
125 }
126
127 /////////////////////////////////////////////////////////////////////////////
128 // OCC_2dView diagnostics
129
130 #ifdef _DEBUG
131 void OCC_2dView::AssertValid() const
132 {
133   CView::AssertValid();
134 }
135
136 void OCC_2dView::Dump(CDumpContext& dc) const
137 {
138   CView::Dump(dc);
139 }
140
141 OCC_2dDoc* OCC_2dView::GetDocument() // non-debug version is inline
142 {
143   //ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(OCC_2dDoc)));
144   return (OCC_2dDoc*)m_pDocument;
145 }
146 #endif //_DEBUG
147 void OCC_2dView::OnBUTTONGridRectLines() 
148 {
149   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
150   Handle(Graphic3d_AspectMarker3d) aGridAspect = new Graphic3d_AspectMarker3d(Aspect_TOM_RING1,Quantity_NOC_WHITE,2);
151   aViewer->SetGridEcho(aGridAspect);
152   Standard_Integer aWidth=0, aHeight=0, anOffset=0;
153   myV2dView->Window()->Size(aWidth,aHeight);
154   aViewer->SetRectangularGridGraphicValues(aWidth,aHeight,anOffset);
155   aViewer->ActivateGrid(Aspect_GT_Rectangular, Aspect_GDM_Lines);
156   FitAll();
157   
158   if (TheCircularGridDialog.IsWindowVisible())
159   {
160     TheCircularGridDialog.ShowWindow(SW_HIDE);
161     TheRectangularGridDialog.UpdateValues();
162     TheRectangularGridDialog.ShowWindow(SW_SHOW);
163   }
164 }
165
166 void OCC_2dView::OnBUTTONGridRectPoints() 
167 {
168   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
169   Handle(Graphic3d_AspectMarker3d) aGridAspect = new Graphic3d_AspectMarker3d(Aspect_TOM_RING1,Quantity_NOC_WHITE,2);
170   aViewer->SetGridEcho(aGridAspect);
171   Standard_Integer aWidth=0, aHeight=0, anOffset=0;
172   myV2dView->Window()->Size(aWidth,aHeight);
173   aViewer->SetRectangularGridGraphicValues(aWidth,aHeight,anOffset);
174   aViewer->ActivateGrid(Aspect_GT_Rectangular, Aspect_GDM_Points);
175   FitAll();
176
177   if (TheCircularGridDialog.IsWindowVisible())
178   {
179     TheCircularGridDialog.ShowWindow(SW_HIDE);
180     TheRectangularGridDialog.UpdateValues();
181     TheRectangularGridDialog.ShowWindow(SW_SHOW);
182   }
183 }
184
185 void OCC_2dView::OnBUTTONGridCircLines() 
186 {
187   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
188   Handle(Graphic3d_AspectMarker3d) aGridAspect = new Graphic3d_AspectMarker3d(Aspect_TOM_RING1,Quantity_NOC_WHITE,2);
189   aViewer->SetGridEcho(aGridAspect);
190   Standard_Integer aWidth=0, aHeight=0, anOffset=0;
191   myV2dView->Window()->Size(aWidth,aHeight);
192   aViewer->SetCircularGridGraphicValues(aWidth>aHeight?aWidth:aHeight,anOffset);
193   aViewer->ActivateGrid(Aspect_GT_Circular, Aspect_GDM_Lines);
194   FitAll();
195  
196
197   if (TheRectangularGridDialog.IsWindowVisible())
198   {
199     TheRectangularGridDialog.ShowWindow(SW_HIDE);
200     TheCircularGridDialog.UpdateValues();
201     TheCircularGridDialog.ShowWindow(SW_SHOW);
202   }
203 }
204
205 void OCC_2dView::OnBUTTONGridCircPoints() 
206 {
207   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
208   Handle(Graphic3d_AspectMarker3d) aGridAspect = new Graphic3d_AspectMarker3d(Aspect_TOM_RING1,Quantity_NOC_WHITE,2);
209   aViewer->SetGridEcho(aGridAspect);
210   Standard_Integer aWidth=0, aHeight=0, anOffset=0;
211   myV2dView->Window()->Size(aWidth,aHeight);
212   aViewer->SetCircularGridGraphicValues(aWidth>aHeight?aWidth:aHeight,anOffset);
213   aViewer->ActivateGrid(Aspect_GT_Circular, Aspect_GDM_Points);
214   FitAll();
215   if (TheRectangularGridDialog.IsWindowVisible())
216   {
217     TheRectangularGridDialog.ShowWindow(SW_HIDE);
218     TheCircularGridDialog.UpdateValues();
219     TheCircularGridDialog.ShowWindow(SW_SHOW);
220   }
221 }
222
223 void OCC_2dView::OnBUTTONGridValues() 
224 {
225   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
226   Aspect_GridType  TheGridtype = aViewer->GridType();
227
228   switch( TheGridtype ) 
229   {
230   case  Aspect_GT_Rectangular:
231     TheRectangularGridDialog.UpdateValues();
232     TheRectangularGridDialog.ShowWindow(SW_SHOW);
233     break;
234   case  Aspect_GT_Circular:
235     TheCircularGridDialog.UpdateValues();
236     TheCircularGridDialog.ShowWindow(SW_SHOW);
237     break;
238   default :
239     Standard_Failure::Raise("invalid Aspect_GridType");
240   }
241 }
242 void OCC_2dView::OnUpdateBUTTONGridValues(CCmdUI* pCmdUI) 
243 {
244   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
245   pCmdUI-> Enable( aViewer->IsActive() );
246 }
247
248 void OCC_2dView::OnBUTTONGridCancel() 
249 {
250   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
251   aViewer->DeactivateGrid();
252   TheRectangularGridDialog.ShowWindow(SW_HIDE);
253   TheCircularGridDialog.ShowWindow(SW_HIDE);
254   aViewer->Update();
255 }
256 void OCC_2dView::OnUpdateBUTTONGridCancel(CCmdUI* pCmdUI) 
257 {
258   Handle(V3d_Viewer) aViewer = myV2dView->Viewer();
259   pCmdUI-> Enable( aViewer->IsActive() );       
260 }
261
262 void OCC_2dView::OnLButtonDown(UINT nFlags, CPoint point) 
263 {
264   //  save the current mouse coordinate in min 
265   myXmin=point.x;  myYmin=point.y;
266   myXmax=point.x;  myYmax=point.y;
267
268   if ( nFlags & CASCADESHORTCUTKEY ) 
269   {
270     // Button MB1 down Control :start zomming 
271     // 
272   }
273   else // if ( MULTISELECTIONKEY )
274   {
275     switch (myCurrentMode)
276     {
277     case CurAction2d_Nothing : // start a drag
278       DragEvent2D(point.x,point.y,-1);
279       break;
280     case CurAction2d_DynamicZooming : // nothing
281       break;
282     case CurAction2d_WindowZooming : // nothing
283       break;
284     case CurAction2d_DynamicPanning :// nothing
285       break;
286     case CurAction2d_GlobalPanning :// nothing
287       break;
288     default :
289       Standard_Failure::Raise(" incompatible Current Mode ");
290       break;
291     }
292   }
293 }
294
295
296 void OCC_2dView::OnLButtonUp(UINT nFlags, CPoint point) 
297 {
298   // TODO: Add your message handler code here and/or call default
299   if ( nFlags & CASCADESHORTCUTKEY ) 
300   {
301     return;
302   }
303   else // if ( Ctrl )
304   {
305     switch (myCurrentMode)
306     {
307     case CurAction2d_Nothing :
308       if (point.x == myXmin && point.y == myYmin)
309       { // no offset between down and up --> selectEvent
310         myXmax=point.x;  
311         myYmax=point.y;
312         if (nFlags & MULTISELECTIONKEY )
313           MultiInputEvent2D(point.x,point.y);
314         else
315           InputEvent2D     (point.x,point.y);
316       } else
317       {
318         DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
319         myXmax=point.x;  
320         myYmax=point.y;
321         if (nFlags & MULTISELECTIONKEY)
322           MultiDragEvent2D(point.x,point.y,1);
323         else
324           DragEvent2D(point.x,point.y,1);
325       }
326       break;
327     case CurAction2d_DynamicZooming :
328       // 
329       myCurrentMode = CurAction2d_Nothing;
330       break;
331     case CurAction2d_WindowZooming :
332       myXmax=point.x;     myYmax=point.y;
333       DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
334       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
335         // Test if the zoom window is greater than a minimale window.
336       {
337         // Do the zoom window between Pmin and Pmax
338         myV2dView->WindowFit(myXmin,myYmin,myXmax,myYmax);  
339       }  
340       myCurrentMode = CurAction2d_Nothing;
341       break;
342     case CurAction2d_DynamicPanning :
343       myCurrentMode = CurAction2d_Nothing;
344       break;
345     case CurAction2d_GlobalPanning :
346       myV2dView->Place(point.x,point.y,myCurZoom); 
347       myCurrentMode = CurAction2d_Nothing;
348       break;
349     default :
350       Standard_Failure::Raise(" incompatible Current Mode ");
351       break;
352     } //switch (myCurrentMode)
353   } //  else // if ( CASCADESHORTCUTKEY )       
354 }
355
356 void OCC_2dView::OnMButtonDown(UINT nFlags, CPoint /*point*/) 
357 {
358   if ( nFlags & CASCADESHORTCUTKEY ) 
359   {
360     // Button MB2 down + CASCADESHORTCUTKEY : panning init  
361     // 
362   }
363 }
364
365 void OCC_2dView::OnMButtonUp(UINT nFlags, CPoint /*point*/) 
366 {
367   if ( nFlags & CASCADESHORTCUTKEY ) 
368   {
369     // Button MB2 up + CASCADESHORTCUTKEY : panning stop 
370   }
371 }
372
373 void OCC_2dView::OnRButtonDown(UINT nFlags, CPoint point) 
374 {
375 #ifdef POPUPONBUTTONDOWN
376    if ( !(nFlags & CASCADESHORTCUTKEY) ) 
377      Popup2D(point.x,point.y);
378 #endif
379 }
380
381 void OCC_2dView::OnRButtonUp(UINT 
382 #ifndef POPUPONBUTTONDOWN
383                              nFlags
384 #endif
385                              , CPoint 
386 #ifndef POPUPONBUTTONDOWN
387                              point
388 #endif
389                              )
390 {
391 #ifndef POPUPONBUTTONDOWN
392    if ( !(nFlags & CASCADESHORTCUTKEY) )
393     Popup2D(point.x,point.y);
394 #endif
395 }
396
397 void OCC_2dView::OnMouseMove(UINT nFlags, CPoint point) 
398 {
399   //   ============================  LEFT BUTTON =======================
400   if ( (nFlags & MK_LBUTTON) &! (nFlags & MK_RBUTTON) ) // Left + Right is specific
401   {
402     if ( nFlags & CASCADESHORTCUTKEY ) 
403     {
404       // move with MB1 and CASCADESHORTCUTKEY : on the dynamic zooming  
405       // Do the zoom in function of mouse's coordinates  
406       myV2dView->Zoom(myXmax,myYmax,point.x,point.y);
407       // save the current mouse coordinate in min 
408       myXmax = point.x; 
409       myYmax = point.y; 
410     }
411     else // if ( CASCADESHORTCUTKEY )
412     {
413       switch (myCurrentMode)
414       {
415       case CurAction2d_Nothing :
416         myXmax = point.x;     myYmax = point.y; 
417         DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
418         DragEvent2D(myXmax,myYmax,0);  
419         DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True);
420         break;
421       case CurAction2d_DynamicZooming :
422         myV2dView->Zoom(myXmax,myYmax,point.x,point.y);
423         // save the current mouse coordinate in min \n";
424         myXmax=point.x;  myYmax=point.y;
425         break;
426       case CurAction2d_WindowZooming :
427         myXmax = point.x; myYmax = point.y;     
428         DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
429         DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
430         break;
431       case CurAction2d_DynamicPanning :
432         myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
433         myXmax = point.x; myYmax = point.y;     
434         break;
435       case CurAction2d_GlobalPanning : // nothing           
436         break;
437       default :
438         Standard_Failure::Raise(" incompatible Current Mode ");
439         break;
440       }//  switch (myCurrentMode)
441     }// if ( nFlags & CASCADESHORTCUTKEY )  else 
442   } else //   if ( nFlags & MK_LBUTTON) 
443     //   ============================  MIDDLE BUTTON =======================
444     if ( nFlags & MK_MBUTTON)
445     {
446       if ( nFlags & CASCADESHORTCUTKEY ) 
447       {
448         myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
449         myXmax = point.x; myYmax = point.y;     
450
451       }
452     } else //  if ( nFlags & MK_MBUTTON)
453       //   ============================  RIGHT BUTTON =======================
454       if ( (nFlags & MK_RBUTTON) &! (nFlags & MK_LBUTTON) ) // Left + Right is specific
455       {
456       }else //if ( nFlags & MK_RBUTTON)
457         if ( (nFlags & MK_RBUTTON) && (nFlags & MK_LBUTTON) )
458         {
459           // in case of Left + Right : same as Middle
460           if ( nFlags & CASCADESHORTCUTKEY ) 
461           {
462             myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
463             myXmax = point.x; myYmax = point.y; 
464           }
465         }else //if ( nFlags & MK_RBUTTON)&& (nFlags & MK_LBUTTON) 
466           //   ============================  NO BUTTON =======================
467         {  // No buttons 
468           myXmax = point.x; myYmax = point.y;   
469           if (nFlags & MULTISELECTIONKEY)
470             MultiMoveEvent2D(point.x,point.y);
471           else
472             MoveEvent2D(point.x,point.y);
473         }
474 }
475
476
477 void OCC_2dView::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/) 
478 {
479   // Take care : This fonction is call before OnInitialUpdate
480   if (!myV2dView.IsNull())
481     myV2dView->MustBeResized(); 
482
483 }
484
485 void OCC_2dView::OnBUTTONFitAll() 
486 {
487   myV2dView->FitAll();
488 }
489
490 void OCC_2dView::OnBUTTONGlobPanning() 
491 {
492   //save the current zoom value
493   myCurZoom = myV2dView->Scale();  
494
495   // Do a Global Zoom 
496   myV2dView->FitAll();
497
498   // Set the mode
499   myCurrentMode = CurAction2d_GlobalPanning;
500 }
501 void OCC_2dView::OnBUTTONPanning() 
502 {
503   myCurrentMode = CurAction2d_DynamicPanning;
504 }
505 void OCC_2dView::OnBUTTONZoomProg() 
506 {
507   myCurrentMode = CurAction2d_DynamicZooming;
508 }
509 void OCC_2dView::OnBUTTONZoomWin() 
510 {
511   myCurrentMode = CurAction2d_WindowZooming;
512 }
513 void OCC_2dView::OnChangeBackground() 
514 {
515   Standard_Real R1, G1, B1;
516   Handle(Aspect_Window) aWindow = myV2dView->Window();
517   Aspect_Background ABack = aWindow->Background();
518   Quantity_Color aColor = ABack.Color();
519   aColor.Values(R1,G1,B1,Quantity_TOC_RGB);
520   COLORREF m_clr ;
521   m_clr = RGB(R1*255,G1*255,B1*255);
522
523   CColorDialog dlgColor(m_clr);
524   if (dlgColor.DoModal() == IDOK)
525   {
526     m_clr = dlgColor.GetColor();
527     R1 = GetRValue(m_clr)/255.;
528     G1 = GetGValue(m_clr)/255.;
529     B1 = GetBValue(m_clr)/255.;
530     aColor.SetValues(R1,G1,B1,Quantity_TOC_RGB);
531     myV2dView->SetBackgroundColor(aColor);
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 = NULL;
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())->GetInteractiveContext()->MoveTo(x,y,myV2dView);
640     ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->Select(theButtonDownX,theButtonDownY,x,y,myV2dView);
641   }
642
643   if (TheState == 1)
644   {
645     ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->Select(true);
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())->GetInteractiveContext()->Select(true);
657 }
658
659 //-----------------------------------------------------------------------------------------
660 //
661 //-----------------------------------------------------------------------------------------
662 void OCC_2dView::MoveEvent2D(const Standard_Integer  x,
663                             const Standard_Integer  y) 
664 {
665   if(myV2dView->Viewer()->Grid()->IsActive())
666   {
667     Quantity_Length aGridX=0,aGridY=0,aGridZ=0;
668     myV2dView->ConvertToGrid(x,y,aGridX,aGridY,aGridZ);
669     //View is not updated automatically in ConvertToGrid
670     myV2dView->Update();
671   }
672   ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->MoveTo(x,y,myV2dView);
673 }
674
675 //-----------------------------------------------------------------------------------------
676 //
677 //-----------------------------------------------------------------------------------------
678 void OCC_2dView::MultiMoveEvent2D(const Standard_Integer  x,
679                                   const Standard_Integer  y) 
680 {
681 // MultiMoveEvent2D means we move the mouse in a multi selection mode
682 ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->MoveTo(x,y,myV2dView);
683 }
684
685 //-----------------------------------------------------------------------------------------
686 //
687 //-----------------------------------------------------------------------------------------
688 void OCC_2dView::MultiDragEvent2D(const Standard_Integer  x        ,
689                                   const Standard_Integer  y        ,
690                                   const Standard_Integer  TheState) 
691 {
692   static Standard_Integer theButtonDownX=0;
693   static Standard_Integer theButtonDownY=0;
694
695   if (TheState == -1)
696   {
697     theButtonDownX=x;
698     theButtonDownY=y;
699   }
700
701   if (TheState == 0)
702   {
703     ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->MoveTo(x,y,myV2dView);
704     ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->ShiftSelect(theButtonDownX,theButtonDownY,x,y,myV2dView);;
705   }
706
707   if (TheState == 1)
708   {
709     ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->ShiftSelect(true);
710   }
711 }
712
713
714 //-----------------------------------------------------------------------------------------
715 //
716 //-----------------------------------------------------------------------------------------
717 void OCC_2dView::MultiInputEvent2D(const Standard_Integer /*x*/,
718                                    const Standard_Integer /*y*/)
719 {
720   ((OCC_2dDoc*)GetDocument())->GetInteractiveContext()->ShiftSelect(true);
721 }
722
723 //-----------------------------------------------------------------------------------------
724 //
725 //-----------------------------------------------------------------------------------------
726 void  OCC_2dView::Popup2D(const Standard_Integer  x,
727                          const Standard_Integer  y ) 
728 {
729   CMenu menu;
730   CMenu* pPopup ;
731
732   // load the 'normal' popup     
733   VERIFY(menu.LoadMenu(IDR_Popup2D));
734   // activate the sub menu '0'
735   pPopup= menu.GetSubMenu(0);
736   ASSERT(pPopup != NULL);
737
738   // display the popup
739   POINT winCoord = { x , y };
740   ClientToScreen ( &winCoord);
741   pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON , winCoord.x, winCoord.y , AfxGetMainWnd());
742 }
743
744 void OCC_2dView::FitAll()
745 {
746   myV2dView->FitAll();
747 }