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++
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);
|
|
}
|
|
|
|
}
|