BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Need tip to create undo with TObject derived

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage)
View previous topic :: View next topic  
Author Message
René Wilhelmy
Guest





PostPosted: Tue Dec 16, 2003 7:27 pm    Post subject: Need tip to create undo with TObject derived Reply with quote



Hi,
I'm looking for any suggestions about undo data changes using my derived
objects, like the one (so usefull!) found in CBuilder example.
I read little bit about the use of the type Variant.
Is it a good way to track down the modifications of the properties and
values around my Class?
Thanks,

rene

Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Dec 16, 2003 9:07 pm    Post subject: Re: Need tip to create undo with TObject derived Reply with quote




"René Wilhelmy" <r.wil (AT) sympatico (DOT) ca> wrote


Quote:
I'm looking for any suggestions about undo data changes
using my derived objects, like the one (so usefull!) found
in CBuilder example.

What exactly are you trying to accomplish? Please provide more details,
your description is very vague.


Gambit



Back to top
René Wilhelmy
Guest





PostPosted: Wed Dec 17, 2003 4:44 pm    Post subject: Re: Need tip to create undo with TObject derived Reply with quote



Thanks for your time Remy!

I'm developping a CAD application which use plenty of derived TObject,
TGraphicControl etc. So I want to track down all the real time user's
actions with the soft: like moving a control point (value X and Y),
adding or removing an object on the drawing etc., changing Properties on
a specific object; and giving to the user
the possibility to undo (or redo) one or multiple action(s) at anytime.
At first, my rough approach could be to use a TObjectList and adding on
it a special Class Object for each user's action, and which could point
properly to different modified value and hold the specific value at his
original state. So my first request is to know if a Variant can
correctly point to a Propertie and a VCL Class and of course if another
way could more appropriate...

Many thanks,

Rene Wilhelmy


Remy Lebeau (TeamB) a écrit:
Quote:
"René Wilhelmy" <r.wil (AT) sympatico (DOT) ca> wrote in message
news:3FDF5C8C.3080200 (AT) sympatico (DOT) ca...


What exactly are you trying to accomplish? Please provide more details,
your description is very vague.


Gambit




Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Dec 17, 2003 6:42 pm    Post subject: Re: Need tip to create undo with TObject derived Reply with quote


"René Wilhelmy" <r.wil (AT) sympatico (DOT) ca> wrote


Quote:
I want to track down all the real time user's actions with the soft:
like moving a control point (value X and Y), adding or removing
an object on the drawing etc., changing Properties on a specific
object; and giving to the user the possibility to undo (or redo) one
or multiple action(s) at anytime.

Since the VCL has no such provisions available, you will just have to
inclement your own system manually.

Quote:
At first, my rough approach could be to use a TObjectList
and adding on it a special Class Object for each user's action

That is one way to do it. Why use a TObjectList, though? That requires
your "special" class to be a TObject descendant, which is unnecessary for
what you are asking. You could just use a TList or STL container
(std::vector, std::deque, etc) instead.

Quote:
So my first request is to know if a Variant can correctly
point to a Propertie

Not to the property itself, no, only a copy of the value that it contains.

Quote:
and a VCL Class

No.

I would not recommend using a Variant for what you ask anyway, even if it
did support it. I would instead suggest creating specialized classes for
each particular operation that you want to be able to undo, derived from an
abstract base class that has a virtual Undo() method that each descendant
overrides to perform the actual undo operations. That way, you can have a
list of base class pointers, and for each operation that supports undoing
since create an instance of the appropriate Undo class and add it to the
list. Then, when needed you can simply run through the list and call Undo()
for each operation desired, without actually knowing what the operation
actually is, and let polymorphism work for you in determine what actions
need to be performed.

For example (untested):

--- UndoClasses.h ---

class TUndoActionBase
{
public:
virtual void Undo() = 0;
};

TControlPointChangeUndo : public TUndoActionBase
{
private:
TControl *Control;
int PreviousX, PreviousY;
public:
TControlPointChangeUndo(TControl *AControl);
void Undo();
}

TAddObjectUndo : public TUndoActionBase
{
private:
TObject *Object;
public:
TAddObjectUndo(TObject *AObject);
void Undo();
}

#include <TypInfo.hpp>
// note - this class only supports undoing *published* properties.
// if you need to undo *public* properties instead, then you will
// have to come up with your own mechanism for it.
TChangePropertyUndo : public TUndoActionBase
{
private:
TObject *Object;
PPropInfo PropInfo;
Variant PreviousValue;
public:
TChangePropertyUndo(TObject *AObject, const AnsiString &PropName);
void Undo();
}


--- UndoClasses.cpp ---

TControlPointChangeUndo::TControlPointChangeUndo(TControl *AControl)
: TUndoActionBase()
{
Control = AControl;
PreviousX = Control->Left;
PreviousY = Control->Top;
}

void TControlPointChangeUndo::Undo()
{
Control->Left = PreviousX;
Control->Top = PreviousY;
}


TAddObjectUndo::TAddObjectUndo(TObject *AObject)
: TUndoActionBase()
{
Object = AObject;
}

void TAddObjectUndo::Undo()
{
delete Object;
}

TChangePropertyUndo::TChangePropertyUndo(TObject *AObject, const
AnsiString &PropName)
: TUndoActionBase()
{
Object = AObject;
PropInfo = GetPropInfo(Object, PropName);
if( PropInfo )
PreviousValue = GetVariantProp(Object, PropInfo);
}

void TChangePropertyUndo::Undo()
{
if( PropInfo )
SetVariantProp(Object, PropInfo, PreviousValue);
}


Then, your main code can do something like the following:

#1: using TList:

#include "UndoClasses.h"

TList *UndoList = new TList;
//...
TMyObject *obj = new TMyObject;
UndoList->Add(new TAddObjectUndo(obj));
//...
UndoList->Add(new TControlPointChangeUndo(obj));
obj->Left = NewLeft;
obj->Top = NewTop;
//...
UndoList->Add(new TChangePropertyUndo(obj, "SomeProperty"));
obj->SomeProperty = NewValue;
//...
while( UndoList->Count )
{
TUndoActionBase *pAction = (TUndoActionBase*)
UndoList->Items[UndoList->Count-1];
UndoList->Delete(UndoList->Count-1);
pAction->Undo();
delete pAction;
}
//...
delete UndoList;


#2: Using std::vector

#include "UndoClasses.h"
#include <vector>

std::vector<TUndoActionBase*> UndoList;
//...
TMyObject *obj = new TMyObject;
UndoList.push_back(new TAddObjectUndo(obj));
//...
UndoList.push_back(new TControlPointChangeUndo(obj));
obj->Left = NewLeft;
obj->Top = NewTop;
//...
UndoList.push_back(new TChangePropertyUndo(obj, "SomeProperty"));
obj->SomeProperty = NewValue;
//...
while( !UndoList.empty() )
{
std::vector<TUndoActionBase*>::iterator iter = UndoList.back();
TUndoActionBase *pAction = (*iter);
UndoList.pop_back();
pAction->Undo();
delete pAction;
}


Gambit



Back to top
René Wilhelmy
Guest





PostPosted: Wed Dec 17, 2003 9:10 pm    Post subject: Re: Need tip to create undo with TObject derived Reply with quote

Again thank you very much Remy!

I appreciate a lot the vector aspect and the use of PPropInfo and the
methods of TPropertyEditor which are my missing pieces!

Rene Wilhelmy

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.