DRAWTOOL.CPP
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:11k
- // drawtool.cpp - implementation for drawing tools
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #include "drawcli.h"
- #include "drawdoc.h"
- #include "drawvw.h"
- #include "drawobj.h"
- #include "drawtool.h"
- /////////////////////////////////////////////////////////////////////////////
- // CDrawTool implementation
- CPtrList CDrawTool::c_tools;
- static CSelectTool selectTool;
- static CRectTool lineTool(line);
- static CRectTool rectTool(rect);
- static CRectTool roundRectTool(roundRect);
- static CRectTool ellipseTool(ellipse);
- static CPolyTool polyTool;
- CPoint CDrawTool::c_down;
- UINT CDrawTool::c_nDownFlags;
- CPoint CDrawTool::c_last;
- DrawShape CDrawTool::c_drawShape = selection;
- CDrawTool::CDrawTool(DrawShape drawShape)
- {
- m_drawShape = drawShape;
- c_tools.AddTail(this);
- }
- CDrawTool* CDrawTool::FindTool(DrawShape drawShape)
- {
- POSITION pos = c_tools.GetHeadPosition();
- while (pos != NULL)
- {
- CDrawTool* pTool = (CDrawTool*)c_tools.GetNext(pos);
- if (pTool->m_drawShape == drawShape)
- return pTool;
- }
- return NULL;
- }
- void CDrawTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- // deactivate any in-place active item on this view!
- COleClientItem* pActiveItem = pView->GetDocument()->GetInPlaceActiveItem(pView);
- if (pActiveItem != NULL)
- {
- pActiveItem->Close();
- ASSERT(pView->GetDocument()->GetInPlaceActiveItem(pView) == NULL);
- }
- pView->SetCapture();
- c_nDownFlags = nFlags;
- c_down = point;
- c_last = point;
- }
- void CDrawTool::OnLButtonDblClk(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& /*point*/)
- {
- }
- void CDrawTool::OnLButtonUp(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& point)
- {
- ReleaseCapture();
- if (point == c_down)
- c_drawShape = selection;
- }
- void CDrawTool::OnMouseMove(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& point)
- {
- c_last = point;
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
- }
- void CDrawTool::OnEditProperties(CDrawView* /*pView*/)
- {
- }
- void CDrawTool::OnCancel()
- {
- c_drawShape = selection;
- }
- ////////////////////////////////////////////////////////////////////////////
- // CResizeTool
- enum SelectMode
- {
- none,
- netSelect,
- move,
- size
- };
- SelectMode selectMode = none;
- int nDragHandle;
- CPoint lastPoint;
- CSelectTool::CSelectTool()
- : CDrawTool(selection)
- {
- }
- void CSelectTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- CPoint local = point;
- pView->ClientToDoc(local);
- CDrawObj* pObj;
- selectMode = none;
- // Check for resizing (only allowed on single selections)
- if (pView->m_selection.GetCount() == 1)
- {
- pObj = pView->m_selection.GetHead();
- nDragHandle = pObj->HitTest(local, pView, TRUE);
- if (nDragHandle != 0)
- selectMode = size;
- }
- // See if the click was on an object, select and start move if so
- if (selectMode == none)
- {
- pObj = pView->GetDocument()->ObjectAt(local);
- if (pObj != NULL)
- {
- selectMode = move;
- if (!pView->IsSelected(pObj))
- pView->Select(pObj, (nFlags & MK_SHIFT) != 0);
- // Ctrl+Click clones the selection...
- if ((nFlags & MK_CONTROL) != 0)
- pView->CloneSelection();
- }
- }
- // Click on background, start a net-selection
- if (selectMode == none)
- {
- if ((nFlags & MK_SHIFT) == 0)
- pView->Select(NULL);
- selectMode = netSelect;
- CClientDC dc(pView);
- CRect rect(point.x, point.y, point.x, point.y);
- rect.NormalizeRect();
- dc.DrawFocusRect(rect);
- }
- lastPoint = local;
- CDrawTool::OnLButtonDown(pView, nFlags, point);
- }
- void CSelectTool::OnLButtonDblClk(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- if ((nFlags & MK_SHIFT) != 0)
- {
- // Shift+DblClk deselects object...
- CPoint local = point;
- pView->ClientToDoc(local);
- CDrawObj* pObj = pView->GetDocument()->ObjectAt(local);
- if (pObj != NULL)
- pView->Deselect(pObj);
- }
- else
- {
- // "Normal" DblClk opens properties, or OLE server...
- if (pView->m_selection.GetCount() == 1)
- pView->m_selection.GetHead()->OnOpen(pView);
- }
- CDrawTool::OnLButtonDblClk(pView, nFlags, point);
- }
- void CSelectTool::OnEditProperties(CDrawView* pView)
- {
- if (pView->m_selection.GetCount() == 1)
- pView->m_selection.GetHead()->OnEditProperties();
- }
- void CSelectTool::OnLButtonUp(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- if (pView->GetCapture() == pView)
- {
- if (selectMode == netSelect)
- {
- CClientDC dc(pView);
- CRect rect(c_down.x, c_down.y, c_last.x, c_last.y);
- rect.NormalizeRect();
- dc.DrawFocusRect(rect);
- pView->SelectWithinRect(rect, TRUE);
- }
- else if (selectMode != none)
- {
- pView->GetDocument()->UpdateAllViews(pView);
- }
- }
- CDrawTool::OnLButtonUp(pView, nFlags, point);
- }
- void CSelectTool::OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- if (pView->GetCapture() != pView)
- {
- if (c_drawShape == selection && pView->m_selection.GetCount() == 1)
- {
- CDrawObj* pObj = pView->m_selection.GetHead();
- CPoint local = point;
- pView->ClientToDoc(local);
- int nHandle = pObj->HitTest(local, pView, TRUE);
- if (nHandle != 0)
- {
- SetCursor(pObj->GetHandleCursor(nHandle));
- return; // bypass CDrawTool
- }
- }
- if (c_drawShape == selection)
- CDrawTool::OnMouseMove(pView, nFlags, point);
- return;
- }
- if (selectMode == netSelect)
- {
- CClientDC dc(pView);
- CRect rect(c_down.x, c_down.y, c_last.x, c_last.y);
- rect.NormalizeRect();
- dc.DrawFocusRect(rect);
- rect.SetRect(c_down.x, c_down.y, point.x, point.y);
- rect.NormalizeRect();
- dc.DrawFocusRect(rect);
- CDrawTool::OnMouseMove(pView, nFlags, point);
- return;
- }
- CPoint local = point;
- pView->ClientToDoc(local);
- CPoint delta = (CPoint)(local - lastPoint);
- POSITION pos = pView->m_selection.GetHeadPosition();
- while (pos != NULL)
- {
- CDrawObj* pObj = pView->m_selection.GetNext(pos);
- CRect position = pObj->m_position;
- if (selectMode == move)
- {
- position += delta;
- pObj->MoveTo(position, pView);
- }
- else if (nDragHandle != 0)
- {
- pObj->MoveHandleTo(nDragHandle, local, pView);
- }
- }
- lastPoint = local;
- if (selectMode == size && c_drawShape == selection)
- {
- c_last = point;
- SetCursor(pView->m_selection.GetHead()->GetHandleCursor(nDragHandle));
- return; // bypass CDrawTool
- }
- c_last = point;
- if (c_drawShape == selection)
- CDrawTool::OnMouseMove(pView, nFlags, point);
- }
- ////////////////////////////////////////////////////////////////////////////
- // CRectTool (does rectangles, round-rectangles, and ellipses)
- CRectTool::CRectTool(DrawShape drawShape)
- : CDrawTool(drawShape)
- {
- }
- void CRectTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- CDrawTool::OnLButtonDown(pView, nFlags, point);
- CPoint local = point;
- pView->ClientToDoc(local);
- CDrawRect* pObj = new CDrawRect(CRect(local, CSize(0, 0)));
- switch (m_drawShape)
- {
- default:
- ASSERT(FALSE); // unsuported shape!
- case rect:
- pObj->m_nShape = CDrawRect::rectangle;
- break;
- case roundRect:
- pObj->m_nShape = CDrawRect::roundRectangle;
- break;
- case ellipse:
- pObj->m_nShape = CDrawRect::ellipse;
- break;
- case line:
- pObj->m_nShape = CDrawRect::line;
- break;
- }
- pView->GetDocument()->Add(pObj);
- pView->Select(pObj);
- selectMode = size;
- nDragHandle = 1;
- lastPoint = local;
- }
- void CRectTool::OnLButtonDblClk(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- CDrawTool::OnLButtonDblClk(pView, nFlags, point);
- }
- void CRectTool::OnLButtonUp(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- if (point == c_down)
- {
- // Don't create empty objects...
- CDrawObj *pObj = pView->m_selection.GetTail();
- pView->GetDocument()->Remove(pObj);
- pObj->Remove();
- selectTool.OnLButtonDown(pView, nFlags, point); // try a select!
- }
- selectTool.OnLButtonUp(pView, nFlags, point);
- }
- void CRectTool::OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
- selectTool.OnMouseMove(pView, nFlags, point);
- }
- ////////////////////////////////////////////////////////////////////////////
- // CPolyTool
- CPolyTool::CPolyTool()
- : CDrawTool(poly)
- {
- m_pDrawObj = NULL;
- }
- void CPolyTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- CDrawTool::OnLButtonDown(pView, nFlags, point);
- CPoint local = point;
- pView->ClientToDoc(local);
- if (m_pDrawObj == NULL)
- {
- pView->SetCapture();
- m_pDrawObj = new CDrawPoly(CRect(local, CSize(0, 0)));
- pView->GetDocument()->Add(m_pDrawObj);
- pView->Select(m_pDrawObj);
- m_pDrawObj->AddPoint(local, pView);
- }
- else if (local == m_pDrawObj->m_points[0])
- {
- // Stop when the first point is repeated...
- ReleaseCapture();
- m_pDrawObj->m_nPoints -= 1;
- if (m_pDrawObj->m_nPoints < 2)
- {
- m_pDrawObj->Remove();
- }
- else
- {
- pView->InvalObj(m_pDrawObj);
- }
- m_pDrawObj = NULL;
- c_drawShape = selection;
- return;
- }
- local.x += 1; // adjacent points can't be the same!
- m_pDrawObj->AddPoint(local, pView);
- selectMode = size;
- nDragHandle = m_pDrawObj->GetHandleCount();
- lastPoint = local;
- }
- void CPolyTool::OnLButtonUp(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& /*point*/)
- {
- // Don't release capture yet!
- }
- void CPolyTool::OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)
- {
- if (m_pDrawObj != NULL && (nFlags & MK_LBUTTON) != 0)
- {
- CPoint local = point;
- pView->ClientToDoc(local);
- m_pDrawObj->AddPoint(local);
- nDragHandle = m_pDrawObj->GetHandleCount();
- lastPoint = local;
- c_last = point;
- SetCursor(AfxGetApp()->LoadCursor(IDC_PENCIL));
- }
- else
- {
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
- selectTool.OnMouseMove(pView, nFlags, point);
- }
- }
- void CPolyTool::OnLButtonDblClk(CDrawView* pView, UINT , const CPoint& )
- {
- ReleaseCapture();
- int nPoints = m_pDrawObj->m_nPoints;
- if (nPoints > 2 &&
- (m_pDrawObj->m_points[nPoints - 1] == m_pDrawObj->m_points[nPoints - 2] ||
- m_pDrawObj->m_points[nPoints - 1].x - 1 == m_pDrawObj->m_points[nPoints - 2].x &&
- m_pDrawObj->m_points[nPoints - 1].y == m_pDrawObj->m_points[nPoints - 2].y))
- {
- // Nuke the last point if it's the same as the next to last...
- m_pDrawObj->m_nPoints -= 1;
- pView->InvalObj(m_pDrawObj);
- }
- m_pDrawObj = NULL;
- c_drawShape = selection;
- }
- void CPolyTool::OnCancel()
- {
- CDrawTool::OnCancel();
- m_pDrawObj = NULL;
- }
- /////////////////////////////////////////////////////////////////////////////