From 351086486441b80cfe71550b43cbe1e4dc440f5d Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期一, 09 二月 2026 13:58:30 +0800
Subject: [PATCH] 1.状态图右侧数据,Slot不刷新,修复刷新逻辑。

---
 SourceCode/Bond/Servo/EqsGraphWnd.cpp |  218 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 196 insertions(+), 22 deletions(-)

diff --git a/SourceCode/Bond/Servo/EqsGraphWnd.cpp b/SourceCode/Bond/Servo/EqsGraphWnd.cpp
index fbdd34b..1a5f474 100644
--- a/SourceCode/Bond/Servo/EqsGraphWnd.cpp
+++ b/SourceCode/Bond/Servo/EqsGraphWnd.cpp
@@ -64,6 +64,8 @@
 	m_nMagneticLinHoz = 0;
 	m_nMagneticLinVer = 0;
 	m_hFontTitle = nullptr;
+	m_nIndicatorSize = 10;
+	m_nIndicatorMargin = 3;
 
 }
 
@@ -157,6 +159,20 @@
 
 	m_crItemIdText[0] = CColorTransfer::ApproximateColor(m_crItemNameText[0], -0.3f);
 	m_crItemIdText[1] = CColorTransfer::ApproximateColor(m_crItemNameText[1], -0.3f);
+}
+
+void CEqsGraphWnd::SetIndicatorSize(int nSize)
+{
+	if (nSize > 0) {
+		m_nIndicatorSize = nSize;
+	}
+}
+
+void CEqsGraphWnd::SetIndicatorMargin(int nMargin)
+{
+	if (nMargin >= 0) {
+		m_nIndicatorMargin = nMargin;
+	}
 }
 
 void CEqsGraphWnd::EnableScroll(BOOL bEnable)
@@ -479,14 +495,7 @@
 
 void CEqsGraphWnd::SetOnListener(EqsGraphListener& listener)
 {
-	m_listener.onConnectPin = listener.onConnectPin;
-	m_listener.onCheckConnectPin = listener.onCheckConnectPin;
-	m_listener.onDisconnectPin = listener.onDisconnectPin;
-	m_listener.onDeleteEqItem = listener.onDeleteEqItem;
-	m_listener.onEqItemPosChanged = listener.onEqItemPosChanged;
-	m_listener.onDblckEqItem = listener.onDblckEqItem;
-	m_listener.onRclickEqItem = listener.onRclickEqItem;
-	m_listener.onSelectEqItem = listener.onSelectEqItem;
+	m_listener = listener;
 }
 
 BOOL CEqsGraphWnd::SetCurSel(int nSel)
@@ -755,6 +764,64 @@
 	return 0;
 }
 
+void CEqsGraphWnd::SetManualRoute(PIN* pOutPin, PIN* pInPin, BOOL bUp)
+{
+	if (pOutPin == NULL || pInPin == NULL) {
+		return;
+	}
+	if (pOutPin->pItem == NULL || pInPin->pItem == NULL) {
+		return;
+	}
+
+	if (pOutPin->pConnectedPin != pInPin) {
+		pOutPin->pConnectedPin = pInPin;
+		pInPin->pConnectedPin = pOutPin;
+	}
+
+	POINT pt1, pt2;
+	if (!GetPinPoint(pOutPin, &pt1) || !GetPinPoint(pInPin, &pt2)) {
+		return;
+	}
+
+	RECT rc1, rc2;
+	GetItemRect(pOutPin->pItem, &rc1);
+	GetItemRect(pInPin->pItem, &rc2);
+	::OffsetRect(&rc1, +m_nOffsetX, +m_nOffsetY);
+	::OffsetRect(&rc2, +m_nOffsetX, +m_nOffsetY);
+	pt1.x += m_nOffsetX;
+	pt1.y += m_nOffsetY;
+	pt2.x += m_nOffsetX;
+	pt2.y += m_nOffsetY;
+
+	int nMargin = 12;
+	int x1 = pt1.x + 10 + pOutPin->nIndex * nMargin;
+	int xEnd = pt2.x - 5;
+	int x2 = xEnd - (PINWIDTH + 12);
+	int y1;
+	if (bUp) {
+		int topY = min(rc1.top, rc2.top);
+		y1 = topY - 30 - pOutPin->nIndex * 6;
+	}
+	else {
+		int bottomY = max(rc1.bottom, rc2.bottom);
+		y1 = bottomY + 30 + pOutPin->nIndex * 6;
+	}
+
+	pOutPin->ptConnectedLine[0].x = pt1.x;
+	pOutPin->ptConnectedLine[0].y = pt1.y;
+	pOutPin->ptConnectedLine[1].x = x1;
+	pOutPin->ptConnectedLine[1].y = pt1.y;
+	pOutPin->ptConnectedLine[2].x = x1;
+	pOutPin->ptConnectedLine[2].y = y1;
+	pOutPin->ptConnectedLine[3].x = x2;
+	pOutPin->ptConnectedLine[3].y = y1;
+	pOutPin->ptConnectedLine[4].x = x2;
+	pOutPin->ptConnectedLine[4].y = pt2.y;
+	pOutPin->ptConnectedLine[5].x = xEnd;
+	pOutPin->ptConnectedLine[5].y = pt2.y;
+	pOutPin->nLinePtCount = 6;
+}
+
 // 鍒犻櫎Item, 濡傛灉pin鏈夎繛鎺ワ紝娉ㄦ剰鍏堟柇寮�
 int CEqsGraphWnd::DeleteItem(EQITEM* pItem)
 {
@@ -981,6 +1048,8 @@
 	// 濡傛灉娌℃湁缂撳瓨绾挎潯鐨凱OINT锛屽垯鍏堣绠楀苟缂撳瓨
 	ASSERT(pOwnerPin);
 
+	bool canDraw = (pGraphics != nullptr && pPen != nullptr);
+
 	int nPinCount = ((CPtrArray*)pOwnerPin->pItem->pOutPins)->GetSize();
 	int nArrowLen = 8;
 	int nStartMinX = 8;
@@ -1033,8 +1102,9 @@
 				pOwnerPin->nLinePtCount = 6;
 			}
 			else {
+				int baseY = max(lpRect1->bottom, lpRect2->bottom) + 30;
+				y1 = baseY + pOwnerPin->nIndex * nMargin;
 				x2 = min(lpRect1->left, lpRect2->left) - 30;
-				y1 = max(lpRect1->bottom, lpRect2->bottom) + 30;
 				pOwnerPin->ptConnectedLine[0].x = lpPt1->x;
 				pOwnerPin->ptConnectedLine[0].y = lpPt1->y;
 				pOwnerPin->ptConnectedLine[1].x = x1;
@@ -1052,10 +1122,69 @@
 		}
 	}
 
+	if (!canDraw) {
+		return;
+	}
+
 	if (pOwnerPin->nLinePtCount >= 2) {
+		const int kJumpRadius = 6;
 		for (int i = 0; i < pOwnerPin->nLinePtCount - 1; i++) {
-			pGraphics->DrawLine(pPen, pOwnerPin->ptConnectedLine[i].x - m_nOffsetX, pOwnerPin->ptConnectedLine[i].y - m_nOffsetY,
-				pOwnerPin->ptConnectedLine[i + 1].x - m_nOffsetX, pOwnerPin->ptConnectedLine[i + 1].y - m_nOffsetY);
+			POINT a = pOwnerPin->ptConnectedLine[i];
+			POINT b = pOwnerPin->ptConnectedLine[i + 1];
+			bool isHorizontal = (a.y == b.y);
+			bool jumped = false;
+
+			if (isHorizontal) {
+				int y = a.y;
+				int xMin = min(a.x, b.x);
+				int xMax = max(a.x, b.x);
+				bool found = false;
+				int hitX = 0;
+				int x1 = 0;
+				int x2 = 0;
+				for (const auto& seg : m_verticalSegments) {
+					bool segVertical = (seg.a.x == seg.b.x);
+					if (!segVertical) {
+						continue;
+					}
+					int vx = seg.a.x;
+					int vyMin = min(seg.a.y, seg.b.y);
+					int vyMax = max(seg.a.y, seg.b.y);
+					if (vx > xMin + 1 && vx < xMax - 1
+						&& y > vyMin + 1 && y < vyMax - 1) {
+						hitX = vx;
+						found = true;
+						break;
+					}
+				}
+
+				if (found) {
+					x1 = hitX - kJumpRadius;
+					x2 = hitX + kJumpRadius;
+					if (x1 <= xMin) x1 = xMin + 1;
+					if (x2 >= xMax) x2 = xMax - 1;
+					if (x2 <= x1) {
+						found = false;
+					}
+				}
+
+				if (found) {
+					pGraphics->DrawLine(pPen, a.x - m_nOffsetX, a.y - m_nOffsetY,
+						x1 - m_nOffsetX, y - m_nOffsetY);
+
+					Gdiplus::Rect arcRect(x1 - m_nOffsetX, y - kJumpRadius - m_nOffsetY, kJumpRadius * 2, kJumpRadius * 2);
+					pGraphics->DrawArc(pPen, arcRect, 180.0f, -180.0f);
+
+					pGraphics->DrawLine(pPen, x2 - m_nOffsetX, y - m_nOffsetY,
+						b.x - m_nOffsetX, b.y - m_nOffsetY);
+					jumped = true;
+				}
+			}
+			if (!jumped) {
+				pGraphics->DrawLine(pPen, a.x - m_nOffsetX, a.y - m_nOffsetY,
+					b.x - m_nOffsetX, b.y - m_nOffsetY);
+			}
+
 		}
 
 		DrawArrow(pGraphics, pBrush, pPen, pOwnerPin->ptConnectedLine[pOwnerPin->nLinePtCount-1].x - m_nOffsetX,
@@ -1335,6 +1464,8 @@
 		GetItemRect(m_pCurItem, &rcItem);
 
 		if (::GetCapture() == NULL) {
+			const int kDragThreshold = 3; // debounce: click should not trigger line recalculation
+			bool bDragging = false;
 			SetCapture(m_hWnd);
 			ASSERT(m_hWnd == GetCapture());
 			AfxLockTempMaps();
@@ -1350,6 +1481,14 @@
 				case WM_MOUSEMOVE:
 					ptNew = msg.pt;
 					::ScreenToClient(m_hWnd, &ptNew);
+					if (!bDragging) {
+						if (abs(ptNew.x - pt.x) >= kDragThreshold || abs(ptNew.y - pt.y) >= kDragThreshold) {
+							bDragging = true;
+						}
+						else {
+							break;
+						}
+					}
 					rcNewItem.left = rcItem.left + (ptNew.x - pt.x);
 					rcNewItem.right = rcItem.right + (ptNew.x - pt.x);
 					rcNewItem.top = rcItem.top + (ptNew.y - pt.y);
@@ -1365,6 +1504,10 @@
 				case WM_LBUTTONUP:
 					ptNew = msg.pt;
 					::ScreenToClient(m_hWnd, &ptNew);
+					if (!bDragging) {
+						ReleaseCapture();
+						goto ExitLoop;
+					}
 					m_pCurItem->rect.left = m_nMagneticLinVer > 0 ? m_nMagneticLinVer : (rcItem.left + (ptNew.x - pt.x) + m_nOffsetX);
 					m_pCurItem->rect.right = m_pCurItem->rect.left + (rcItem.right - rcItem.left);
 					m_pCurItem->rect.top = m_nMagneticLinHoz > 0 ? m_nMagneticLinHoz : (rcItem.top + (ptNew.y - pt.y) + m_nOffsetY);
@@ -1964,10 +2107,10 @@
 			::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcItem,
 				DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
 
-			// 澶氫釜鎸囩ず鐏細宸︿笂瑙掞紝鎸� 4 鍒� 脳 2 琛屾帓鍒�
-			const int indicatorSize = 10;
-			const int indicatorMargin = 3;
-			const int indicatorsPerRow = 4;
+			// indicators vertical column layout
+			const int indicatorSize = m_nIndicatorSize;
+			const int indicatorMargin = m_nIndicatorMargin;
+			const int indicatorX = rcItem.left + 5;
 
 			for (int k = 0; k < EQITEM_INDICATOR_COUNT; ++k) {
 				BYTE indicatorState = pItem->nIndicatorState[k];
@@ -1975,17 +2118,12 @@
 					continue;
 				}
 
-				int row = k / indicatorsPerRow;
-				int col = k % indicatorsPerRow;
-
 				RECT rcIndicator;
-				rcIndicator.left = rcItem.left + 5 + col * (indicatorSize + indicatorMargin);
-				rcIndicator.top = rcItem.top + 5 + row * (indicatorSize + indicatorMargin);
+				rcIndicator.left = indicatorX;
+				rcIndicator.top = rcItem.top + 5 + k * (indicatorSize + indicatorMargin);
 				rcIndicator.right = rcIndicator.left + indicatorSize;
 				rcIndicator.bottom = rcIndicator.top + indicatorSize;
 
-
-				// 鐢婚珮浜�/鐏拌壊鏂瑰潡
 				RECT rcInner = rcIndicator;
 				::InflateRect(&rcInner, -1, -1);
 				::FillRect(hMemDC, &rcInner, indicatorState == INDICATOR_STATE_HIGHLIGHT
@@ -2076,6 +2214,42 @@
 			::SelectObject(hMemDC, hFontOld);
 		}
 
+		// 棰勫厛璁$畻鎵�鏈夎繛鎺ョ嚎鐨勭偣骞舵敹闆嗗瀭鐩寸嚎娈碉紝鐢ㄤ簬璺崇嚎鍒ゆ柇
+		m_verticalSegments.clear();
+		for (int i = 0; i < nItemCount; i++) {
+			EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i);
+			if (pItem->nFlashFlag == 1) {
+				continue;
+			}
+
+			PIN* pPin = NULL;
+			CPtrArray* pPins = (CPtrArray*)pItem->pOutPins;
+			RECT rcItem1, rcItem2;
+			for (int j = 0; j < pPins->GetSize(); j++) {
+				pPin = (PIN*)pPins->GetAt(j);
+				if (pPin->pConnectedPin != NULL) {
+					POINT pt1, pt2;
+					if (GetPinPoint(pPin, &pt1) && GetPinPoint(pPin->pConnectedPin, &pt2)) {
+						GetItemRect(pItem, &rcItem1);
+						GetItemRect(pPin->pConnectedPin->pItem, &rcItem2);
+						DrawPinConnectedLine(nullptr, nullptr, nullptr, &pt1, &pt2, &rcItem1, &rcItem2, pPin);
+						if (pPin->nLinePtCount >= 2) {
+							for (int k = 0; k < pPin->nLinePtCount - 1; k++) {
+								POINT a = pPin->ptConnectedLine[k];
+								POINT b = pPin->ptConnectedLine[k + 1];
+								if (a.x == b.x) {
+									LineSeg seg;
+									seg.a = a;
+									seg.b = b;
+									m_verticalSegments.push_back(seg);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+
 		// 鍐嶇粯鍒惰繛鎺ョ嚎
 		for (int i = 0; i < nItemCount; i++) {
 			EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i);

--
Gitblit v1.9.3