Connecting CustomDataType to CustomGui?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 22/11/2008 at 14:05, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R9-11 
Platform:   Windows  ; Mac  ;  Mac OSX  ; 
Language(s) :     C++  ;

---------
So, how would I go about making my CustomDataType know about its CustomGui and vice versa?

These are added via ELEMENTID id { CUSTOMGUI xxx } in the .res file.

I'd kill for a 'simple' *full* example in the spirit of the CUSTOMDATATYPE_SPLINE (with or without the Spline library accessibility) to understand the requirements and complexities of doing this rather than groping endlessly in the dark murkiness. I have a deep feeling that endless groping is what leads to unstable/crashy code (since there must be correct ways and incorrect ways to do this stuff). If I have to guess or use what might be considered improper methodologies, I can't be held responsible.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/11/2008 at 03:44, xxxxxxxx wrote:

I assume you don´t need to specify the customgui in the resource files. The customdatatype should know about it as it simply belongs to it.

All you need to do is

YOURDATATYPEID id {Parameters}

Or do you mean something else? What are you trying to achieve?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/11/2008 at 04:55, xxxxxxxx wrote:

You need to overload GetProperties()and GetResourceDataType(LONG*& table) of your CustomGuiData and your CustomDataTypeClass. Also return the string for the resource files in GetResourceSym() for your custom data type and your cusom gui.

This stuff is best explained in a full example. I am currently working on one and hope I can post something this week.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/11/2008 at 09:50, xxxxxxxx wrote:

Here is some code and such so far (it's a lot). Problem is that I don't quite understand GetProperties() or GetResourceDataType() enough. GetProperties() looks to just specify variable configuration flags of the customgui/customdatatype - I don't need those really.

This is the Description Resource for the plugin object using the customgui/customdatatype (I was led by the docs to believe that the ELEMENTID and CUSTOMGUI should be the same name specified in GetResourceSym() for these) :

> CONTAINER Omagnetudezone \> { \>      ... \>      GROUP     ID_OBJECTPROPERTIES \>      { \>           ... \>           KDZFALLOFF     MAGNETUDE_ZONE_GRAPH               { CUSTOMGUI KDZFALLOFFGRAPH; } \>      } \> }

Here's the header for the customgui/customdatatype (note: I've omitted the GeUserArea as this code isn't relevant for our purposes) :

> //////////////////////////////////////////////////////////////// \> // KDZ_Falloff.h \> //////////////////////////////////////////////////////////////// \> // CustomDataType/CustomGui KDZ_Falloff \> //////////////////////////////////////////////////////////////// \> // V0.1 2008.11.18 Robert Templeton \> //////////////////////////////////////////////////////////////// \> #ifndef \_KDZ_FALLOFF_H\_ \> #define \_KDZ_FALLOFF_H\_ \> \> // Includes \> #include "c4d.h" \> #include "Dkdzfalloff.h" \> \> // Plugin IDs \> // - KDZFalloffGuiData Plugin ID \> const LONG     CUSTOMGUI_KDZFALLOFF          =     1023308L; \> // - KDZFalloffDataTypeClass Plugin ID \> const LONG     CUSTOMDATATYPE_KDZFALLOFF     =     1023271L; \> \> \> // CustomDataType ============================================================= \> // CLASS: KDZFalloff \> class KDZFalloff : public iCustomDataType<KDZFalloff> \> { \>      LONG          type;                    // Spline type (see Dkdzfalloff.h) \>      LONG          count;                    // Number of spline points \>      Vector\*          points;                    // Spline points: 'z' is ignored \> \>      public: \>           KDZFalloff(); \>           ~KDZFalloff(); \>           KDZFalloff(const KDZFalloff& rhs); \>           KDZFalloff& operator=(const KDZFalloff& rhs); \>           operator GeData() const \>           { \>                return GeData(CUSTOMDATATYPE_KDZFALLOFF, \*this); \>           } \>           Bool                    Init(); \>           Bool                    CopyTo(KDZFalloff\* dest); \>           Bool                    Read(HyperFile\* hf); \>           Bool                    Write(HyperFile\* hf); \>           LONG                    GetType() const; \>           LONG                    GetCount() const; \>           Vector                    GetPoint(const LONG& index) const; \>           Vector\*                    GetPoints() const; \>           void                    SetType(const LONG& t_type); \>           void                    SetCount(const LONG& t_count); \>           void                    SetPoint(const LONG& index, const Vector& pt); \> }; \> \> // CLASS: KDZFalloffDataTypeClass \> class KDZFalloffDataTypeClass : public CustomDataTypeClass \> { \>      INSTANCEOF(KDZFalloffDataTypeClass,CustomDataTypeClass) \> \>      public: \>           LONG                     GetId(); \>           CustomDataType\*      AllocData(); \>           void                     FreeData(CustomDataType\* data); \>           Bool                     CopyData(const CustomDataType\* src, CustomDataType\* dst, AliasTrans\* aliastrans); \>           LONG                    Compare(const CustomDataType\* d1, const CustomDataType\* d2); \>           Bool                     WriteData(const CustomDataType\* t_d, HyperFile\* hf); \>           Bool                     ReadData(CustomDataType\* t_d, HyperFile\* hf, LONG level); \>           CHAR\*                    GetResourceSym(); \>           //CustomProperty\*          GetProperties(); \>           void                     GetDefaultProperties(BaseContainer& data); \>           Bool                     \_GetDescription(const CustomDataType\* data, Description& desc, LONG& flags, const BaseContainer& parentdescription, DescID\* singledescid); \>           Bool                     GetParameter(const CustomDataType\* data, const DescID& id, GeData& t_data, LONG& flags); \>           Bool                     SetDParameter(CustomDataType\* data, const DescID& id, const GeData& t_data, LONG& flags); \>           Bool                     GetEnabling(const CustomDataType\* data, const DescID& id, GeData& t_data, LONG& flags, const BaseContainer\* itemdesc); \> }; \> \> // CustomGui ================================================================== \> // CLASS: KDZFalloffGui \> class KDZFalloffGui : public iCustomGui \> { \>      INSTANCEOF(KDZFalloffGui,iCustomGui) \> \>      private: \>           BaseContainer          m_settings; \>           // Pointer to CustomDataType data class (no good) \>           KDZFalloff\*               falloff; \> \>      public: \>           KDZFalloffGui(const BaseContainer& settings, CUSTOMGUIPLUGIN\* t_plugin); \>           ~KDZFalloffGui(); \>           // iCustomGui \>           LONG                    CustomGuiWidth(); \>           LONG                    CustomGuiHeight(); \>           void                    CustomGuiRedraw(); \>           Bool                    SetDefaultForResEdit(); \>           Bool                    SetData(const TriState<GeData>& tristate); \>           TriState<GeData>     GetData(); \>           // GeDialog \>           Bool                    CreateLayout(); \>           Bool                    InitValues(); \>           LONG                    Message(const BaseContainer& msg, BaseContainer& result); \>           Bool                    Command(LONG id, const BaseContainer &msg;); \> }; \> \> // CLASS: KDZFalloffGuiData \> class KDZFalloffGuiData : public CustomGuiData \> { \>      INSTANCEOF(KDZFalloffGuiData,CustomGuiData) \> \>      public: \>           LONG                     GetId(); \>           CDialog\*               Alloc(const BaseContainer& settings); \>           void                    Free(CDialog\* dlg, void\* userdata); \>           CHAR\*                    GetResourceSym(); \>           LONG                    GetResourceDataType(LONG\*& table); \> }; \> #endif     // \_KDZ_FALLOFF_H\_ \>

And, finally, here's the source (omitting the GeUserArea code) :

> //////////////////////////////////////////////////////////////// \> // KDZ_Falloff.cpp \> //////////////////////////////////////////////////////////////// \> // CustomDataType and CustomGui KDZFalloff \> //////////////////////////////////////////////////////////////// \> // V0.1 2008.11.18 Robert Templeton \> //////////////////////////////////////////////////////////////// \> \> // Includes \> #include "KDZ_Falloff.h" \> \> // Maximum number of spline points \> const LONG     MAX_KDZPOINTS =          128L; \> \> // METHODS: KDZFalloff =============================================================================================================== \> // Constructor \> //\*---------------------------------------------------------------------------\* \> KDZFalloff::KDZFalloff() \> //\*---------------------------------------------------------------------------\* \> { \>      type =          KDZ_FALLOFF_TYPE_CONTINUOUS; \>      count =          0L; \>      points =     NULL; \> } \> // Destructor \> //\*---------------------------------------------------------------------------\* \> KDZFalloff::~KDZFalloff() \> //\*---------------------------------------------------------------------------\* \> { \>      bDelete(points); \> } \> // Copy Constructor \> //\*---------------------------------------------------------------------------\* \> KDZFalloff::KDZFalloff(const KDZFalloff& rhs) \> //\*---------------------------------------------------------------------------\* \> { \>      if (this == &rhs;)     return; \>      // Copy Data \>      type =                    rhs.type; \>      count =                    rhs.count; \>      if (!points)          points =     bNew Vector[MAX_KDZPOINTS]; \>      if (!points) \>      { \>           count =     0L; \>           return; \>      } \>      if (!count)               return; \>      CopyMem(rhs.points, points, sizeof(Vector)\*MAX_KDZPOINTS); \> } \> // Copy Assignment Operator \> //\*---------------------------------------------------------------------------\* \> KDZFalloff& KDZFalloff::operator=(const KDZFalloff& rhs) \> //\*---------------------------------------------------------------------------\* \> { \>      if (this == &rhs;)     return \*this; \>      // Copy Data \>      type =                    rhs.type; \>      count =                    rhs.count; \>      if (!points)          points =     bNew Vector[MAX_KDZPOINTS]; \>      if (!points) \>      { \>           count =     0L; \>           return \*this; \>      } \>      if (!count)               return \*this; \>      CopyMem(rhs.points, points, sizeof(Vector)\*MAX_KDZPOINTS); \>      return \*this; \> } \> // Initialize the CustomDataType data \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloff::Init() \> //\*---------------------------------------------------------------------------\* \> { \>      if (!points)     points =     bNew Vector[MAX_KDZPOINTS]; \>      if (!points) \>      { \>           count =     0L; \>           return FALSE; \>      } \>      // Initialize as continuous bell-shaped spline \>      type =               KDZ_FALLOFF_TYPE_CONTINUOUS; \>      count =               2L; \>      points[0] =          Vector(0.0f, 1.0f, 0.0f); \>      points[1] =          Vector(1.0f, 0.0f, 0.0f); \>      return TRUE; \> } \> // Copy this to 'dest' \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloff::CopyTo(KDZFalloff\* dest) \> //\*---------------------------------------------------------------------------\* \> { \>      if (this == dest)     return TRUE; \>      // Copy Data \>      dest->type =          type; \>      dest->count =          count; \>      if (!dest->points)     dest->points =     bNew Vector[MAX_KDZPOINTS]; \>      if (!dest->points) \>      { \>           dest->count =     0L; \>           return TRUE; \>      } \>      if (!count)               return TRUE; \>      CopyMem(points, dest->points, sizeof(Vector)\*MAX_KDZPOINTS); \>      return TRUE; \> } \> // Read from C4D File \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloff::Read(HyperFile\* hf) \> //\*---------------------------------------------------------------------------\* \> { \>      if (!hf->ReadLong(&type;))     return FALSE; \>      if (!hf->ReadLong(&count;))     return FALSE; \>      points =                         bNew Vector[MAX_KDZPOINTS]; \>      if (!points)                    return FALSE; \>      if (!count)                         return TRUE; \>      Vector\*     p =                         points; \>      for (LONG i = 0L; i != count; ++i) \>      { \>           if (!hf->ReadVector(p))     return FALSE; \>           ++p; \>      } \>      return TRUE; \> } \> // Write to C4D File \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloff::Write(HyperFile\* hf) \> //\*---------------------------------------------------------------------------\* \> { \>      if (!hf->WriteLong(type))     return FALSE; \>      if (!hf->WriteLong(count))     return FALSE; \>      if (!count)                         return TRUE; \>      if (!points)                    return FALSE; \>      Vector\*     p =                         points; \>      for (LONG i = 0L; i != count; ++i) \>      { \>           if (!hf->WriteVector(\*p))     return FALSE; \>           ++p; \>      } \>      return TRUE; \> } \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloff::GetType() const \> //\*---------------------------------------------------------------------------\* \> { \>      return type; \> } \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloff::GetCount() const \> //\*---------------------------------------------------------------------------\* \> { \>      return count; \> } \> //\*---------------------------------------------------------------------------\* \> Vector KDZFalloff::GetPoint(const LONG& index) const \> //\*---------------------------------------------------------------------------\* \> { \>      if (index < 0L)                    return Vector(0.0f); \>      if (index >= MAX_KDZPOINTS)     return Vector(0.0f); \>      return points[index]; \> } \> //\*---------------------------------------------------------------------------\* \> Vector\* KDZFalloff::GetPoints() const \> //\*---------------------------------------------------------------------------\* \> { \>      return points; \> } \> //\*---------------------------------------------------------------------------\* \> void KDZFalloff::SetType(const LONG& t_type) \> //\*---------------------------------------------------------------------------\* \> { \>      type =          t_type; \> } \> //\*---------------------------------------------------------------------------\* \> void KDZFalloff::SetCount(const LONG& t_count) \> //\*---------------------------------------------------------------------------\* \> { \>      if (t_count < 0L)                    return; \>      if (t_count > MAX_KDZPOINTS)     return; \>      count =                                   t_count; \> } \> //\*---------------------------------------------------------------------------\* \> void KDZFalloff::SetPoint(const LONG& index, const Vector& pt) \> //\*---------------------------------------------------------------------------\* \> { \>      if (index < 0L)                    return; \>      if (index >= MAX_KDZPOINTS)     return; \>      points[index] =                    pt; \> } \> \> \> // METHODS: KDZFalloffDataTypeClass ================================================================================================== \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffDataTypeClass::GetId() \> //\*---------------------------------------------------------------------------\* \> { \>      return CUSTOMDATATYPE_KDZFALLOFF; \> } \> //\*---------------------------------------------------------------------------\* \> CustomDataType\* KDZFalloffDataTypeClass::AllocData() \> //\*---------------------------------------------------------------------------\* \> { \>      return gNew KDZFalloff; \> }; \> //\*---------------------------------------------------------------------------\* \> void KDZFalloffDataTypeClass::FreeData(CustomDataType\* data) \> //\*---------------------------------------------------------------------------\* \> { \>      KDZFalloff\*     d =          static_cast<KDZFalloff\*>(data); \>      gDelete(d); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::CopyData(const CustomDataType\* src, CustomDataType\* dst, AliasTrans\* aliastrans) \> //\*---------------------------------------------------------------------------\* \> { \>      KDZFalloff\*     s =          (KDZFalloff\* )src; \>      KDZFalloff\*     d =          (KDZFalloff\* )dst; \>      if (!(s && d))          return FALSE; \> \>      if (!s->CopyTo(d))     return FALSE; \> \>      return TRUE; \> } \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffDataTypeClass::Compare(const CustomDataType\* d1,const CustomDataType\* d2) \> //\*---------------------------------------------------------------------------\* \> { \>      KDZFalloff\*     s =          (KDZFalloff\* )d1; \>      KDZFalloff\*     d =          (KDZFalloff\* )d2; \>      if (!(s && d))          return FALSE; \> \>      return 0L; \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::WriteData(const CustomDataType\* t_d, HyperFile\* hf) \> //\*---------------------------------------------------------------------------\* \> { \>      if (!(t_d && hf))     return FALSE; \>      KDZFalloff\*     d =          (KDZFalloff\* )t_d; \>      return d->Write(hf); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::ReadData(CustomDataType\* t_d, HyperFile\* hf, LONG level) \> //\*---------------------------------------------------------------------------\* \> { \>      if (!(t_d && hf))     return FALSE; \>      return (static_cast<KDZFalloff\*>(t_d))->Read(hf); \> } \> //\*---------------------------------------------------------------------------\* \> CHAR\* KDZFalloffDataTypeClass::GetResourceSym() \> //\*---------------------------------------------------------------------------\* \> { \>      return "KDZFALLOFF"; \> } \> /\* \> //\*---------------------------------------------------------------------------\* \> CustomProperty\*     KDZFalloffDataTypeClass::GetProperties() \> //\*---------------------------------------------------------------------------\* \> { \>      return datatypeprops; \> } \> \*/ \> //\*---------------------------------------------------------------------------\* \> void KDZFalloffDataTypeClass::GetDefaultProperties(BaseContainer& data) \> //\*---------------------------------------------------------------------------\* \> { \>      // fill default DESC_xxx values \>      data.SetLong(DESC_CUSTOMGUI,               CUSTOMGUI_KDZFALLOFF); \>      data.SetLong(DESC_ANIMATE,                    DESC_ANIMATE_ON); \>      data.SetBool(DESC_HIDE,                         FALSE); \>      data.SetBool(DESC_REMOVEABLE,               FALSE); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::\_GetDescription(const CustomDataType\* data, Description& desc, LONG& flags, const BaseContainer& parentdescription, DescID\* singledescid) \> //\*---------------------------------------------------------------------------\* \> { \>      Bool     res =     desc.LoadDescription(GetId()); \>      if (res)          flags |=     DESCFLAGS_DESC_LOADED; \>      return SUPER::\_GetDescription(data, desc, flags, parentdescription, singledescid); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::GetParameter(const CustomDataType\* data, const DescID& id, GeData& t_data, LONG& flags) \> //\*---------------------------------------------------------------------------\* \> { \>      const KDZFalloff\*     s =     (KDZFalloff\* )data; \>      if (!s)                         return FALSE; \>      if (id[0].id == KDZ_FALLOFF_TYPE) \>      { \>           t_data =     GeData(s->GetType()); \>           flags |=     DESCFLAGS_PARAM_GET; \>      } \>      return SUPER::GetParameter(data, id, t_data, flags); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::SetDParameter(CustomDataType\* data, const DescID& id, const GeData& t_data, LONG& flags) \> //\*---------------------------------------------------------------------------\* \> { \>      KDZFalloff\*     s =     (KDZFalloff\* )data; \>      if (!s)               return FALSE; \>      if (id[0].id == KDZ_FALLOFF_TYPE) \>      { \>           s->SetType(t_data.GetLong()); \>           flags |=     DESCFLAGS_PARAM_SET; \>      } \>      return SUPER::SetDParameter(data, id, t_data, flags); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffDataTypeClass::GetEnabling(const CustomDataType\* data, const DescID& id, GeData& t_data, LONG& flags, const BaseContainer\* itemdesc) \> //\*---------------------------------------------------------------------------\* \> { \>      return SUPER::GetEnabling(data, id, t_data, flags, itemdesc); \> } \> \> \> // METHODS: KDZFalloffGui ================================================================================================== \> static LONG restypetable[] =     { CUSTOMDATATYPE_KDZFALLOFF }; \> // Constructor \> //\*---------------------------------------------------------------------------\* \> KDZFalloffGui::KDZFalloffGui(const BaseContainer& settings, CUSTOMGUIPLUGIN\* t_plugin) : iCustomGui(settings, t_plugin) \> //\*---------------------------------------------------------------------------\* \> { \>      m_settings =     BaseContainer(settings); \>      grid =               NULL; \> } \> // Destructor \> //\*---------------------------------------------------------------------------\* \> KDZFalloffGui::~KDZFalloffGui() \> //\*---------------------------------------------------------------------------\* \> { \>      gDelete(grid); \> } \> // iCustomGui Methods \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffGui::CustomGuiWidth() \> //\*---------------------------------------------------------------------------\* \> { \>      return 256L; \> } \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffGui::CustomGuiHeight() \> //\*---------------------------------------------------------------------------\* \> { \>      return 256L; \> } \> //\*---------------------------------------------------------------------------\* \> void KDZFalloffGui::CustomGuiRedraw() \> //\*---------------------------------------------------------------------------\* \> { \>      // Update UserArea \>      grid->Redraw(); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffGui::SetDefaultForResEdit() \> //\*---------------------------------------------------------------------------\* \> { \>      return TRUE; \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffGui::SetData(const TriState<GeData>& tristate) \> //\*---------------------------------------------------------------------------\* \> { \>      // Never called \>      KDZFalloff\* d =     static_cast<KDZFalloff\*>(tristate.GetValue().GetCustomDataType(CUSTOMDATATYPE_KDZFALLOFF)); \>      if (!d)               { GePrint("SetData Failed!"); return FALSE; } \>      if (!d->Init())     return FALSE; \>     falloff =          d; \>      if (grid)          grid->SetCustomData(falloff); \>     return InitValues(); \> } \> //\*---------------------------------------------------------------------------\* \> TriState<GeData> KDZFalloffGui::GetData() \> //\*---------------------------------------------------------------------------\* \> { \>      // Doesn't work \>      if (!falloff)     return GeData(DA_NIL); \>      LONG     type =     falloff->GetType(); \>      GetLong(KDZ_FALLOFF_TYPE, type); \>      return GeData(\*falloff); \> } \> // GeDialog Methods \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffGui::CreateLayout() \> //\*---------------------------------------------------------------------------\* \> { \>      GroupBegin(0L, BFH_SCALEFIT|BFV_SCALEFIT , 1L, 0L, String(""), 0L); \>      { \>           // Falloff Graph \>           grid =          gNew Falloff_UserArea(); \>           if (!grid)     return FALSE; \>           AddUserArea(KDZ_FALLOFF_GRAPH, BFH_SCALEFIT|BFV_TOP, 256L, 256L); \>           AttachUserArea(\*grid, KDZ_FALLOFF_GRAPH, 0L); \> \>           // Spline Interpolation/Type \>           AddComboBox(KDZ_FALLOFF_TYPE, BFH_LEFT|BFV_CENTER); \>           AddChild(KDZ_FALLOFF_TYPE, KDZ_FALLOFF_TYPE_CONSTANT,     String("Constant")); \>           AddChild(KDZ_FALLOFF_TYPE, KDZ_FALLOFF_TYPE_LINEAR,          String("Linear")); \>           AddChild(KDZ_FALLOFF_TYPE, KDZ_FALLOFF_TYPE_CONTINUOUS,     String("Continuous")); \>           AddChild(KDZ_FALLOFF_TYPE, KDZ_FALLOFF_TYPE_BEZIER,          String("Bezier")); \>      } \>      GroupEnd(); \>      return TRUE; \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffGui::InitValues() \> //\*---------------------------------------------------------------------------\* \> { \>      // Doesn't work \>      if (falloff)     SetLong(KDZ_FALLOFF_TYPE, falloff->GetType()); \>      return TRUE; \> } \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffGui::Message(const BaseContainer& msg, BaseContainer& result) \> //\*---------------------------------------------------------------------------\* \> { \>      return SUPER::Message(msg, result); \> } \> //\*---------------------------------------------------------------------------\* \> Bool KDZFalloffGui::Command(LONG id, const BaseContainer &msg;) \> //\*---------------------------------------------------------------------------\* \> { \>      // ?? No Idea why Mikael does this \>      switch (id) \>      { \>           case KDZ_FALLOFF_TYPE: \>           { \>                BaseContainer m(msg); \>                m.SetLong(BFM_ACTION_ID, GetId()); \>                m.RemoveData(BFM_ACTION_VALUE); \>                m.SetData(BFM_ACTION_VALUE, GetData().GetValue()); \>                SendParentMessage(m); \>                break; \>           } \>      } \>      return TRUE; \> } \> \> \> // METHODS: KDZFalloffGuiData ================================================================================================== \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffGuiData::GetId() \> //\*---------------------------------------------------------------------------\* \> { \>      return CUSTOMGUI_KDZFALLOFF; \> } \> //\*---------------------------------------------------------------------------\* \> CDialog\* KDZFalloffGuiData::Alloc(const BaseContainer& settings) \> //\*---------------------------------------------------------------------------\* \> { \>      KDZFalloffGui\*     dlg =     gNew KDZFalloffGui(settings, GetPlugin()); \>      if (!dlg)                    return NULL; \> \>      CDialog\*          cdlg =     dlg->Get(); \>      if (!cdlg)                    return NULL; \> \>      return cdlg; \> } \> //\*---------------------------------------------------------------------------\* \> void KDZFalloffGuiData::Free(CDialog\* dlg, void\* userdata) \> //\*---------------------------------------------------------------------------\* \> { \>      if (!(dlg && userdata))     return; \>      KDZFalloffGui\*     sub =     static_cast<KDZFalloffGui\*>(userdata); \>      gDelete(sub); \> } \> //\*---------------------------------------------------------------------------\* \> CHAR\* KDZFalloffGuiData::GetResourceSym() \> //\*---------------------------------------------------------------------------\* \> { \>      return "KDZFALLOFFGRAPH"; \> } \> //\*---------------------------------------------------------------------------\* \> LONG KDZFalloffGuiData::GetResourceDataType(LONG\*& table) \> //\*---------------------------------------------------------------------------\* \> { \>      table =     restypetable; \>      return sizeof(restypetable)/sizeof(LONG); \> } \> \> \> // Global Registrant for KDZFalloff (CustomDataType and CustomGui) \> //\*---------------------------------------------------------------------------\* \> Bool RegisterKDZFalloff(void) \> //\*---------------------------------------------------------------------------\* \> { \>      RegisterDescription(CUSTOMDATATYPE_KDZFALLOFF, "Dkdzfalloff"); \>      static BaseCustomGuiLib     mylib; \>      ClearMem(&mylib;, sizeof(mylib)); \>      FillBaseCustomGui(mylib); \>      LONG     info =     CUSTOMDATATYPE_INFO_TOGGLEDISPLAY|CUSTOMDATATYPE_INFO_HASSUBDESCRIPTION|CUSTOMDATATYPE_INFO_UNDOSAMECUSTOMGUI; \>      return InstallLibrary(CUSTOMGUI_KDZFALLOFF, &mylib;, 1000L, sizeof(mylib)) && RegisterCustomDataTypePlugin("KDZ Falloff DataType", info, gNew KDZFalloffDataTypeClass, 0L) && RegisterCustomGuiPlugin("KDZ Falloff Gui", 0L, gNew KDZFalloffGuiData); \> }

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/11/2008 at 21:50, xxxxxxxx wrote:

Adding the GetProperties to both seems to have worked (just added the KDZ_FALLOFF_TYPE for now).

Of course, there is no GetResourceDataType() in the CustomDataTypeClass (or iCustomDataType). But I do have GetProperties() and GetResourceSym() in both CustomGuiData and CustomDataTypeClass and GetResourceDataType() in CustomGuiData.

Now the problem is working with the non-standard spline/GeUserArea. In C4D, they use the CustomSplineKnot in which to store the points in the appropriate class - but in my case, this spline will not necessarily be C4D-like. Just need the type and the points - stored in KDZFalloff.

Also, when I change the type, C4D crashes sometimes. Probably to do with storing the KDZFalloff* and using it. See, this is where I am confused. KDZFalloff stores the spline data while the GeUserArea (attached to iCustomGui) displays it and monitors user interaction. How does one go between these? I see that the SplineData has a Messages (and Function tables - but hopefully these are only for the library access). :)