Gizmo Values Inside of Messages [SOLVED]



  • On 07/10/2014 at 14:20, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   13 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi,
    When the user changes a gizmo in a node based plugin. Is there a way to get the specific gizmo's new value from a message?

    Right now I have two ways to check if a specific gizmo was changed in a node based plugin:
    1- use a class member variable to poll the specific gizmo if the value is different
    2- Send out my own custom message if a gizmo was changed by the user

    Both of these are cumbersome. Because I'm getting the gizmo's value manually with my own custom hand written code.
    What If I have dozens of gizmo's I wanted to monitor?
    I would need to use dozens of class member variables. Or use dozens of unique message ID#s.

    The BFM messages in GeDialog plugins send out the value of the gizmo without needing to write our own polling code like above.
    This is very nice because we can retrieve the value directly from the message. But I don't see an equivalent for node type plugins.

      
    //GeDialog gizmos send out valuable information inside BFM messages besides just the generic "something was changed" message  
    //These messages carry information about the specific gizmo (ID & value) that the user is changing  
      
      BaseContainer msg;  
      LONG gizmoID = msg.GetLong(BFM_ACTION_ID);  
      GeData d = msg.GetData(BFM_ACTION_VALUE);  
      if(d.GetType() == DA_LONG) GePrint(LongToString(gizmoID) + " " + LongToString(msg.GetLong(BFM_ACTION_VALUE)));
    

    Is there an equivalent message we can use to get the changed gizmo's values like this when using node based plugin's?
    Writing custom polling code for each gizmo by hand seems silly to me.

    -ScottA



  • On 11/10/2014 at 09:48, xxxxxxxx wrote:

    Hi,
    I had thought NodeData would behave exactly like ObjectData (rather the other way around) in regards to messages. I have not set up a NodeData plugin to test it here (and I'll probably wait on your reply with doing so), though.
    But I'd expect to receive at least a MSG_DESCRIPTION_VALIDATE in Message(), when changing any parameter. Also a MSG_DESCRIPTION_CHECKUPDATE would be nice... you say, you don't receive these?



  • On 11/10/2014 at 14:51, xxxxxxxx wrote:

    Some BFM messages seem to work with both GeDialogs and node based plugins. And others don't.

    Here's an example that I hope illustrates the problem.

    Bool SimpleTag::Message(GeListNode *node, LONG type, void *data)  
    {  
      //Lets try to use BFM_ACTION_ID & BFM_ACTION_VALUE in a node type plugin (a tag)  
      //This works in GeDialogs and its gets the ID and gizmo value for whatever gizmo is being cahnged by the user  
      //But it doesn't seem to work in node based plugins  
      BaseContainer msg;  
      LONG gizmoID = msg.GetLong(BFM_ACTION_ID);  
      GePrint(LongToString(gizmoID));            //<--- Always prints zero!!!  
      
      //Trying to get the value of the gizmo that the user is changing  
      //Doesn't work  
      GeData d = msg.GetData(BFM_ACTION_VALUE);  
      if(d.GetType() == DA_LONG) GePrint(LongToString(gizmoID) + " " + LongToString(msg.GetLong(BFM_ACTION_VALUE)));  
      if(d.GetType() == DA_REAL) GePrint(RealToString(gizmoID) + " " + RealToString(msg.GetReal(BFM_ACTION_VALUE)));  
      
      
      //If I grab the specific gizmo manually with this getter function it does work  
      //However..this requires me to write a getter for every single gizmo *YUCK!  
      //GeDialogs use BFM_ACTION_VALUE which can grab the value without writing a getter for each gizmo *Nice  
      BaseTag    *tag = (BaseTag* )node;  
      
      Real value = tag->GetData().GetReal(MYSLIDER);  
      GePrint(RealToString(value));   //Works  
       
      tag->SetDirty(DIRTYFLAGS_DATA); //Used to update a Tag's AM GUI items  
      return TRUE;  
    }
    

    The BFM messages for GeDialogs seem to have the getters built into them. Which makes getting the values for the gimzo being changed a lot easier. With much less code.
    The mesages for node based plugins seem to require everything to be done by hand.
    Which can be quite lengthy code if you're watching a lot of gizmos.

    I was wondering if there was a shorter way to poll the gizmos in a node based plugin. To only get the value of the one gizmo being changed. Similar to how GeDialogs can get the values from the BFM messages?
    Keeping track of many gizmos with hand written getters, messages, or class member variables is sort of a mess when you have a dozen or so gizmos to monitor.

    -ScottA



  • On 12/10/2014 at 02:59, xxxxxxxx wrote:

    Hi Scott,
    I'm sorry, I thought your main concern was polling, where my understanding may be a little different.
    Anyway.. please try this in your Message() function and let me know, if it is at least close to what you are looking for:

      if (type == MSG_DESCRIPTION_CHECKUPDATE) {
        DescriptionCheckUpdate* pDCU = static_cast<DescriptionCheckUpdate*>(data);
        if (pDCU) {
          if (pDCU->descid->GetDepth()) {
            GePrint("CHECKUPDATE: " + LongToString((*pDCU->descid)[0].id));
          }
        }
      }
    

    NOTE: The code doesn't pay attention to more complex descriptions. It's just a quick shot, to see, if we are on the same track. I tested this in an ObjectData plugin, but i think it should work for basic NodeData as well.



  • On 12/10/2014 at 07:49, xxxxxxxx wrote:

    Yes!
    That's exactly what I was looking for.
    But it only gets the gizmo's ID. Can I also get the gizmo's value with this too?

    -ScottA



  • On 12/10/2014 at 07:52, xxxxxxxx wrote:

    Are you never satisfied? ;) Just kidding...
    I had thought via

    GetDParameter(GeListNode* node, const DescID& id, GeData& t_data, DESCFLAGS_GET& flags)
    


  • On 12/10/2014 at 08:11, xxxxxxxx wrote:

    Lol,
    Never mind I found it.
    Here's the entire thing that will return whatever gizmo is changed by the user.

    Bool SimpleTag::Message(GeListNode *node, LONG type, void *data)  
    {  
      BaseTag *tag = (BaseTag* )node;  
      
      if(type == MSG_DESCRIPTION_CHECKUPDATE)   
      {  
          DescriptionCheckUpdate *pDCU = static_cast<DescriptionCheckUpdate*>(data);  
          if(pDCU)   
          {  
              DescID idNum;   
              if(pDCU->descid->GetDepth())   
              {  
                  idNum = (*pDCU->descid)[0].id;  
                  GePrint("gizmo ID: " + LongToString( idNum[0].id) );  
              }               
                
              GeData d;  
              tag->GetParameter(DescID(idNum), d, DESCFLAGS_GET_0);  
              Real gizmoValue = d.GetReal();              
              GePrint(RealToString(gizmoValue));  
          }  
      }  
      
      return TRUE;  
    }
    

    I was dreading having to write tons of individual getters just to poll which gizmo was changed by the user.

    Thanks for the help.👍
    -ScottA



  • On 12/10/2014 at 08:16, xxxxxxxx wrote:

    You are welcome. Glad you didn't mind, on Sundays I sometimes get a little cheeky... 🙂
    And thanks for posting a final solution. I appreciate, this is what makes such threads valuable for future users.
    Will mark this as solved. We can always reopen later, if you have additional questions.


Log in to reply