High precision custom GUI for float

12 10 2009

As you probably know C4D is limited to 3 decimal places and thats frankly not enough in some situations.
So here’s some c++ code for the c4d plugin developer to get around that limitation. might be useful to some of you guys. maybe.

However its not possible to append unit strings (m, mm, °, etc.)

Looks like this:
High precision custom GUI for float

The code after the break…

The code:

#include "c4d.h"

const LONG CINDIGO_REAL_CUSTOMGUI = 1000001; //TODO: get plugin ID

static LONG restypetable[] = { DA_REAL };

class CindigoRealDlg : public iCustomGui
     {
          INSTANCEOF(CindigoRealDlg, iCustomGui)
     private:
          BaseContainer m_settings;
          
          Real m_real;
          Bool m_tristate;
          
     public:
          CindigoRealDlg(const BaseContainer &settings, CUSTOMGUIPLUGIN *plugin)
          : iCustomGui(settings, plugin), m_real(), m_tristate(false), m_settings(settings)
          {
               
          }

          virtual void CustomGuiRedraw()
          {
          }

          virtual void DestroyWindow(void)
          {

          }
          
          virtual Bool CreateLayout (void)
          {
               AddEditNumberArrows(1000,0,80,0);
               
               return TRUE;
          }
          
          virtual Bool SupportLayoutSwitch()
          {
               return FALSE;
          }
          
          virtual Bool InitValues()
          {
               SetUnclampedReal(m_real);

               return TRUE;
          }

          void SetUnclampedReal(Real r)
          {
               SetReal(1000, r);
               String s = RealToString(r,-1,5);

               //if r == 0.0 set 0
               if (r == 0.0) {
                    s = "0";
               } else {
                    //cut of trailing zeros
                    LONG i = 0;
                    for(i = s.GetLength()-1; i > 0; i--)
                    {
                         if (s[i] != '0') break;
                    }
                    s = s.SubStr(0, i+1);
               }

               SetString(1000, s);
          }
          
          virtual LONG Message(const BaseContainer& msg, BaseContainer& result)
          {
               if ((msg.GetId() == BFM_ACTION) && msg.GetLong(BFM_ACTION_ID) == 1000)
               {
                    if (msg.GetLong(BFM_ACTION_VALCHG) || msg.GetReal(BFM_ACTION_VALUE,MAXREAL) != MAXREAL)
                    {
                         m_real = msg.GetReal(BFM_ACTION_VALUE);

                         SetUnclampedReal(m_real);

                         return TRUE; //message processed
                    }
               }

               return GeDialog::Message(msg,result);
          }
          
          virtual Bool Command(LONG id, const BaseContainer& msg)
          {
               switch (id)
               {
               case 1000:
                    {
                         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;
          }
          
          virtual Bool SetData(const TriState &tristate)
          {
               m_real = tristate.GetValue().GetReal();
               m_tristate = tristate.GetTri();

               return TRUE;
          }
          
          virtual TriState GetData()
          {
               GetReal(1000, m_real);
               return GeData(m_real);
          }
     };

class CindigoRealGui : public CustomGuiData
     {
     public:
          virtual LONG GetId() { return CINDIGO_REAL_CUSTOMGUI; }
          
          virtual CDialog* Alloc(const BaseContainer &settings)
          {
               CindigoRealDlg* dlg = gNew CindigoRealDlg(settings, GetPlugin());
               if (!dlg) return NULL;
               
               CDialog *cdlg = dlg->Get();
               if (!cdlg) return NULL;
               
               return cdlg;
          }
          
          virtual void Free(CDialog *dlg, void *userdata)
          {
               if (!dlg || !userdata) return;
               CindigoRealDlg *sub = static_cast(userdata);
               gDelete(sub);
          }
          
#ifdef CINDIGO_C4D_VERSION_R115
          virtual const CHAR *GetResourceSym()
#else
          virtual CHAR *GetResourceSym()
#endif
          {
               return "CINDIGO_REAL_GUI";
          }
          
          virtual LONG GetResourceDataType(LONG *&table)
          {
               table = restypetable;
               return sizeof(restypetable)/sizeof(LONG);
          }
     };



Bool RegisterRealGUI()
{
     static BaseCustomGuiLib mylib;
     ClearMem(&mylib,sizeof(mylib));
     FillBaseCustomGui(mylib);
     
     return InstallLibrary(CINDIGO_REAL_CUSTOMGUI, &mylib, 1000, sizeof(mylib))
     
     &&
     
     RegisterCustomGuiPlugin("My String GUI", PLUGINFLAG_HIDE, gNew CindigoRealGui);
}

Actions

Information

3 responses

6 11 2009
pixie

I almost cried when I saw these pics… they’re just so beautiful!

25 11 2009
zeitmeister

Lange gewünscht, endlich da… riesendank und supergeil!
Longing for that for ages… and finally! Awesome, thanks a lot!

25 11 2009
fused21

haha, ja, leider hats es nicht in die Cindigo 2.2.8 geschafft. Das ganze ist ein ziemlich haesslicher hack und es hatte einfach zu viele macken. vielleicht im naechsten release 🙂

Leave a comment