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