Скачиваний:
18
Добавлен:
01.05.2014
Размер:
8.95 Кб
Скачать
// RegionSearchDoc.cpp : implementation of the CRegionSearchDoc class
//

#include "stdafx.h"
#include "RegionSearch.h"

#include "RegionSearchDoc.h"

#include "GeneratePointsDlg.h"
#include "OptionsDlg.h"

#include "Bitmaps.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

const int CRegionSearchDoc::MinX = 100;
const int CRegionSearchDoc::MaxX = 1100;
const int CRegionSearchDoc::MinY = 100;
const int CRegionSearchDoc::MaxY = 1100;

/////////////////////////////////////////////////////////////////////////////
// CRegionSearchDoc

IMPLEMENT_DYNCREATE(CRegionSearchDoc, CDocument)

BEGIN_MESSAGE_MAP(CRegionSearchDoc, CDocument)
	//{{AFX_MSG_MAP(CRegionSearchDoc)
	ON_COMMAND(ID_GENERATE_POINTS, OnGeneratePoints)
	ON_COMMAND(ID_BUILD_TREE, OnBuildTree)
	ON_COMMAND(ID_SEARCH, OnSearch)
	ON_UPDATE_COMMAND_UI(ID_SEARCH, OnUpdateSearch)
	ON_UPDATE_COMMAND_UI(ID_BUILD_TREE, OnUpdateBuildTree)
	ON_COMMAND(ID_BUILDSTEP, OnBuildstep)
	ON_UPDATE_COMMAND_UI(ID_BUILDSTEP, OnUpdateBuildstep)
	ON_COMMAND(ID_OPTIONS, OnOptions)
	ON_COMMAND(ID_SEARCH_STEP, OnSearchStep)
	ON_UPDATE_COMMAND_UI(ID_SEARCH_STEP, OnUpdateSearchStep)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRegionSearchDoc construction/destruction

CRegionSearchDoc::CRegionSearchDoc() : Tree(0), 
	RegionState(RegionNotEntered), BuildStepCounter(0), 
	ShowNumbers(TRUE), ShowPoints(TRUE), ShowSegments(FALSE), ShowNodes(FALSE), LevelCount(20)
{
}

CRegionSearchDoc::~CRegionSearchDoc()
{
	if(Tree) delete Tree;
}

BOOL CRegionSearchDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CRegionSearchDoc serialization

void CRegionSearchDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar<<Points.size();
		for(int i=0; i<Points.size(); i++)
			ar<<Points[i].number<<Points[i].first<<Points[i].second;
	}
	else
	{
		int n;
		ar>>n;
		Points.resize(n);
		for(int i=0; i<n; i++)
		{
			int num, x, y;
			ar>>num>>x>>y;
			Point p(x,y);
			p.number=num;
			Points[i]=p;
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CRegionSearchDoc diagnostics

#ifdef _DEBUG
void CRegionSearchDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CRegionSearchDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CRegionSearchDoc commands

void CRegionSearchDoc::OnGeneratePoints() 
{
	if(Tree)
	{
		//если дерево уже есть
		int res=AfxMessageBox("Дерево регионов является статической структурой.\n Добавление новых точек требует построения нового дерева и удаления старого.\n Удалить старое дерево?", MB_OKCANCEL|MB_ICONQUESTION, 0);
		if(res == IDOK) DeleteTree();
	}
	if(!Tree)
	{
		GeneratePointsDlg dlg;
		dlg.m_Number = 10;
		if(dlg.DoModal()==IDOK)
		{
			int n1 = dlg.m_Number;
			int n = Points.size();
			Points.resize(n1+n);

			int seed = GetTickCount();
			srand(seed);
			for(int i=n; i<n1+n; i++)
			{
				Points[i].first = rand()%(MaxX-MinX)+MinX;
				Points[i].second = rand()%(MaxY-MinY)+MinY;
			}

			std::sort(Points.begin(), Points.end(), OrderByX());

			for(i=0; i<n1+n; i++)
				Points[i].number = i+1;
			UpdateAllViews(0);
		}
	}
}

void CRegionSearchDoc::OnBuildTree() 
{
	Tree = new RegionTree(Points);
	BuildStepCounter = Tree->GetNodeCount();
	UpdateAllViews(0);
	OnFinishBuild();
}



bool CRegionSearchDoc::IsRegionDisplayed() const
{
	if(RegionState == RegionEntered || RegionState==RegionEntering) return true;
	else return false;
}

CRect CRegionSearchDoc::GetRegion() const
{
	return Region;
}



void CRegionSearchDoc::StartEnterRegion(CPoint p)
{
	if(IsTreeBuilt() && !IsSearchInProgress())
	{
		Result.clear();
		Region.SetRect(p.x, p.y, p.x, p.y);
		RegionState = RegionEntering;
		RedrawRegion();
	}
}
void CRegionSearchDoc::ContinueEnterRegion(CPoint p)
{
	if(RegionState==RegionEntering) 
	{
		Region.SetRect(Region.TopLeft().x, Region.TopLeft().y, p.x, p.y);
		Region.NormalizeRect();
		RedrawRegion();	
	}
}

void CRegionSearchDoc::EndEnterRegion(CPoint p)
{
	if(RegionState==RegionEntering)	RegionState = RegionEntered;
}

void CRegionSearchDoc::RedrawRegion()
{
	POSITION pos = GetFirstViewPosition();
	CView* view = GetNextView(pos);
	view->Invalidate();
	view->UpdateWindow();
}



void CRegionSearchDoc::OnSearch() 
{
	ResetSearch();
	SearchSteps = Tree->GetSearchSteps();
	UpdateAllViews(0);
	OnFinishSearch();
}

void CRegionSearchDoc::OnUpdateSearch(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable((RegionState == RegionEntered) && IsTreeBuilt());	
}

void CRegionSearchDoc::EnterPoint(CPoint p)
{
	if(Tree)
	{
		//если дерево уже есть
		int res=AfxMessageBox("Дерево регионов является статической структурой.\n Добавление новых точек требует построения нового дерева и удаления старого.\n Удалить старое дерево?", MB_OKCANCEL|MB_ICONQUESTION, 0);
		if(res == IDOK) DeleteTree();
	}
	if(!Tree)
	{
		Point pt(p.x, p.y);
		Points.push_back(pt);
		std::sort(Points.begin(), Points.end(), OrderByX());
		for(int i=0; i<Points.size(); i++)
			Points[i].number = i+1;
		UpdateAllViews(0);
	}
}

void CRegionSearchDoc::OnUpdateBuildTree(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(CanBuildTree());
}

bool CRegionSearchDoc::CanBuildTree() const
{
	bool res;
	if(Tree)
	{
		if(BuildStepCounter==Tree->GetNodeCount()) res = false; else res = true;
	}
	else
	{
		if(Points.size()>0) res = true; else res =false;
	}

	return res;
}


void CRegionSearchDoc::OnBuildstep() 
{
	if(!Tree) 
	{
		Tree = new RegionTree(Points);
	}
	BuildStepCounter++;
	UpdateAllViews(0);
	if(IsTreeBuilt()) OnFinishBuild();
}

void CRegionSearchDoc::DeleteTree()
{
	delete Tree;
	Tree=0;
	BuildStepCounter=0;
	SearchSteps.clear();
	RegionState = RegionNotEntered;
	Result.clear();
	UpdateAllViews(0);
}

void CRegionSearchDoc::OnUpdateBuildstep(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(CanBuildTree());	
}

void CRegionSearchDoc::OnOptions() 
{
	COptionsDlg dlg;
	dlg.m_ShowNumbers = ShowNumbers;
	dlg.m_ShowPoints = ShowPoints;
	dlg.m_LevelCount = LevelCount;
	dlg.m_ShowSegments = ShowSegments;
	dlg.m_ShowNodes = ShowNodes;

	if(dlg.DoModal() == IDOK)
	{
		ShowNumbers = dlg.m_ShowNumbers;
		ShowPoints = dlg.m_ShowPoints;
		LevelCount = dlg.m_LevelCount;
		ShowSegments = dlg.m_ShowSegments;
		ShowNodes = dlg.m_ShowNodes;
		UpdateAllViews(0);
	}
}

void CRegionSearchDoc::OnSearchStep() 
{
	ResetSearch();
	if(CurStep!=Tree->GetSearchSteps().end()) 
		SearchSteps.push_back(*CurStep++);
	UpdateAllViews(0);
	if(SearchSteps.size() == Tree->GetSearchSteps().size())
		OnFinishSearch();
}

void CRegionSearchDoc::OnUpdateSearchStep(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable((RegionState == RegionEntered) && IsTreeBuilt());		
}

//если все шаги поиска выполнены, то перезапустить поиск
void CRegionSearchDoc::ResetSearch()
{
	if(SearchSteps.size() == Tree->GetSearchSteps().size())
	{
		SearchSteps.clear();
		Result=Tree->Search(Region.TopLeft().x, Region.TopLeft().y,
						Region.BottomRight().x, Region.BottomRight().y);
		CurStep = Tree->GetSearchSteps().begin();
		UpdateAllViews(0);
	}
}

void CRegionSearchDoc::OnFinishSearch()
{
	AfxMessageBox("Поиск завершен", MB_OK|MB_ICONINFORMATION);
}

bool CRegionSearchDoc::IsSearchInProgress() const
{
	if(!IsTreeBuilt()) return false;
	int totalSteps = Tree->GetSearchSteps().size();
	if(totalSteps>0 && SearchSteps.size() < totalSteps) return true;
	else return false;
}

void CRegionSearchDoc::OnSaveScreen() 
{
	CFileDialog dlg(FALSE, ".bmp", "SearchTree.bmp");
	if(dlg.DoModal()==IDOK)
	{
		POSITION pos = GetFirstViewPosition();
		GetNextView(pos);
		CView* wnd = GetNextView(pos);
		CBitmap bmp;
		PBITMAPINFO bmpInfo;
		CRect rc;
		wnd->GetClientRect(&rc);
		CDC memoryDC;
		memoryDC.CreateCompatibleDC(wnd->GetDC());
		bmp.CreateCompatibleBitmap(wnd->GetDC(), rc.Width(), rc.Height());
		memoryDC.SelectObject(bmp);
		int res = memoryDC.BitBlt(0, 0 , rc.Width(), rc.Height(), wnd->GetDC(), 0, 0, SRCCOPY);

		bmpInfo = BitmapSaver::CreateBitmapInfoStruct(bmp);
		
		BitmapSaver::CreateBMPFile(dlg.GetFileName(), bmpInfo, bmp, memoryDC.m_hDC);
	}
}

bool CRegionSearchDoc::IsTreeBuilt() const
{
	if(!Tree) return false;
	return (Tree->GetNodeCount()==BuildStepCounter);
}

void CRegionSearchDoc::OnFinishBuild() const
{
	AfxMessageBox("Построение дерева регионов закончено.\nТеперь можно начать поиск, выделив область для поиска мышью.", MB_OK|MB_ICONINFORMATION);
}
Соседние файлы в папке Source