Скачиваний:
12
Добавлен:
01.05.2014
Размер:
16.86 Кб
Скачать
// lab22View.cpp : implementation of the CLab22View class
//

#include "stdafx.h"
#include "lab22.h"

#include "GraphDlg.h"
#include "ScaleDialog.h"
#include "LineDlg.h"
#include "lab22Doc.h"
#include "lab22View.h"
#include <list>

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

/////////////////////////////////////////////////////////////////////////////
// CLab22View

IMPLEMENT_DYNCREATE(CLab22View, CScrollView)

BEGIN_MESSAGE_MAP(CLab22View, CScrollView)
	//{{AFX_MSG_MAP(CLab22View)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_CHAR()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_FIGURE_DELETE, OnFigureDelete)
	ON_COMMAND(ID_SCALE, OnScale)
	ON_COMMAND(ID_CONTEINER_GRAPHVIEW, OnConteinerGraphview)
	ON_COMMAND(ID_ELEMENTS_ADDLINE, OnElementsAddline)
	ON_UPDATE_COMMAND_UI(ID_ELEMENTS_ADDLINE, OnUpdateElementsAddline)
	ON_COMMAND(ID_FIGURE_DELETELINE, OnFigureDeleteline)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLab22View construction/destruction

CLab22View::CLab22View()
{
	// TODO: add construction code here
	m_FirstPoint = CPoint(0,0);       
    m_SecondPoint = CPoint(0,0);   
    m_MoveLastPoint = CPoint(0,0);
    m_pTempElement = 0;
	m_pSelected = 0;
	StringData="";
	CaretCreated=false;
	doMove=false;

	m_Scale=1;
	SetScrollSizes(MM_TEXT, CSize(0,0));

	doLine=false;

	first=0;
	second=0;

}

CLab22View::~CLab22View()
{
}

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

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CLab22View drawing

void CLab22View::OnDraw(CDC* pDC)
{
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	if (pDoc->graph.getCount()!=0)				//Когда окно перерисовывается, рисуем элементы из контейнера
	{
		GrIterator<Shape*> it(pDoc->graph);
		std::list<int> lways;
		std::list<int>::iterator lwaysIt;
		
		CString sind;

		while(!it.isEnd())
		{
			
			if(pDC->RectVisible(it.currentElement()->GetBoundRect()))
			{   
				sind.Format("%d",it.currentIndex());
				
				pDC->TextOut(it.currentElement()->GetX()-10,it.currentElement()->GetY()-10,sind);

				if (it.currentElement()==first)
				{it.currentElement()->Draw(pDC,m_pSelected,true);}
				else
				{
				it.currentElement()->Draw(pDC,m_pSelected);
				}
			}

			lways=pDoc->graph.getNextWays(it.currentIndex());//Рисуем линии
			lwaysIt=lways.begin();

			while (lwaysIt!=lways.end())
			{
				CRect rect1=it.currentElement()->GetBoundRect();
				CPoint fPoint(it.currentElement()->GetX()+rect1.Width()/2,it.currentElement()->GetY());
				CRect rect2=pDoc->graph.getElement(*lwaysIt)->GetBoundRect();
				CPoint sPoint(pDoc->graph.getElement(*lwaysIt)->GetX()+rect2.Width()/2,pDoc->graph.getElement(*lwaysIt)->GetY());

				printLine(fPoint,sPoint);
				lwaysIt++;
			}
			
			it.goNext();
		}
	}
}

void CLab22View::OnInitialUpdate()
{
	   ResetScrollSizes(); 
	CScrollView::OnInitialUpdate();
}

/////////////////////////////////////////////////////////////////////////////
// CLab22View printing

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CLab22View diagnostics

#ifdef _DEBUG
void CLab22View::AssertValid() const
{
	CScrollView::AssertValid();
}

void CLab22View::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

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

/////////////////////////////////////////////////////////////////////////////
// CLab22View message handlers
void CLab22View::printLine(CPoint First,CPoint Second)
{
	CClientDC aDC(this);
   OnPrepareDC(&aDC);

   aDC.MoveTo(First.x,First.y);
   aDC.LineTo(Second.x,Second.y);	

}


Shape* CLab22View::CreateElement()		//создаем элемент выбранного типа
{  	
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);                 

	switch(pDoc->GetElementType())
	{
		case CIRCLE:
			return new CCircle(m_FirstPoint.x,m_FirstPoint.y,(m_SecondPoint.x-m_FirstPoint.x)/2);
     
		case ELLIPSE:
			return new CEllipse(m_FirstPoint.x,m_FirstPoint.y,(m_SecondPoint.x-m_FirstPoint.x)/2,(m_SecondPoint.y-m_FirstPoint.y)/2);

		case TEXT:
			return new CText(m_FirstPoint.x,m_FirstPoint.y,StringData);

		case ELLIPSETEXT:
			return new CEllipseTxt(m_FirstPoint.x,m_FirstPoint.y,(m_SecondPoint.x-m_FirstPoint.x)/2,(m_SecondPoint.y-m_FirstPoint.y)/2,StringData);

		default:
			AfxMessageBox("Bad Element code", MB_OK);
			AfxAbort();
			return 0;
	}
}

Shape* CLab22View::SelectElement(CPoint aPoint)
{															//Указатель на выделенный элемент
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	if (pDoc->graph.getCount()!=0)
	{
		CClientDC aDC(this);
		OnPrepareDC(&aDC);
		aDC.DPtoLP(&aPoint);

		Shape* element=0;
		CRect aRect(0,0,0,0);

		GrIterator<Shape*> it(pDoc->graph);
	
		while(!it.isEnd())
		{
			element=it.currentElement();

			aRect=it.currentElement()->GetBoundRect();
	
			if(aRect.PtInRect(aPoint))
			{
				SelectedIndex=it.currentIndex();
				return element;
			}

			it.goNext();
		}
	}
	return 0;
}

void CLab22View::ShowCursor(CDC* pDC)		//показать курсор
{   CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);         
	
	if (!CaretCreated)
	{
		TEXTMETRIC textmetric;
		pDC->GetTextMetrics(&textmetric);

		CreateSolidCaret(textmetric.tmAveCharWidth/8,textmetric.tmHeight);

		if (pDoc->GetElementType()!=ELLIPSETEXT)
		{

		SetCaretPos(m_FirstPoint);

		ShowCaret();
		CaretCreated=true;
		}
	}
}


void CLab22View::ResetScrollSizes()
{
   CClientDC aDC(this);
   OnPrepareDC(&aDC);
   
   CLab22Doc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);  

   CSize DocSize = pDoc->GetDocSize();       
   aDC.LPtoDP(&DocSize);                        
   SetScrollSizes(MM_TEXT, DocSize);            
}

void CLab22View::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc); 

	CClientDC aDC(this);
	if (doLine)
	{   CRect aRect,bRect;

		if (first)
		{
			if (second)
			{	
			}
			else
			{second=m_pSelected;  
			 
			 if (second)
			 {
				aRect = first->GetBoundRect();
				bRect = second->GetBoundRect();

				int w1=aRect.Width() / 2;
				CPoint f(first->GetX()+w1,first->GetY());
				w1=bRect.Width() /2;
				CPoint s(second->GetX()+w1,second->GetY());

				printLine(f,s);

				GrIterator<Shape*> it(pDoc->graph);

				int fIndex=0;
				int sIndex=0;

				while(!it.isEnd())
				{

					if (it.currentElement()==first) {fIndex=it.currentIndex();}
					if (it.currentElement()==second) {sIndex=it.currentIndex();}

					it.goNext();
				}

				pDoc->graph.AddLine(fIndex,sIndex);
			 }

			 aRect = first->GetBoundRect();
			 first = 0; 
			 aDC.LPtoDP(aRect);
			 aRect.NormalizeRect();
			 InvalidateRect(aRect, FALSE);
			 second = 0;
			}
		}
		else
		{first=m_pSelected;
		
		 if (first)
		 {
			aRect = first->GetBoundRect();
			aDC.LPtoDP(aRect);
			aRect.NormalizeRect();
			InvalidateRect(aRect, FALSE);
		 }
		}

	}
	else
	{
		m_FirstPoint = point;  
		StringData.Empty();

		SetCapture();
		HideCaret();
		CaretCreated=false;
	}
	CScrollView::OnLButtonDown(nFlags, point);
}

void CLab22View::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc); 

	CClientDC aDC(this);
	
	if (pDoc->is_TextEnter)
	{	
		if (!doMove)
		{
			m_SecondPoint = point;
			ShowCursor(&aDC);
		}
		else
		{
			if(this == GetCapture())
			ReleaseCapture(); 
		}
	}
	else
	{
		if (m_pTempElement)			//Если текст не вводим, то добавляем элемент в контейнер
		{
		pDoc->graph.AddElement(m_pTempElement,pDoc->index);
		pDoc->index++;
		Invalidate();
		}

		if(this == GetCapture())
		ReleaseCapture();       
		
	}

	if (doMove==true){doMove=false;}	//если двигали, то больше не двигаем 


	if(m_pTempElement)
	{  	
		m_pTempElement = 0;				//освобождение элемента
	}
	
	CScrollView::OnLButtonUp(nFlags, point);
}

void CLab22View::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CClientDC aDC(this);
	OnPrepareDC(&aDC);

	if((nFlags & MK_LBUTTON) && (this == GetCapture()))
	{
		if (!doMove)
		{								//Если не двигаем, то перерисовываем
			aDC.DPtoLP(&point);
			m_SecondPoint = point; 
	
			if(m_pTempElement)
			{
				aDC.SetROP2(R2_NOTXORPEN); 

				m_pTempElement->Draw(&aDC);
		 		delete m_pTempElement;      
				m_pTempElement = 0;          
			}

			m_pTempElement = CreateElement();
			m_pTempElement->Draw(&aDC);
		}
		else
		{
			aDC.SetROP2(R2_NOTXORPEN);			//Если двигаем
			m_pSelected->Draw(&aDC,m_pSelected); 
			m_pSelected->Move(point.x-m_MoveLastPoint.x,point.y-m_MoveLastPoint.y);
			m_pSelected->Draw(&aDC,m_pSelected);

			Invalidate();
		}
	}
	else
	{
		CRect aRect;			//Если кнопка мыши не нажата, выделяем красным нужные элементы
		Shape* pCurrentSelection = SelectElement(point);
	
		if ((pCurrentSelection==m_pSelected)&&(m_pSelected)){doMove=true;}

		if(pCurrentSelection!=m_pSelected)
		{	doMove=false;
			if(m_pSelected)
			{
				aRect = m_pSelected->GetBoundRect();
				aDC.LPtoDP(aRect);
				aRect.NormalizeRect();
				InvalidateRect(aRect, FALSE);
			}
			m_pSelected = pCurrentSelection;
			if(m_pSelected) 
			{	
				aRect = m_pSelected->GetBoundRect();
				aDC.LPtoDP(aRect);
				aRect.NormalizeRect();
				InvalidateRect(aRect, FALSE);
			}
		}


	}

	m_MoveLastPoint=point;
	
	CScrollView::OnMouseMove(nFlags, point);
}

void CLab22View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	HideCaret();					//Реакция на нажатие клавиш
	CClientDC aDC(this);

	
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc); 


	if (nChar==VK_SPACE)			//Если нажат пробел
	{
		if(m_pTempElement)			//добавляем в контейнер
			{
				m_pTempElement->Draw(&aDC);
		 		
				pDoc->graph.AddElement(m_pTempElement,pDoc->index);
				pDoc->index++;

				m_pTempElement = 0; 
				Invalidate();
			}

		if(this == GetCapture())
		{	ReleaseCapture(); }
		
		HideCaret();CaretCreated=false;
		StringData.Empty();
	}
	else
	{					//если не пробел, то перерисовываем элемент
		if(this == GetCapture())
		{
			StringData+=nChar; 
	
			if(m_pTempElement)
			{
				m_pTempElement->Draw(&aDC);
		 		delete m_pTempElement;      
				m_pTempElement = 0;          
			}

			m_pTempElement = CreateElement();
			m_pTempElement->Draw(&aDC);
			
			CSize size=aDC.GetTextExtent(StringData);

		if (pDoc->GetElementType()!=ELLIPSETEXT)
		{

			CPoint point(m_FirstPoint.x+size.cx,m_FirstPoint.y);
			SetCaretPos(point);

			ShowCaret();
		}
		}
	}
	
	CScrollView::OnChar(nChar, nRepCnt, nFlags);
}

void CLab22View::OnRButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CMenu aMenu;							//Показать контекстное меню
	aMenu.LoadMenu(IDR_CONTEXT_MENU);    
	ClientToScreen(&point);

	if(m_pSelected)
	 {
      aMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
                                                  point.x, point.y, this);
	 }
	else
	{
      WORD ElementType = GetDocument()->GetElementType();
      aMenu.CheckMenuItem(ID_ELEMENTS_CIRCLE,
                (CIRCLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      aMenu.CheckMenuItem(ID_ELEMENTS_ELLIPSE,
           (ELLIPSE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
      aMenu.CheckMenuItem(ID_ELEMENTS_TEXT,
           (TEXT==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
	  aMenu.CheckMenuItem(ID_ELEMENTS_ELLIPSEWITHTEXT,
           (ELLIPSETEXT==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);


      aMenu.GetSubMenu(1)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	}
	
}

void CLab22View::OnFigureDelete() 
{
	// TODO: Add your command handler code here
	CLab22Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);					//Удаление элемента из контейнера
	
		
	GrIterator<Shape*> it(pDoc->graph);
	bool deleted=false;

		while((!it.isEnd())&&(!deleted))
		{
			if (it.currentElement()==m_pSelected)
			{pDoc->graph.delElem(it.currentIndex());
			 deleted=true;
			}

			it.goNext();
		}

    Invalidate();
}

void CLab22View::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	// TODO: Add your specialized code here and/or call the base class
   if(pHint)						//для перерисовки ползунков
   {
      CClientDC aDC(this);            
      OnPrepareDC(&aDC);              
     
      CRect aRect=((Shape*)pHint)->GetBoundRect();
      aDC.LPtoDP(aRect);
      aRect.NormalizeRect();
      InvalidateRect(aRect);          
   }
   else
      InvalidateRect(0);	
	
}

void CLab22View::OnScale() 
{
	// TODO: Add your command handler code here
	CLab22Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);				//Вызов диалога масштаба

	ScaleDialog dlg;
	dlg.m_scale=m_Scale;
	if (dlg.DoModal()==IDOK)
	{
		m_Scale = dlg.m_scale;

		ResetScrollSizes();        // Adjust scrolling to the new scale
		InvalidateRect(0);         // Invalidate the whole window
	}		
}

void CLab22View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
   CScrollView::OnPrepareDC(pDC, pInfo);
/*   CLab22Doc* 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
   long xExtent = (long)DocSize.cx*m_Scale*xLogPixels/100L;
   long yExtent = (long)DocSize.cy*m_Scale*yLogPixels/100L;

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


void CLab22View::OnConteinerGraphview() 
{
	// TODO: Add your command handler code here
	CLab22Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);					//Вызов диалогового окна для контейнера

	GraphDlg dlg;

	if (pDoc->graph.getCount()!=0)
	{
	dlg.graph=pDoc->graph;
	GrIterator<Shape*> it(pDoc->graph);

	dlg.m_x=it.currentElement()->GetX();
	dlg.m_y=it.currentElement()->GetY();

	dlg.m_name=it.currentElement()->getName();
	dlg.m_cnt=pDoc->graph.getCount();
	dlg.m_nom=1;

	}

	if (dlg.DoModal()==IDOK)
	{
		pDoc->graph=dlg.graph;
		InvalidateRect(0);
	}		
}

void CLab22View::OnElementsAddline() 
{
	// TODO: Add your command handler code here
	if (doLine==true) 
	{doLine=false;    
				first = 0;        
				second = 0; 
	}
	else {doLine=true;}
}

void CLab22View::OnUpdateElementsAddline(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(doLine);
}

void CLab22View::OnFigureDeleteline() 
{
	// TODO: Add your command handler code here
	CLab22Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);					//Вызов диалогового окна для контейнера

	LineDlg dlg;

	if (pDoc->graph.getCount()!=0)
	{
		dlg.graph=pDoc->graph;

		dlg.curIndex=SelectedIndex;
	}


	if (dlg.DoModal()==IDOK)
	{
		pDoc->graph=dlg.graph;
		InvalidateRect(0);
	}	
}
Соседние файлы в папке lab22