R12 PrefsDialogHook/PrefsDialogObject/etc.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 12/09/2010 at 07:57, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R12
Platform: Windows ; Mac OSX ;
Language(s) : C++ ;---------
Example of correct usage, please? This area has been completely rewritten, and yet remains undocumented, not even being mentioned in the transition PDF.JD
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/09/2010 at 00:33, xxxxxxxx wrote:
The documentation is currently preliminary and will be updated soon. If I find the time I will try to post a small example later today.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/09/2010 at 06:37, xxxxxxxx wrote:
Thanks. For most of the changes, documentation is hardly even necessary, but I'd prefer not to spend alot of time blindly poking around this particular black box.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/09/2010 at 03:32, xxxxxxxx wrote:
Basically all that is needed now for plugin preference hooks is your own overloaded PrefsDialogObject class. As you may have noticed preferences are description based in R12 and derived from NodeData.
Here an example from our timeline prefs which should get you started. There are still some things unclear to myself but currently the developer responsible for the prefs overhaul is on vacation. I will keep you posted.
class TimelinePrefsObject : public PrefsDialogObject { INSTANCEOF(TimelinePrefsObject,PrefsDialogObject) public: static NodeData *Alloc() { return gNew TimelinePrefsObject; } virtual Bool GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags); virtual Bool GetDParameter(GeListNode *node, const DescID &id,GeData &t_data,DESCFLAGS_GET &flags); virtual Bool SetDParameter(GeListNode *node, const DescID &id,const GeData &t_data,DESCFLAGS_SET &flags); virtual Bool GetDEnabling(GeListNode *node, const DescID &id,const GeData &t_data,DESCFLAGS_ENABLE flags,const BaseContainer *itemdesc); virtual Bool Init(GeListNode* node); virtual Bool InitValues(const DescID &id, Description* desc = NULL); private: BaseContainer* GetTLPrefs(); }; // My own function to get the TL containmer from the world prefs BaseContainer* TimelinePrefsObject::GetTLPrefs() { BaseContainer* bc=GetWorldContainerInstance()->GetContainerInstance(PREFSDIALOG_ID); if (!bc) { GetWorldContainerInstance()->SetContainer(PREFSDIALOG_ID,BaseContainer()); bc = GetWorldContainerInstance()->GetContainerInstance(PREFSDIALOG_ID); if (!bc) return NULL; } return bc; } // Return the Parameter --> make sure to always set the flag Bool TimelinePrefsObject::GetDParameter(GeListNode *node, const DescID &id,GeData &t_data,DESCFLAGS_GET &flags) { BaseContainer* bc = GetTLPrefs(); if (!bc) SUPER::GetDParameter(node,id,t_data,flags); switch (id[0].id) { case PREF_TL_HIGHLIGHT: t_data = bc->GetBool(WPREFS_HIGHLIGHT,TRUE); flags |= DESCFLAGS_GET_PARAM_GET; return TRUE; // ... } return SUPER::GetDParameter(node,id,t_data,flags); } // Enable and disable the parameters Bool TimelinePrefsObject::GetDEnabling(GeListNode *node, const DescID &id,const GeData &t_data,DESCFLAGS_ENABLE flags,const BaseContainer *itemdesc) { BaseContainer* bc = GetTLPrefs(); if (!bc) SUPER::GetDEnabling(node,id,t_data,flags,itemdesc); return SUPER::GetDEnabling(node,id,t_data,flags,itemdesc); } // Set the parameters -> make sure to always set the flag and call GeUpdateUI() Bool TimelinePrefsObject::SetDParameter(GeListNode *node, const DescID &id,const GeData &t_data,DESCFLAGS_SET &flags) { BaseContainer* bc = GetTLPrefs(); if (!bc) SUPER::SetDParameter(node,id,t_data,flags); switch (id[0].id) { case PREF_TL_HIGHLIGHT: bc->SetBool(WPREFS_HIGHLIGHT,t_data.GetLong()); flags |= DESCFLAGS_SET_PARAM_SET; GeUpdateUI(); return TRUE; } return SUPER::SetDParameter(node,id,t_data,flags); } // Init the values Bool TimelinePrefsObject::Init(GeListNode* node) { BaseContainer* bc = GetTLPrefs(); if (!bc) return FALSE; InitPrefsValue(WPREFS_HIGHLIGHT,GeData(TRUE),desc,id,bc); // do this for all values return TRUE; } // Set the description and if the flag DESCFLAGS_DESC_NEEDDEFAULTVALUE was set the user called reset to Parameter Bool TimelinePrefsObject::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags) { if (!description->LoadDescription("Prefstimeline")) return FALSE; if ( flags & DESCFLAGS_DESC_NEEDDEFAULTVALUE ) { InitPrefsValue(WPREFS_HIGHLIGHT,GeData(TRUE),desc,id,bc); // do this for all values } flags |= DESCFLAGS_DESC_LOADED; return SUPER::GetDDescription(node, description, flags); } // Register Bool RegisterPrefs() { PrefsDialogObject::Register(PREFS_TL,TimelinePrefsObject::Alloc,GeLoadString(IDS_TL_TITLEPREFS),"Prefstimeline",0,PREFS_PRI_MODULES); return TRUE; }
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/09/2010 at 20:45, xxxxxxxx wrote:
Thanks for posting the example. Just fyi, there are some mistakes (i.e. missing 'return' @ [if (!bc) SUPER::] in a few methods, and phantom desc/id params being used in Init/GetDDescription), so maybe the post should be edited, to protect against copy/paste coders.
Also, I have no idea what those InitPrefsValue methods are supposed to be doing -- they didn't seem to affect anything at all here.
So, in case anyone else wonders how to make it work: as I was previously doing with the old dialog-based prefs hook, and as you are basically doing here, I just put a BaseContainer into the world container and use Set/GetDParameter to forward UI action to/from that.
Rather than messing around with those InitNnn methods though, I just initialize everything in the BaseContainer on first access, or on DESCFLAGS_DESC_NEEDDEFAULTVALUE. So basically:
Bool TimelinePrefsObject::GetTLPrefs(BaseContainer*& bc)
{
bc = GetWorldContainerInstance()->GetContainerInstance(PREFSDIALOG_ID);
if (!bc)
{
GetWorldContainerInstance()->SetContainer(PREFSDIALOG_ID,BaseContainer());
bc = GetWorldContainerInstance()->GetContainerInstance(PREFSDIALOG_ID);
// no prefs, init values
if (bc) InitContainer(bc);
}return bc != 0;
}Whatever the case, the new system is much better than the old one -- only one object to deal with, and besides that, descriptions just work alot nicer.