Changing description button text? [SOLVED]

On 07/11/2015 at 18:25, xxxxxxxx wrote:

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

The plugin is a generator object and there is a need to do a preliminary phase that 'constructs' the data that the object then uses to create geometry.  In that effort, the user clicks a button to start the preliminary phase and then clicks that button again to stop the process.  Using a GeDialog in the past, the button text could simply be changed to reflect the state of the process.  But it is proving difficult to do the same with a description button that is defined in the .res for the object.  Here is the code attempt in GetDDescription() :

	if (m_bSetButton)
		GeData	data;
		obj->GetParameter(DescID(V4DOBJECT_GROWING), data, DESCFLAGS_GET_0);
		BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);
		if (data.GetBool())
			GePrint("GetDDescription Growing");
			bc.SetString(DESC_SHORT_NAME, "Growing...");
			bc.SetString(DESC_NAME, "Growing...");
			description->SetParameter(DescID(V4DOBJECT_GROW, DTYPE_BUTTON, 0), bc, DescLevel(ID_OBJECTPROPERTIES));
			GePrint("GetDDescription Stop Growing");
			bc.SetString(DESC_SHORT_NAME, "Start Growth Phase");
			bc.SetString(DESC_NAME, "Start Growth Phase");
			description->SetParameter(DescID(V4DOBJECT_GROW, DTYPE_BUTTON, 0), bc, DescLevel(ID_OBJECTPROPERTIES));
		m_bSetButton =	FALSE;

It does not change the button text at all.  If need be, I could employ the Status... system, but it requires the user to notice offhand that the button has initiated the process or stopped the process.  The look-and-feel is not very intuitive from that perspective.

Any ideas?

On 08/11/2015 at 00:24, xxxxxxxx wrote:

don't know why it doesn't work, I guess it should work fine "at least if you define it inside the GetDDescription()"

On 08/11/2015 at 01:08, xxxxxxxx wrote:

Setting m_bSetButton from GetDDescription() looks very sus**cious.
If the button is already defined the in .res file, you want to change the
item description returned by Description::GetParameterI().


Update: Any idea why s u s p i c i o u s is censored? :')

On 08/11/2015 at 05:17, xxxxxxxx wrote:

m_bSetButton is simply a class member variable that is set to TRUE in order to change the button text when the button is clicked (in Message()) and set to FALSE after that change to avoid a lock up in GetDDescription() as it is continually checked there otherwise.  The text only needs to be changed if the button is clicked and at no other time.  I am seeing the GePrint() statements as expected so the logic is good.

I thought about GetParameterI() but that is not how I have done this with dynamic buttons in the past.

On 08/11/2015 at 08:06, xxxxxxxx wrote:

You're having a wrong idea about GetDDescription(). Changes you make
to the Description at a time are not kept for the next time the function is
called. It is rebuilt from scratch every time.

On 08/11/2015 at 17:24, xxxxxxxx wrote:

That is a good point, especially with LoadDescription().  Maybe it will need to be a dynamic description after all (argh!).

On 09/11/2015 at 02:17, xxxxxxxx wrote:


as already said, the Description object you edit in GetDDescription is not stored anywhere but re-created all over again, every time some element is asking for the Description using GetDescription().

To edit a description element already found in the Description (for example after using LoadDescription()) you can use GetParameterI(). Something like this:

BaseContainer* bc;  
bc = desc->GetParameterI(DescLevel(BUTTON_A), nullptr);  
if (bc)  
 bc->SetString(DESC_SHORT_NAME, "This is the new button Label.");  

Also, don't forget to set the flag:


best wishes,

On 09/11/2015 at 04:01, xxxxxxxx wrote:

That does the trick.  And no need for m_bSetButton to avoid a lockup.  If only the descriptions were as easy to work with as the dialog gui elements.

On 09/11/2015 at 04:35, xxxxxxxx wrote:

Well, you could host a Description in your NodeData plugin that would keep all the changes you make,
and copy it in GetDDescription(). 🙂