iCustomGui reference
-
On 17/04/2017 at 02:35, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R14
Platform: Windows ;
Language(s) : C++ ;---------
Hi folks,I have a strange thing happening. I have an object plugin. Inside this object I store a BaseDocument (in memory only). This document will (usually) have another object of the same plugin-type in it's scene. The objects are not related, only that one is stored in a doc that's held in another's memory. When I want to edit the document in memory, I make a clone and stick it in the editor (via Insert/SetActiveDocument() using clone) and work on this copy in the viewport until finished.
Everything appears to correctly reference the right document. For example, when I select my object, base links in the AM gui have the correct objects in them, I can see this by changing one of the object names and the base link in the AM updates correctly. But my iCustomGui's are another thing. They're drawn in the same AM but they are referencing the object from the doc that's still in memory, that is, not the active one! All my iCustomGuis are doing this. Pressing one of my buttons in my iCustomGui's (that are drawn in the same AM) is actioning things on the doc in memory, not on the active document.
I've searched and searched, and searched more, but I can't find any rogue references anywhere. When I print the name of the parent object from inside the iCustomGui it prints the name of the object in memory, not the one from the active document, despite it being 'drawn' in the AM with other elements from the object in the active document.
I've never noticed this before. They have their own plugin IDs. They're drawn only from GetDDescription(). I set references to the object that 'owns' the iCustomGui in Init() using 'this' (see code example below). Why would my AM be drawing an iCustomGui in the same AM as a selected object in the current document, where the iCustomGui is from a different object in a completely different document?
Bool MyPlugin::GetDDescription(...) { // groups and other AM stuff here etc cid = DescLevel(ID_TAB_CUSTOM_GUI,DTYPE_LONG,0); if(!id || cid.IsPartOf(*id,NULL)) { // I've tried all sorts of things here.. BaseContainer bc = GetCustomDataTypeDefault(DTYPE_LONG); bc.SetLong(DESC_CUSTOMGUI,ID_MY_CUSTOMGUI); bc.SetBool(DESC_ALIGNLEFT,TRUE); bc.SetBool(DESC_FORBID_INLINE_FOLDING,TRUE); bc.SetBool(DESC_FORBID_SCALING,TRUE); bc.SetBool(DESC_NOGUISWITCH,TRUE); bc.SetLong(DESC_ANIMATE,DESC_ANIMATE_OFF); bc.SetBool(DESC_GUIOPEN,TRUE); bc.SetString(DESC_NAME,""); bc.SetString(DESC_SHORT_NAME,""); // this works, can read in correct custom gui consturctor, but is not "drawn" bc.SetVoid(ID_MY_OBJECT_ID,this); if(!description->SetParameter(cid,bc,DescLevel(ID_TAB_CUSTOM_GUI_GROUP))){return TRUE;} } return etc.. } // this is how I normally set the references, the iCustomGuis receive a valid, corect link Bool MyPlugin::Init(...) { GeData dvd; dvd.SetVoid(this); node->SetParameter(ID_TAB_CUSTOM_GUI_1,dvd,DESCFLAGS_SET_0); node->SetParameter(ID_TAB_CUSTOM_GUI_2,dvd,DESCFLAGS_SET_0); node->SetParameter(ID_TAB_CUSTOM_GUI_3,dvd,DESCFLAGS_SET_0); node->SetParameter(ID_TAB_CUSTOM_GUI_4,dvd,DESCFLAGS_SET_0); node->SetParameter(ID_TAB_CUSTOM_GUI_5,dvd,DESCFLAGS_SET_0); return TRUE; }
I'm sure it'll be a rookie mistake, but I just can't see it! Any ideas on what might cause this?
WP.
-
On 18/04/2017 at 02:56, xxxxxxxx wrote:
Hello,
in your code you are using the "this" pointer to store a reference to the instance of your NodeData based plugin. You shouldn't do that. The best way to store references to C4DAtom based objects is to use a BaseLink, which can also be stored in a BaseContainer.
But you should not store the data a custom GUI is displaying in the description BaseContainer as you do in GetDDescription(). A custom GUI element should display the data that is given to it (SetData()). This may be the data of one or many parameters (since you can select multiple elements of the same type). The data the custom GUI should display is stored in the given TriState, see the CustomGUI String example.
So if a custom GUI should handle a specific object somehow I guess the best way is to store the BaseLink to that object in the actual parameter the custom GUI element is displaying.
best wishes,
Sebastian -
On 19/04/2017 at 04:35, xxxxxxxx wrote:
Hi Seb,
Originally posted by xxxxxxxx
So if a custom GUI should handle a specific object somehow I guess the best way is to store the BaseLink to that object in the actual parameter the custom GUI element is displaying.
Could you elborate?
WP.
-
On 19/04/2017 at 09:18, xxxxxxxx wrote:
Hello,
a custom GUI typically displays the value of some parameter in the Attribute Manager. So if the custom GUI should display something relevant to a referenced object, why not apply this custom GUI to a parameter of the type DTYPE_BASELISTLINK.
best wishes,
Sebastian -
On 24/04/2017 at 03:51, xxxxxxxx wrote:
I'm passing the void link in the description basecontainer to the gui element, and am using it to set a iCustomGui class-level baselink (set in the custom gui's constructor). Seems to work - is this safe?
WP.
Edit: Fyi, I'm passing the node reference.
-
On 24/04/2017 at 09:18, xxxxxxxx wrote:
Hello,
as said above, one should always use a BaseLink to store a reference to an element. It is never save just to store a void pointer.
best wishes,
Sebastian -
On 26/04/2017 at 02:55, xxxxxxxx wrote:
Apologies, I should have just said passing 'link', not 'void link' (poor wording on my part!) - I changed to using the basecontainer SetLink().
There doesn't appear to be any more reference issues. Thanks Seb!
WP.