www.pudn.com > drawpad.zip > eselection.cpp


#include "stdafx.h" 
 
#include "eselection.h" 
#include "entity.h" 
#include "DrawPadDoc.h" 
#include "DrawPadView.h" 
 
//===================================================================== 
// Class: PICK_ENT 
//===================================================================== 
 
PICK_ENT::PICK_ENT() 
{ 
	Ent = NULL; 
} 
 
PICK_ENT::PICK_ENT(ENTITY *ent, const CPoint &pick) 
{ 
	Ent = ent; 
	Pick = pick; 
} 
 
//===================================================================== 
// Class: SELECTION 
//===================================================================== 
 
// Create a new SELECTION 
SELECTION::SELECTION(CView *view) 
{ 
	m_pOwner = view; 
	notify = FALSE; 
	xormode = TRUE; 
	selCB.func = 0; 
} 
 
// Delete a selection 
SELECTION::~SELECTION() 
{ 
} 
 
// internally add an entity to the selection 
void SELECTION::add(ENTITY * ent) 
{ 
	m_pEntityList.AddTail(ent); 
	if( notify ) Highlight(ent, TRUE); 
} 
 
// internally remove an entity from the selection 
void SELECTION::remove(ENTITY * ent) 
{ 
	if( Contains(ent) ) { 
		if( notify ) Highlight(ent, FALSE); 
		// remove possible pick-ray record of this void 
		PICK_ENT *pickray; 
		if( GetPickRay(ent, pickray) ) { 
			POSITION atRemove = m_pPickList.Find(pickray); 
			m_pPickList.RemoveAt(atRemove); 
			delete pickray; 
		} 
	} 
	m_pEntityList.RemoveAt(m_pEntityList.Find(ent)); 
} 
 
// Add an entity to the selection 
void SELECTION::Add(ENTITY * ent) 
{ 
	if( !Contains(ent) ) 
		add(ent); 
	else if( xormode ) 
		remove(ent); 
	onSelChange(); 
} 
 
void SELECTION::Add(CObList *ents) 
{ 
	int containp = Contains(ents); 
	selCBOn = FALSE; 
	if( containp==0 || containp==2 ) { 
		int oldxor = SetXor(FALSE); 
		for( POSITION pos = ents->GetHeadPosition(); pos != NULL; ) { 
			Add((ENTITY *)ents->GetNext(pos)); 
		} 
		SetXor(oldxor); 
	} 
	else if( xormode ) { 
		Remove(ents); 
	} 
	selCBOn = TRUE; 
	onSelChange(); 
} 
 
// Add a picked void, recording the pick ray 
void SELECTION::Add(ENTITY *ent, const CPoint &pick) 
{ 
	if( !Contains(ent) ) { 
		add(ent); 
		m_pPickList.AddTail(new PICK_ENT(ent,pick)); 
	} 
	else { 
		if( xormode ) 
			remove(ent); 
		else { 
			// update possible pick-ray record of this void 
			remove(ent); 
			add(ent); 
			m_pPickList.AddTail(new PICK_ENT(ent,pick)); 
		} 
	} 
	onSelChange(); 
} 
 
// Remove an entity from the selection 
void SELECTION::Remove(ENTITY * ent) 
{ 
	remove(ent); 
	onSelChange(); 
} 
 
void SELECTION::Remove(CObList * ents) 
{ 
	selCBOn = FALSE; 
	for( POSITION pos = ents->GetHeadPosition(); pos != NULL; ) { 
		Remove((ENTITY *)ents->GetNext(pos)); 
	} 
	selCBOn = TRUE; 
	onSelChange(); 
} 
 
// Clear the Selection 
void SELECTION::Clear() 
{ 
	if( notify ) SetHighlight(FALSE); 
	// free all records of pick-rays. 
	for( POSITION pos = m_pPickList.GetHeadPosition(); pos != NULL; ) { 
		delete m_pPickList.GetNext(pos); 
	} 
	m_pPickList.RemoveAll(); 
	m_pEntityList.RemoveAll(); 
	onSelChange(); 
} 
 
// Clear the Selection 
void SELECTION::Clear(int display) 
{ 
	if( display ) SetHighlight(FALSE); 
	for( POSITION pos = m_pPickList.GetHeadPosition(); pos != NULL; ) { 
		delete m_pPickList.GetNext(pos); 
	} 
	m_pPickList.RemoveAll(); 
	m_pEntityList.RemoveAll(); 
	onSelChange(); 
} 
 
// See if the selection already contains a given entity 
int SELECTION::Contains(ENTITY * ent) 
{ 
	return (m_pEntityList.Find(ent) != NULL); 
} 
 
//   See if a selection contains given entities, 2=partially 
int SELECTION::Contains(CObList *ents) 
{ 
	int allin=1, allout=1; 
	for( POSITION pos = ents->GetHeadPosition(); pos != NULL; ) { 
		if( Contains((ENTITY *)ents->GetNext(pos)) ) 
			allout=0; 
		else 
			allin=0; 
	} 
	if( allout ) return 0; 
	if( allin ) return 1; 
	return 2; 
} 
 
void SELECTION::Draw() 
{ 
	for( POSITION pos = m_pEntityList.GetHeadPosition(); pos != NULL; ) { 
		Highlight((ENTITY *)m_pEntityList.GetNext(pos), TRUE); 
	} 
} 
 
// Find the pick ray record of selected entity 
int SELECTION::GetPickRay(ENTITY *ent, PICK_ENT *&pent) 
{ 
	pent = 0; 
	if( !Contains(ent) ) return 0; 
	for( POSITION pos = m_pPickList.GetHeadPosition(); pos != NULL; ) { 
		pent = (PICK_ENT *)m_pPickList.GetNext(pos); 
		if( ent == pent->entity() ) return 1; 
	} 
	return 0; 
} 
 
void SELECTION::onSelChange() 
{ 
	if( selCBOn && selCB.func ) 
		(*selCB.func)(selCB.arg); 
} 
 
void SELECTION::SetSelChangeCallback(ArgCallback func, void *arg) 
{ 
	selCB.func = func; 
	selCB.arg = arg; 
	selCB.option = 0; 
} 
 
//   Highlight or unhighlight the selection 
//   This method uses aht procedure api_gi_highlight_entity which 
//   is defined in the 3D Toolkit.  If you are not using the 3D Toolkit, you 
//   will have to change the implementation of this method. 
void SELECTION::SetHighlight(BOOL onoff) 
{ 
	if( m_pEntityList.GetCount() > 0 ) 
		for( POSITION pos = m_pEntityList.GetHeadPosition(); pos != NULL; ) { 
			Highlight((ENTITY *)m_pEntityList.GetNext(pos), onoff); 
		} 
} 
 
void SELECTION::Highlight(ENTITY *ent, BOOL onoff) 
{ 
	if( onoff ) 
		((CDrawPadView *)m_pOwner)->DrawEntity(ent, DRAWSEL); 
	else 
		((CDrawPadView *)m_pOwner)->DrawEntity(ent, DRAWNORM); 
} 
 
#ifdef _DEBUG 
 
//---------------------------------------------------------------------- 
// purpose--- 
//   See if the selection is valid 
//---------------------------------------------------------------------- 
void SELECTION::AssertValid() const 
{ 
	CObject::AssertValid(); 
} 
 
//---------------------------------------------------------------------- 
// purpose--- 
//   Do a debug Dump of the selection 
//---------------------------------------------------------------------- 
void SELECTION::Dump(CDumpContext& dc) const 
{ 
	CObject::Dump(dc); 
	dc << "Count = " << GetCount(); 
} 
 
#endif