How to communicate with iCustomGui?



  • On 24/02/2014 at 00:53, xxxxxxxx wrote:

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

    ---------
    Hi, I have a couple of questions regarding the iCustomGui.
    Thanks to Niklas' TriState example; i have come forward with this.
    https://github.com/nr-plugins/example-tristate-gui/tree/e090322e5ff3aca795254d74e1021213d7cf39e5

    But I still do not really know what this "Tristate" really is, it is a "convenience" Class according to the docs, but I still have no clue about how to use it.

    In my case, I am able to create the iCustomGui and paint to it, make some fun to do it, look here:

    The stupid thing is that I cannot really use it for anything meaningful. Yet.
    I have tried Niklas' example, but as nice looking as it is, it floats aroun in outer space, I am unable to communicate with it.

    This code

    virtual TriState<GeData> GetData()
    {
    return TriState<GeData>(GeData(12345));
    }
    

    makes sense, in the meaning that I am able to get hold of the value in the tag that is using he iCustomGui, like this:

    in the RES file:
    LONG TEST_CUSTOM_GUI {CUSTOMGUI ID_MY_TEST_GUI;} 
    and then in the tag, under Message()
    GeData geData;
    node->GetParameter(TEST_CUSTOM_GUI , geData, DESCFLAGS_GET_0);
    LONG testValue = geData.GetLong();
    // Here testValue is 12345 - which is correct
    

    So far, fairly good.

    But I have no idea how I can send data in the other direction.
    How do I alter (any) value in the iCustomgui, from my tag code?

    this

      virtual Bool SetData(const TriState<GeData> &tristate)
    {
    _MyTestGui_UA.Redraw();
    return TRUE;
    }
    

    is never fired.

    All in all - a complete example on how to use a iCustomGui inside something else than itself, is sorely needed. I must be able to send data in both directions, and have no idea how to do it.
    I also think that it is possible not only to send an integer back and forth, but to send whole structures (classes), like I can do with the SplineData gustom GUI. Right? It is here where the so called "convenience" Tristate thingie comes in, right?

    When I am at it, I would also like to add "ordinary" controls inside my iCustomGui, and I am sure this is possible too. Like a Real Slider.
    All in all, reading the docs all the weekend, searching the internet all over, many hours, I feel like I started programming yesterday, and not 15 years ago..
    Any help, is very much appreciated!
    If there is a plugin somewhere with sourcecode which uses the iCustomGui, even better! And the simpler the example, the better.

    Lastly - what does the word Tristate denote, what does it mean? Three states?

    Edit by NiklasR: Updated link to Tristate GUI Example.



  • On 24/02/2014 at 09:03, xxxxxxxx wrote:

    Are you asking how to do something like this?

    -ScottA



  • On 24/02/2014 at 09:47, xxxxxxxx wrote:

    Hi Scott!
    Nice animation! Looks great!
    To reply: No, this I can do now. I can invoke an action in the iCustomGui, and then read the result from the outside, albeit in a very rudimentary manner (a LONG or a Real).
    What I want is to do it the other way around, I want to change some data and make the iCustomGui respond accordingly.

    How can I explain this.. look at the image in my first post in this thread. Yo see the text Foo = 0. I want, from the outside, to change a value inside the iCustomGui, so that when I do this:

    	node->SetParameter(TEST_CUSTOM_GUI , GeData(2014), DESCFLAGS_SET_0);   
    

    my iCustomGui shows Foo = 2014.

    If I explain this poorly, please tell me!
    Basically - I want, from the outside, to set values inside the iCustomGui i.e. the UserArea.
    Just like we do it all the time we plugin writers when we set the value of GUI elements in the Init() functions in our tag plugins.
    It has to be a simple solution, it is just me that explain it poorly.



  • On 25/02/2014 at 01:12, xxxxxxxx wrote:

    Here is an update, I found this thread from August last year:
    https://plugincafe.maxon.net/topic/7379/8989_seeking-am-customgui-helpexample&KW=GetCustomDataType&PN=2

    It is a very long thread, and you folks fight almost the same problems I have.
    I myself have no problems with what is happening inside the CustomGui, when it comes to painting etc. It is communicating with the CustomGui that I have problems with.

    From the aforementioned thread:
    WickedP wrote:
    _Ok, I've stumped myself on this one. I can't get SetData() to call, or any auto-refreshing of the user area happening. I've tried my own custom functions and sending messages... and I just can't seem to get it to work without having to click in the user area itself in the attributes manager. Come to think of it, I don't think SetData() is even called when I 'load' the tool plugin.  
    _

    This is what I am fighting with myself too. I am just plain unable to alter any data in the  CustomGui because I cannot access it at all.
    So far I haven't found any code examples on how to use a CustomGui in, let us say, a tag plugin. I have the NiklasR Tristate example, which works fine on its own. But please, if Niklas or anyone else reading this - can you please provide an example on how to use this Tristate inside another plugin? How to alter the "traffic lights" from the outside?

    Here is an example of something that works:

         //Stores the data gotten from SplineData
        GeData gdSplineData(CUSTOMDATATYPE_SPLINE, DEFAULTVALUE);
     
      //Creates an instance of the SplineData class
        SplineData *spd = (SplineData* )gdSplineData.GetCustomDataType(CUSTOMDATATYPE_SPLINE); 
         if (!spd) **// For my own CustomGui classes, this is always null.  **
          return;
        CustomSplineKnot *knot1;   //The first spline knot
        CustomSplineKnot *knot2;   //The second spline knot
      
        spd->MakeLinearSplineBezier(2);
        
        spd->SetRange(0.0, 1.0, 0.01, 0.0, 1.0, 0.01);
      
        //Set The first spline knot's position to 0,0,0
        knot1 = spd->GetKnot(0);
        knot1->vPos = Vector(0, 0, 0);
        knot1->lFlagsSettings |= FLAG_KNOT_LOCK_X|ADD_KNOT_ADAPT_TANGENTS;
        knot1->vTangentRight = Vector(0.2, 0.0, 0);
      
        //Set The second spline knot's position to 100,100,0
        knot2 = spd->GetKnot(1);
        knot2->vPos = Vector(1, 1, 0);
        knot2->lFlagsSettings |= FLAG_KNOT_LOCK_X|ADD_KNOT_ADAPT_TANGENTS;
        knot2->vTangentLeft = Vector(-0.2, 0, 0);
      
        Bool success = node->SetParameter(DRBASETAG_SPLINE_SLIDESLICE, gdSplineData, DESCFLAGS_SET_0);
    

    This works!!
    But I am completely unable to make it work for my own CustomGui classes, se the comment "For my own CustomGui classes, it is always null" in the code.
    _ Any_ examples complete with source code on how to make this work, **_for home made  _**CustomGui classes, is sorely needed.
    I have searched the Internet, searched all source code in my R13, R14, and R15  SDK libraries, there are several ways to do this, but I always get a NULL as the result. I seems I can never get my own CustomGuiData classes instantiated. In any way.



  • On 25/02/2014 at 11:14, xxxxxxxx wrote:

    I am throwing in the towel now, on this one, I will start a new thread, because this is cluttered with (mostly) my messages.



  • On 03/03/2014 at 12:29, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Are you asking how to do something like this?

    -ScottA

    Hi Scott,
    could you show us how you have done this?

    -Pim



  • On 03/03/2014 at 13:49, xxxxxxxx wrote:

    Hi Pim,

    It's done by creating a iCustomDataType plugin. Which adds the slider to the list of available UserData gizmos.
    I'd be happy to post the plugin on my site for anyone that wants it. But Niklas provided most of the code I'm using in it. And I wouldn't feel right posting it without his consent.

    There is an example in the SDK called datatype.cpp that you can try to learn from.
    But it's a bit hard to follow because there's no comments in it like I put in my plugins.

    -ScottA



  • On 03/03/2014 at 14:13, xxxxxxxx wrote:

    Hi Scott,
    I would be very interested to see how you implemented this. Because I thought I did not need that "datatype" at all, to make this work.
    Any information on the iCustomGui and related objects / classes / structures is very much welcome. As a starter, an overview on what they do, and why they are needed, would be very welcome. The SDK docs have a few lines, for me that is far from enough, I do not really understand the purpose of some of the classes. Not to mention how to use them.



  • On 03/03/2014 at 14:31, xxxxxxxx wrote:

    Well...Talk to Niklas guys.
    If he doesn't mind me posting a plugin that's 95% his code. I'll post it.
    It's really up to him.

    -ScottA



  • On 03/03/2014 at 22:50, xxxxxxxx wrote:

    Thank you Scott for waiting for my permission. Yes, you may make it public :-)

    Best,
    -Niklas



  • On 04/03/2014 at 00:47, xxxxxxxx wrote:

    Great, thanks guys.



  • On 04/03/2014 at 01:27, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Thank you Scott for waiting for my permission. Yes, you may make it public :-)

    Fantastic, thanks! :)



  • On 04/03/2014 at 08:53, xxxxxxxx wrote:

    Ok guys. You can grab it here.
    https://sites.google.com/site/scottayersmedia/plugins

    I don't own a mac. So it's only compiled for Windows.
    But the source code is what you really want anyway. 😉

    -ScottA



  • On 04/03/2014 at 10:41, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Ok guys. You can grab it here.
    But the source code is what you really want anyway. 😉

    Right! And thank you so much! I have seen similar things, like Niklas' Tristate example. The comments in the source code are what makes it so valuable, so I learnt from  this!

    What I am after, and what I meant with the thread topic title, is how to communicate with the iCustomGui when you have several gadgets in the same iCustmGui.
    Look here, I extended Scott's User Data, by adding a Real Slider:

    	virtual Bool CreateLayout()
    	{
    		//Attach the User Area to the custom GUI gizmo
    		AddUserArea(1000, BFH_SCALEFIT, 0, 0);
    		AttachUserArea(ua, 1000);
    		 **AddEditSlider(1001, BFH_SCALEFIT, 80);**
    		return TRUE;
    	}
    

    But when using xpresso, I only have access to Scott's slider, not the added slider:

     
    This is not a topic when using UserData like this. But it becomes interesting when using it in a RES file, to add gadgets to you tag.
    While I now can send a few real values back and forth between my tag and the iCustomGui, I cannot replicate the SplineData behaviour, if you are familiar with that one.

    So my initial question in this thread remains, I do not know how to properly send data from my tag plugin to my iCustomGui, and read those data back, when the iCustomGui has several gadgets.
    I have managed to do it somehow, but, I am almost sure, in an inadequate way.

    A full working example on how to do this, is what I want, with all files involved. It doesn't have to be fancy, actually just two Real gadgets wold do. I must be able to set the values of both from my tag, read back the values again, after they are changed by the user. And they must remember their positions when
    a) the project is saved and closed, b) another tag is selected so that it loses focus.

    I am still almost in start position on this task, unfortunately.



  • On 04/03/2014 at 11:32, xxxxxxxx wrote:

    Yeah.
    Controlling the gizmo if it's added within the .res file and not with the UserData is still not known to me yet.
    And one reason why I keep asking Maxon for an example of their slider gui code. So we can see what they're doing in there to make that work.
    I get turned down every time I ask them for the code.

    -ScottA



  • On 04/03/2014 at 12:22, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Yeah.
    Controlling the gizmo if it's added within the .res file and not with the UserData is still not known to me yet.

    I know how to do it in a way, but I doubt it is the correct way.

    Originally posted by xxxxxxxx

    Yeah.
    And one reason why I keep asking Maxon for an example of their slider gui code. So we can see what they're doing in there to make that work.
    I get turned down every time I ask them for the code.

    Well, I sent a mail ti dev support, - total silence..
    One might think it would benefit Maxon, the end user - and us plugin writers - if we were taught how to do it the correct way. Well, maybe they do not have working examples, and I guess they have their days filled up..



  • On 04/03/2014 at 12:39, xxxxxxxx wrote:

    Oh shoot.
    I forgot to add this to the notes in the code. But I do know how to poll the slider's values when using this gizmo when it's created in the .res file instead of the UserData pallet.
    I know you want to go the other direction and control the slider itself.
    But this is how to get the value of the custom slider if it's been created in a .res file.

    Lets say that you're creating a tag plugin and you want to use this custom slider by creating it in the tag's .res file.
    This is what the .res file should look like:

    CONTAINER tsimpletag  
    {  
      NAME tsimpletag;  
      INCLUDE Texpression;  
        
        
      GROUP ID_TAGPROPERTIES   //The default tab named "TAB"  
      {  
         //"MYSLIDER" is the ID for the CUSTOMGUI gizmo hard coded within it's source code  
         LONG MY_SLIDER_GIZMO { CUSTOMGUI MYSLIDER; MIN 0;}    
      }  
    }
    

    Then in one of your tag's methods you can get the value of the slider like this:

    Bool MyTag::Message(GeListNode *node, LONG type, void *data)  
    {  
      BaseTag *tag = (BaseTag* )node;                                    //Get the tag and assign it to a variable  
      BaseContainer *tagdata = ((BaseList2D* )node)->GetDataInstance();  //Get the container for the tag  
      
      LONG sv = tagdata->GetLong(MY_SLIDER_GIZMO);  
      
      //The value is very large(in pixels) so we chop it down to return 0-10  
      sv = sv/200000000;  
      GePrint(LongToString(sv));  
       
      tag->SetDirty(DIRTYFLAGS_DATA); //Used to update a Tag's AM GUI items  
      return TRUE;  
    }
    

    Not really what you're asking for.
    But most people will probably just want to get the value of the slider. And that how to do it.
    I should have included that information in the notes.

    -ScottA



  • On 25/03/2014 at 03:22, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    What I am after, and what I meant with the thread topic title, is how to communicate with the iCustomGui when you have several gadgets in the same iCustmGui.
    Look here, I extended Scott's User Data, by adding a Real Slider:

    	virtual Bool CreateLayout()
    	{
    		//Attach the User Area to the custom GUI gizmo
    		AddUserArea(1000, BFH_SCALEFIT, 0, 0);
    		AttachUserArea(ua, 1000);
    		 **AddEditSlider(1001, BFH_SCALEFIT, 80);**
    		return TRUE;
    	}
    

    But when using xpresso, I only have access to Scott's slider, not the added slider:

     
    This is not a topic when using UserData like this. But it becomes interesting when using it in a RES file, to add gadgets to you tag.
    While I now can send a few real values back and forth between my tag and the iCustomGui, I cannot replicate the SplineData behaviour, if you are familiar with that one.

    So my initial question in this thread remains, I do not know how to properly send data from my tag plugin to my iCustomGui, and read those data back, when the iCustomGui has several gadgets.
    I have managed to do it somehow, but, I am almost sure, in an inadequate way.

    A full working example on how to do this, is what I want, with all files involved. It doesn't have to be fancy, actually just two Real gadgets wold do. I must be able to set the values of both from my tag, read back the values again, after they are changed by the user. And they must remember their positions when
    a) the project is saved and closed, b) another tag is selected so that it loses focus.

    I am still almost in start position on this task, unfortunately.

    Have you created an iCustomDataType for your iCustomGUI? Since you now display two values in
    your GUI, it can not be represented by a single float value anymore which is why it needs its own
    new datatype.

    Best,
    -Niklas



  • On 25/03/2014 at 03:37, xxxxxxxx wrote:

    Hi Niklas,
    > Have you created an iCustomDataType for your iCustomGUI?
    Yes, I tried at least.

    _> Since you now display two values in  your GUI, it can not be _
    > represented by a single float value anymore
    I understand this!

    > which is why it needs its own new datatype.
    I understand this too!

    What I need, is a fully working example on how to do this.
    It is a long time since I posted my first question in this thread, and in the mean time, I have found a sort of a solution by passing a BaseContainer between my Tag plugin, and my iCustomGui. But I still do not know how to employ the iCustomDataType.

    So on my wishlist is a fully working example on how to communuiate between a BaseTag and a iCustomGui, using the iCustomDataType. Because this is still Greek to me..



  • On 25/03/2014 at 03:52, xxxxxxxx wrote:

    Hi Ingvar,

    out of interest, how do you communicate between your Tag and iCustomGui?

    I'll try to make an example this week, it is on my Todo list.

    Best,
    -Niklas


Log in to reply