// drawerView.cpp : implementation of the CDrawerView class // #include "stdafx.h" #include "drawer.h" #include "drawerDoc.h" #include "drawerView.h" #include "PolyLine.h" #include "MainFrm.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDrawerView IMPLEMENT_DYNCREATE(CDrawerView, CScrollView) BEGIN_MESSAGE_MAP(CDrawerView, CScrollView) //{{AFX_MSG_MAP(CDrawerView) ON_COMMAND(ID_POLYLINE_CREATE, OnPolylineCreate) ON_UPDATE_COMMAND_UI(ID_POLYLINE_CREATE, OnUpdatePolylineCreate) ON_COMMAND(ID_POLYLINE_REMOVE, OnPolylineRemove) ON_UPDATE_COMMAND_UI(ID_POLYLINE_REMOVE, OnUpdatePolylineRemove) ON_COMMAND(ID_POLYLINE_SELECT, OnPolylineSelect) ON_UPDATE_COMMAND_UI(ID_POLYLINE_SELECT, OnUpdatePolylineSelect) ON_COMMAND(ID_FILE_NEW, OnFileNew) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_FILE_SAVE, OnFileSave) ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) ON_WM_LBUTTONDOWN() ON_WM_KEYDOWN() ON_WM_RBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_CONTEXTMENU() ON_COMMAND(ID_POLYLINE_POINT_REMOVE, OnPolylinePointRemove) //}}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() ///////////////////////////////////////////////////////////////////////////// // CDrawerView construction/destruction CDrawerView::CDrawerView() : clickState(clickCreate), m_sizeEllipse(10,10), startNewPolyLine(true), newPolyLine(), isMovingPoint(false), draggingPolyLine (NULL), draggingPoint(-1) { } CDrawerView::~CDrawerView() { clearDrawList(); } BOOL CDrawerView::PreCreateWindow(CREATESTRUCT& cs) { return CScrollView::PreCreateWindow(cs); } void CDrawerView::clearDrawList() { while (!drawList.IsEmpty()) { delete drawList.RemoveHead(); } } ///////////////////////////////////////////////////////////////////////////// // CDrawerView drawing void CDrawerView::OnDraw(CDC* pDC) { CDrawerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CPen newPen(PS_SOLID, 2, RGB(0,0,0)); CPen* pOldPen = pDC->SelectObject(&newPen); POSITION curPos = drawList.GetHeadPosition(); while (curPos != NULL) { PolyLine* nextPoly = drawList.GetNext(curPos); Point curPoint; if (clickState == clickSelect || clickState == clickRemove) { pDC->SelectStockObject(GRAY_BRUSH); for (int i=0; i< nextPoly->getNumPoints(); i++) { curPoint = nextPoly->getPoint(i); CPoint m_pointTopLeft(curPoint.getX()-m_sizeEllipse.cx/2, curPoint.getY()-m_sizeEllipse.cy/2); CRect rectNew(m_pointTopLeft, m_sizeEllipse); pDC->Ellipse(rectNew); } pDC->SelectObject(&newPen); } for (int i=0; i < nextPoly->getNumPoints(); i++) { curPoint = nextPoly->getPoint(i); if (i==0) pDC->MoveTo(curPoint.getX(), curPoint.getY()); else pDC->LineTo(curPoint.getX(), curPoint.getY()); } } // Draw out the current polyline, if necessary if (clickState==clickCreate && newPolyLine.getNumPoints() > 1) { for (int i=0; i< newPolyLine.getNumPoints(); i++) { Point curPoint = newPolyLine.getPoint(i); if (i==0) pDC->MoveTo(curPoint.getX(), curPoint.getY()); else pDC->LineTo(curPoint.getX(), curPoint.getY()); } } pDC->SelectObject(pOldPen); } void CDrawerView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal(800, 1050); CSize sizePage(sizeTotal.cx / 2, sizeTotal.cy / 2); CSize sizeLine(sizeTotal.cx / 50, sizeTotal.cy / 50); SetScrollSizes(MM_LOENGLISH, sizeTotal, sizePage, sizeLine); } ///////////////////////////////////////////////////////////////////////////// // CDrawerView printing BOOL CDrawerView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CDrawerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CDrawerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CDrawerView diagnostics #ifdef _DEBUG void CDrawerView::AssertValid() const { CScrollView::AssertValid(); } void CDrawerView::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); } CDrawerDoc* CDrawerView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawerDoc))); return (CDrawerDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CDrawerView message handlers void CDrawerView::OnPolylineCreate() { clickState = clickCreate; newPolyLine.reset(); // drawList.AddTail ( new PolyLine); InvalidateRect(NULL); } void CDrawerView::OnUpdatePolylineCreate(CCmdUI* pCmdUI) { pCmdUI->SetCheck(clickState==clickCreate); } void CDrawerView::OnPolylineRemove() { clickState = clickRemove; InvalidateRect(NULL); } void CDrawerView::OnUpdatePolylineRemove(CCmdUI* pCmdUI) { pCmdUI->SetCheck(clickState==clickRemove); } void CDrawerView::OnPolylineSelect() { clickState = clickSelect; InvalidateRect(NULL); } void CDrawerView::OnUpdatePolylineSelect(CCmdUI* pCmdUI) { pCmdUI->SetCheck(clickState==clickSelect); } void CDrawerView::OnFileNew() { clearDrawList(); pathName = "Untitled"; CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; pFrame->SetWindowText(pathName + " - Drawer "); InvalidateRect(NULL, TRUE); } void CDrawerView::OnFileOpen() { CFileDialog fileInput(TRUE, "ply", "*.ply"); if (fileInput.DoModal() == IDOK) { ifstream infile; pathName = fileInput.GetPathName(); infile.open(pathName, ios::in | ios::nocreate); if (infile) { clearDrawList(); PolyLine newPolyLine; while (infile >> newPolyLine) { drawList.AddTail(new PolyLine(newPolyLine)); } CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; pFrame->SetWindowText(pathName + " - Drawer "); InvalidateRect(NULL, TRUE); } } } void CDrawerView::save() { ofstream outfile(pathName); if (outfile) { POSITION curPos = drawList.GetHeadPosition(); while (curPos != NULL) { PolyLine* nextPoly = drawList.GetNext(curPos); if (nextPoly->getNumPoints() > 1) outfile << *nextPoly << endl; } } } void CDrawerView::OnFileSave() { if (pathName == "Untitled" || pathName == "") OnFileSaveAs(); save(); } void CDrawerView::OnFileSaveAs() { // TODO: Add your command handler code here CFileDialog fileInput(FALSE, "ply", "*.ply"); if (fileInput.DoModal() == IDOK) { pathName = fileInput.GetPathName(); CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; pFrame->SetWindowText(pathName + " - Drawer "); save(); } } void CDrawerView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { switch(nChar) { case VK_HOME: OnVScroll(SB_TOP, 0, NULL); OnHScroll(SB_LEFT, 0, NULL); break; case VK_END: OnVScroll(SB_BOTTOM, 0, NULL); OnHScroll(SB_RIGHT, 0, NULL); break; case VK_UP: OnVScroll(SB_LINEUP, 0, NULL); break; case VK_DOWN: OnVScroll(SB_LINEDOWN, 0, NULL); break; case VK_PRIOR: OnVScroll(SB_PAGEUP, 0, NULL); break; case VK_NEXT: OnVScroll(SB_PAGEDOWN, 0, NULL); break; case VK_LEFT: OnHScroll(SB_LINELEFT, 0, NULL); break; case VK_RIGHT: OnHScroll(SB_LINERIGHT, 0, NULL); break; default: break; } CScrollView::OnKeyDown(nChar, nRepCnt, nFlags); } void CDrawerView::OnLButtonDown(UINT nFlags, CPoint point) { CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point, 1); Point newPoint; newPoint.setX(point.x); newPoint.setY(point.y); PolyLine* polyline; POSITION curPos, checkPos; int closePointLoc; switch(clickState) { case clickCreate: newPolyLine.addPoint(newPoint); if (newPolyLine.getNumPoints() == 1) newPolyLine.addPoint(newPoint); InvalidateRect(NULL); break; case clickRemove: curPos = drawList.GetTailPosition(); while (curPos != NULL) { checkPos = curPos; polyline = drawList.GetPrev(curPos); if (polyline->getPositionClosestTo(newPoint, m_sizeEllipse.cx/2) > -1) { drawList.RemoveAt(checkPos); delete polyline; curPos = NULL; } } InvalidateRect(NULL); break; case clickSelect: curPos = drawList.GetTailPosition(); while (curPos != NULL) { checkPos = curPos; polyline = drawList.GetPrev(curPos); closePointLoc = polyline-> getPositionClosestTo(newPoint, m_sizeEllipse.cx/2); if (closePointLoc > -1) { isMovingPoint = true; draggingPolyLine = polyline; draggingPoint = closePointLoc; SetCapture(); ::SetCursor(::LoadCursor(NULL,IDC_CROSS)); } } break; default: break; } CScrollView::OnLButtonDown(nFlags, point); } void CDrawerView::OnLButtonUp(UINT nFlags, CPoint point) { if (isMovingPoint) { isMovingPoint = false; ::ReleaseCapture(); } CScrollView::OnLButtonUp(nFlags, point); } void CDrawerView::OnRButtonDown(UINT nFlags, CPoint point) { switch(clickState) { case clickCreate: if (newPolyLine.getNumPoints() > 1) drawList.AddTail(new PolyLine(newPolyLine)); newPolyLine.reset(); InvalidateRect(NULL); break; default: break; } CScrollView::OnRButtonDown(nFlags, point); } void CDrawerView::OnMouseMove(UINT nFlags, CPoint point) { CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point, 1); Point newPoint; newPoint.setX(point.x); newPoint.setY(point.y); currentMousePoint.setX(point.x); currentMousePoint.setY(point.y); if (isMovingPoint) { draggingPolyLine->setPoint(draggingPoint, newPoint); InvalidateRect(NULL); } else if (clickState == clickCreate && newPolyLine.getNumPoints() > 1 ) { newPolyLine.setPoint(newPolyLine.getNumPoints()-1, newPoint); InvalidateRect(NULL); } CString str; CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd; CStatusBar* pStatus = &pFrame->m_wndStatusBar; if (pStatus) { if (clickState == clickCreate) { str = "Left Button for a continuing point, Right Button to end a polyline"; pStatus->SetPaneText(0, str); } else if (clickState == clickSelect) { str = "Left Click and Drag control points around."; pStatus->SetPaneText(0, str); } else if (clickState == clickRemove) { str = "Left Click on a control point to remove its PolyLine."; pStatus->SetPaneText(0,str); } str.Format("x = %d", point.x); pStatus->SetPaneText(1, str); str.Format("y = %d", point.y); pStatus->SetPaneText(2, str); } CScrollView::OnMouseMove(nFlags, point); } void CDrawerView::OnContextMenu(CWnd* pWnd, CPoint point) { if (clickState == clickSelect) { CMenu menu; menu.LoadMenu(IDR_FLOATING_MENU); menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } } void CDrawerView::OnPolylinePointRemove() { POSITION curPos, checkPos; int closePointLoc; PolyLine* polyline; Point newPoint; newPoint.setX(currentMousePoint.getX()); newPoint.setY(currentMousePoint.getY()); if (clickState == clickSelect) { curPos = drawList.GetHeadPosition(); while (curPos != NULL) { checkPos = curPos; polyline = drawList.GetNext(curPos); closePointLoc = polyline-> getPositionClosestTo(newPoint, m_sizeEllipse.cx/2); if (closePointLoc > -1) { if (polyline->getNumPoints() > 2) polyline->removePoint(closePointLoc); else { drawList.RemoveAt(checkPos); delete polyline; } curPos = NULL; } } InvalidateRect(NULL); } }