⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diagrameditor.cpp

📁 大家用过UML的流程图设计器吧
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	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 + -