umleditor.cpp
来自「uml编辑器很牛」· C++ 代码 · 共 1,677 行 · 第 1/4 页
CPP
1,677 行
// Click on the arrow up icon
CString package = GetPackage();
int size = round( 20 * GetZoom() );
if( package.GetLength() && point.x < size && point.y < size )
{
CUMLEntity* obj = GetAllNamedObject( package );
if( obj )
SetPackage( obj->GetPackage() );
else
SetPackage( _T( "" ) );
RedrawWindow();
return;
}
// Store the line being drawn, if any
CPoint virtpoint( point );
ScreenToVirtual( virtpoint );
CUMLLineSegment* seg = NULL;
if( m_drawingLine && GetInteractMode() == MODE_RESIZING )
seg = dynamic_cast< CUMLLineSegment* >( GetSelectedObject() );
// If we are starting to draw a new link, we save the object
// link point under the cursor, as we want to set the start
// of the link to this object.
int type = LINK_NONE;
int savedtype = LINK_NONE;
CUMLEntity* obj = NULL;
CUMLEntity* mainobj = NULL;
if( GetInteractMode() == MODE_DRAWING )
{
m_drawingLine = FALSE;
CUMLLineSegment* seg = dynamic_cast< CUMLLineSegment* >( GetDrawingObject() );
if( seg )
{
int count = 0;
while( ( obj = GetObjectAt( count++ ) ) )
{
if( obj->GetPackage() == GetPackage() )
{
type = obj->GetLinkCode( virtpoint );
if( type & LINK_ALL )
{
mainobj = obj;
m_drawingLine = TRUE;
savedtype = type;
count = -2;
}
}
}
// there was no object under the cursor, and we
// will not be able to draw a link
if( !m_drawingLine )
SetInteractMode( MODE_NONE );
}
}
CDiagramEditor::OnLButtonDown( nFlags, point );
if( GetInteractMode() == MODE_RESIZING && m_drawingLine && mainobj && savedtype != LINK_NONE )
{
// We have added a line segment, and set the link start point to it
CUMLLineSegment* seg = dynamic_cast< CUMLLineSegment* >( GetSelectedObject() );
if( seg )
{
seg->SetLink( LINK_START, mainobj->GetName() );
seg->SetLinkType( LINK_START, savedtype );
int diff = 0;
if( savedtype == LINK_TOP || savedtype == LINK_BOTTOM )
{
diff = virtpoint.x - static_cast< int >( mainobj->GetLeft() );
if( GetSnapToGrid() )
diff = SnapX( diff );
}
else if( savedtype == LINK_LEFT || savedtype == LINK_RIGHT )
{
diff = virtpoint.y - static_cast< int >( mainobj->GetTop() );
if( GetSnapToGrid() )
diff = SnapY( diff );
}
seg->SetOffset( LINK_START, diff );
if( savedtype == LINK_END )
{
CUMLLineSegment* line = dynamic_cast< CUMLLineSegment* >( mainobj );
line->SetLink( LINK_END, seg->GetName() );
line->SetLinkType( LINK_END, LINK_START );
}
else
{
CSize minsize = mainobj->GetMinimumSize();
if( savedtype == LINK_TOP || savedtype == LINK_BOTTOM )
{
if( minsize.cx < diff )
mainobj->SetMinimumSize( CSize( diff, minsize.cy ) );
}
else
if( minsize.cy < diff )
mainobj->SetMinimumSize( CSize( minsize.cx, diff ) );
}
}
}
if( GetInteractMode() == MODE_RUBBERBANDING && m_drawingLine )
{
// Clicked outside the link point. Force continue drawing.
if( !seg )
m_drawingLine = FALSE;
else
{
if( seg->IsHorizontal() )
seg->SetRight( virtpoint.x );
else
seg->SetBottom( virtpoint.y );
seg->Select( TRUE );
SetInteractMode( MODE_RESIZING, DEHT_BOTTOMRIGHT );
}
}
SetCursor( point );
}
void CUMLEditor::OnLButtonUp( UINT nFlags, CPoint point )
/* ============================================================
Function : CUMLEditor::OnLButtonUp
Description : Handler for "WM_LBUTTONUP" message.
Access : Protected
Return : void
Parameters : UINT nFlags - Not used
CPoint point - Position of mouse cursor
Usage : Called from MFC. Used to link lines if we
are drawing lines.
============================================================*/
{
// We get this before the base class implementation
// to avoid any unselects in there.
CUMLEntityContainer* objs = GetUMLEntityContainer();
CUMLLineSegment* selobj = dynamic_cast< CUMLLineSegment* >( GetSelectedObject() );
CDiagramEditor::OnLButtonUp( nFlags, point );
if( selobj && m_drawingLine )
{
if( selobj->GetRight() == selobj->GetLeft() && selobj->GetTop() == selobj->GetBottom() )
// If we have a zero-size line, we force resizing
SetInteractMode( MODE_RESIZING, DEHT_BOTTOMRIGHT );
else
{
// We try to find a link point to attach this line to
UnselectAll();
// Check if we can attatch to a link point.
BOOL attached = FALSE;
int count = 0;
CUMLEntity* obj;
point = selobj->GetRect().BottomRight();
while( ( obj = GetObjectAt( count++ ) ) )
{
if( obj->GetPackage() == GetPackage() )
{
int linkCode = obj->GetLinkCode( point );
if( linkCode != LINK_NONE && obj != selobj )
{
if( ( selobj->IsHorizontal() && ( linkCode == LINK_LEFT || linkCode == LINK_RIGHT ) ) ||
( !selobj->IsHorizontal() && ( linkCode == LINK_TOP || linkCode == LINK_BOTTOM ) ) )
{
// We have a hit
// Attach to an object
attached = TRUE;
selobj->SetLink( LINK_END, obj->GetName() );
selobj->SetLinkType( LINK_END, linkCode );
int diff = 0;
if( linkCode == LINK_TOP || linkCode == LINK_BOTTOM )
{
diff = point.x - static_cast< int >( obj->GetLeft() );
if( GetSnapToGrid() )
diff = SnapX( diff );
}
else if( linkCode == LINK_LEFT || linkCode == LINK_RIGHT )
{
diff = point.y - static_cast< int >( obj->GetTop() );
if( GetSnapToGrid() )
diff = SnapY( diff );
}
selobj->SetOffset( LINK_END, diff );
if( linkCode == LINK_START || linkCode == LINK_END )
{
CUMLLineSegment* line = dynamic_cast< CUMLLineSegment* >( obj );
if( line )
{
line->SetLink( LINK_START, selobj->GetName() );
line->SetLinkType( LINK_START, LINK_END );
}
}
else
{
CSize minsize = obj->GetMinimumSize();
if( linkCode == LINK_TOP || linkCode == LINK_BOTTOM )
{
if( minsize.cx < diff )
obj->SetMinimumSize( CSize( diff, minsize.cy ) );
}
else
if( minsize.cy < diff )
obj->SetMinimumSize( CSize( minsize.cx, diff ) );
}
objs->ReduceLine( selobj );
objs->SetDefaultLineStyle( selobj );
RedrawWindow();
count = -2;
}
}
}
}
if( !attached )
{
CUMLLineSegment* line = static_cast< CUMLLineSegment* >( GetDrawingObject()->Clone() );
CRect rect = selobj->GetRect();
CPoint virtpoint( rect.BottomRight() );
line->SetRect( CRect( virtpoint.x, virtpoint.y, virtpoint.x , virtpoint.y ) );
line->Select( TRUE );
// Create a link between selobj and newobj
selobj->SetLinkType( LINK_END, LINK_START );
selobj->SetLink( LINK_END, line->GetName() );
line->SetLink( LINK_START, selobj->GetName() );
line->SetLinkType( LINK_START, LINK_END );
objs->ReduceLine( selobj );
// Add the object to the container
objs->Add( line );
SetInteractMode( MODE_RESIZING, DEHT_BOTTOMRIGHT );
}
else
m_drawingLine = FALSE;
}
}
if( GetInteractMode() == MODE_NONE || GetInteractMode() == MODE_RUBBERBANDING )
{
GetUMLEntityContainer()->DeleteDanglingLines();
RedrawWindow();
}
SetCursor( point );
}
void CUMLEditor::OnMouseMove( UINT nFlags, CPoint point )
/* ============================================================
Function : CUMLEditor::OnMouseMove
Description : Handler for the "WM_MOUSEMOVE" message.
Access : Protected
Return : void
Parameters : UINT nFlags - Not used
CPoint point - Not used
Usage : Called from MFC. We add handling
to close screen redraws as we are moving
lots of stuff (all the attached objects in
addition to the primarily moved). We also
do secondary movements here - that is,
objects linked to the one(s) being moved
must be moved as well, even if they are
not selected.
============================================================*/
{
SetCursor( point );
// We want to skip mouse movement handling if a couple
// of lines are selected.
if( !PartialLinesSelected() )
{
CRect rect;
CUMLLineSegment* savedobj = NULL;
if( ( GetInteractMode() == MODE_MOVING || GetInteractMode() == MODE_RESIZING ) )
{
SetRedraw( FALSE );
if( GetSelectCount() == 1 )
{
CUMLLineSegment* obj = dynamic_cast< CUMLLineSegment* >( GetSelectedObject() );
if( obj )
{
if( IsConnected( obj ) )
{
rect = obj->GetRect();
savedobj = obj;
}
}
}
}
CDiagramEditor::OnMouseMove( nFlags, point );
// We want to stop movement of connected lines in the line direction.
// This is accomplished here, by resetting either the horizontal or
// vertical coordinates.
if( ( GetInteractMode() == MODE_MOVING || GetInteractMode() == MODE_RESIZING ) )
{
if( savedobj )
{
// Forced move
if( rect.top == rect.bottom )
{
savedobj->SetLeft( rect.left );
savedobj->SetRight( rect.right );
}
else
{
savedobj->SetTop( rect.top );
savedobj->SetBottom( rect.bottom );
}
}
ModifyLinkedPositions();
SetRedraw( TRUE );
RedrawWindow();
}
}
}
void CUMLEditor::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
/* ============================================================
Function : CUMLEditor::OnKeyDown
Description : Handles the WM_KEYDOWN-message.
Access : Protected
Return : void
Parameters : UINT nChar - Not used
UINT nRepCnt - Not used
UINT nFlags - Not used
Usage : Called from MFC. We override this as
objects might be moved and we will have
to move unlinked objects as well.
============================================================*/
{
if( !PartialLinesSelected() || nChar == VK_DELETE )
{
SetRedraw( FALSE );
CRect rect;
CUMLLineSegment* savedobj = NULL;
if( GetSelectCount() == 1 )
{
CUMLLineSegment* obj = dynamic_cast< CUMLLineSegment* >( GetSelectedObject() );
if( obj && IsConnected( obj ) )
{
rect = obj->GetRect();
savedobj = obj;
}
}
CDiagramEditor::OnKeyDown( nChar, nRepCnt, nFlags );
if( nChar != VK_DELETE )
{
if( savedobj )
{
// Forced move
if( rect.top == rect.bottom )
{
savedobj->SetLeft( rect.left );
savedobj->SetRight( rect.right );
}
else
{
savedobj->SetTop( rect.top );
savedobj->SetBottom( rect.bottom );
}
}
}
ModifyLinkedPositions();
SetRedraw( TRUE );
RedrawWindow();
}
}
BOOL CUMLEditor::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
/* ============================================================
Function : CUMLEditor::OnSetCursor
Description : Handler for the "WM_SETCURSOR" message.
Access : Protected
Return : BOOL - "TRUE" if handled
Parameters : CWnd* pWnd - Not used
UINT nHitTest - Not used
UINT message - Not used
Usage : Called from MFC. We set out custom cursors.
============================================================*/
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?