Скачиваний:
9
Добавлен:
01.05.2014
Размер:
28.2 Кб
Скачать
// SketcherView.cpp : implementation of the CSketcherView class
//

#include "stdafx.h"
#include "Sketcher.h"
#include "OurConstants.h"

#include "SketcherDoc.h"
#include "SketcherView.h"
#include "ScaleDialog.h"
#include "ChildFrm.h"

#include "Figure.h"
#include "Triangle.h"
#include "Pentagon.h"
#include "Text.h"
#include "TextInPentagon.h"

#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSketcherView

IMPLEMENT_DYNCREATE(CSketcherView, CScrollView)

BEGIN_MESSAGE_MAP(CSketcherView, CScrollView)
	//{{AFX_MSG_MAP(CSketcherView)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_MOVE, OnMove)
	ON_COMMAND(ID_SENDTOBACK, OnSendtoback)
	ON_COMMAND(ID_DELETE, OnDelete)
	ON_COMMAND(ID_MODE_LINK, OnModeLink)
	ON_UPDATE_COMMAND_UI(ID_MODE_LINK, OnUpdateModeLink)
	ON_COMMAND(ID_MODE_EDIT, OnModeEdit)
	ON_UPDATE_COMMAND_UI(ID_MODE_EDIT, OnUpdateModeEdit)
	ON_COMMAND(ID_MODE_TOUR, OnModeTour)
	ON_UPDATE_COMMAND_UI(ID_MODE_TOUR, OnUpdateModeTour)
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_ELEMENT_COLOR_BLACK, OnElementColorBlack)
	ON_COMMAND(ID_ELEMENT_COLOR_BLUE, OnElementColorBlue)
	ON_COMMAND(ID_ELEMENT_COLOR_GREEN, OnElementColorGreen)
	ON_COMMAND(ID_ELEMENT_COLOR_RED, OnElementColorRed)
	ON_COMMAND(ID_MODE_UNLINK, OnModeUnlink)
	ON_UPDATE_COMMAND_UI(ID_MODE_UNLINK, OnUpdateModeUnlink)
	ON_COMMAND(ID_SCALE, OnScale)
	ON_COMMAND(ID_MODE_ITERATOR, OnModeIterator)
	ON_UPDATE_COMMAND_UI(ID_MODE_ITERATOR, OnUpdateModeIterator)
	ON_COMMAND(ID_ELEMENT_FIND, OnElementFind)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSketcherView construction/destruction

CSketcherView::CSketcherView()
{
    m_FirstPoint = CPoint(0,0);         // Set 1st recorded point to 0,0
    m_SecondPoint = CPoint(0,0);        // Set 2nd recorded point to 0,0
    m_pTempElement = NULL;              // Set temporary element pointer to 0
    m_pSelected = NULL;                 // No element selected initially
    m_MoveMode = FALSE;                 // Set move mode off
    m_CursorPos = CPoint(0,0);          // Initialize as zero
    m_FirstPos = CPoint(0,0);           // Initialize as zer0o
	vertex1 = NULL;
	vertex2 = NULL;
	m_pTourSel = NULL;
	m_pTourSelNext = NULL;
	m_Scale = 1;
	mode = EDIT;
	SetScrollSizes(MM_TEXT, CSize(0,0));  // Set arbitrary scrollers
	m_pNodeFound = NULL;
}	

CSketcherView::~CSketcherView()
{
}

BOOL CSketcherView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CSketcherView drawing

void CSketcherView::OnDraw(CDC* pDC)
{
   CSketcherDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);

   Iterator<Figure*>*i = (GetDocument()->elements).iterator();
   Figure*pElement = NULL;

   for(i->first();!i->endNext();i->next()) {

	   pElement = i->current();

	   COLORREF color = pElement->getColor();
		int pen = DEFAULT_PEN;

		if (pElement == m_pSelected) {
			if (mode == LINK || mode == UNLINK) {
			
				if(!vertex1) {
					color = VERT1_SELECT_COLOR;
				} else {
					color = VERT2_SELECT_COLOR;
				}
					
			} else {
				color = SELECT_COLOR;
			}
		}

		if (pElement == vertex1) {
			color = VERT1_SELECT_COLOR;
		}

		if (pElement == m_pTourSel || pElement == m_pNodeFound) {
//			color = TOUR_SEL_COLOR;
			pen = TOUR_PEN;
		}
				
		Graph<Figure*>* cont = &(GetDocument()->elements);
		int size=0;
		Figure** arr = cont->getNodesFrom(cont->getNodeByVal(pElement),&size);


		for (int i=0;i<size;i++) {

		CPen aPen;
		COLORREF aColor = LINK_COLOR;
		int penWidth = DEFAULT_PEN;


		if (pElement == m_pTourSel && arr[i] == m_pTourSelNext) {
			aColor = TOUR_SEL_LINK_COLOR;
			penWidth = TOUR_PEN;
		}

		aPen.CreatePen(PS_DOT,penWidth,aColor);
		CPen*oldPen = pDC->SelectObject(&aPen);

			CRect aRec1(pElement->getBoundRect());
			CPoint lp1(aRec1.TopLeft());
			lp1.x+=aRec1.Width()/2;
			CRect aRec2(arr[i]->getBoundRect());
			CPoint lp2(aRec2.BottomRight());
			lp2.x-=aRec2.Width()/2;
			
			pDC->MoveTo(lp1);
			pDC->LineTo(lp2);
			
			pDC->Ellipse(
				CRect(
					CPoint((int)lp1.x-4,(int)lp1.y-4),
					CPoint((int)lp1.x+4,(int)lp1.y+4)
					)
				);

			pDC->Ellipse(
				CRect(
					CPoint((int)lp2.x-10,(int)lp2.y-10),
					CPoint((int)lp2.x+10,(int)lp2.y+10)
					)
				);

		pDC->SelectObject(oldPen);
		
		}

		delete[] arr;

		pElement->draw(pDC,color,pen);

		CRect r = pElement->getBoundRect();
		CPoint p = r.TopLeft();
		char num[32];
		itoa((GetDocument()->elements).getNodeByVal(pElement),num,10);
		pDC->SetTextColor(NODE_NUM_COLOR);
		pDC->TextOut(p.x,p.y,num);
	}

   delete i; // free memory

   if(m_pTempElement) {
	m_pTempElement->draw(pDC,BLACK,DEFAULT_PEN);
   }

     // Build the message string
     CString StatusMsg("View Scale:");
     StatusMsg += (char)('0' + GetDocument()->m_view_scale);
      // Write the string to the status bar
	       // Get the frame window for this view
     CChildFrame* viewFrame = (CChildFrame*)GetParentFrame();
     viewFrame->m_StatusBar.GetStatusBarCtrl().SetText(StatusMsg, 0, 0);

}

/////////////////////////////////////////////////////////////////////////////
// CSketcherView printing

BOOL CSketcherView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CSketcherView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CSketcherView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CSketcherView diagnostics

#ifdef _DEBUG
void CSketcherView::AssertValid() const
{
	CView::AssertValid();
}

void CSketcherView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CSketcherDoc* CSketcherView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSketcherDoc)));
	return (CSketcherDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CSketcherView message handlers

void CSketcherView::OnLButtonDown(UINT nFlags, CPoint point) 
{
   CClientDC aDC(this);                // Create a device context
   OnPrepareDC(&aDC);                  // Get origin adjusted
   aDC.DPtoLP(&point);                 // convert point to Logical

	if (mode == ITERATOR) return; // nothing to draw.

   if(m_MoveMode)
   {
      // In moving mode, so drop the element
      m_MoveMode = FALSE;                 // Kill move mode
      m_pSelected = NULL;                 // De-select the element
      GetDocument()->UpdateAllViews(0);   // Redraw all the views
   }
   else
   {
      m_FirstPoint = point;               // Record the cursor position
      SetCapture();                       // Capture subsequent mouse messages
   }
}

void CSketcherView::OnLButtonUp(UINT nFlags, CPoint point) 
{
   if(this == GetCapture())
      ReleaseCapture();        // Stop capturing mouse messages

   if(mode == ITERATOR) return;

   if(mode == LINK || mode == UNLINK) { // Some element could be selected.
	   Figure* pCurrentSelection = SelectElement(point);
	   if (pCurrentSelection) {
		   if (!vertex1) {
			   vertex1 = pCurrentSelection;
		   } else { // vertex1 already selected
			   vertex2 = pCurrentSelection;
			   
			   Graph<Figure*> *f = &(GetDocument()->elements);
			   try {
				   if (mode == LINK) {
					f->link(f->getNodeByVal(vertex1),f->getNodeByVal(vertex2));
				   } else {
					f->unlink(f->getNodeByVal(vertex2),f->getNodeByVal(vertex1));
				   }
			   } catch (GraphStructureException ex) {
					AfxMessageBox(ex.getCauseMsg(),MB_OK);
			   }
			   vertex1 = NULL;
			   vertex2 = NULL;
		   }
	   }

	   RedrawWindow();
	   return;
   }

   if (mode == TOUR) { // Select element to 
       Figure* pCurrentSelection = SelectElement(point);
	   if (pCurrentSelection) {
			m_pTourSel = pCurrentSelection;

			while (!vertexes.empty()) {
				vertexes.pop();
			} // clear stack

			m_pTourSelNext = NULL;
			selectRLink();
	   }

	   RedrawWindow();
	   return;
   }

   // If there is an element, add it to the document
   if(m_pTempElement)
   {  
//      GetDocument()->AddElement(m_pTempElement);
//      GetDocument()->UpdateAllViews(0,0,m_pTempElement);  // Tell all the views
		
	   nodeDlg.m_Number++;
	   if(nodeDlg.DoModal() == IDOK) {
		   try {
			Graph<Figure*>* g = &(GetDocument()->elements);
			g->add(m_pTempElement,nodeDlg.m_Number);
		   } catch (GraphStructureException ex) {
				AfxMessageBox(ex.getCauseMsg(),MB_OK);
		   }
		    
	   }
	   
	    
		m_pTempElement = NULL;        // Reset the element pointer
   }
   RedrawWindow();
}

void CSketcherView::OnMouseMove(UINT nFlags, CPoint point) 
{
   // Define a Device Context object for the view
   CClientDC aDC(this);
   OnPrepareDC(&aDC);            // Get origin adjusted

   // If we are in move mode, move the selected element and return
   if(m_MoveMode)
   {
      aDC.DPtoLP(&point);        // Convert to logical coordinatess
      MoveElement(aDC, point);   // Move the element
      return;
   }

   if (mode == LINK || mode == TOUR || mode == UNLINK) { // JUST DO HIGHTLIGTING
	  
	  CRect aRect;
      Figure* pCurrentSelection = SelectElement(point);

      if(pCurrentSelection!=m_pSelected)
      {
         if(m_pSelected)             // Old elemented selected?
         {                           // Yes, so draw it unselected
            aRect = m_pSelected->getBoundRect(); // Get bounding rectangle
            aDC.LPtoDP(aRect);                   // Conv to device coords
            aRect.NormalizeRect();               // Normalize
            InvalidateRect(aRect, FALSE);        // Invalidate area
         }
         m_pSelected = pCurrentSelection;        // Save elem under cursor
         if(m_pSelected)                         // Is there one?
         {                                       // Yes, so get it redrawn
            aRect = m_pSelected->getBoundRect(); // Get bounding rectangle
            aDC.LPtoDP(aRect);                   // Conv to device coords
            aRect.NormalizeRect();               // Normalize
            InvalidateRect(aRect, FALSE);        // Invalidate area
         }
      }
	  return;
   }
   
   if((nFlags & MK_LBUTTON) && (this == GetCapture()))
   {
      aDC.DPtoLP(&point);        // convert point to Logical
      m_SecondPoint = point;     // Save the current cursor position

      if(m_pTempElement)
      {
         aDC.SetROP2(R2_NOTXORPEN);      // Set drawing mode

         // Redraw the old element so it disappears from the view
		 
         m_pTempElement->draw(&aDC,m_pTempElement->getColor(),DEFAULT_PEN);
         delete m_pTempElement;        // Delete the old element
         m_pTempElement = NULL;           // Reset the pointer to 0
      }

      // Create a temporary element of the type and color that
      // is recorded in the document object, and draw it
      m_pTempElement = CreateElement();  // Create a new element
      m_pTempElement->draw(&aDC, m_pTempElement->getColor(),DEFAULT_PEN);        // Draw the element
   }
   else        // We are not drawing an element...
   {           // ...so do highlighting
      CRect aRect;
      Figure* pCurrentSelection = SelectElement(point);

      if(pCurrentSelection!=m_pSelected)
      {
         if(m_pSelected)						 // Old elemented selected?
         {										 // Yes, so draw it unselected
            aRect = m_pSelected->getBoundRect(); // Get bounding rectangle
            aDC.LPtoDP(aRect);                   // Conv to device coords
            aRect.NormalizeRect();               // Normalize
            InvalidateRect(aRect, FALSE);        // Invalidate area
         }
         m_pSelected = pCurrentSelection;        // Save elem under cursor
         if(m_pSelected)                         // Is there one?
         {                                       // Yes, so get it redrawn
            aRect = m_pSelected->getBoundRect(); // Get bounding rectangle
            aDC.LPtoDP(aRect);                   // Conv to device coords
            aRect.NormalizeRect();               // Normalize
            InvalidateRect(aRect, FALSE);        // Invalidate area
         }
      }
   }
}

Figure* CSketcherView::CreateElement()
{
	// Get a pointer to the document for this view
	CSketcherDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);                  // Verify the pointer is good

	int x1 = m_FirstPoint.x;
	int y1 = m_FirstPoint.y;
			
	int x2 = m_SecondPoint.x;
	int y2 = m_SecondPoint.y;

	double size = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
	
	// Now select the element using the type stored in the document
	switch(pDoc->GetElementType())
	{
	
		case TRIANGLE:

			return new Triangle(m_FirstPoint,(int)size,pDoc->GetElementColor());
		
		case PENTAGON:
			
			return new Pentagon(m_FirstPoint,(int)size,pDoc->GetElementColor());

		case TEXT:
			
			return new Text(pDoc->ptext,m_FirstPoint,pDoc->GetElementColor());

		case TEXT_IN_PENTAGON:
			return new TextInPentagon(m_FirstPoint,(int)size,pDoc->ptext,pDoc->GetElementColor());

		default:
			//	Something's gone wrong
			AfxMessageBox("Bad Element code", MB_OK);
			AfxAbort();
			return NULL;
	}
}

// Find the element at the cursor
Figure* CSketcherView::SelectElement(CPoint aPoint)
{
   // Convert parameter aPoint to logical coordinates
   CClientDC aDC(this);
   OnPrepareDC(&aDC);
   aDC.DPtoLP(&aPoint);

   CSketcherDoc* pDoc=GetDocument();      // Get a pointer to the document
   Figure* pElement = 0;                // Store an element pointer
   CRect aRect(0,0,0,0);                  // Store a rectangle

   Iterator<Figure*>* i = (pDoc->elements).iterator();
   Figure*f = NULL;

   for(i->first();!i->endNext();i->next())
   {
		f = i->current();
		aRect = f->getBoundRect();
		if (aRect.PtInRect(aPoint))	return f;
   }

	return NULL;
//   POSITION aPos = pDoc->GetListTailPosition();  // Get last element posn

//   while(aPos)                            // Iterate through the list
//   {
//      pElement = pDoc->GetPrev(aPos);
//      aRect = pElement->GetBoundRect();
      // Select the first element that appears under the cursor
//      if(aRect.PtInRect(aPoint))
//         return pElement;
//   }
}

void CSketcherView::MoveElement(CClientDC& aDC, CPoint& point)
{
   //////////////////////////
   	CSize Distance = point - m_CursorPos;   // Get move distance
	m_CursorPos = point;          // Set current point as 1st for next time

	// If there is an element, selected, move it
	if(m_pSelected)	{

		CRect     aRect = m_pSelected->getBoundRect(); // Get bounding rectangle
		aDC.LPtoDP(aRect);                   // Conv to device coords
		aRect.NormalizeRect();               // Normalize
		InvalidateRect(aRect);        // Invalidate area

		aDC.SetROP2(R2_NOTXORPEN);
		m_pSelected->draw(&aDC, m_pSelected->getColor(),DEFAULT_PEN); // Draw the element to erase it
		m_pSelected->move(Distance);         // Now move the element
		m_pSelected->draw(&aDC, m_pSelected->getColor(),DEFAULT_PEN); // Draw the moved element
	}
   ///////////////////////////
}

void CSketcherView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	if(m_MoveMode)
	{
	    // In moving mode, so drop element back in original position
		CClientDC aDC(this);
		OnPrepareDC(&aDC);                  // Get origin adjusted
		MoveElement(aDC, m_FirstPos);       // Move element to orig position
		m_MoveMode = FALSE;                 // Kill move mode
		m_pSelected = NULL;                 // De-select element
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
	
		return;                             // We are done
	}
}


void CSketcherView::OnRButtonUp(UINT nFlags, CPoint point) 
{
	if (mode == LINK || mode == TOUR || mode == UNLINK || mode == ITERATOR) {
		return; // menu is not needed
	}
// Create the cursor menu
   CMenu aMenu;
   aMenu.LoadMenu(IDR_CURSOR_MENU);    // Load the cursor menu
   ClientToScreen(&point);             // Convert to screen coordinates

   // Display the pop-up at the cursor position
   if(m_pSelected)
   {
      aMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
                                                  point.x, point.y, this);
   }
   else
   {
      // Check color menu items
      COLORREF Color = GetDocument()->GetElementColor();
      aMenu.CheckMenuItem(ID_COLOR_BLACK,
                     (BLACK==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      aMenu.CheckMenuItem(ID_COLOR_RED,
                       (RED==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      aMenu.CheckMenuItem(ID_COLOR_GREEN,
                       (GREEN==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      aMenu.CheckMenuItem(ID_COLOR_BLUE,
                       (BLUE==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      // Check element menu items
      WORD ElementType = GetDocument()->GetElementType();
/*      aMenu.CheckMenuItem(ID_ELEMENT_LINE,
                (LINE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      aMenu.CheckMenuItem(ID_ELEMENT_RECTANGLE,
           (RECTANGLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
*/
      // Display the context pop-up
      aMenu.GetSubMenu(1)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
   }
   
}

void CSketcherView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
   // Invalidate the area corresponding to the element pointed to
   // if there is one, otherwise invalidate the whole client area
   if(pHint)
   {
      CClientDC aDC(this);            // Create a device context
      OnPrepareDC(&aDC);              // Get origin adjusted

      // Get the enclosing rectangle and convert to client coordinates
      CRect aRect=((Figure*)pHint)->getBoundRect();
      aDC.LPtoDP(aRect);
      aRect.NormalizeRect();
      InvalidateRect(aRect);          // Get the area redrawn
   }
   else
      InvalidateRect(0);
}

void CSketcherView::OnInitialUpdate() 
{
   ResetScrollSizes();               // Set up the scrollbars
   CScrollView::OnInitialUpdate();
}

void CSketcherView::OnMove() 
{
   CClientDC aDC(this);
   OnPrepareDC(&aDC);              // Set up the device context
   GetCursorPos(&m_CursorPos);     // Get cursor position in screen coords
   ScreenToClient(&m_CursorPos);   // Convert to client coords
   aDC.DPtoLP(&m_CursorPos);       // Convert to logical
   m_FirstPos = m_CursorPos;       // Remember first position
   m_MoveMode = TRUE;              // Start move mode
	
}

void CSketcherView::selectLLink()
{
	if ( m_pTourSel == NULL ) return;

	Graph<Figure*>*g = &(GetDocument()->elements);
	int size=0;
	Figure** vertexes = g->getNodesFrom(g->getNodeByVal(m_pTourSel),&size);
	if (m_pTourSelNext == NULL) { // select first element then
		if (size != 0) {
			m_pTourSelNext = vertexes[0];
		} else {
			m_pTourSelNext = NULL;
		}
	} else {
		
		for (int i = 0; i < size; i++) {
			if (m_pTourSelNext == vertexes[i]) {
				if (i-1 >= 0) {
					m_pTourSelNext = vertexes[i-1];
				} else {
					m_pTourSelNext = vertexes[size-1]; // select first element if we are at last.
				}
				break; // break loop.
			}
		}

	}

	delete[] vertexes;
}

void CSketcherView::selectRLink()
{	
	if ( m_pTourSel == NULL ) return;

	Graph<Figure*>*g = &(GetDocument()->elements);
	int size=0;
	Figure** vertexes = g->getNodesFrom(g->getNodeByVal(m_pTourSel),&size);
	if (m_pTourSelNext == NULL) { // select first element then
		if (size != 0) {
			m_pTourSelNext = vertexes[0];
		} else {
			m_pTourSelNext = NULL;
		}
	} else {
		
		for (int i = 0; i < size; i++) {
			if (m_pTourSelNext == vertexes[i]) {
				if (i+1 < size) {
					m_pTourSelNext = vertexes[i+1];
				} else {
					m_pTourSelNext = vertexes[0]; // select first element if we are at last.
				}
				break; // break loop.
			}
		}

	}

	delete[] vertexes;

}


void CSketcherView::OnSendtoback() 
{
//   GetDocument()->SendToBack(m_pSelected);  // Move element in list	
}

void CSketcherView::OnDelete() 
{
   if(m_pSelected)
   {
      CSketcherDoc* pDoc = GetDocument();  // Get the document pointer
      pDoc->DeleteElement(m_pSelected);    // Delete the element
      pDoc->UpdateAllViews(0);             // Redraw all the views
      m_pSelected = 0;                     // Reset selected element ptr
   }	
}


void CSketcherView::OnModeLink() 
{
	// TODO: Add your command handler code here
	mode = LINK;
	resetSelections();
}

void CSketcherView::OnUpdateModeLink(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(mode == LINK);
}

void CSketcherView::OnModeEdit() 
{
	// TODO: Add your command handler code here
	mode = EDIT;
	resetSelections();
}

void CSketcherView::OnUpdateModeEdit(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(mode == EDIT);
}

void CSketcherView::OnModeTour() 
{
	// TODO: Add your command handler code here
//	m_TourMode = TRUE;
	m_MoveMode = FALSE;
//	m_SelectVertexMode = FALSE;
	mode = TOUR;
	resetSelections();

}

void CSketcherView::OnUpdateModeTour(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(mode == TOUR);
}

void CSketcherView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	if (mode == TOUR) {
		if (nChar == VK_RIGHT) {
			selectRLink();
		} else if (nChar == VK_LEFT) {
			selectLLink();
		} else if (nChar == VK_DOWN) {
			if (m_pTourSelNext == NULL) return; // LEAF
			
			// else
			vertexes.push(m_pTourSel);
			m_pTourSel = m_pTourSelNext;
			m_pTourSelNext = NULL;
			selectRLink();
		} else if (nChar == VK_UP) {
			if(!vertexes.empty()) {
				m_pTourSelNext = m_pTourSel;
				m_pTourSel= vertexes.top();
				vertexes.pop();
			}
		}
	} else if (mode == ITERATOR) {
		
		Graph<Figure*>*g = &(GetDocument()->elements);
		
		Graph<Figure*>::GraphIterator* gi = g->pInnerIterator;

		if (nChar == VK_RIGHT) {

			if (g->pInnerIterator->hasNext()) {
				g->pInnerIterator->next();
				m_pTourSel = g->pInnerIterator->current();
			} else {
				AfxMessageBox("Has no next element.",MB_OK);
			}
			

		} else if (nChar == VK_LEFT) {
			
			if (g->pInnerIterator->hasPrevious()) {
				g->pInnerIterator->previous();
				m_pTourSel = g->pInnerIterator->current();
			} else {
				AfxMessageBox("Has no previous element.",MB_OK);
			}
		} else if (nChar == VK_UP) {

			if (gi->last()) m_pTourSel = gi->current();

		} else if (nChar == VK_DOWN) {

			if (gi->first()) m_pTourSel = gi->current();

		}
	}
	RedrawWindow();
//	CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CSketcherView::resetSelections()
{
	vertex1 = NULL;
	vertex2 = NULL;
	m_pTourSel = NULL;
	m_pTourSelNext = NULL;
	m_pNodeFound = NULL;

	while (!vertexes.empty()) {
		vertexes.pop();
	} // clear stack
	RedrawWindow();
}

void CSketcherView::OnElementColorBlack() 
{
	// TODO: Add your command handler code here
	if(m_pSelected) {
		m_pSelected->setColor(BLACK);
	}
}

void CSketcherView::OnElementColorBlue() 
{
	// TODO: Add your command handler code here
	if(m_pSelected) {
		m_pSelected->setColor(BLUE);
	}
}

void CSketcherView::OnElementColorGreen() 
{
	// TODO: Add your command handler code here
	if(m_pSelected) {
		m_pSelected->setColor(GREEN);
	}
}

void CSketcherView::OnElementColorRed() 
{
	// TODO: Add your command handler code here
	if(m_pSelected) {
		m_pSelected->setColor(RED);
	}	
}

void CSketcherView::OnModeUnlink() 
{
	// TODO: Add your command handler code here
	m_MoveMode = FALSE;
	mode = UNLINK;
	resetSelections();
}

void CSketcherView::OnUpdateModeUnlink(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(mode==UNLINK);
}

void CSketcherView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
	
   CScrollView::OnPrepareDC(pDC, pInfo);
   CSketcherDoc* pDoc = GetDocument();
   pDC->SetMapMode(MM_ANISOTROPIC);           // Set the map mode
   CSize DocSize = pDoc->GetDocSize();        // Get the document size

   // y extent must be negative because we want MM_LOENGLISH
   DocSize.cy = -DocSize.cy;                  // Change sign of y
   pDC->SetWindowExt(DocSize);                // Now set the window extent

   // Get the number of pixels per inch in x and y
   int xLogPixels = pDC->GetDeviceCaps(LOGPIXELSX);
   int yLogPixels = pDC->GetDeviceCaps(LOGPIXELSY);

   // Calculate the viewport extent in x and y
   int scale = GetDocument()->m_view_scale;

   long xExtent = (long)DocSize.cx*scale*xLogPixels/100L;
   long yExtent = (long)DocSize.cy*scale*yLogPixels/100L;

   pDC->SetViewportExt((int)xExtent, (int)-yExtent); // Set viewport extent
}

void CSketcherView::ResetScrollSizes()
{
   CClientDC aDC(this);
   OnPrepareDC(&aDC);                            // Set up the device context
   CSize DocSize = GetDocument()->GetDocSize();  // Get the document size
   aDC.LPtoDP(&DocSize);                         // Get the size in pixels
   SetScrollSizes(MM_TEXT, DocSize);             // Set up the scrollbars
}

void CSketcherView::OnScale() 
{
   CScaleDialog aDlg;            // Create a dialog object
   aDlg.m_Scale = m_Scale;       // Pass the view scale to the dialog
   if(aDlg.DoModal() == IDOK)
   {
      m_Scale = aDlg.m_Scale;    // Get the new scale
	  GetDocument()->m_view_scale = m_Scale; // write to document

      // Get the frame window for this view
      CChildFrame* viewFrame = (CChildFrame*)GetParentFrame();

      // Build the message string
      CString StatusMsg("View Scale:");
      StatusMsg += (char)('0' + m_Scale);

      // Write the string to the status bar
      viewFrame->m_StatusBar.GetStatusBarCtrl().SetText(StatusMsg, 0, 0);
      ResetScrollSizes();        // Adjust scrolling to the new scale
      InvalidateRect(0);         // Invalidate the whole window
   }	
}

void CSketcherView::OnModeIterator() 
{
	// TODO: Add your command handler code here
	mode = ITERATOR;
	resetSelections();
	
	Graph<Figure*>*g = &(GetDocument()->elements);
	if (g->pInnerIterator->first()) {
			m_pTourSel = g->pInnerIterator->current();
	}
	RedrawWindow();
}

void CSketcherView::OnUpdateModeIterator(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(mode == ITERATOR);
}

void CSketcherView::OnElementFind() 
{
	// TODO: Add your command handler code here
	if (nodeDlg.DoModal() == IDOK) {
		Graph<Figure*>*f = &(GetDocument()->elements);
		try {
			m_pNodeFound = f->getValByNode(nodeDlg.m_Number);
		} catch (GraphStructureException ex) {
			AfxMessageBox(ex.getCauseMsg(),MB_OK);
			m_pNodeFound = NULL;
		}
	} else {
		m_pNodeFound = NULL;
	}
	RedrawWindow();
}
Соседние файлы в папке Лабораторная работа 23