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.
615 lines
16 KiB
C++
615 lines
16 KiB
C++
// XTPFlowGraphPaintManager.cpp : implementation of the CXTPFlowGraphPaintManager class.
|
|
//
|
|
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include <math.h>
|
|
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "GraphicLibrary/GdiPlus/GdiPlus.h"
|
|
|
|
#include "XTPFlowGraphTools.h"
|
|
#include "XTPFlowGraphElement.h"
|
|
#include "XTPFlowGraphPaintManager.h"
|
|
#include "XTPFlowGraphDrawContext.h"
|
|
#include "XTPFlowGraphControl.h"
|
|
#include "XTPFlowGraphNode.h"
|
|
#include "XTPFlowGraphNodeGroup.h"
|
|
#include "XTPFlowGraphPage.h"
|
|
#include "XTPFlowGraphConnection.h"
|
|
#include "XTPFlowGraphConnectionPoint.h"
|
|
#include "XTPFlowGraphConnectionPoints.h"
|
|
#include "XTPFlowGraphImage.h"
|
|
|
|
using namespace Gdiplus;
|
|
|
|
CXTPFlowGraphPaintManager::CXTPFlowGraphPaintManager()
|
|
{
|
|
m_clrBackground = RGB(255, 255, 255);
|
|
m_clrSelection = RGB(247, 150, 70);
|
|
m_clrTextColor = RGB(255, 255, 255);
|
|
m_clrConnection = RGB(0, 0, 0);
|
|
m_clrGridColor = RGB(240, 240, 240);
|
|
|
|
m_clrNodeBackground = RGB(192, 80, 77);
|
|
|
|
m_nNodeFrameSize = 3;
|
|
m_nPointTextMargin = 6;
|
|
m_bDrawArrow = TRUE;
|
|
m_nEllipseSize = 9;
|
|
m_bShowGrid = FALSE;
|
|
|
|
m_bShowNodeGroupsAlways = FALSE;
|
|
|
|
m_nConnectorType = xtpFlowGraphConnectorCurved;
|
|
|
|
memset(&m_lfText, 0, sizeof(m_lfText));
|
|
XTPDrawHelpers()->GetIconLogFont(&m_lfText);
|
|
|
|
m_lfText.lfHeight = 18;
|
|
m_lfText.lfWeight = FW_NORMAL;
|
|
m_lfCaption = m_lfText;
|
|
|
|
m_dMinZoomLevelBackground = 0.2;
|
|
m_dMinZoomLevelConnectionPoints = 0.3;
|
|
m_dMinZoomLevelConnections = 0.05;
|
|
m_dMinZoomLevelGDIQuality = 0.4;
|
|
|
|
}
|
|
|
|
CXTPFlowGraphPaintManager::~CXTPFlowGraphPaintManager()
|
|
{
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::Cleanup()
|
|
{
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::RefreshMetrics()
|
|
{
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::DrawControlBackground(CXTPFlowGraphDrawContext* pDC, CXTPFlowGraphControl* pControl)
|
|
{
|
|
pDC->Clear(m_clrBackground);
|
|
|
|
if (m_bShowGrid && !pDC->IsPrinting() && pControl->GetZoomLevel() >= m_dMinZoomLevelBackground)
|
|
{
|
|
CRect rc;
|
|
pControl->GetClientRect(&rc);
|
|
|
|
pDC->DrawGrid(rc, pControl->GetScrollOffset(), pControl->GetZoomLevel(), m_clrGridColor);
|
|
}
|
|
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::RecalcNodeLayout(CXTPFlowGraphDrawContext* pDC, CXTPFlowGraphNode* pNode)
|
|
{
|
|
pNode->m_rcWindow.SetRectEmpty();
|
|
|
|
CString strCaption = pNode->GetCaption();
|
|
|
|
pDC->SetFont(&m_lfCaption);
|
|
CSize szCaption;
|
|
|
|
if (pNode->GetMarkupUIElement())
|
|
szCaption = pDC->MeasureMarkupElement(pNode->GetMarkupUIElement());
|
|
else
|
|
szCaption = pDC->MeasureString(strCaption);
|
|
|
|
szCaption.cy += 2;
|
|
|
|
CXTPFlowGraphImage* pImage = pNode->GetImage();
|
|
if (pImage)
|
|
{
|
|
szCaption.cx += 2 + pImage->GetSize().cx + 3;
|
|
}
|
|
|
|
CSize szSize = szCaption;
|
|
|
|
pDC->SetFont(&m_lfText);
|
|
|
|
int i;
|
|
CXTPFlowGraphConnectionPoints* pPoints = pNode->GetConnectionPoints();
|
|
|
|
for (i = 0; i < pPoints->GetCount(); i++)
|
|
{
|
|
CXTPFlowGraphConnectionPoint* pPoint = pPoints->GetAt(i);
|
|
CSize szItem = pPoint->GetMarkupUIElement() ?
|
|
pDC->MeasureMarkupElement(pPoint->GetMarkupUIElement()) :
|
|
pDC->MeasureString(pPoint->GetCaption());
|
|
szItem.cy += 2;
|
|
|
|
if (pPoint->GetImage())
|
|
szItem.cx += pPoint->GetImage()->GetSize().cx + 2;
|
|
|
|
pPoint->m_rcPoint.SetRect(0, 0, szItem.cx, szItem.cy);
|
|
|
|
|
|
szSize.cy += szItem.cy;
|
|
szSize.cx = max(szSize.cx, szItem.cx);
|
|
}
|
|
|
|
int nTop = 2 * m_nNodeFrameSize + szCaption.cy;
|
|
szSize.cx += 10 + 2 * m_nPointTextMargin;
|
|
|
|
CSize sz = pNode->GetWindowSize();
|
|
if (sz != CSize(0, 0))
|
|
{
|
|
szSize.cy += sz.cy + m_nNodeFrameSize;
|
|
|
|
szSize.cx = max(szSize.cx, sz.cx + 2 * m_nNodeFrameSize);
|
|
|
|
pNode->m_rcWindow.SetRect(m_nNodeFrameSize, nTop, szSize.cx - m_nNodeFrameSize, nTop + sz.cy);
|
|
|
|
nTop += sz.cy + m_nNodeFrameSize;
|
|
}
|
|
|
|
szSize.cx = max(szSize.cx, pNode->GetUserSize().cx);
|
|
|
|
pNode->m_rcCaption.SetRect(m_nNodeFrameSize, m_nNodeFrameSize, szSize.cx - m_nNodeFrameSize, m_nNodeFrameSize + szCaption.cy);
|
|
|
|
if (pPoints->GetCount())
|
|
szSize.cy += m_nNodeFrameSize;
|
|
|
|
for (i = 0; i < pPoints->GetCount(); i++)
|
|
{
|
|
CXTPFlowGraphConnectionPoint* pPoint = pPoints->GetAt(i);
|
|
pPoint->m_rcPoint.SetRect(m_nNodeFrameSize, nTop, szSize.cx - m_nNodeFrameSize, nTop + pPoint->m_rcPoint.Height());
|
|
|
|
nTop += pPoint->m_rcPoint.Height();
|
|
}
|
|
|
|
|
|
szSize.cy += 2 * m_nNodeFrameSize;
|
|
|
|
szSize.cy = max(szSize.cy, pNode->GetUserSize().cy);
|
|
|
|
pNode->m_szActualSize = szSize;
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::RecalcConnectionLayout(CXTPFlowGraphDrawContext* /*pDC*/, CXTPFlowGraphConnection* pConnection)
|
|
{
|
|
CXTPFlowGraphConnectionPoint* pFrom = pConnection->GetOutputPoint();
|
|
CXTPFlowGraphConnectionPoint* pTo = pConnection->GetInputPoint();
|
|
|
|
if (pFrom == NULL)
|
|
return;
|
|
|
|
CPoint ptFrom, ptTo;
|
|
|
|
ptFrom = pFrom->GetNode()->GetLocation();
|
|
ptFrom.x += pFrom->GetNode()->GetSize().cx;
|
|
ptFrom.y += pFrom->m_rcPoint.CenterPoint().y;
|
|
|
|
if (pTo != NULL)
|
|
{
|
|
ptTo = pTo->GetNode()->GetLocation();
|
|
ptTo.y += pTo->m_rcPoint.CenterPoint().y;
|
|
|
|
if (pTo->GetType() == xtpFlowGraphPointInputAndOutput)
|
|
{
|
|
if (ptFrom.x > ptTo.x)
|
|
ptTo.x += pTo->GetNode()->GetSize().cx;
|
|
}
|
|
|
|
pConnection->m_ptInputPoint = ptTo;
|
|
}
|
|
else
|
|
{
|
|
ptTo = pConnection->m_ptInputPoint;
|
|
}
|
|
|
|
if (pFrom->GetType() == xtpFlowGraphPointInputAndOutput)
|
|
{
|
|
if (ptTo.x < ptFrom.x - pFrom->GetNode()->GetSize().cx / 2)
|
|
ptFrom.x -= pFrom->GetNode()->GetSize().cx;
|
|
}
|
|
|
|
|
|
pConnection->m_ptOutputPoint = ptFrom;
|
|
|
|
GraphicsPath* path = new GraphicsPath();
|
|
|
|
XTPFlowGraphConnectorType type = pConnection->GetStyle() == -1 ? m_nConnectorType : (XTPFlowGraphConnectorType)pConnection->GetStyle();
|
|
|
|
CPoint ptControlPoint = pConnection->GetControlPoint();
|
|
|
|
if (type == xtpFlowGraphConnectorStraight)
|
|
{
|
|
if (ptControlPoint != CPoint(-1, -1))
|
|
{
|
|
Point pts[] = {Point(ptFrom.x, ptFrom.y), Point(ptControlPoint.x, ptControlPoint.y), Point(ptTo.x, ptTo.y) };
|
|
|
|
path->AddLines(pts, 3);
|
|
}
|
|
else
|
|
{
|
|
path->AddLine(ptFrom.x, ptFrom.y, ptTo.x, ptTo.y);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ptControlPoint != CPoint(-1, -1))
|
|
{
|
|
/*PointF pt[3] = {PointF((REAL)ptFrom.x, (REAL)ptFrom.y), PointF((REAL)pConnection->GetControlPoint().x, (REAL)pConnection->GetControlPoint().y),
|
|
PointF((REAL)ptTo.x, (REAL)ptTo.y) };
|
|
path->AddCurve(pt, 3);*/
|
|
|
|
PointF pt2[4] = {PointF((REAL)ptFrom.x, (REAL)ptFrom.y),
|
|
PointF((REAL)ptControlPoint.x, (REAL)ptFrom.y), PointF((REAL)ptControlPoint.x, (REAL)ptTo.y),
|
|
PointF((REAL)ptTo.x, (REAL)ptTo.y) };
|
|
|
|
path->AddBeziers(pt2, 4);
|
|
|
|
}
|
|
else
|
|
{
|
|
PointF pt[4] = {PointF((REAL)ptFrom.x, (REAL)ptFrom.y), PointF((REAL)(ptFrom.x + ptTo.x) / 2, (REAL)ptFrom.y),
|
|
PointF(REAL(ptFrom.x + ptTo.x) / 2, (REAL)ptTo.y), PointF((REAL)ptTo.x, (REAL)ptTo.y) };
|
|
path->AddBeziers(pt, 4);
|
|
}
|
|
}
|
|
|
|
|
|
SAFE_DELETE(pConnection->m_pPath);
|
|
pConnection->m_pPath = path;
|
|
|
|
}
|
|
|
|
COLORREF CXTPFlowGraphPaintManager::GetDarkColor(COLORREF clrBackground)
|
|
{
|
|
DWORD dwHSLBackground = CXTPDrawHelpers::RGBtoHSL(clrBackground);
|
|
DWORD dwL = GetBValue(dwHSLBackground);
|
|
|
|
DWORD dwDark = MulDiv(dwL, 2, 3);
|
|
return CXTPDrawHelpers::HSLtoRGB(RGB(GetRValue(dwHSLBackground), GetGValue(dwHSLBackground), dwDark));
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::DrawNode(CXTPFlowGraphDrawContext* pDC, CXTPFlowGraphNode* pNode)
|
|
{
|
|
CRect rcNodeBounds = GetNodeBoundingRectangle(pNode);
|
|
CRect rcBounds = pDC->GetClipRect();
|
|
CXTPFlowGraphControl* pControl = pNode->GetControl();
|
|
|
|
if (rcBounds.right < rcNodeBounds.left || rcBounds.left > rcNodeBounds.right || rcBounds.top > rcNodeBounds.bottom || rcBounds.bottom < rcNodeBounds.top)
|
|
return;
|
|
|
|
CRect rc(pNode->GetLocation(), pNode->GetSize());
|
|
|
|
COLORREF clrNode = pNode->GetColor();
|
|
if (clrNode == -1) clrNode = m_clrNodeBackground;
|
|
COLORREF clrSelection = m_clrSelection;
|
|
if (pNode->IsSelected())
|
|
clrNode = clrSelection;
|
|
|
|
COLORREF clrFrame = GetDarkColor(clrNode);
|
|
|
|
pDC->FillSolidRect(rc, clrNode);
|
|
|
|
pDC->DrawFrame(rc.left, rc.top, rc.Width(), rc.Height(), m_nNodeFrameSize, clrFrame);
|
|
|
|
CString strCaption = pNode->GetCaption();
|
|
|
|
pDC->SetFont(&m_lfCaption);
|
|
|
|
int nCaptionHeight = pNode->m_rcCaption.Height();
|
|
|
|
pDC->SetTextColor(m_clrTextColor);
|
|
|
|
CRect rcCaption(rc.left, rc.top + m_nNodeFrameSize, rc.right, rc.top + nCaptionHeight + m_nNodeFrameSize);
|
|
UINT uCaptionFormat = DT_CENTER | DT_VCENTER;
|
|
|
|
CXTPFlowGraphImage* pImage = pNode->GetImage();
|
|
if (pImage)
|
|
{
|
|
CSize sz = pImage->GetSize();
|
|
|
|
pDC->DrawImage(pImage, CRect(CPoint(rc.left + m_nNodeFrameSize + 3, rc.top + m_nNodeFrameSize + (nCaptionHeight - sz.cy) / 2), sz));
|
|
|
|
rcCaption = CRect(rc.left + m_nNodeFrameSize + 3 + sz.cx + 2, rc.top + m_nNodeFrameSize, rc.right, rc.top + nCaptionHeight + m_nNodeFrameSize);
|
|
uCaptionFormat = DT_LEFT | DT_VCENTER;
|
|
}
|
|
|
|
if (pNode->GetMarkupUIElement())
|
|
{
|
|
pDC->DrawMarkupElement(pNode->GetMarkupUIElement(), rcCaption, uCaptionFormat);
|
|
}
|
|
else
|
|
{
|
|
pDC->DrawText(pNode->GetCaption(), rcCaption, uCaptionFormat);
|
|
}
|
|
|
|
int nCount = pNode->GetConnectionPoints()->GetCount();
|
|
|
|
if (nCount > 0 || !pNode->m_rcWindow.IsRectEmpty())
|
|
{
|
|
pDC->FillSolidRect(rc.left, rc.top + nCaptionHeight + m_nNodeFrameSize, rc.Width(), m_nNodeFrameSize, clrFrame);
|
|
}
|
|
|
|
if (nCount > 0 && !pNode->m_rcWindow.IsRectEmpty())
|
|
{
|
|
pDC->FillSolidRect(rc.left, rc.top + pNode->m_rcWindow.bottom, rc.Width(), m_nNodeFrameSize, clrFrame);
|
|
}
|
|
|
|
if (!pNode->m_rcWindow.IsRectEmpty() && pNode->GetWindowHandle() == NULL)
|
|
{
|
|
pNode->DrawWindowContent(pDC);
|
|
}
|
|
|
|
pDC->SetFont(&m_lfText);
|
|
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPFlowGraphConnectionPoint* pPoint = pNode->GetConnectionPoints()->GetAt(i);
|
|
CSize szItem = pPoint->m_rcPoint.Size();
|
|
|
|
int nTop = pPoint->m_rcPoint.top + rc.top;
|
|
|
|
if (pControl->GetZoomLevel() >= m_dMinZoomLevelConnectionPoints)
|
|
{
|
|
pDC->SetTextColor(m_clrTextColor);
|
|
|
|
CRect rcText(rc.left + m_nNodeFrameSize + m_nPointTextMargin, nTop, rc.right - (m_nNodeFrameSize + m_nPointTextMargin), nTop + szItem.cy);
|
|
|
|
if (pPoint->GetImage())
|
|
{
|
|
CSize sz = pPoint->GetImage()->GetSize();
|
|
|
|
pDC->DrawImage(pPoint->GetImage(), CRect(CPoint(rcText.left, (rcText.top + rcText.bottom - sz.cy) / 2), sz));
|
|
|
|
rcText.left += sz.cx + 2;
|
|
|
|
}
|
|
|
|
UINT uFormat = DT_VCENTER | (pPoint->GetType() == xtpFlowGraphPointOutput ? DT_RIGHT : DT_LEFT);
|
|
|
|
if (pPoint->GetMarkupUIElement())
|
|
pDC->DrawMarkupElement(pPoint->GetMarkupUIElement(), rcText, uFormat);
|
|
else
|
|
pDC->DrawText(pPoint->GetCaption(), rcText, uFormat);
|
|
}
|
|
|
|
COLORREF clrEllipse = pPoint->GetColor();
|
|
if (clrEllipse == (COLORREF)-1)
|
|
clrEllipse = clrFrame;
|
|
|
|
if (pPoint->GetType() & xtpFlowGraphPointInput)
|
|
{
|
|
pDC->SetBrush(pPoint->IsSelected() ? clrSelection : clrEllipse);
|
|
pDC->SetPen(0, 0);
|
|
|
|
CPoint pt(rc.left + 1, nTop + szItem.cy / 2);
|
|
|
|
|
|
pDC->Ellipse(CRect(pt.x - m_nEllipseSize / 2, pt.y - m_nEllipseSize / 2, pt.x + m_nEllipseSize - m_nEllipseSize / 2, pt.y + m_nEllipseSize - m_nEllipseSize / 2));
|
|
}
|
|
|
|
if (pPoint->GetType() & xtpFlowGraphPointOutput)
|
|
{
|
|
pDC->SetBrush(pPoint->IsSelected() ? clrSelection : clrEllipse);
|
|
pDC->SetPen(0, 0);
|
|
|
|
CPoint pt(rc.right - 1, nTop + szItem.cy / 2);
|
|
|
|
pDC->Ellipse(CRect(pt.x - (m_nEllipseSize - m_nEllipseSize / 2), pt.y - (m_nEllipseSize - m_nEllipseSize / 2), pt.x + m_nEllipseSize / 2, pt.y + m_nEllipseSize / 2));
|
|
}
|
|
}
|
|
}
|
|
|
|
REAL XTPGetDistance(PointF& a, PointF& b)
|
|
{
|
|
return (REAL)sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y));
|
|
}
|
|
|
|
PointF XTPGetPosition(GraphicsPath* path, REAL dist)
|
|
{
|
|
int pointCount = path->GetPointCount();
|
|
|
|
PointF* points = (PointF*)malloc(pointCount * sizeof(PointF));
|
|
path->GetPathPoints(points, pointCount);
|
|
|
|
PointF res(points[pointCount - 1]);
|
|
|
|
if (dist >= 0)
|
|
{
|
|
for (int i = 0; i < pointCount - 1; i++)
|
|
{
|
|
REAL diff = (REAL)XTPGetDistance(points[i + 1], points[i]);
|
|
if (diff < dist)
|
|
{
|
|
dist -= diff;
|
|
continue;
|
|
}
|
|
|
|
res.X = points[i].X + (points[i + 1].X - points[i].X) * dist / diff;
|
|
res.Y = points[i].Y + (points[i + 1].Y - points[i].Y) * dist / diff;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dist = -dist;
|
|
res = points[0];
|
|
|
|
for (int i = pointCount - 1; i >= 1; i--)
|
|
{
|
|
REAL diff = (REAL)XTPGetDistance(points[i - 1], points[i]);
|
|
if (diff < dist)
|
|
{
|
|
dist -= diff;
|
|
continue;
|
|
}
|
|
|
|
res.X = points[i].X + (points[i - 1].X - points[i].X) * dist / diff;
|
|
res.Y = points[i].Y + (points[i - 1].Y - points[i].Y) * dist / diff;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
free(points);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::DrawConnection(CXTPFlowGraphDrawContext* pDC, CXTPFlowGraphConnection* pConnection)
|
|
{
|
|
CRect rcConnectionBounds = pConnection->GetBoundingRect();
|
|
CRect rcBounds = pDC->GetClipRect();
|
|
CXTPFlowGraphControl* pControl = pConnection->GetControl();
|
|
|
|
if (rcBounds.right < rcConnectionBounds.left || rcBounds.left > rcConnectionBounds.right ||
|
|
rcBounds.top > rcConnectionBounds.bottom || rcBounds.bottom < rcConnectionBounds.top)
|
|
return;
|
|
|
|
if (pControl->GetZoomLevel() < m_dMinZoomLevelConnections)
|
|
return;
|
|
|
|
|
|
COLORREF clrConnection = pConnection->GetColor() != (COLORREF)-1 ? pConnection->GetColor() : m_clrConnection;
|
|
if (pConnection->IsSelected())
|
|
clrConnection = m_clrSelection;
|
|
|
|
pDC->SetPen(clrConnection, 2);
|
|
pDC->DrawCurve(pConnection->m_pPath);
|
|
|
|
if (pConnection->IsSelected() && pConnection->GetControlPoint() != CPoint(-1, -1))
|
|
{
|
|
pDC->SetPen(0, 0);
|
|
pDC->SetBrush(clrConnection);
|
|
|
|
CPoint pt(pConnection->GetControlPoint());
|
|
pDC->Ellipse(CRect(pt.x - 3, pt.y - 3, pt.x + 3, pt.y + 3));
|
|
}
|
|
|
|
if (m_bDrawArrow)
|
|
{
|
|
Gdiplus::GraphicsPath* path = pConnection->m_pPath->Clone();
|
|
path->Flatten();
|
|
|
|
const REAL rArrow = 10.0;
|
|
PointF ptEnd = XTPGetPosition(path, REAL(-m_nEllipseSize / 2));
|
|
PointF ptFrom = XTPGetPosition(path, REAL(- (m_nEllipseSize / 2 + rArrow)));
|
|
|
|
Point ptArrow[3];
|
|
|
|
PointF ptDiff = ptFrom - ptEnd;
|
|
|
|
ptArrow[0] = Point((int)ptEnd.X, (int)ptEnd.Y);
|
|
ptArrow[1] = Point(int(ptFrom.X - ptDiff.Y * (4.0) / rArrow), int(ptFrom.Y + ptDiff.X * (4.0) / rArrow));
|
|
ptArrow[2] = Point(int(ptFrom.X + ptDiff.Y * (4.0) / rArrow), int(ptFrom.Y - ptDiff.X * (4.0) / rArrow));
|
|
|
|
pDC->SetBrush(clrConnection);
|
|
pDC->FillPolygon((POINT*)ptArrow, 3);
|
|
|
|
delete path;
|
|
}
|
|
}
|
|
|
|
CRect CXTPFlowGraphPaintManager::GetNodeBoundingRectangle(CXTPFlowGraphNode* pNode)
|
|
{
|
|
CRect rc(pNode->GetLocation(), pNode->GetSize());
|
|
rc.InflateRect(m_nEllipseSize / 2, 0);
|
|
|
|
return rc;
|
|
}
|
|
|
|
BOOL CXTPFlowGraphPaintManager::HitTestConnectionArea(const CXTPFlowGraphConnectionPoint* pPoint, CPoint point)
|
|
{
|
|
CXTPFlowGraphNode* pNode = pPoint->GetNode();
|
|
if (!pNode)
|
|
return FALSE;
|
|
|
|
CXTPFlowGraphPage* pPage = pNode->GetPage();
|
|
point = pPage->ScreenToPage(point);
|
|
point.Offset(-pNode->GetLocation());
|
|
|
|
|
|
CRect rc = pPoint->m_rcPoint;
|
|
|
|
if (pPoint->GetType() & xtpFlowGraphPointInput)
|
|
{
|
|
CRect rc(rc.left - m_nEllipseSize / 2, rc.top, rc.left + m_nEllipseSize / 2, rc.bottom);
|
|
|
|
if (rc.PtInRect(point))
|
|
return TRUE;
|
|
}
|
|
|
|
if (pPoint->GetType() & xtpFlowGraphPointOutput)
|
|
{
|
|
CRect rc(rc.right - m_nEllipseSize / 2, rc.top, rc.right + m_nEllipseSize / 2, rc.bottom);
|
|
if (rc.PtInRect(point))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
CRect CXTPFlowGraphPaintManager::GetCaptionRect(CXTPFlowGraphElement* pElement)
|
|
{
|
|
CRect rc(0, 0, 0, 0);
|
|
|
|
if (pElement->IsKindOf(RUNTIME_CLASS(CXTPFlowGraphNode)))
|
|
{
|
|
CXTPFlowGraphNode* pNode = (CXTPFlowGraphNode*)pElement;
|
|
rc = pNode->m_rcCaption;
|
|
rc.OffsetRect(pNode->GetLocation());
|
|
}
|
|
else if(pElement->IsKindOf(RUNTIME_CLASS(CXTPFlowGraphConnectionPoint)))
|
|
{
|
|
CXTPFlowGraphConnectionPoint* pConnectionPoint = (CXTPFlowGraphConnectionPoint*)pElement;
|
|
|
|
CXTPFlowGraphNode* pNode = pConnectionPoint->GetNode();
|
|
|
|
rc = pConnectionPoint->m_rcPoint;
|
|
rc.DeflateRect(m_nPointTextMargin, 0, m_nPointTextMargin, 1);
|
|
rc.OffsetRect(pNode->GetLocation());
|
|
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
void CXTPFlowGraphPaintManager::DrawNodeGroup(CXTPFlowGraphDrawContext* pDC, CXTPFlowGraphNodeGroup* pNodeGroup)
|
|
{
|
|
CRect rc = pNodeGroup->GetWorkRect();
|
|
rc.InflateRect(m_nEllipseSize / 2, 10);
|
|
|
|
BOOL bSelected = pNodeGroup->GetAt(0)->IsSelected();
|
|
|
|
COLORREF clrGroup = bSelected ? m_clrSelection : RGB(220, 220, 220);
|
|
|
|
|
|
COLORREF clrSelection = clrGroup | 0x55000000;
|
|
pDC->FillSolidRect(rc, clrSelection);
|
|
|
|
COLORREF clrFrame = GetDarkColor(clrGroup);
|
|
|
|
pDC->DrawFrame(rc.left, rc.top, rc.Width(), rc.Height(), 1, clrFrame);
|
|
}
|
|
|
|
|
|
|
|
|