|
/*
***************************************************************************
kis v 1
(c) 2006, Florin DUMITRESCU
mailto: fdproxy@gmail.com
$Workfile: _Graphic.h $
***************************************************************************
*/
#ifndef _GRAPHIC_H_
#define _GRAPHIC_H_
//-------------------------------------------------------------------------
/** [To be supplied.] */
inline std::string ReadSignature( std::istream& a_is )
{
using namespace std;
ws( a_is );
char c;
string Result;
while ( a_is.get( c ) && std::isalnum( c, std::locale::classic() ) )
Result += c;
return Result;
}
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_BadSignature
{
// empty
};
//-------------------------------------------------------------------------
/** C_Graphic is the base calss of all graphic objects. */
class C_Graphic
{
public:
virtual ~C_Graphic() = 0
{
// nop
}
virtual C_Graphic* Clone() const = 0;
virtual bool IsEmpty() const = 0;
virtual unsigned int GetBytesCount() const = 0;
virtual void Draw( CDC* a_pDC ) const = 0;
virtual void ReadData( std::istream& a_is ) = 0;
virtual void ReadSignature( std::istream& a_os ) = 0;
virtual void WriteData( std::ostream& a_os ) = 0;
virtual void WriteSignature( std::ostream& a_os ) = 0;
void Read( std::istream& a_is )
{
ReadSignature( a_is );
ReadData( a_is );
}
void Write( std::ostream& a_os )
{
WriteSignature( a_os );
WriteData( a_os );
}
};
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_Graphic_Simple : public C_Graphic
{
public:
C_Graphic_Simple()
:
m_PenColor( RGB( 255, 127, 63 ) ),
m_PenWidth( 50 )
{
// nop
}
virtual ~C_Graphic_Simple()
{
// nop
}
void SetPenWidth( const int a_PenWidth )
{
m_PenWidth = a_PenWidth;
}
int GetPenWidth() const
{
return m_PenWidth;
}
protected:
COLORREF m_PenColor;
int m_PenWidth;
};
//-------------------------------------------------------------------------
/** C_Graphic_Simple is the base class of graphic objects that
can be described by two points. */
class C_Graphic_TwoPoints : public C_Graphic_Simple
{
public:
C_Graphic_TwoPoints( const CPoint& a_StartPoint, const CPoint& a_EndPoint )
:
m_StartPoint( a_StartPoint ),
m_EndPoint( a_EndPoint )
{
// nop
}
C_Graphic_TwoPoints()
:
m_StartPoint( 0, 0 ),
m_EndPoint( 0, 0 )
{
// nop
}
void SetStartPoint( const CPoint a_StartPoint )
{
m_StartPoint = a_StartPoint;
}
const CPoint& GetStartPoint() const
{
return m_StartPoint;
}
void SetEndPoint( const CPoint a_EndPoint )
{
m_EndPoint = a_EndPoint;
}
const CPoint& GetEndPoint() const
{
return m_EndPoint;
}
/*override*/ unsigned int GetBytesCount() const
{
return sizeof( *this );
}
/*override*/ bool IsEmpty() const
{
return !!(m_StartPoint == m_EndPoint);
}
/*override*/ void WriteData( std::ostream& a_os )
{
using namespace std;
ASSERT( a_os.good() );
a_os
<< '\t' << m_StartPoint.x << endl
<< '\t' << m_StartPoint.y << endl
<< '\t' << m_EndPoint.x << endl
<< '\t' << m_EndPoint.y << endl;
}
/*override*/ void ReadData( std::istream& a_is )
{
ASSERT( a_is.good() );
a_is
>> m_StartPoint.x
>> m_StartPoint.y
>> m_EndPoint.x
>> m_EndPoint.y;
}
protected:
CPoint m_StartPoint;
CPoint m_EndPoint;
};
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_Graphic_Segment : public C_Graphic_TwoPoints
{
public:
C_Graphic_Segment()
{
// nop
}
C_Graphic_Segment( const CPoint& a_StartPoint, const CPoint& a_EndPoint )
:
C_Graphic_TwoPoints( a_StartPoint, a_EndPoint )
{
// nop
}
/*override*/ void Draw( CDC* a_pDC ) const
{
int OldMM = a_pDC->SetMapMode( MM_HIMETRIC );
CPen Pen( PS_SOLID, m_PenWidth, m_PenColor );
CPen* pOldPen = a_pDC->SelectObject( &Pen );
a_pDC->MoveTo( m_StartPoint );
a_pDC->LineTo( m_EndPoint );
a_pDC->SelectObject( pOldPen );
a_pDC->SetMapMode( OldMM );
}
/*override*/ C_Graphic* Clone() const
{
return new C_Graphic_Segment( *this );
}
/*override*/ void WriteSignature( std::ostream& a_os )
{
a_os << Signature() << std::endl;
}
/*override*/ void ReadSignature( std::istream& a_is )
{
if ( ::ReadSignature( a_is ) != Signature() )
throw C_BadSignature();
}
static std::string Signature()
{
return "Segment";
}
static C_Graphic* New()
{
return new C_Graphic_Segment();
}
};
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_Graphic_Rectangle : public C_Graphic_TwoPoints
{
public:
/*override*/ void Draw( CDC* a_pDC ) const
{
int OldMM = a_pDC->SetMapMode( MM_HIMETRIC );
CPen Pen( PS_SOLID, m_PenWidth, m_PenColor );
CBrush* pOldBrush = (CBrush*)a_pDC->SelectStockObject( HOLLOW_BRUSH );
CPen* pOldPen = a_pDC->SelectObject( &Pen );
a_pDC->Rectangle( m_StartPoint.x, m_StartPoint.y, m_EndPoint.x, m_EndPoint.y );
a_pDC->SelectObject( pOldPen );
a_pDC->SelectObject( pOldBrush );
a_pDC->SetMapMode( OldMM );
}
/*override*/ C_Graphic* Clone() const
{
return new C_Graphic_Rectangle( *this );
}
/*override*/ void WriteSignature( std::ostream& a_os )
{
a_os << Signature() << std::endl;
}
/*override*/ void ReadSignature( std::istream& a_is )
{
if ( ::ReadSignature( a_is ) != Signature() )
throw C_BadSignature();
}
static std::string Signature()
{
return "Rectangle";
}
static C_Graphic* New()
{
return new C_Graphic_Rectangle();
}
};
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_Graphic_Ellipse : public C_Graphic_TwoPoints
{
public:
/*override*/ void Draw( CDC* a_pDC ) const
{
int OldMM = a_pDC->SetMapMode( MM_HIMETRIC );
CPen Pen( PS_SOLID, m_PenWidth, m_PenColor );
CBrush* pOldBrush = (CBrush*)a_pDC->SelectStockObject( HOLLOW_BRUSH );
CPen* pOldPen = a_pDC->SelectObject( &Pen );
a_pDC->Ellipse( m_StartPoint.x, m_StartPoint.y, m_EndPoint.x, m_EndPoint.y );
a_pDC->SelectObject( pOldPen );
a_pDC->SelectObject( pOldBrush );
a_pDC->SetMapMode( OldMM );
}
/*override*/ C_Graphic* Clone() const
{
return new C_Graphic_Ellipse( *this );
}
/*override*/ void WriteSignature( std::ostream& a_os )
{
a_os << Signature() << std::endl;
}
/*override*/ void ReadSignature( std::istream& a_is )
{
if ( ::ReadSignature( a_is ) != Signature() )
throw C_BadSignature();
}
static std::string Signature()
{
return "Ellipse";
}
static C_Graphic* New()
{
return new C_Graphic_Ellipse();
}
};
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_Reader
{
public:
C_Reader()
{
m_Map[C_Graphic_Segment::Signature()] = &C_Graphic_Segment::New;
m_Map[C_Graphic_Rectangle::Signature()] = &C_Graphic_Rectangle::New;
m_Map[C_Graphic_Ellipse::Signature()] = &C_Graphic_Ellipse::New;
}
C_Graphic* Read( std::istream& a_is )
{
using namespace std;
string Signature = ::ReadSignature( a_is );
P_NewFun New = m_Map[ Signature ];
if ( ! New )
return 0;
C_Graphic* pGraphic = New();
pGraphic->ReadData( a_is );
return pGraphic;
}
protected:
typedef C_Graphic* (*P_NewFun)();
std::map< std::string, P_NewFun > m_Map;
};
//-------------------------------------------------------------------------
/** [To be supplied.] */
class C_Drawing : public C_Graphic
{
public:
C_Drawing()
{
// nop
}
C_Drawing( const C_Drawing& a_Src )
{
Copy( a_Src );
}
~C_Drawing()
{
Delete();
}
void Delete()
{
for ( std::size_t i = 0; i < m_Graphics.size(); ++i )
delete m_Graphics[i];
m_Graphics.clear();
}
void Copy( const C_Drawing& a_Src )
{
Delete();
for ( std::size_t i = 0; i < a_Src.m_Graphics.size(); ++i )
if ( C_Graphic* pGraphic = dynamic_cast<C_Graphic*>( a_Src.m_Graphics[i]->Clone() ) )
m_Graphics.push_back( pGraphic );
}
C_Drawing& operator=( const C_Drawing& a_Rhs )
{
Copy( a_Rhs );
return *this;
}
/*override*/ void Draw( CDC* a_pDC ) const
{
for ( std::size_t i = 0; i < m_Graphics.size(); ++i )
m_Graphics[i]->Draw( a_pDC );
}
/*override*/ C_Graphic* Clone() const
{
return new C_Drawing( *this );
}
unsigned int Add( const C_Graphic& a_Graphic )
{
m_Graphics.push_back( a_Graphic.Clone() );
return unsigned int( m_Graphics.size() - 1 );
}
void RemoveAt( unsigned int a_ZIdx )
{
delete m_Graphics[ a_ZIdx ];
m_Graphics[ a_ZIdx ] = 0;
m_Graphics.erase( m_Graphics.begin() + a_ZIdx );
}
unsigned int GetCount() const
{
return unsigned int( m_Graphics.size() );
}
C_Graphic& At( int a_ZIdx )
{
return *m_Graphics[a_ZIdx];
}
/*override*/ unsigned int GetBytesCount() const
{
unsigned int Result = sizeof( *this );
for ( std::size_t i = 0; i < m_Graphics.size(); ++i )
Result += m_Graphics[i]->GetBytesCount();
return Result;
}
/*override*/ bool IsEmpty() const
{
return m_Graphics.empty();
}
/*override*/ void WriteData( std::ostream& a_os )
{
for ( std::size_t i = 0; i < m_Graphics.size(); ++i )
m_Graphics[i]->Write( a_os );
}
/*override*/ void ReadData( std::istream& a_is )
{
using namespace std;
C_Reader Reader;
while ( C_Graphic* pGraphic = Reader.Read( a_is ) )
m_Graphics.push_back( pGraphic );
}
/*override*/ void WriteSignature( std::ostream& a_os )
{
a_os << Signature() << std::endl;
}
/*override*/ void ReadSignature( std::istream& a_is )
{
if ( ::ReadSignature( a_is ) != Signature() )
throw C_BadSignature();
}
static std::string Signature()
{
return "Drawing";
}
static C_Graphic* New()
{
return new C_Drawing();
}
protected:
std::vector< C_Graphic* > m_Graphics;
};
#endif _GRAPHIC_H_
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.