You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
4.5 KiB
C++

#include "stdafx.h"
#include "ItemMeasure.h"
#include "Util.h"
#include "SigmaDoc.h"
namespace NItem
{
CItemMeasure::CItemMeasure(CSigmaDoc* ppDoc)
: CItem(ppDoc)
{
SetType(ITEM_MEASURE);
m_pSpatialIndex = std::make_unique<CSpatialIndex>(*GetDoc()->GetDraw());
}
CItemMeasure::~CItemMeasure()
{
}
void CItemMeasure::OnLButtonDblClk(UINT nFlags, CPoint point)
{
}
void CItemMeasure::OnLButtonDown(CDC* pDC, UINT nFlags, CPoint point, int vk)
{
if (m_state == MeasureState::Idle)
{
m_state = MeasureState::SelectingStart;
std::optional<CPoint2D> adsPoint = GetSnapPoint(point);
CPoint2D realPoint = adsPoint ? adsPoint.value() : GetDC()->GetReal(point);
m_startPoint = realPoint;
m_prevPoint = m_startPoint;
}
}
void CItemMeasure::OnLButtonUp(CDC* pDC, UINT nFlags, CPoint point, int vk)
{
if (m_state == MeasureState::SelectingStart)
{
m_endPoint = point;
DrawAssistant(pDC, point.x, point.y);
m_state = MeasureState::Idle;
}
}
int CItemMeasure::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point)
{
if (m_state == MeasureState::SelectingStart)
{
CPen pen(PS_SOLID, m_penWidth, m_penColor);
// 保存当前状态
CPen* pOldPen = pDC->SelectObject(&pen);
int oldROP2 = pDC->SetROP2(R2_NOTXORPEN);
std::optional<CPoint2D> adsPoint = GetSnapPoint(point);
CPoint2D realPoint = adsPoint ? adsPoint.value() : GetReal(point);
m_endPoint = realPoint;
CPoint cPoint = GetScreenPoint(realPoint);
CPoint startPoint = GetScreenPoint(m_startPoint);
CPoint prevPoint = GetScreenPoint(m_prevPoint);
// 擦除前一次的线
pDC->MoveTo(startPoint);
pDC->LineTo(prevPoint);
// 绘制新线
pDC->MoveTo(startPoint);
pDC->LineTo(cPoint);
// 恢复状态
pDC->SelectObject(pOldPen);
pDC->SetROP2(oldROP2);
m_prevPoint = GetReal(cPoint);
}
return 0;
}
void CItemMeasure::OnMouseMoveStatus(CDC* pDC, UINT nFlags, CPoint point, BYTE*& destBuffer, int& destLen)
{
if (m_state == MeasureState::SelectingStart)
{
}
}
BOOL CItemMeasure::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
return 0;
}
BOOL CItemMeasure::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE)
{
return TRUE;
}
return FALSE;
}
BOOL CItemMeasure::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
return 0;
}
void CItemMeasure::OnDraw(CXyDC* pDC)
{
}
void CItemMeasure::OnDraw(CXyDC* pXyDC, CDC* pDC)
{
}
void CItemMeasure::DrawAssistant(CDC* pDC, int mouseX, int mouseY)
{
if (m_state == MeasureState::SelectingStart)
{
CPoint startPoint = GetScreenPoint(m_startPoint);
DrawLineScreen(startPoint.x, startPoint.y, mouseX, mouseY);
}
}
void CItemMeasure::OnOK(void)
{
m_state = MeasureState::SelectingEnd;
}
void CItemMeasure::OnCancel(void)
{
m_state = MeasureState::Idle;
}
CString CItemMeasure::GetCurrentInfo() const
{
if (m_state == MeasureState::SelectingStart)
{
double distance = CalcDistance(m_startPoint.x0, m_startPoint.y0, m_endPoint.x0, m_endPoint.y0);
double angle = AfxGetPublicFunction()->GetAngle(m_startPoint.x0, m_startPoint.y0, m_endPoint.x0, m_endPoint.y0);
double width = fabs(m_endPoint.x0 - m_startPoint.x0);
double height = fabs(m_endPoint.y0 - m_startPoint.y0);
CString str;
str.Format("距离: %lf, 角度: %.2lf, (%.6lf x %.6lf)\n", distance, angle, width, height);
return str;
}
return CString();
}
void CItemMeasure::EnableSnap()
{
m_isSnapEnabled = true;
}
void CItemMeasure::DisableSnap()
{
m_isSnapEnabled = false;
}
bool CItemMeasure::IsSnapEnabled() const
{
return m_isSnapEnabled;
}
void CItemMeasure::DrawCross(Gdiplus::Graphics& graphics, Gdiplus::PointF center, int length, const Gdiplus::Pen& pen) const
{
Gdiplus::PointF horizontalStart(center.X - length, center.Y);
Gdiplus::PointF horizontalEnd(center.X + length, center.Y);
Gdiplus::PointF verticalStart(center.X, center.Y - length);
Gdiplus::PointF verticalEnd(center.X, center.Y + length);
graphics.DrawLine(&pen, horizontalStart, horizontalEnd);
graphics.DrawLine(&pen, verticalStart, verticalEnd);
}
CPoint CItemMeasure::GetScreenPoint(const CPoint2D& realPoint) const
{
return const_cast<CItemMeasure*>(this)->GetDC()->GetScreen(realPoint.x0, realPoint.y0);
}
std::optional<CPoint2D> CItemMeasure::GetSnapPoint(const CPoint& point) const
{
if (!m_isSnapEnabled)
{
return const_cast<CItemMeasure*>(this)->GetReal(point);
}
CItemMeasure* mutItem = const_cast<CItemMeasure*>(this);
CPoint2D realPoint = mutItem->GetDC()->GetReal(point.x, point.y);
double realRadius = mutItem->GetDC()->GetRealWidth(m_snapRange);
return m_pSpatialIndex->GetSnapPoint(realPoint, realRadius);
}
}