[Closed] [sdk] 'Storing' a controller
What would be the best way to save a controller selection? A users picks one using the TrackViewPickDlg() and I end up with a IControl which is the picked controller. Now I want to save that selection in the scene, as an AppDataChunk for example but that only saves strings. I probably could find ‘a’ path to the controller but that is not very pretty. And controllers don’t have handles like nodes do. Any ideas?
they have anim handles but they are not save safe so no use to you anyway also appdata is any binary data you just need to allocate with MaxAlloc() (also not much help). Your best bet is use the a IParamBlock2 type TYPE_REFTARG_TAB in a parameter block
then set and get with
virtual BOOL SetValue (ParamID id, TimeValue t, ReferenceTarget *v, int tabIndex=0)=0
virtual BOOL GetValue (ParamID id, TimeValue t, ReferenceTarget *&v, Interval &ivalid, int tabIndex=0)=0
there also an example of appdata being used to store on an Animatable in \maxsdk\samples\utilities\appdata.cpp not exactly what you want but not to much work knock it into shape…
say to add a simple selected tag to each control selected.
something (untested) like
bool SetControlPicked(Control* cntrl, BOOL picked)
{
int* ptr = static_cast<int*>(MAX_malloc(sizeof(int)));
if(!ptr)
return false;
*ptr = picked;
cntrl->RemoveAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID);
cntrl->AddAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID, sizeof(int), ptr);
return true;
}
BOOL GetControlPicked(Control* cntrl)
{
AppDataChunk* appdata = cntrl->GetAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID);
return appdata ? *static_cast<int*>(appdata->data) : FALSE;
}
how you might handle enumerating or clearing a “tag” after a file is loaded
much the same just made just moved it up a class or 2
bool SetControlPicked(Animatable* anim, BOOL picked)
{
int* ptr = static_cast<int*>(MAX_malloc(sizeof(int)));
if(!ptr)
return false;
*ptr = picked;
anim->RemoveAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID);
anim->AddAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID, sizeof(int), ptr);
return true;
}
BOOL GetControlPicked(Animatable *anim)
{
AppDataChunk* appdata = anim->GetAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID);
return appdata ? *static_cast<int*>(appdata->data) : FALSE;
}
enumerator classes
class ClearAllPickedCntrls : public Animatable::EnumAnimList
{
public:
bool proc(Animatable *anim)
{
anim->RemoveAppDataChunk(MY_CLASS_ID, MY_SUPERCLASS_ID, MY_PICK_ID);
return true;
}
};
class enumPickedCntrl : public Animatable::EnumAnimList
{
public:
Tab<Animatable*> cntrls;
bool proc(Animatable *anim)
{
if(GetControlPicked(anim))
cntrls.Append(1,&anim);
return true;
}
};
usage where ip is pointer to the max interface...
enumPickedCntrl enumerator;
ClearAllPickedCntrls clearPicked;
Animatable* root = ip->GetScenePointer();
root->EnumerateAllAnimatables(enumerator); // collect all the "tagged" controls
int nctrl = enumerator.cntrls.Count(); // in the cntrls tab
root->EnumerateAllAnimatables(clearPicked);
the clearPicked enumeration is probably overkill having already collected the relevant Controls