#pragma once #include "Item.h" #include "SpatialIndex.h" namespace NItem { class CItemMeasure : public CItem { public: CItemMeasure(CSigmaDoc* ppDoc); ~CItemMeasure(); void OnLButtonDblClk(UINT nFlags, CPoint point) override; void OnLButtonDown(CDC* pDC, UINT nFlags, CPoint point, int vk) override; void OnLButtonUp(CDC* pDC, UINT nFlags, CPoint point, int vk) override; int OnMouseMove(CDC* pDC, UINT nFlags, CPoint point) override; void OnMouseMoveStatus(CDC* pDC, UINT nFlags, CPoint point, BYTE*& destBuffer, int& destLen) override; BOOL OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) override; BOOL OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) override; BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) override; void OnDraw(CXyDC* pDC) override; void OnDraw(CXyDC* pXyDC, CDC* pDC) override; void DrawAssistant(CDC* pDC, int mouseX, int mouseY) override; void OnOK(void) override; void OnCancel(void) override; CString GetCurrentInfo() const; /** * 开启吸附功能 * */ void EnableSnap(); /** * 关闭吸附功能 * */ void DisableSnap(); bool IsSnapEnabled() const; private: void DrawCross(Gdiplus::Graphics& graphics, Gdiplus::PointF center, int length, const Gdiplus::Pen& pen) const; /** * 将真实坐标转换为屏幕坐标 * * \param realPoint 真实坐标 * \return 屏幕坐标 */ CPoint GetScreenPoint(const CPoint2D& realPoint) const; /** * 获取吸附点 * * \param point 当前光标位置,屏幕坐标 * \return 如果吸附点存在,返回屏幕坐标,否则返回 std::nullopt; */ std::optional GetSnapPoint(const CPoint& point) const; /** * 当前状态 */ enum class MeasureState { Idle, SelectingStart, SelectingEnd }; bool m_isSnapEnabled = true; // 吸附的正方形范围,这个是屏幕坐标系,不是实际坐标系 double m_snapRange = 30.0; MeasureState m_state = MeasureState::Idle; CPoint2D m_startPoint; CPoint2D m_endPoint; CPoint2D m_prevPoint; COLORREF m_penColor = RGB(0, 0, 0); int m_penWidth = 1; // 线宽 std::unique_ptr m_pSpatialIndex; }; }