📄 diagrameditor.cpp
字号:
Return : void
Parameters : int keyInterface - The new flags
Usage : Call to set the keys the editor will handle.
See "GetKeyboardInterface".
============================================================*/
{
m_keyInterface = keyInterface;
}
void CDiagramEditor::SetPopupMenu( CDiagramMenu* popupmenu )
/* ============================================================
Function : CDiagramEditor::SetPopupMenu
Description : Sets the editor popup menu to popupmenu.
Access : Public
Return : void
Parameters : CDiagramMenu* popupmenu - The popup menu
to use.
Usage : Call to set the popup menu for the editor.
Note that the editor owns the popup menu.
============================================================*/
{
if( m_popupMenu )
delete m_popupMenu;
m_popupMenu = popupmenu;
}
CDiagramMenu* CDiagramEditor::GetPopupMenu() const
/* ============================================================
Function : CDiagramEditor::GetPopupMenu
Description : Returns a pointer to the editor popup menu.
Access : Public
Return : CDiagramMenu* - The popup menu.
Might be "NULL".
Parameters : none
Usage : Call to get a pointer to the editor popup
menu. Note that the editor owns the menu.
============================================================*/
{
return m_popupMenu;
}
/////////////////////////////////////////////////////////////////////////////
// CDiagramEditor mouse handling
void CDiagramEditor::OnLButtonDown( UINT nFlags, CPoint point )
/* ============================================================
Function : CDiagramEditor::OnLButtonDown
Description : Handles the "WM_LBUTTONDOWN" message. We
select/deselect objects and set internal
modes as appropriate.
Access : Protected
Return : void
Parameters : UINT nFlags - Key-down flag
CPoint point - Mouse position
Usage : Called from MFC. Do not call from code.
============================================================*/
{
SetPanning( FALSE );
// Declarations
int count = 0;
CDiagramEntity* obj;
CPoint virtpoint( point );
ScreenToVirtual( virtpoint );
// Setting up
SetFocus();
SetCapture();
// Resetting modes
if( m_interactMode != MODE_DRAWING )
{
m_interactMode = MODE_NONE;
m_subMode = DEHT_NONE;
}
m_bgResizeSelected = FALSE;
m_multiSelObj = NULL;
// If we click on an already selected object,
// and have more than one object selected,
// we want to move all selected objects
if( m_objs && GetSelectCount() > 1 && !( nFlags & MK_CONTROL ) )
{
while( ( obj = m_objs->GetAt( count++ ) ) )
{
if( obj->GetHitCode( virtpoint ) == DEHT_BODY && obj->IsSelected() )
{
m_interactMode = MODE_MOVING;
CRect rect = obj->GetRect();
// We might need to use a denormalized
// rect, as lines will not be normalized.
BOOL useright = FALSE;
BOOL usebottom = FALSE;
if( rect.left > rect.right )
useright = TRUE;
if( rect.top > rect.bottom )
usebottom = TRUE;
VirtualToScreen( rect );
int startx = rect.left;
if( useright )
startx = rect.right;
int starty = rect.top;
if( usebottom )
starty = rect.bottom;
// Anchor object
m_multiSelObj = obj;
// Offset from top-left corner
// in the anchor object.
m_deltaPoint = point - CPoint( startx, starty );
}
}
if( m_interactMode == MODE_MOVING )
{
// We have clicked in one of many selected objects.
// Set cursor and snapshot for Undo.
::SetCursor( m_multiSelObj->GetCursor( DEHT_BODY ) );
m_objs->Snapshot();
}
}
if( m_objs && m_interactMode == MODE_DRAWING )
{
// The user wants to draw an object.
// We add it to the data container and sets the appropriate mode
if( OutsideRestraints( virtpoint ) )
{
m_interactMode = MODE_NONE;
return;
}
m_objs->Snapshot();
UnselectAll();
CDiagramEntity* newobj = m_drawObj->Clone();
// If snap-to-grid is on, we must
// update the desired position
if( m_snap )
{
virtpoint.x = SnapX( virtpoint.x );
virtpoint.y = SnapY( virtpoint.y );
}
newobj->SetRect( CRect( virtpoint.x, virtpoint.y, virtpoint.x , virtpoint.y ) );
newobj->Select( TRUE );
// Add the object to the container
AddObject( newobj );
// Set modes
m_interactMode = MODE_RESIZING;
m_subMode = DEHT_BOTTOMRIGHT;
}
if( m_objs && m_interactMode == MODE_NONE )
{
// Clearing states
// If Ctrl is not held down, we
// clear all selections
if( !( nFlags & MK_CONTROL ) )
UnselectAll();
count = GetObjectCount();
BOOL goon = TRUE;
// We check if we click on any object. If that is
// the case, we return on what part of the object
// we clicked.
while( goon && ( obj = m_objs->GetAt( --count ) ) )
{
CRect rect = obj->GetRect();
VirtualToScreen( rect );
int hitCode = obj->GetHitCode( point, rect );
if( hitCode != DEHT_NONE )
{
goon = FALSE;
if( !( nFlags & MK_CONTROL ) )
{
// We unselect all again, as we might
// have overlapping objects
UnselectAll();
obj->Select( TRUE );
}
else
{
// We toggle the selection of the
// object if Ctrl is pressed
if( obj->IsSelected() )
obj->Select( FALSE );
else
obj->Select( TRUE );
}
// We set the appropriate mode, either
// moving or resizing depending on where
// the click hit.
if( hitCode == DEHT_BODY && !( nFlags & MK_CONTROL ) )
{
::SetCursor( obj->GetCursor( DEHT_BODY ) );
m_interactMode = MODE_MOVING;
CRect rect = obj->GetRect();
// We might need to use a denormalized
// rect, as lines will not be normalized.
BOOL useright = FALSE;
BOOL usebottom = FALSE;
if( rect.left > rect.right )
useright = TRUE;
if( rect.top > rect.bottom )
usebottom = TRUE;
VirtualToScreen( rect );
int startx = rect.left;
if( useright )
startx = rect.right;
int starty = rect.top;
if( usebottom )
starty = rect.bottom;
if( GetSelectCount() > 1 )
m_multiSelObj = obj;
m_deltaPoint = point - CPoint( startx, starty );
}
else if( !( nFlags & MK_CONTROL ) )
{
m_interactMode = MODE_RESIZING;
m_subMode = hitCode;
}
else
m_interactMode = MODE_NONE;
}
}
// Save to undo-stack...
if( m_interactMode != MODE_NONE )
m_objs->Snapshot();
// If no objects were selected, we assume either
// rubberbanding or background resize
if( !IsAnyObjectSelected() )
{
if( m_bgResize )
{
// If we allow background resizing, we test if
// the click was inside the resize zone.
if( ( virtpoint.x >= GetVirtualSize().cx - m_bgResizeZone &&
virtpoint.x <= GetVirtualSize().cx )
||
( virtpoint.y >= GetVirtualSize().cy - m_bgResizeZone &&
virtpoint.y <= GetVirtualSize().cy )
)
{
m_bgResizeSelected = TRUE;
int hitCode = GetHitCode( virtpoint );
if( hitCode != DEHT_NONE && hitCode != DEHT_BODY )
{
// It was - set the appropriate mode
m_interactMode = MODE_BGRESIZING;
m_subMode = hitCode;
m_objs->Snapshot();
}
RedrawWindow();
}
}
if( m_interactMode == MODE_NONE )
{
// If nothing else is set, we assume
// rubberbanding.
m_selectionRect.left = m_selectionRect.right = point.x;
m_selectionRect.top = m_selectionRect.bottom = point.y;
m_interactMode = MODE_RUBBERBANDING;
}
}
}
// Cleaning up and redrawing as necessary.
RemoveUnselectedPropertyDialogs();
if( m_interactMode != MODE_NONE )
RedrawWindow();
CWnd::OnLButtonDown( nFlags, point );
}
void CDiagramEditor::OnMouseMove( UINT nFlags, CPoint point )
/* ============================================================
Function : CDiagramEditor::OnMouseMove
Description : Handles the "WM_MOUSEMOVE" message. We handle
moving or resizing of objects, or resizing
of the virtual screen.
Access : Protected
Return : void
Parameters : UINT nFlags - Key-down flags
CPoint point - Mouse position
Usage : Called from MFC. Do not call from code.
============================================================*/
{
if( m_interactMode != MODE_NONE )
{
CClientDC dc( this );
CRect clientRect;
GetClientRect( &clientRect );
CPoint virtpoint( point );
ScreenToVirtual( virtpoint );
if( m_interactMode == MODE_BGRESIZING )
{
if( m_snap )
{
virtpoint.x = SnapX( virtpoint.x );
virtpoint.y = SnapY( virtpoint.y );
}
virtpoint.x = max( virtpoint.x, 1 );
virtpoint.y = max( virtpoint.y, 1 );
int xsize = GetVirtualSize().cx;
int ysize = GetVirtualSize().cy;
if( m_subMode == DEHT_TOPRIGHT )
{
xsize = virtpoint.x;
}
else if( m_subMode == DEHT_RIGHTMIDDLE )
{
xsize = virtpoint.x;
}
else if( m_subMode == DEHT_BOTTOMRIGHT )
{
xsize = virtpoint.x;
ysize = virtpoint.y;
}
else if( m_subMode == DEHT_BOTTOMMIDDLE )
{
ysize = virtpoint.y;
}
else if( m_subMode == DEHT_BOTTOMLEFT )
{
ysize = virtpoint.y;
}
if( m_restraint == RESTRAINT_VIRTUAL )
{
CSize size = GetContainingSize();
xsize = max( size.cx, xsize );
ysize = max( size.cy, ysize );
}
else if( m_restraint == RESTRAINT_MARGIN )
{
CSize size = GetContainingSize();
xsize = max( size.cx + m_rightMargin, xsize );
ysize = max( size.cy + m_bottomMargin, ysize );
xsize = max( m_leftMargin + m_rightMargin, xsize );
ysize = max( m_topMargin + m_bottomMargin, ysize );
}
SetVirtualSize( CSize( xsize, ysize ) );
ScrollPoint( point );
}
if( m_interactMode == MODE_RESIZING )
{
if( m_snap )
{
virtpoint.x = SnapX( virtpoint.x );
virtpoint.y = SnapY( virtpoint.y );
}
// If we are moving, we will update one or
// two sides of the object.
double ypos = static_cast< double >( virtpoint.y );
double xpos = static_cast< double >( virtpoint.x );
CDiagramEntity* obj = GetSelectedObject();
if( obj )
{
CSize minimum = obj->GetMinimumSize();
CSize maximum = obj->GetMaximumSize();
if( m_subMode == DEHT_BOTTOMMIDDLE )
{
// Constraints
if( minimum.cy != -1 && ypos - obj->GetTop() < minimum.cy )
ypos = obj->GetTop() + minimum.cy;
if( maximum.cy != -1 && ypos - obj->GetTop() > maximum.cy )
ypos = obj->GetTop() + maximum.cy;
AdjustForRestraints( xpos, ypos );
obj->SetRect( obj->GetLeft(), obj->GetTop(), obj->GetRight(), ypos );
}
else if( m_subMode == DEHT_TOPMIDDLE )
{
// Constraints
if( minimum.cy != -1 && obj->GetBottom() - ypos < minimum.cy )
ypos = obj->GetBottom() - minimum.cy;
if( maximum.cy != -1 && obj->GetBottom() - ypos > maximum.cy )
ypos = obj->GetBottom() - maximum.cy;
AdjustForRestraints( xpos, ypos );
obj->SetRect( obj->GetLeft(), ypos, obj->GetRight(), obj->GetBottom() );
}
else if( m_subMode == DEHT_LEFTMIDDLE )
{
// Constraints
if( minimum.cx != -1 && obj->GetRight() - xpos < minimum.cx )
xpos = obj->GetRight() - minimum.cx;
if( maximum.cx != -1 && obj->GetRight() - xpos > maximum.cx )
xpos = obj->GetRight() - max
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -