| | |
| | | |
| | | 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) |
| | |
| | | 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) |
| | | { |
| | |
| | | // 如果没有缓存线条的POINT,则先计算并缓存 |
| | | ASSERT(pOwnerPin); |
| | | |
| | | bool canDraw = (pGraphics != nullptr && pPen != nullptr); |
| | | |
| | | int nPinCount = ((CPtrArray*)pOwnerPin->pItem->pOutPins)->GetSize(); |
| | | int nArrowLen = 8; |
| | | int nStartMinX = 8; |
| | |
| | | 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; |
| | |
| | | } |
| | | } |
| | | |
| | | 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, |
| | |
| | | ::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); |