#pragma once
namespace mouse_modes {
using namespace visual_objects;
enum MOUSE_MODE {Mode_Move, Mode_Line, Mode_Square, Mode_Ellipse};
class CMouseMode
{
protected:
ref<CWindowImplBase> m_rWindow;
ref<CDocument> m_rDocument;
ref<CVisualObject> m_rVisualObject;
public:
MOUSE_MODE m_MouseModeCode;
CPoint m_LastMousePoint;
CMouseMode(ref<CWindowImplBase> rWindow, ref<CDocument> rDocument, MOUSE_MODE MouseModeCode)
{
m_rWindow=rWindow;
m_rDocument=rDocument;
int i=0;
m_MouseModeCode=MouseModeCode;
}
xvirtual ~CMouseMode()
{
}
virtual void OnLButtonDblClk(UINT nFlags, CPoint point)
{
m_rVisualObject=m_rDocument->HitTest(point);
if(m_rVisualObject && m_rDocument)
{
m_rDocument->ShowObjectProperties(m_rVisualObject);
}
else if(m_rDocument)
m_rDocument->ShowObjectProperties(NULL);
}
virtual void OnLButtonDown(UINT nFlags, CPoint point)=0;
virtual void OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_rDocument && m_rDocument->m_oObjectDlg)
{
m_rVisualObject=m_rDocument->HitTest(point);
if(m_rVisualObject && m_rDocument)
{
m_rDocument->ShowObjectProperties(m_rVisualObject);
}
else if(m_rDocument)
m_rDocument->ShowObjectProperties(NULL);
}
}
virtual void OnMouseMove(UINT nFlags, CPoint point)=0;
virtual void SetModeCursor()=0;
};
class CMouseModeMove : public CMouseMode
{
public:
CMouseModeMove(ref<CWindowImplBase> rWindow, ref<CDocument> rDocument)
:CMouseMode(rWindow, rDocument, Mode_Move)
{
}
~CMouseModeMove()
{
}
virtual void OnLButtonDown(UINT nFlags, CPoint point)
{
m_LastMousePoint=point;
m_rVisualObject=m_rDocument->HitTest(point);
m_rDocument->SetSelectedVisualObject(m_rVisualObject);
SetModeCursor();
}
virtual void OnLButtonUp(UINT nFlags, CPoint point)
{
m_rVisualObject=NULL;
CMouseMode::OnLButtonUp(nFlags, point);
}
virtual void OnMouseMove(UINT nFlags, CPoint point)
{
if(nFlags & MK_LBUTTON)
{
if(m_rVisualObject)
{
m_rVisualObject->MoveBy(point-m_LastMousePoint);
}
}
else
{
ref<CVisualObject> rVisualObject=m_rDocument->HitTest(point);
if(rVisualObject)
{
if(rVisualObject->IsSizing())
SetCursor(AtlLoadCursor(IDC_SIZING));
else
SetCursor(AtlLoadCursor(IDC_MOVE));
}
}
m_LastMousePoint=point;
}
virtual void SetModeCursor()
{
if(m_rVisualObject)
{
if(m_rVisualObject->IsSizing())
SetCursor(AtlLoadCursor(IDC_SIZING));
else
SetCursor(AtlLoadCursor(IDC_MOVE));
}
else
SetCursor(AtlLoadCursor(IDC_MYARROW));
}
};
class CMouseModeBox;
class CMouseModeBoxMove : public CMouseModeMove
{
ref<CMouseModeBox> m_rMouseModeBox;
public:
CMouseModeBoxMove(ref<CWindowImplBase> rWindow, ref<CDocument> rDocument, ref<CMouseModeBox> rMouseModeBox)
: CMouseModeMove(rWindow, rDocument)
{
m_rMouseModeBox=rMouseModeBox;
}
~CMouseModeBoxMove()
{
}
virtual void OnMouseMove(UINT nFlags, CPoint point);
};
class CMouseModeBox : public CMouseMode, public enable_ref_ptr_to_this<CMouseModeBox>
{
CPoint m_DownPoint;
ref<CBox> m_rNewBox;
public:
owner_ptr<CMouseModeBoxMove> m_oMouseModeBoxMove;
CMouseModeBox(ref<CWindowImplBase> rWindow, ref<CDocument> rDocument, MOUSE_MODE MouseModeCode)
:CMouseMode(rWindow, rDocument, MouseModeCode)
{
}
~CMouseModeBox()
{
}
virtual void OnLButtonDown(UINT nFlags, CPoint point)
{
if(m_oMouseModeBoxMove)
m_oMouseModeBoxMove->OnLButtonDown(nFlags, point);
else
m_DownPoint=point;
}
virtual void OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_oMouseModeBoxMove)
m_oMouseModeBoxMove->OnLButtonUp(nFlags, point);
else
m_rNewBox=NULL;
CMouseMode::OnLButtonUp(nFlags, point);
}
virtual void OnMouseMove(UINT nFlags, CPoint point)
{
if(m_oMouseModeBoxMove)
{
m_oMouseModeBoxMove->OnMouseMove(nFlags,point);
return;
}
if(NULL==m_rDocument)
return;
ref<CVisualObject> rVisualObject=m_rDocument->HitTest(point);
if(rVisualObject)
{
if(NULL==m_oMouseModeBoxMove)
{
int i=0;
m_oMouseModeBoxMove=new CMouseModeBoxMove(m_rWindow, m_rDocument, ref_ptr_to_this());
}
m_oMouseModeBoxMove->OnMouseMove(nFlags, point);
return;
}
else
m_oMouseModeBoxMove=NULL;
if(nFlags & MK_LBUTTON && point.x-m_DownPoint.x>15 && point.y-m_DownPoint.y>15)
{
if(NULL==m_rNewBox)
{
switch(m_MouseModeCode)
{
case Mode_Square:
/*{
new_ptr<CRectangleBox> newRectangleBox=m_rDocument->NewRectangleBox(m_DownPoint, CSize(point.x-m_DownPoint.x, point.y-m_DownPoint.y));
m_rDocument->m_VisualObjects.Add(newRectangleBox);
m_rNewBox=newRectangleBox;
}*/
m_rNewBox=m_rDocument->AddRectangleBox(m_DownPoint, CSize(point.x-m_DownPoint.x, point.y-m_DownPoint.y));
break;
case Mode_Ellipse:
m_rNewBox=m_rDocument->AddEllipseBox(m_DownPoint, CSize(point.x-m_DownPoint.x, point.y-m_DownPoint.y));
break;
}
m_rDocument->SetSelectedVisualObject(m_rNewBox);
}
else
{
m_rNewBox->m_Size=CSize(point.x-m_DownPoint.x, point.y-m_DownPoint.y);
}
}
}
virtual void SetModeCursor()
{
if(m_oMouseModeBoxMove)
{
m_oMouseModeBoxMove->SetModeCursor();
return;
}
switch(m_MouseModeCode)
{
case Mode_Square:
SetCursor(AtlLoadCursor(IDC_SQUARE));
break;
case Mode_Ellipse:
SetCursor(AtlLoadCursor(IDC_ELLIPSE));
break;
}
}
};
void CMouseModeBoxMove::OnMouseMove(UINT nFlags, CPoint point)
{
if(nFlags & MK_LBUTTON)
{
if(m_rVisualObject)
{
m_rVisualObject->MoveBy(point-m_LastMousePoint);
}
}
else
{
ref<CVisualObject> rVisualObject=m_rDocument->HitTest(point);
if(rVisualObject)
{
if(rVisualObject->IsSizing())
SetCursor(AtlLoadCursor(IDC_SIZING));
else
SetCursor(AtlLoadCursor(IDC_MOVE));
}
else
{
m_rMouseModeBox->m_oMouseModeBoxMove=NULL;
return;
}
}
m_LastMousePoint=point;
}
class CMouseModeLine : public CMouseMode
{
ref<CBox> m_rFirstBox;
public:
CMouseModeLine(ref<CWindowImplBase> rWindow, ref<CDocument> rDocument)
:CMouseMode(rWindow, rDocument, Mode_Line)
{
}
~CMouseModeLine()
{
}
virtual void OnLButtonDown(UINT nFlags, CPoint point)
{
CMouseMode::OnLButtonUp(nFlags, point);
}
virtual void OnLButtonUp(UINT nFlags, CPoint point)
{
m_rVisualObject=m_rDocument->HitTest(point);
ref<CVisualObject> rVO=m_rVisualObject;
if(m_rVisualObject && m_rVisualObject->GetType().Find(_T("Box"))>-1)
{
if(NULL==m_rFirstBox)
m_rFirstBox=up_cast<CBox, CVisualObject>(m_rVisualObject);
else if(m_rVisualObject!=m_rFirstBox && false==m_rFirstBox->HasLineTo(up_cast<CBox, CVisualObject>(m_rVisualObject)))
{
m_rDocument->AddLine(m_rFirstBox, up_cast<CBox, CVisualObject>(m_rVisualObject));
m_rFirstBox=NULL;
}
else
m_rFirstBox=NULL;
m_rDocument->SetSelectedVisualObject(m_rVisualObject);
}
else
m_rFirstBox=NULL;
m_rWindow->Invalidate();
m_rWindow->UpdateWindow();
SetModeCursor();
}
virtual void OnMouseMove(UINT nFlags, CPoint point)
{
if(NULL==m_rDocument)
return;;
m_rVisualObject=m_rDocument->HitTest(point);
if(m_rFirstBox)
{
CClientDC dc(m_rWindow->m_hWnd);
ref<CVisualObject> rVisualObject=m_rDocument->m_rSelectedVisualObject;
m_rDocument->m_rSelectedVisualObject=NULL;
m_rWindow->Invalidate();
m_rWindow->UpdateWindow();
m_rDocument->m_rSelectedVisualObject=rVisualObject;
dc.MoveTo(m_rFirstBox->GetCentrePoint());
dc.LineTo(point);
}
}
virtual void SetModeCursor()
{
if(m_rFirstBox)
{
if(m_rVisualObject && m_rVisualObject!=m_rFirstBox && false==m_rFirstBox->HasLineTo(up_cast<CBox, CVisualObject>(m_rVisualObject)))
SetCursor(AtlLoadCursor(IDC_SECOND_POINT));
else
SetCursor(AtlLoadCursor(IDC_HALFLINE));
}
else
{
if(m_rVisualObject)
SetCursor(AtlLoadCursor(IDC_FIRST_POINT));
else
SetCursor(AtlLoadCursor(IDC_LINE));
}
}
};
}