211 lines
4.6 KiB
C
211 lines
4.6 KiB
C
|
#ifndef __UNDO_H__
|
||
|
#define __UNDO_H__
|
||
|
|
||
|
|
||
|
// A CBmObjSequence holds the codes for one undo or redo operation.
|
||
|
class CBmObjSequence : public CByteArray
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
CBmObjSequence();
|
||
|
~CBmObjSequence();
|
||
|
|
||
|
void Retrieve(BYTE* rgb, int cb);
|
||
|
void RetrieveStr(CString& str);
|
||
|
|
||
|
inline void RetrieveByte(BYTE& b) { Retrieve(&b, 1); }
|
||
|
inline void RetrieveInt(int& n) { Retrieve((BYTE*)&n , sizeof (int)); }
|
||
|
inline void RetrieveLong(long& n) { Retrieve((BYTE*)&n , sizeof (long)); }
|
||
|
inline void RetrieveNum(double& num) { Retrieve((BYTE*)&num, sizeof (double)); }
|
||
|
inline void RetrievePtr(CBitmapObj*& ptr) { Retrieve((BYTE*)&ptr, sizeof (CBitmapObj*)); }
|
||
|
inline void RetrieveRect(CRect& rc) { Retrieve((BYTE*)&rc , sizeof (rc)); }
|
||
|
inline void RetrievePoint(CPoint& pt) { Retrieve((BYTE*)&pt , sizeof (pt)); }
|
||
|
|
||
|
void Cleanup();
|
||
|
BOOL IsUseful(CBitmapObj*&, int&);
|
||
|
void Apply();
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
void Dump();
|
||
|
#endif
|
||
|
|
||
|
int m_nCursor;
|
||
|
CString m_strDescription;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CUndoBmObj : public CBitmapObj
|
||
|
{
|
||
|
DECLARE_DYNAMIC(CUndoBmObj)
|
||
|
|
||
|
public:
|
||
|
CUndoBmObj();
|
||
|
~CUndoBmObj();
|
||
|
|
||
|
void BeginUndo(const TCHAR* szCmd, BOOL bResetCursor = TRUE);
|
||
|
void BeginUndo(const UINT idCmd, BOOL bResetCursor = TRUE);
|
||
|
void EndUndo();
|
||
|
|
||
|
inline BOOL CanUndo() const
|
||
|
{ return m_nRedoSeqs < m_seqs.GetCount(); }
|
||
|
|
||
|
inline BOOL CanRedo() const
|
||
|
{ return m_nRedoSeqs > 0; }
|
||
|
|
||
|
inline BOOL InUndoRedo() const
|
||
|
{ return m_bPerformingUndoRedo; }
|
||
|
|
||
|
void GetUndoString(CString& strUndo);
|
||
|
void GetRedoString(CString& strRedo);
|
||
|
|
||
|
void DoUndo();
|
||
|
void DoRedo();
|
||
|
|
||
|
void SetMaxLevels(int nLevels);
|
||
|
int GetMaxLevels() const;
|
||
|
|
||
|
void OnSetIntProp( CBitmapObj* pChangedSlob, UINT nPropID, UINT nOldVal );
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
void Dump();
|
||
|
#endif
|
||
|
|
||
|
inline BOOL IsRecording() { return m_nRecording != 0 && m_nPauseLevel == 0; }
|
||
|
|
||
|
inline void Pause() { m_nPauseLevel += 1; }
|
||
|
|
||
|
inline void Resume() { ASSERT(m_nPauseLevel > 0); m_nPauseLevel -= 1; }
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
// Note correspondence with PRD
|
||
|
opStart,
|
||
|
opEnd,
|
||
|
opAction,
|
||
|
opIntProp,
|
||
|
opLongProp,
|
||
|
opBoolProp,
|
||
|
opDoubleProp,
|
||
|
opStrProp,
|
||
|
opSlobProp,
|
||
|
opRectProp,
|
||
|
opPointProp
|
||
|
};
|
||
|
|
||
|
UINT Insert(const void* rgb, int cb);
|
||
|
UINT InsertStr(const TCHAR* sz);
|
||
|
|
||
|
inline UINT InsertByte(BYTE b) { return Insert(&b, 1); }
|
||
|
inline UINT InsertInt(int n) { return Insert((BYTE*)&n, sizeof (int)); }
|
||
|
inline UINT InsertLong(long n) { return Insert((BYTE*)&n, sizeof (long)); }
|
||
|
inline UINT InsertNum(double num) { return Insert((BYTE*)&num, sizeof (double)); }
|
||
|
inline UINT InsertPtr(const void* ptr)
|
||
|
{
|
||
|
if (ptr != NULL)
|
||
|
{
|
||
|
ASSERT(((CObject*)ptr)->IsKindOf(RUNTIME_CLASS(CBitmapObj)));
|
||
|
((CBitmapObj*)ptr)->AddDependant(this);
|
||
|
}
|
||
|
return Insert((BYTE*)&ptr, sizeof (CBitmapObj*));
|
||
|
}
|
||
|
inline UINT InsertRect(const CRect& rc) { return Insert((BYTE*)&rc, sizeof (CRect)); }
|
||
|
inline UINT InsertPoint(const CPoint& pt) { return Insert((BYTE*)&pt, sizeof (CPoint)); }
|
||
|
|
||
|
void Flush();
|
||
|
|
||
|
void OnInform(CBitmapObj* pChangedSlob, UINT idChange);
|
||
|
|
||
|
void FlushLast();
|
||
|
|
||
|
private:
|
||
|
|
||
|
void Truncate();
|
||
|
|
||
|
int m_nRecording; // BeginUndo() nesting count
|
||
|
int m_nPauseLevel; // Pause() nesting count
|
||
|
|
||
|
int m_cbUndo;
|
||
|
|
||
|
// These ?Last* variables are used to coalesce consecutive changes
|
||
|
// to the same property...
|
||
|
CBitmapObj* m_pLastSlob;
|
||
|
int m_nLastPropID;
|
||
|
|
||
|
// Properties...
|
||
|
int m_nMaxLevels;
|
||
|
|
||
|
CObList m_seqs; // pointers to CBmObjSequences
|
||
|
int m_nRedoSeqs;
|
||
|
CBmObjSequence* m_pCurSeq;
|
||
|
|
||
|
BOOL m_bPerformingUndoRedo;
|
||
|
|
||
|
friend class CBmObjSequence;
|
||
|
};
|
||
|
|
||
|
|
||
|
#pragma pack(1)
|
||
|
|
||
|
class CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
BYTE m_op;
|
||
|
CBitmapObj* m_pBitmapObj;
|
||
|
UINT m_nPropID;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CIntUndoRecord : public CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
int m_nOldVal;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CLongUndoRecord : public CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
long m_nOldVal;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CDoubleUndoRecord : public CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
double m_numOldVal;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CRectUndoRecord : public CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
CRect m_rectOldVal;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CPointUndoRecord : public CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
CPoint m_ptOldVal;
|
||
|
};
|
||
|
|
||
|
|
||
|
class CBitmapObjUndoRecord : public CUndoRecord
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
const CBitmapObj* m_pOldVal;
|
||
|
};
|
||
|
|
||
|
#pragma pack()
|
||
|
|
||
|
extern CUndoBmObj NEAR theUndo;
|
||
|
|
||
|
#endif // __UNDO_H__
|